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++)

Reply via email to