The common part of rtwn(4) needs help from attachment drivers to determine the chip type. The PCI/USB driver parts must detect the chip type based on PCI/USB vendor and device IDs. There seems to be no other way of doing this. Even the Linux vendor driver does it this way.
The common part is still responsible for details of a particular chip type, such as the amount of transmit and receive chains provided by the chip. This paves the way for future 8188EE chip support in ic/rtwn.c. Tested on 8188CE (RTWN_CHIP_88C, PCI). Index: ic/rtwn.c =================================================================== RCS file: /cvs/src/sys/dev/ic/rtwn.c,v retrieving revision 1.5 diff -u -p -r1.5 rtwn.c --- ic/rtwn.c 15 Mar 2016 10:28:31 -0000 1.5 +++ ic/rtwn.c 19 Mar 2016 13:30:03 -0000 @@ -84,7 +84,7 @@ uint32_t rtwn_rf_read(struct rtwn_softc void rtwn_cam_write(struct rtwn_softc *, uint32_t, uint32_t); uint8_t rtwn_efuse_read_1(struct rtwn_softc *, uint16_t); void rtwn_efuse_read(struct rtwn_softc *); -int rtwn_read_chipid(struct rtwn_softc *); +int rtwn_read_chipid(struct rtwn_softc *, uint32_t); void rtwn_read_rom(struct rtwn_softc *); int rtwn_media_change(struct ifnet *); int rtwn_ra_init(struct rtwn_softc *); @@ -140,7 +140,7 @@ void rtwn_stop(struct ifnet *); #define rtwn_bb_read rtwn_read_4 int -rtwn_attach(struct device *pdev, struct rtwn_softc *sc) +rtwn_attach(struct device *pdev, struct rtwn_softc *sc, uint32_t chip_type) { struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = &ic->ic_if; @@ -150,17 +150,21 @@ rtwn_attach(struct device *pdev, struct task_set(&sc->init_task, rtwn_init_task, sc); - error = rtwn_read_chipid(sc); + error = rtwn_read_chipid(sc, chip_type); if (error != 0) { printf("%s: unsupported test chip\n", sc->sc_pdev->dv_xname); return (ENXIO); } + if (sc->chip == 0) { + printf("%s: could not read chip ID\n", sc->sc_pdev->dv_xname); + return (ENXIO); + } /* Determine number of Tx/Rx chains. */ if (sc->chip & RTWN_CHIP_92C) { sc->ntxchains = (sc->chip & RTWN_CHIP_92C_1T2R) ? 1 : 2; sc->nrxchains = 2; - } else { + } else if (sc->chip & RTWN_CHIP_88C) { sc->ntxchains = 1; sc->nrxchains = 1; } @@ -475,9 +479,8 @@ rtwn_efuse_read(struct rtwn_softc *sc) #endif } -/* rtwn_read_chipid: reg=0x40073b chipid=0x0 */ int -rtwn_read_chipid(struct rtwn_softc *sc) +rtwn_read_chipid(struct rtwn_softc *sc, uint32_t chip_type) { uint32_t reg; @@ -486,18 +489,22 @@ rtwn_read_chipid(struct rtwn_softc *sc) /* Unsupported test chip. */ return (EIO); - if (reg & R92C_SYS_CFG_TYPE_92C) { - sc->chip |= RTWN_CHIP_92C; - /* Check if it is a castrated 8192C. */ - if (MS(rtwn_read_4(sc, R92C_HPON_FSM), - R92C_HPON_FSM_CHIP_BONDING_ID) == - R92C_HPON_FSM_CHIP_BONDING_ID_92C_1T2R) - sc->chip |= RTWN_CHIP_92C_1T2R; - } - if (reg & R92C_SYS_CFG_VENDOR_UMC) { - sc->chip |= RTWN_CHIP_UMC; - if (MS(reg, R92C_SYS_CFG_CHIP_VER_RTL) == 0) - sc->chip |= RTWN_CHIP_UMC_A_CUT; + if ((chip_type & (RTWN_CHIP_92C | RTWN_CHIP_88C)) != 0) { + if (reg & R92C_SYS_CFG_TYPE_92C) { + sc->chip = RTWN_CHIP_92C; + /* Check if it is a castrated 8192C. */ + if (MS(rtwn_read_4(sc, R92C_HPON_FSM), + R92C_HPON_FSM_CHIP_BONDING_ID) == + R92C_HPON_FSM_CHIP_BONDING_ID_92C_1T2R) + sc->chip |= RTWN_CHIP_92C_1T2R; + } else + sc->chip = RTWN_CHIP_88C; + + if (reg & R92C_SYS_CFG_VENDOR_UMC) { + sc->chip |= RTWN_CHIP_UMC; + if (MS(reg, R92C_SYS_CFG_CHIP_VER_RTL) == 0) + sc->chip |= RTWN_CHIP_UMC_A_CUT; + } } return (0); } Index: ic/rtwnvar.h =================================================================== RCS file: /cvs/src/sys/dev/ic/rtwnvar.h,v retrieving revision 1.4 diff -u -p -r1.4 rtwnvar.h --- ic/rtwnvar.h 15 Mar 2016 10:28:31 -0000 1.4 +++ ic/rtwnvar.h 19 Mar 2016 12:14:43 -0000 @@ -49,16 +49,17 @@ struct rtwn_softc { enum ieee80211_state, int); struct task init_task; int ac2idx[EDCA_NUM_AC]; - u_int sc_flags; + uint32_t sc_flags; #define RTWN_FLAG_CCK_HIPWR 0x01 #define RTWN_FLAG_BUSY 0x02 - u_int chip; -#define RTWN_CHIP_88C 0x00 + uint32_t chip; #define RTWN_CHIP_92C 0x01 #define RTWN_CHIP_92C_1T2R 0x02 #define RTWN_CHIP_UMC 0x04 #define RTWN_CHIP_UMC_A_CUT 0x08 +#define RTWN_CHIP_88C 0x10 +#define RTWN_CHIP_88E 0x20 uint8_t board_type; uint8_t regulatory; @@ -77,7 +78,7 @@ struct rtwn_softc { uint32_t rf_chnlbw[R92C_MAX_CHAINS]; }; -int rtwn_attach(struct device *, struct rtwn_softc *); +int rtwn_attach(struct device *, struct rtwn_softc *, uint32_t); int rtwn_detach(struct rtwn_softc *, int); int rtwn_activate(struct rtwn_softc *, int); int8_t rtwn_get_rssi(struct rtwn_softc *, int, void *); Index: pci/if_rtwn.c =================================================================== RCS file: /cvs/src/sys/dev/pci/if_rtwn.c,v retrieving revision 1.19 diff -u -p -r1.19 if_rtwn.c --- pci/if_rtwn.c 15 Mar 2016 10:28:32 -0000 1.19 +++ pci/if_rtwn.c 19 Mar 2016 12:09:01 -0000 @@ -351,7 +351,7 @@ rtwn_pci_attach(struct device *parent, s sc->sc_sc.sc_ops.next_scan = rtwn_pci_next_scan; sc->sc_sc.sc_ops.cancel_scan = rtwn_cancel_scan; - error = rtwn_attach(&sc->sc_dev, &sc->sc_sc); + error = rtwn_attach(&sc->sc_dev, &sc->sc_sc, RTWN_CHIP_88C); if (error != 0) { rtwn_free_rx_list(sc); for (i = 0; i < RTWN_NTXQUEUES; i++)