The urtwn(4) driver does different things to init dma. So it seems better
to move all DMA init code into the bus-specific part of the driver, not
just a small part of it.
Tested on:
MAC/BB RTL8188CE, RF 6052 1T1R
Index: ic/rtwn.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/rtwn.c,v
retrieving revision 1.3
diff -u -p -r1.3 rtwn.c
--- ic/rtwn.c 9 Mar 2016 20:36:16 -0000 1.3
+++ ic/rtwn.c 11 Mar 2016 12:36:06 -0000
@@ -58,14 +58,6 @@
#include <dev/ic/r92creg.h>
#include <dev/ic/rtwnvar.h>
-#define R92C_PUBQ_NPAGES 176
-#define R92C_HPQ_NPAGES 41
-#define R92C_LPQ_NPAGES 28
-#define R92C_TXPKTBUF_COUNT 256
-#define R92C_TX_PAGE_COUNT \
- (R92C_PUBQ_NPAGES + R92C_HPQ_NPAGES + R92C_LPQ_NPAGES)
-#define R92C_TX_PAGE_BOUNDARY (R92C_TX_PAGE_COUNT + 1)
-
#define RTWN_RIDX_COUNT 28
#define RTWN_LED_LINK 0
@@ -90,7 +82,6 @@ int rtwn_fw_cmd(struct rtwn_softc *, ui
void rtwn_rf_write(struct rtwn_softc *, int, uint8_t, uint32_t);
uint32_t rtwn_rf_read(struct rtwn_softc *, int, uint8_t);
void rtwn_cam_write(struct rtwn_softc *, uint32_t, uint32_t);
-int rtwn_llt_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 *);
@@ -113,11 +104,9 @@ void rtwn_start(struct ifnet *);
void rtwn_watchdog(struct ifnet *);
int rtwn_ioctl(struct ifnet *, u_long, caddr_t);
int rtwn_power_on(struct rtwn_softc *);
-int rtwn_llt_init(struct rtwn_softc *);
void rtwn_fw_reset(struct rtwn_softc *);
int rtwn_fw_loadpage(struct rtwn_softc *, int, uint8_t *, int);
int rtwn_load_firmware(struct rtwn_softc *);
-int rtwn_dma_init(struct rtwn_softc *);
void rtwn_mac_init(struct rtwn_softc *);
void rtwn_bb_init(struct rtwn_softc *);
void rtwn_rf_init(struct rtwn_softc *);
@@ -416,25 +405,6 @@ rtwn_cam_write(struct rtwn_softc *sc, ui
SM(R92C_CAMCMD_ADDR, addr));
}
-int
-rtwn_llt_write(struct rtwn_softc *sc, uint32_t addr, uint32_t data)
-{
- int ntries;
-
- rtwn_write_4(sc, R92C_LLT_INIT,
- SM(R92C_LLT_INIT_OP, R92C_LLT_INIT_OP_WRITE) |
- SM(R92C_LLT_INIT_ADDR, addr) |
- SM(R92C_LLT_INIT_DATA, data));
- /* Wait for write operation to complete. */
- for (ntries = 0; ntries < 20; ntries++) {
- if (MS(rtwn_read_4(sc, R92C_LLT_INIT), R92C_LLT_INIT_OP) ==
- R92C_LLT_INIT_OP_NO_ACTIVE)
- return (0);
- DELAY(5);
- }
- return (ETIMEDOUT);
-}
-
uint8_t
rtwn_efuse_read_1(struct rtwn_softc *sc, uint16_t addr)
{
@@ -1340,32 +1310,6 @@ rtwn_power_on(struct rtwn_softc *sc)
return (0);
}
-int
-rtwn_llt_init(struct rtwn_softc *sc)
-{
- int i, error;
-
- /* Reserve pages [0; R92C_TX_PAGE_COUNT]. */
- for (i = 0; i < R92C_TX_PAGE_COUNT; i++) {
- if ((error = rtwn_llt_write(sc, i, i + 1)) != 0)
- return (error);
- }
- /* NB: 0xff indicates end-of-list. */
- if ((error = rtwn_llt_write(sc, i, 0xff)) != 0)
- return (error);
- /*
- * Use pages [R92C_TX_PAGE_COUNT + 1; R92C_TXPKTBUF_COUNT - 1]
- * as ring buffer.
- */
- for (++i; i < R92C_TXPKTBUF_COUNT - 1; i++) {
- if ((error = rtwn_llt_write(sc, i, i + 1)) != 0)
- return (error);
- }
- /* Make the last page point to the beginning of the ring buffer. */
- error = rtwn_llt_write(sc, i, R92C_TX_PAGE_COUNT + 1);
- return (error);
-}
-
void
rtwn_fw_reset(struct rtwn_softc *sc)
{
@@ -1525,54 +1469,6 @@ rtwn_load_firmware(struct rtwn_softc *sc
return (error);
}
-int
-rtwn_dma_init(struct rtwn_softc *sc)
-{
- uint32_t reg;
- int error;
-
- /* Initialize LLT table. */
- error = rtwn_llt_init(sc);
- if (error != 0)
- return error;
-
- /* Set number of pages for normal priority queue. */
- rtwn_write_2(sc, R92C_RQPN_NPQ, 0);
- rtwn_write_4(sc, R92C_RQPN,
- /* Set number of pages for public queue. */
- SM(R92C_RQPN_PUBQ, R92C_PUBQ_NPAGES) |
- /* Set number of pages for high priority queue. */
- SM(R92C_RQPN_HPQ, R92C_HPQ_NPAGES) |
- /* Set number of pages for low priority queue. */
- SM(R92C_RQPN_LPQ, R92C_LPQ_NPAGES) |
- /* Load values. */
- R92C_RQPN_LD);
-
- rtwn_write_1(sc, R92C_TXPKTBUF_BCNQ_BDNY, R92C_TX_PAGE_BOUNDARY);
- rtwn_write_1(sc, R92C_TXPKTBUF_MGQ_BDNY, R92C_TX_PAGE_BOUNDARY);
- rtwn_write_1(sc, R92C_TXPKTBUF_WMAC_LBK_BF_HD, R92C_TX_PAGE_BOUNDARY);
- rtwn_write_1(sc, R92C_TRXFF_BNDY, R92C_TX_PAGE_BOUNDARY);
- rtwn_write_1(sc, R92C_TDECTRL + 1, R92C_TX_PAGE_BOUNDARY);
-
- reg = rtwn_read_2(sc, R92C_TRXDMA_CTRL);
- reg &= ~R92C_TRXDMA_CTRL_QMAP_M;
- reg |= 0xF771;
- rtwn_write_2(sc, R92C_TRXDMA_CTRL, reg);
-
- rtwn_write_4(sc, R92C_TCR, R92C_TCR_CFENDFORM | (1 << 12) | (1 << 13));
-
- sc->sc_ops.configure_dma(sc->sc_ops.cookie);
-
- /* Set Tx/Rx transfer page boundary. */
- rtwn_write_2(sc, R92C_TRXFF_BNDY + 2, 0x27ff);
-
- /* Set Tx/Rx transfer page size. */
- rtwn_write_1(sc, R92C_PBP,
- SM(R92C_PBP_PSRX, R92C_PBP_128) |
- SM(R92C_PBP_PSTX, R92C_PBP_128));
- return (0);
-}
-
void
rtwn_mac_init(struct rtwn_softc *sc)
{
@@ -2492,7 +2388,7 @@ rtwn_init(struct ifnet *ifp)
}
/* Initialize DMA. */
- error = rtwn_dma_init(sc);
+ error = sc->sc_ops.dma_init(sc->sc_ops.cookie);
if (error != 0) {
printf("%s: could not initialize DMA\n",
sc->sc_pdev->dv_xname);
Index: ic/rtwnvar.h
===================================================================
RCS file: /cvs/src/sys/dev/ic/rtwnvar.h,v
retrieving revision 1.2
diff -u -p -r1.2 rtwnvar.h
--- ic/rtwnvar.h 9 Mar 2016 20:36:16 -0000 1.2
+++ ic/rtwnvar.h 11 Mar 2016 12:14:07 -0000
@@ -29,7 +29,7 @@ struct rtwn_ops {
void (*write_4)(void *, uint16_t, uint32_t);
void (*next_scan)(void *);
int (*tx)(void *, struct mbuf *, struct ieee80211_node *);
- int (*configure_dma)(void *);
+ int (*dma_init)(void *);
void (*enable_intr)(void *);
void (*disable_intr)(void *);
void (*stop)(void *);
Index: pci/if_rtwn.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_rtwn.c,v
retrieving revision 1.17
diff -u -p -r1.17 if_rtwn.c
--- pci/if_rtwn.c 9 Mar 2016 20:36:16 -0000 1.17
+++ pci/if_rtwn.c 11 Mar 2016 12:37:05 -0000
@@ -61,6 +61,15 @@
/*
* Driver definitions.
*/
+
+#define R92C_PUBQ_NPAGES 176
+#define R92C_HPQ_NPAGES 41
+#define R92C_LPQ_NPAGES 28
+#define R92C_TXPKTBUF_COUNT 256
+#define R92C_TX_PAGE_COUNT \
+ (R92C_PUBQ_NPAGES + R92C_HPQ_NPAGES + R92C_LPQ_NPAGES)
+#define R92C_TX_PAGE_BOUNDARY (R92C_TX_PAGE_COUNT + 1)
+
#define RTWN_NTXQUEUES 9
#define RTWN_RX_LIST_COUNT 256
#define RTWN_TX_LIST_COUNT 256
@@ -218,7 +227,9 @@ void rtwn_tx_done(struct rtwn_pci_softc
void rtwn_pci_stop(void *);
int rtwn_intr(void *);
int rtwn_is_oactive(void *);
-int rtwn_configure_dma(void *);
+int rtwn_llt_write(struct rtwn_pci_softc *, uint32_t, uint32_t);
+int rtwn_llt_init(struct rtwn_pci_softc *);
+int rtwn_dma_init(void *);
void rtwn_enable_intr(void *);
void rtwn_disable_intr(void *);
@@ -320,7 +331,7 @@ rtwn_pci_attach(struct device *parent, s
sc->sc_sc.sc_ops.read_4 = rtwn_pci_read_4;
sc->sc_sc.sc_ops.next_scan = rtwn_pci_next_scan;
sc->sc_sc.sc_ops.tx = rtwn_tx;
- sc->sc_sc.sc_ops.configure_dma = rtwn_configure_dma;
+ sc->sc_sc.sc_ops.dma_init = rtwn_dma_init;
sc->sc_sc.sc_ops.enable_intr = rtwn_enable_intr;
sc->sc_sc.sc_ops.disable_intr = rtwn_disable_intr;
sc->sc_sc.sc_ops.stop = rtwn_pci_stop;
@@ -1177,9 +1188,88 @@ rtwn_is_oactive(void *cookie)
}
int
-rtwn_configure_dma(void *cookie)
+rtwn_llt_write(struct rtwn_pci_softc *sc, uint32_t addr, uint32_t data)
+{
+ int ntries;
+
+ rtwn_pci_write_4(sc, R92C_LLT_INIT,
+ SM(R92C_LLT_INIT_OP, R92C_LLT_INIT_OP_WRITE) |
+ SM(R92C_LLT_INIT_ADDR, addr) |
+ SM(R92C_LLT_INIT_DATA, data));
+ /* Wait for write operation to complete. */
+ for (ntries = 0; ntries < 20; ntries++) {
+ if (MS(rtwn_pci_read_4(sc, R92C_LLT_INIT), R92C_LLT_INIT_OP) ==
+ R92C_LLT_INIT_OP_NO_ACTIVE)
+ return (0);
+ DELAY(5);
+ }
+ return (ETIMEDOUT);
+}
+
+int
+rtwn_llt_init(struct rtwn_pci_softc *sc)
+{
+ int i, error;
+
+ /* Reserve pages [0; R92C_TX_PAGE_COUNT]. */
+ for (i = 0; i < R92C_TX_PAGE_COUNT; i++) {
+ if ((error = rtwn_llt_write(sc, i, i + 1)) != 0)
+ return (error);
+ }
+ /* NB: 0xff indicates end-of-list. */
+ if ((error = rtwn_llt_write(sc, i, 0xff)) != 0)
+ return (error);
+ /*
+ * Use pages [R92C_TX_PAGE_COUNT + 1; R92C_TXPKTBUF_COUNT - 1]
+ * as ring buffer.
+ */
+ for (++i; i < R92C_TXPKTBUF_COUNT - 1; i++) {
+ if ((error = rtwn_llt_write(sc, i, i + 1)) != 0)
+ return (error);
+ }
+ /* Make the last page point to the beginning of the ring buffer. */
+ error = rtwn_llt_write(sc, i, R92C_TX_PAGE_COUNT + 1);
+ return (error);
+}
+
+int
+rtwn_dma_init(void *cookie)
{
struct rtwn_pci_softc *sc = cookie;
+ uint32_t reg;
+ int error;
+
+ /* Initialize LLT table. */
+ error = rtwn_llt_init(sc);
+ if (error != 0)
+ return error;
+
+ /* Set number of pages for normal priority queue. */
+ rtwn_pci_write_2(sc, R92C_RQPN_NPQ, 0);
+ rtwn_pci_write_4(sc, R92C_RQPN,
+ /* Set number of pages for public queue. */
+ SM(R92C_RQPN_PUBQ, R92C_PUBQ_NPAGES) |
+ /* Set number of pages for high priority queue. */
+ SM(R92C_RQPN_HPQ, R92C_HPQ_NPAGES) |
+ /* Set number of pages for low priority queue. */
+ SM(R92C_RQPN_LPQ, R92C_LPQ_NPAGES) |
+ /* Load values. */
+ R92C_RQPN_LD);
+
+ rtwn_pci_write_1(sc, R92C_TXPKTBUF_BCNQ_BDNY, R92C_TX_PAGE_BOUNDARY);
+ rtwn_pci_write_1(sc, R92C_TXPKTBUF_MGQ_BDNY, R92C_TX_PAGE_BOUNDARY);
+ rtwn_pci_write_1(sc, R92C_TXPKTBUF_WMAC_LBK_BF_HD,
+ R92C_TX_PAGE_BOUNDARY);
+ rtwn_pci_write_1(sc, R92C_TRXFF_BNDY, R92C_TX_PAGE_BOUNDARY);
+ rtwn_pci_write_1(sc, R92C_TDECTRL + 1, R92C_TX_PAGE_BOUNDARY);
+
+ reg = rtwn_pci_read_2(sc, R92C_TRXDMA_CTRL);
+ reg &= ~R92C_TRXDMA_CTRL_QMAP_M;
+ reg |= 0xF771;
+ rtwn_pci_write_2(sc, R92C_TRXDMA_CTRL, reg);
+
+ rtwn_pci_write_4(sc, R92C_TCR,
+ R92C_TCR_CFENDFORM | (1 << 12) | (1 << 13));
/* Configure Tx DMA. */
rtwn_pci_write_4(sc, R92C_BKQ_DESA,
@@ -1199,6 +1289,14 @@ rtwn_configure_dma(void *cookie)
/* Configure Rx DMA. */
rtwn_pci_write_4(sc, R92C_RX_DESA, sc->rx_ring.map->dm_segs[0].ds_addr);
+
+ /* Set Tx/Rx transfer page boundary. */
+ rtwn_pci_write_2(sc, R92C_TRXFF_BNDY + 2, 0x27ff);
+
+ /* Set Tx/Rx transfer page size. */
+ rtwn_pci_write_1(sc, R92C_PBP,
+ SM(R92C_PBP_PSRX, R92C_PBP_128) |
+ SM(R92C_PBP_PSTX, R92C_PBP_128));
return (0);
}