svn commit: r291698 - head/sys/dev/usb/wlan
Andriy Voskoboinyk
avos at FreeBSD.org
Thu Dec 3 14:38:57 UTC 2015
Author: avos
Date: Thu Dec 3 14:38:55 2015
New Revision: 291698
URL: https://svnweb.freebsd.org/changeset/base/291698
Log:
urtwn(4): add error handling for urtwn_write_X() functions.
- Call ieee80211_stop() when urtwn_init() fails
(i.e., stop vap explicitly)
- Return an error when urtwn_write_<smth>() fails.
- Handle errors from them in:
* urtwn_fw_cmd();
* urtwn_llt_write();
* urtwn_efuse_*();
* urtwn_*_power_on();
* urtwn_*_dma_init();
* urtwn_mac_init();
* urtwn_init();
Tested with RTL8188EU, STA mode
Reviewed by: kevlo
Approved by: adrian (mentor)
Differential Revision: https://reviews.freebsd.org/D4291
Modified:
head/sys/dev/usb/wlan/if_urtwn.c
Modified: head/sys/dev/usb/wlan/if_urtwn.c
==============================================================================
--- head/sys/dev/usb/wlan/if_urtwn.c Thu Dec 3 14:32:54 2015 (r291697)
+++ head/sys/dev/usb/wlan/if_urtwn.c Thu Dec 3 14:38:55 2015 (r291698)
@@ -195,12 +195,12 @@ static void urtwn_free_rx_list(struct u
static void urtwn_free_tx_list(struct urtwn_softc *);
static struct urtwn_data * _urtwn_getbuf(struct urtwn_softc *);
static struct urtwn_data * urtwn_getbuf(struct urtwn_softc *);
-static int urtwn_write_region_1(struct urtwn_softc *, uint16_t,
+static usb_error_t urtwn_write_region_1(struct urtwn_softc *, uint16_t,
uint8_t *, int);
-static void urtwn_write_1(struct urtwn_softc *, uint16_t, uint8_t);
-static void urtwn_write_2(struct urtwn_softc *, uint16_t, uint16_t);
-static void urtwn_write_4(struct urtwn_softc *, uint16_t, uint32_t);
-static int urtwn_read_region_1(struct urtwn_softc *, uint16_t,
+static usb_error_t urtwn_write_1(struct urtwn_softc *, uint16_t, uint8_t);
+static usb_error_t urtwn_write_2(struct urtwn_softc *, uint16_t, uint16_t);
+static usb_error_t urtwn_write_4(struct urtwn_softc *, uint16_t, uint32_t);
+static usb_error_t urtwn_read_region_1(struct urtwn_softc *, uint16_t,
uint8_t *, int);
static uint8_t urtwn_read_1(struct urtwn_softc *, uint16_t);
static uint16_t urtwn_read_2(struct urtwn_softc *, uint16_t);
@@ -223,7 +223,7 @@ static void urtwn_dump_rom_contents(str
#endif
static int urtwn_efuse_read(struct urtwn_softc *, uint8_t *,
uint16_t);
-static void urtwn_efuse_switch_power(struct urtwn_softc *);
+static int urtwn_efuse_switch_power(struct urtwn_softc *);
static int urtwn_read_chipid(struct urtwn_softc *);
static int urtwn_read_rom(struct urtwn_softc *);
static int urtwn_r88e_read_rom(struct urtwn_softc *);
@@ -267,7 +267,7 @@ static int urtwn_fw_loadpage(struct urt
static int urtwn_load_firmware(struct urtwn_softc *);
static int urtwn_r92c_dma_init(struct urtwn_softc *);
static int urtwn_r88e_dma_init(struct urtwn_softc *);
-static void urtwn_mac_init(struct urtwn_softc *);
+static int urtwn_mac_init(struct urtwn_softc *);
static void urtwn_bb_init(struct urtwn_softc *);
static void urtwn_rf_init(struct urtwn_softc *);
static void urtwn_cam_init(struct urtwn_softc *);
@@ -298,7 +298,7 @@ static void urtwn_set_chan(struct urtwn
struct ieee80211_channel *);
static void urtwn_iq_calib(struct urtwn_softc *);
static void urtwn_lc_calib(struct urtwn_softc *);
-static void urtwn_init(struct urtwn_softc *);
+static int urtwn_init(struct urtwn_softc *);
static void urtwn_stop(struct urtwn_softc *);
static void urtwn_abort_xfers(struct urtwn_softc *);
static int urtwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
@@ -516,9 +516,10 @@ urtwn_detach(device_t self)
/* Prevent further ioctls. */
URTWN_LOCK(sc);
sc->sc_flags |= URTWN_DETACHED;
- urtwn_stop(sc);
URTWN_UNLOCK(sc);
+ urtwn_stop(sc);
+
callout_drain(&sc->sc_watchdog_ch);
/* stop all USB transfers */
@@ -1051,7 +1052,7 @@ urtwn_getbuf(struct urtwn_softc *sc)
return (bf);
}
-static int
+static usb_error_t
urtwn_write_region_1(struct urtwn_softc *sc, uint16_t addr, uint8_t *buf,
int len)
{
@@ -1065,28 +1066,27 @@ urtwn_write_region_1(struct urtwn_softc
return (urtwn_do_request(sc, &req, buf));
}
-static void
+static usb_error_t
urtwn_write_1(struct urtwn_softc *sc, uint16_t addr, uint8_t val)
{
- urtwn_write_region_1(sc, addr, &val, 1);
+ return (urtwn_write_region_1(sc, addr, &val, sizeof(val)));
}
-
-static void
+static usb_error_t
urtwn_write_2(struct urtwn_softc *sc, uint16_t addr, uint16_t val)
{
val = htole16(val);
- urtwn_write_region_1(sc, addr, (uint8_t *)&val, 2);
+ return (urtwn_write_region_1(sc, addr, (uint8_t *)&val, sizeof(val)));
}
-static void
+static usb_error_t
urtwn_write_4(struct urtwn_softc *sc, uint16_t addr, uint32_t val)
{
val = htole32(val);
- urtwn_write_region_1(sc, addr, (uint8_t *)&val, 4);
+ return (urtwn_write_region_1(sc, addr, (uint8_t *)&val, sizeof(val)));
}
-static int
+static usb_error_t
urtwn_read_region_1(struct urtwn_softc *sc, uint16_t addr, uint8_t *buf,
int len)
{
@@ -1134,6 +1134,7 @@ static int
urtwn_fw_cmd(struct urtwn_softc *sc, uint8_t id, const void *buf, int len)
{
struct r92c_fw_cmd cmd;
+ usb_error_t error;
int ntries;
/* Wait for current FW box to be empty. */
@@ -1155,10 +1156,14 @@ urtwn_fw_cmd(struct urtwn_softc *sc, uin
memcpy(cmd.msg, buf, len);
/* Write the first word last since that will trigger the FW. */
- urtwn_write_region_1(sc, R92C_HMEBOX_EXT(sc->fwcur),
+ error = urtwn_write_region_1(sc, R92C_HMEBOX_EXT(sc->fwcur),
(uint8_t *)&cmd + 4, 2);
- urtwn_write_region_1(sc, R92C_HMEBOX(sc->fwcur),
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
+ error = urtwn_write_region_1(sc, R92C_HMEBOX(sc->fwcur),
(uint8_t *)&cmd + 0, 4);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
sc->fwcur = (sc->fwcur + 1) % R92C_H2C_NBOX;
return (0);
@@ -1221,12 +1226,15 @@ urtwn_rf_read(struct urtwn_softc *sc, in
static int
urtwn_llt_write(struct urtwn_softc *sc, uint32_t addr, uint32_t data)
{
+ usb_error_t error;
int ntries;
- urtwn_write_4(sc, R92C_LLT_INIT,
+ error = urtwn_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));
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
/* Wait for write operation to complete. */
for (ntries = 0; ntries < 20; ntries++) {
if (MS(urtwn_read_4(sc, R92C_LLT_INIT), R92C_LLT_INIT_OP) ==
@@ -1241,6 +1249,7 @@ static int
urtwn_efuse_read_next(struct urtwn_softc *sc, uint8_t *val)
{
uint32_t reg;
+ usb_error_t error;
int ntries;
if (sc->last_rom_addr >= URTWN_EFUSE_MAX_LEN)
@@ -1250,7 +1259,9 @@ urtwn_efuse_read_next(struct urtwn_softc
reg = RW(reg, R92C_EFUSE_CTRL_ADDR, sc->last_rom_addr);
reg &= ~R92C_EFUSE_CTRL_VALID;
- urtwn_write_4(sc, R92C_EFUSE_CTRL, reg);
+ error = urtwn_write_4(sc, R92C_EFUSE_CTRL, reg);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
/* Wait for read operation to complete. */
for (ntries = 0; ntries < 100; ntries++) {
reg = urtwn_read_4(sc, R92C_EFUSE_CTRL);
@@ -1327,7 +1338,7 @@ urtwn_efuse_read(struct urtwn_softc *sc,
uint8_t msk, off, reg;
int error;
- urtwn_efuse_switch_power(sc);
+ URTWN_CHK(urtwn_efuse_switch_power(sc));
/* Read full ROM image. */
sc->last_rom_addr = 0;
@@ -1370,29 +1381,40 @@ end:
#undef URTWN_CHK
}
-static void
+static int
urtwn_efuse_switch_power(struct urtwn_softc *sc)
{
+ usb_error_t error;
uint32_t reg;
- urtwn_write_1(sc, R92C_EFUSE_ACCESS, R92C_EFUSE_ACCESS_ON);
+ error = urtwn_write_1(sc, R92C_EFUSE_ACCESS, R92C_EFUSE_ACCESS_ON);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
reg = urtwn_read_2(sc, R92C_SYS_ISO_CTRL);
if (!(reg & R92C_SYS_ISO_CTRL_PWC_EV12V)) {
- urtwn_write_2(sc, R92C_SYS_ISO_CTRL,
+ error = urtwn_write_2(sc, R92C_SYS_ISO_CTRL,
reg | R92C_SYS_ISO_CTRL_PWC_EV12V);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
}
reg = urtwn_read_2(sc, R92C_SYS_FUNC_EN);
if (!(reg & R92C_SYS_FUNC_EN_ELDR)) {
- urtwn_write_2(sc, R92C_SYS_FUNC_EN,
+ error = urtwn_write_2(sc, R92C_SYS_FUNC_EN,
reg | R92C_SYS_FUNC_EN_ELDR);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
}
reg = urtwn_read_2(sc, R92C_SYS_CLKR);
if ((reg & (R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M)) !=
(R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M)) {
- urtwn_write_2(sc, R92C_SYS_CLKR,
+ error = urtwn_write_2(sc, R92C_SYS_CLKR,
reg | R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
}
+
+ return (0);
}
static int
@@ -2360,24 +2382,23 @@ static void
urtwn_parent(struct ieee80211com *ic)
{
struct urtwn_softc *sc = ic->ic_softc;
- int startall = 0;
URTWN_LOCK(sc);
if (sc->sc_flags & URTWN_DETACHED) {
URTWN_UNLOCK(sc);
return;
}
- if (ic->ic_nrunning > 0) {
- if ((sc->sc_flags & URTWN_RUNNING) == 0) {
- urtwn_init(sc);
- startall = 1;
- }
- } else if (sc->sc_flags & URTWN_RUNNING)
- urtwn_stop(sc);
URTWN_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
+ if (ic->ic_nrunning > 0) {
+ if (urtwn_init(sc) != 0) {
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+ if (vap != NULL)
+ ieee80211_stop(vap);
+ } else
+ ieee80211_start_all(ic);
+ } else
+ urtwn_stop(sc);
}
static __inline int
@@ -2391,6 +2412,7 @@ static int
urtwn_r92c_power_on(struct urtwn_softc *sc)
{
uint32_t reg;
+ usb_error_t error;
int ntries;
/* Wait for autoload done bit. */
@@ -2406,24 +2428,34 @@ urtwn_r92c_power_on(struct urtwn_softc *
}
/* Unlock ISO/CLK/Power control register. */
- urtwn_write_1(sc, R92C_RSV_CTRL, 0);
+ error = urtwn_write_1(sc, R92C_RSV_CTRL, 0);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
/* Move SPS into PWM mode. */
- urtwn_write_1(sc, R92C_SPS0_CTRL, 0x2b);
+ error = urtwn_write_1(sc, R92C_SPS0_CTRL, 0x2b);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
urtwn_ms_delay(sc);
reg = urtwn_read_1(sc, R92C_LDOV12D_CTRL);
if (!(reg & R92C_LDOV12D_CTRL_LDV12_EN)) {
- urtwn_write_1(sc, R92C_LDOV12D_CTRL,
+ error = urtwn_write_1(sc, R92C_LDOV12D_CTRL,
reg | R92C_LDOV12D_CTRL_LDV12_EN);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
urtwn_ms_delay(sc);
- urtwn_write_1(sc, R92C_SYS_ISO_CTRL,
+ error = urtwn_write_1(sc, R92C_SYS_ISO_CTRL,
urtwn_read_1(sc, R92C_SYS_ISO_CTRL) &
~R92C_SYS_ISO_CTRL_MD2PP);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
}
/* Auto enable WLAN. */
- urtwn_write_2(sc, R92C_APS_FSMCO,
+ error = urtwn_write_2(sc, R92C_APS_FSMCO,
urtwn_read_2(sc, R92C_APS_FSMCO) | R92C_APS_FSMCO_APFM_ONMAC);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
for (ntries = 0; ntries < 1000; ntries++) {
if (!(urtwn_read_2(sc, R92C_APS_FSMCO) &
R92C_APS_FSMCO_APFM_ONMAC))
@@ -2437,17 +2469,23 @@ urtwn_r92c_power_on(struct urtwn_softc *
}
/* Enable radio, GPIO and LED functions. */
- urtwn_write_2(sc, R92C_APS_FSMCO,
+ error = urtwn_write_2(sc, R92C_APS_FSMCO,
R92C_APS_FSMCO_AFSM_HSUS |
R92C_APS_FSMCO_PDN_EN |
R92C_APS_FSMCO_PFM_ALDN);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
/* Release RF digital isolation. */
- urtwn_write_2(sc, R92C_SYS_ISO_CTRL,
+ error = urtwn_write_2(sc, R92C_SYS_ISO_CTRL,
urtwn_read_2(sc, R92C_SYS_ISO_CTRL) & ~R92C_SYS_ISO_CTRL_DIOR);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
/* Initialize MAC. */
- urtwn_write_1(sc, R92C_APSD_CTRL,
+ error = urtwn_write_1(sc, R92C_APSD_CTRL,
urtwn_read_1(sc, R92C_APSD_CTRL) & ~R92C_APSD_CTRL_OFF);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
for (ntries = 0; ntries < 200; ntries++) {
if (!(urtwn_read_1(sc, R92C_APSD_CTRL) &
R92C_APSD_CTRL_OFF_STATUS))
@@ -2466,9 +2504,13 @@ urtwn_r92c_power_on(struct urtwn_softc *
R92C_CR_TXDMA_EN | R92C_CR_RXDMA_EN | R92C_CR_PROTOCOL_EN |
R92C_CR_SCHEDULE_EN | R92C_CR_MACTXEN | R92C_CR_MACRXEN |
R92C_CR_ENSEC;
- urtwn_write_2(sc, R92C_CR, reg);
+ error = urtwn_write_2(sc, R92C_CR, reg);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
- urtwn_write_1(sc, 0xfe10, 0x19);
+ error = urtwn_write_1(sc, 0xfe10, 0x19);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
return (0);
}
@@ -2476,6 +2518,7 @@ static int
urtwn_r88e_power_on(struct urtwn_softc *sc)
{
uint32_t reg;
+ usb_error_t error;
int ntries;
/* Wait for power ready bit. */
@@ -2491,24 +2534,34 @@ urtwn_r88e_power_on(struct urtwn_softc *
}
/* Reset BB. */
- urtwn_write_1(sc, R92C_SYS_FUNC_EN,
+ error = urtwn_write_1(sc, R92C_SYS_FUNC_EN,
urtwn_read_1(sc, R92C_SYS_FUNC_EN) & ~(R92C_SYS_FUNC_EN_BBRSTB |
R92C_SYS_FUNC_EN_BB_GLB_RST));
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
- urtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 2,
+ error = urtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 2,
urtwn_read_1(sc, R92C_AFE_XTAL_CTRL + 2) | 0x80);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
/* Disable HWPDN. */
- urtwn_write_2(sc, R92C_APS_FSMCO,
+ error = urtwn_write_2(sc, R92C_APS_FSMCO,
urtwn_read_2(sc, R92C_APS_FSMCO) & ~R92C_APS_FSMCO_APDM_HPDN);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
/* Disable WL suspend. */
- urtwn_write_2(sc, R92C_APS_FSMCO,
+ error = urtwn_write_2(sc, R92C_APS_FSMCO,
urtwn_read_2(sc, R92C_APS_FSMCO) &
~(R92C_APS_FSMCO_AFSM_HSUS | R92C_APS_FSMCO_AFSM_PCIE));
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
- urtwn_write_2(sc, R92C_APS_FSMCO,
+ error = urtwn_write_2(sc, R92C_APS_FSMCO,
urtwn_read_2(sc, R92C_APS_FSMCO) | R92C_APS_FSMCO_APFM_ONMAC);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
for (ntries = 0; ntries < 5000; ntries++) {
if (!(urtwn_read_2(sc, R92C_APS_FSMCO) &
R92C_APS_FSMCO_APFM_ONMAC))
@@ -2519,16 +2572,22 @@ urtwn_r88e_power_on(struct urtwn_softc *
return (ETIMEDOUT);
/* Enable LDO normal mode. */
- urtwn_write_1(sc, R92C_LPLDO_CTRL,
+ error = urtwn_write_1(sc, R92C_LPLDO_CTRL,
urtwn_read_1(sc, R92C_LPLDO_CTRL) & ~0x10);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
/* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */
- urtwn_write_2(sc, R92C_CR, 0);
+ error = urtwn_write_2(sc, R92C_CR, 0);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
reg = urtwn_read_2(sc, R92C_CR);
reg |= R92C_CR_HCI_TXDMA_EN | R92C_CR_HCI_RXDMA_EN |
R92C_CR_TXDMA_EN | R92C_CR_RXDMA_EN | R92C_CR_PROTOCOL_EN |
R92C_CR_SCHEDULE_EN | R92C_CR_ENSEC | R92C_CR_CALTMR_EN;
- urtwn_write_2(sc, R92C_CR, reg);
+ error = urtwn_write_2(sc, R92C_CR, reg);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
return (0);
}
@@ -2598,7 +2657,8 @@ static int
urtwn_fw_loadpage(struct urtwn_softc *sc, int page, const uint8_t *buf, int len)
{
uint32_t reg;
- int off, mlen, error = 0;
+ usb_error_t error = USB_ERR_NORMAL_COMPLETION;
+ int off, mlen;
reg = urtwn_read_4(sc, R92C_MCUFWDL);
reg = RW(reg, R92C_MCUFWDL_PAGE, page);
@@ -2615,7 +2675,7 @@ urtwn_fw_loadpage(struct urtwn_softc *sc
/* XXX fix this deconst */
error = urtwn_write_region_1(sc, off,
__DECONST(uint8_t *, buf), mlen);
- if (error != 0)
+ if (error != USB_ERR_NORMAL_COMPLETION)
break;
off += mlen;
buf += mlen;
@@ -2748,6 +2808,7 @@ fail:
static __inline int
urtwn_dma_init(struct urtwn_softc *sc)
{
+ usb_error_t usb_err;
int error;
/* Initialize LLT table. */
@@ -2760,9 +2821,11 @@ urtwn_dma_init(struct urtwn_softc *sc)
return (error);
/* Set Tx/Rx transfer page size. */
- urtwn_write_1(sc, R92C_PBP,
+ usb_err = urtwn_write_1(sc, R92C_PBP,
SM(R92C_PBP_PSRX, R92C_PBP_128) |
SM(R92C_PBP_PSTX, R92C_PBP_128));
+ if (usb_err != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
return (0);
}
@@ -2771,6 +2834,7 @@ static int
urtwn_r92c_dma_init(struct urtwn_softc *sc)
{
int hashq, hasnq, haslq, nqueues, nqpages, nrempages;
+ usb_error_t error;
uint32_t reg;
/* Get Tx queues to USB endpoints mapping. */
@@ -2792,8 +2856,10 @@ urtwn_r92c_dma_init(struct urtwn_softc *
nrempages = (R92C_TX_PAGE_COUNT - R92C_PUBQ_NPAGES) % nqueues;
/* Set number of pages for normal priority queue. */
- urtwn_write_1(sc, R92C_RQPN_NPQ, hasnq ? nqpages : 0);
- urtwn_write_4(sc, R92C_RQPN,
+ error = urtwn_write_1(sc, R92C_RQPN_NPQ, hasnq ? nqpages : 0);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
+ error = urtwn_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. */
@@ -2802,12 +2868,24 @@ urtwn_r92c_dma_init(struct urtwn_softc *
SM(R92C_RQPN_LPQ, haslq ? nqpages : 0) |
/* Load values. */
R92C_RQPN_LD);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
- urtwn_write_1(sc, R92C_TXPKTBUF_BCNQ_BDNY, R92C_TX_PAGE_BOUNDARY);
- urtwn_write_1(sc, R92C_TXPKTBUF_MGQ_BDNY, R92C_TX_PAGE_BOUNDARY);
- urtwn_write_1(sc, R92C_TXPKTBUF_WMAC_LBK_BF_HD, R92C_TX_PAGE_BOUNDARY);
- urtwn_write_1(sc, R92C_TRXFF_BNDY, R92C_TX_PAGE_BOUNDARY);
- urtwn_write_1(sc, R92C_TDECTRL + 1, R92C_TX_PAGE_BOUNDARY);
+ error = urtwn_write_1(sc, R92C_TXPKTBUF_BCNQ_BDNY, R92C_TX_PAGE_BOUNDARY);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
+ error = urtwn_write_1(sc, R92C_TXPKTBUF_MGQ_BDNY, R92C_TX_PAGE_BOUNDARY);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
+ error = urtwn_write_1(sc, R92C_TXPKTBUF_WMAC_LBK_BF_HD, R92C_TX_PAGE_BOUNDARY);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
+ error = urtwn_write_1(sc, R92C_TRXFF_BNDY, R92C_TX_PAGE_BOUNDARY);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
+ error = urtwn_write_1(sc, R92C_TDECTRL + 1, R92C_TX_PAGE_BOUNDARY);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
/* Set queue to USB pipe mapping. */
reg = urtwn_read_2(sc, R92C_TRXDMA_CTRL);
@@ -2829,10 +2907,14 @@ urtwn_r92c_dma_init(struct urtwn_softc *
reg |= R92C_TRXDMA_CTRL_QMAP_HQ_LQ;
} else
reg |= R92C_TRXDMA_CTRL_QMAP_3EP;
- urtwn_write_2(sc, R92C_TRXDMA_CTRL, reg);
+ error = urtwn_write_2(sc, R92C_TRXDMA_CTRL, reg);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
/* Set Tx/Rx transfer page boundary. */
- urtwn_write_2(sc, R92C_TRXFF_BNDY + 2, 0x27ff);
+ error = urtwn_write_2(sc, R92C_TRXFF_BNDY + 2, 0x27ff);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
return (0);
}
@@ -2842,6 +2924,7 @@ urtwn_r88e_dma_init(struct urtwn_softc *
{
struct usb_interface *iface;
uint32_t reg;
+ usb_error_t error;
int nqueues;
/* Get Tx queues to USB endpoints mapping. */
@@ -2851,14 +2934,28 @@ urtwn_r88e_dma_init(struct urtwn_softc *
return (EIO);
/* Set number of pages for normal priority queue. */
- urtwn_write_2(sc, R92C_RQPN_NPQ, 0x000d);
- urtwn_write_4(sc, R92C_RQPN, 0x808e000d);
+ error = urtwn_write_2(sc, R92C_RQPN_NPQ, 0x000d);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
+ error = urtwn_write_4(sc, R92C_RQPN, 0x808e000d);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
- urtwn_write_1(sc, R92C_TXPKTBUF_BCNQ_BDNY, R88E_TX_PAGE_BOUNDARY);
- urtwn_write_1(sc, R92C_TXPKTBUF_MGQ_BDNY, R88E_TX_PAGE_BOUNDARY);
- urtwn_write_1(sc, R92C_TXPKTBUF_WMAC_LBK_BF_HD, R88E_TX_PAGE_BOUNDARY);
- urtwn_write_1(sc, R92C_TRXFF_BNDY, R88E_TX_PAGE_BOUNDARY);
- urtwn_write_1(sc, R92C_TDECTRL + 1, R88E_TX_PAGE_BOUNDARY);
+ error = urtwn_write_1(sc, R92C_TXPKTBUF_BCNQ_BDNY, R88E_TX_PAGE_BOUNDARY);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
+ error = urtwn_write_1(sc, R92C_TXPKTBUF_MGQ_BDNY, R88E_TX_PAGE_BOUNDARY);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
+ error = urtwn_write_1(sc, R92C_TXPKTBUF_WMAC_LBK_BF_HD, R88E_TX_PAGE_BOUNDARY);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
+ error = urtwn_write_1(sc, R92C_TRXFF_BNDY, R88E_TX_PAGE_BOUNDARY);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
+ error = urtwn_write_1(sc, R92C_TDECTRL + 1, R88E_TX_PAGE_BOUNDARY);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
/* Set queue to USB pipe mapping. */
reg = urtwn_read_2(sc, R92C_TRXDMA_CTRL);
@@ -2869,31 +2966,42 @@ urtwn_r88e_dma_init(struct urtwn_softc *
reg |= R92C_TRXDMA_CTRL_QMAP_HQ_NQ;
else
reg |= R92C_TRXDMA_CTRL_QMAP_3EP;
- urtwn_write_2(sc, R92C_TRXDMA_CTRL, reg);
+ error = urtwn_write_2(sc, R92C_TRXDMA_CTRL, reg);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
/* Set Tx/Rx transfer page boundary. */
- urtwn_write_2(sc, R92C_TRXFF_BNDY + 2, 0x23ff);
+ error = urtwn_write_2(sc, R92C_TRXFF_BNDY + 2, 0x23ff);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
return (0);
}
-static void
+static int
urtwn_mac_init(struct urtwn_softc *sc)
{
+ usb_error_t error;
int i;
/* Write MAC initialization values. */
if (sc->chip & URTWN_CHIP_88E) {
for (i = 0; i < nitems(rtl8188eu_mac); i++) {
- urtwn_write_1(sc, rtl8188eu_mac[i].reg,
+ error = urtwn_write_1(sc, rtl8188eu_mac[i].reg,
rtl8188eu_mac[i].val);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
}
urtwn_write_1(sc, R92C_MAX_AGGR_NUM, 0x07);
} else {
for (i = 0; i < nitems(rtl8192cu_mac); i++)
- urtwn_write_1(sc, rtl8192cu_mac[i].reg,
+ error = urtwn_write_1(sc, rtl8192cu_mac[i].reg,
rtl8192cu_mac[i].val);
+ if (error != USB_ERR_NORMAL_COMPLETION)
+ return (EIO);
}
+
+ return (0);
}
static void
@@ -3711,19 +3819,21 @@ urtwn_lc_calib(struct urtwn_softc *sc)
}
}
-static void
+static int
urtwn_init(struct urtwn_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint8_t macaddr[IEEE80211_ADDR_LEN];
uint32_t reg;
+ usb_error_t usb_err = USB_ERR_NORMAL_COMPLETION;
int error;
- URTWN_ASSERT_LOCKED(sc);
-
- if (sc->sc_flags & URTWN_RUNNING)
- urtwn_stop(sc);
+ URTWN_LOCK(sc);
+ if (sc->sc_flags & URTWN_RUNNING) {
+ URTWN_UNLOCK(sc);
+ return (0);
+ }
/* Init firmware commands ring. */
sc->fwcur = 0;
@@ -3752,22 +3862,36 @@ urtwn_init(struct urtwn_softc *sc)
/* Init interrupts. */
if (sc->chip & URTWN_CHIP_88E) {
- urtwn_write_4(sc, R88E_HISR, 0xffffffff);
- urtwn_write_4(sc, R88E_HIMR, R88E_HIMR_CPWM | R88E_HIMR_CPWM2 |
+ usb_err = urtwn_write_4(sc, R88E_HISR, 0xffffffff);
+ if (usb_err != USB_ERR_NORMAL_COMPLETION)
+ goto fail;
+ usb_err = urtwn_write_4(sc, R88E_HIMR, R88E_HIMR_CPWM | R88E_HIMR_CPWM2 |
R88E_HIMR_TBDER | R88E_HIMR_PSTIMEOUT);
- urtwn_write_4(sc, R88E_HIMRE, R88E_HIMRE_RXFOVW |
+ if (usb_err != USB_ERR_NORMAL_COMPLETION)
+ goto fail;
+ usb_err = urtwn_write_4(sc, R88E_HIMRE, R88E_HIMRE_RXFOVW |
R88E_HIMRE_TXFOVW | R88E_HIMRE_RXERR | R88E_HIMRE_TXERR);
- urtwn_write_1(sc, R92C_USB_SPECIAL_OPTION,
+ if (usb_err != USB_ERR_NORMAL_COMPLETION)
+ goto fail;
+ usb_err = urtwn_write_1(sc, R92C_USB_SPECIAL_OPTION,
urtwn_read_1(sc, R92C_USB_SPECIAL_OPTION) |
R92C_USB_SPECIAL_OPTION_INT_BULK_SEL);
+ if (usb_err != USB_ERR_NORMAL_COMPLETION)
+ goto fail;
} else {
- urtwn_write_4(sc, R92C_HISR, 0xffffffff);
- urtwn_write_4(sc, R92C_HIMR, 0xffffffff);
+ usb_err = urtwn_write_4(sc, R92C_HISR, 0xffffffff);
+ if (usb_err != USB_ERR_NORMAL_COMPLETION)
+ goto fail;
+ usb_err = urtwn_write_4(sc, R92C_HIMR, 0xffffffff);
+ if (usb_err != USB_ERR_NORMAL_COMPLETION)
+ goto fail;
}
/* Set MAC address. */
IEEE80211_ADDR_COPY(macaddr, vap ? vap->iv_myaddr : ic->ic_macaddr);
- urtwn_write_region_1(sc, R92C_MACID, macaddr, IEEE80211_ADDR_LEN);
+ usb_err = urtwn_write_region_1(sc, R92C_MACID, macaddr, IEEE80211_ADDR_LEN);
+ if (usb_err != USB_ERR_NORMAL_COMPLETION)
+ goto fail;
/* Set initial network type. */
urtwn_set_mode(sc, R92C_MSR_INFRA);
@@ -3842,7 +3966,12 @@ urtwn_init(struct urtwn_softc *sc)
goto fail;
/* Initialize MAC/BB/RF blocks. */
- urtwn_mac_init(sc);
+ error = urtwn_mac_init(sc);
+ if (error != 0) {
+ device_printf(sc->sc_dev,
+ "%s: error while initializing MAC block\n", __func__);
+ goto fail;
+ }
urtwn_bb_init(sc);
urtwn_rf_init(sc);
@@ -3858,10 +3987,14 @@ urtwn_init(struct urtwn_softc *sc)
/* Turn CCK and OFDM blocks on. */
reg = urtwn_bb_read(sc, R92C_FPGA0_RFMOD);
reg |= R92C_RFMOD_CCK_EN;
- urtwn_bb_write(sc, R92C_FPGA0_RFMOD, reg);
+ usb_err = urtwn_bb_write(sc, R92C_FPGA0_RFMOD, reg);
+ if (usb_err != USB_ERR_NORMAL_COMPLETION)
+ goto fail;
reg = urtwn_bb_read(sc, R92C_FPGA0_RFMOD);
reg |= R92C_RFMOD_OFDM_EN;
- urtwn_bb_write(sc, R92C_FPGA0_RFMOD, reg);
+ usb_err = urtwn_bb_write(sc, R92C_FPGA0_RFMOD, reg);
+ if (usb_err != USB_ERR_NORMAL_COMPLETION)
+ goto fail;
/* Clear per-station keys table. */
urtwn_cam_init(sc);
@@ -3897,19 +4030,30 @@ urtwn_init(struct urtwn_softc *sc)
callout_reset(&sc->sc_watchdog_ch, hz, urtwn_watchdog, sc);
fail:
- return;
+ if (usb_err != USB_ERR_NORMAL_COMPLETION)
+ error = EIO;
+
+ URTWN_UNLOCK(sc);
+
+ return (error);
}
static void
urtwn_stop(struct urtwn_softc *sc)
{
- URTWN_ASSERT_LOCKED(sc);
+ URTWN_LOCK(sc);
+ if (!(sc->sc_flags & URTWN_RUNNING)) {
+ URTWN_UNLOCK(sc);
+ return;
+ }
+
sc->sc_flags &= ~URTWN_RUNNING;
callout_stop(&sc->sc_watchdog_ch);
urtwn_abort_xfers(sc);
urtwn_drain_mbufq(sc);
+ URTWN_UNLOCK(sc);
}
static void
More information about the svn-src-all
mailing list