diff options
author | Hante Meuleman <meuleman@broadcom.com> | 2015-01-25 14:31:35 -0500 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2015-01-29 02:59:03 -0500 |
commit | a1cee865c3e79b71c10cd6a3de03d0dd73f7bdd9 (patch) | |
tree | bee251ec1c5eacdd21aa8d6b1bca09929b6304b0 /drivers/net/wireless/brcm80211 | |
parent | 8982cd40ace9b7f109ac8c63e6763409e39feb55 (diff) |
brcmfmac: SDIO: avoid using bus state for private states.
Each bus driver is maintaing an exported bus state indicating
if upper layers can or cannot send data. SDIO is using this state
also for more private states. This makes handling the states and
state changes complex. This patch minimises the exposed states
and makes SDIO keep track of an internal state where necessary.
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/brcm80211')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 17 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/bus.h | 14 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/core.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/fwil.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/pcie.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/sdio.c | 45 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/sdio.h | 8 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/usb.c | 2 |
8 files changed, 43 insertions, 53 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 9afaeb6d2af5..7944224e3fc9 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | |||
@@ -269,6 +269,12 @@ static int brcmf_sdiod_request_data(struct brcmf_sdio_dev *sdiodev, u8 fn, | |||
269 | return ret; | 269 | return ret; |
270 | } | 270 | } |
271 | 271 | ||
272 | static void brcmf_sdiod_nomedium_state(struct brcmf_sdio_dev *sdiodev) | ||
273 | { | ||
274 | sdiodev->state = BRCMF_STATE_NOMEDIUM; | ||
275 | brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_DOWN); | ||
276 | } | ||
277 | |||
272 | static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, | 278 | static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, |
273 | u8 regsz, void *data, bool write) | 279 | u8 regsz, void *data, bool write) |
274 | { | 280 | { |
@@ -276,7 +282,7 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, | |||
276 | s32 retry = 0; | 282 | s32 retry = 0; |
277 | int ret; | 283 | int ret; |
278 | 284 | ||
279 | if (sdiodev->bus_if->state == BRCMF_BUS_NOMEDIUM) | 285 | if (sdiodev->state == BRCMF_STATE_NOMEDIUM) |
280 | return -ENOMEDIUM; | 286 | return -ENOMEDIUM; |
281 | 287 | ||
282 | /* | 288 | /* |
@@ -302,7 +308,7 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, | |||
302 | retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); | 308 | retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); |
303 | 309 | ||
304 | if (ret == -ENOMEDIUM) | 310 | if (ret == -ENOMEDIUM) |
305 | brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_NOMEDIUM); | 311 | brcmf_sdiod_nomedium_state(sdiodev); |
306 | else if (ret != 0) { | 312 | else if (ret != 0) { |
307 | /* | 313 | /* |
308 | * SleepCSR register access can fail when | 314 | * SleepCSR register access can fail when |
@@ -325,7 +331,7 @@ brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) | |||
325 | int err = 0, i; | 331 | int err = 0, i; |
326 | u8 addr[3]; | 332 | u8 addr[3]; |
327 | 333 | ||
328 | if (sdiodev->bus_if->state == BRCMF_BUS_NOMEDIUM) | 334 | if (sdiodev->state == BRCMF_STATE_NOMEDIUM) |
329 | return -ENOMEDIUM; | 335 | return -ENOMEDIUM; |
330 | 336 | ||
331 | addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK; | 337 | addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK; |
@@ -454,7 +460,7 @@ static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, | |||
454 | err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr, | 460 | err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr, |
455 | req_sz); | 461 | req_sz); |
456 | if (err == -ENOMEDIUM) | 462 | if (err == -ENOMEDIUM) |
457 | brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_NOMEDIUM); | 463 | brcmf_sdiod_nomedium_state(sdiodev); |
458 | return err; | 464 | return err; |
459 | } | 465 | } |
460 | 466 | ||
@@ -589,8 +595,7 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn, | |||
589 | 595 | ||
590 | ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error; | 596 | ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error; |
591 | if (ret == -ENOMEDIUM) { | 597 | if (ret == -ENOMEDIUM) { |
592 | brcmf_bus_change_state(sdiodev->bus_if, | 598 | brcmf_sdiod_nomedium_state(sdiodev); |
593 | BRCMF_BUS_NOMEDIUM); | ||
594 | break; | 599 | break; |
595 | } else if (ret != 0) { | 600 | } else if (ret != 0) { |
596 | brcmf_err("CMD53 sg block %s failed %d\n", | 601 | brcmf_err("CMD53 sg block %s failed %d\n", |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bus.h b/drivers/net/wireless/brcm80211/brcmfmac/bus.h index ef344e47218a..55d36ff5439d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/bus.h | |||
@@ -33,11 +33,8 @@ | |||
33 | 33 | ||
34 | /* The level of bus communication with the dongle */ | 34 | /* The level of bus communication with the dongle */ |
35 | enum brcmf_bus_state { | 35 | enum brcmf_bus_state { |
36 | BRCMF_BUS_UNKNOWN, /* Not determined yet */ | ||
37 | BRCMF_BUS_NOMEDIUM, /* No medium access to dongle */ | ||
38 | BRCMF_BUS_DOWN, /* Not ready for frame transfers */ | 36 | BRCMF_BUS_DOWN, /* Not ready for frame transfers */ |
39 | BRCMF_BUS_LOAD, /* Download access only (CPU reset) */ | 37 | BRCMF_BUS_UP /* Ready for frame transfers */ |
40 | BRCMF_BUS_DATA /* Ready for frame transfers */ | ||
41 | }; | 38 | }; |
42 | 39 | ||
43 | /* The level of bus communication with the dongle */ | 40 | /* The level of bus communication with the dongle */ |
@@ -188,18 +185,9 @@ void brcmf_bus_wowl_config(struct brcmf_bus *bus, bool enabled) | |||
188 | bus->ops->wowl_config(bus->dev, enabled); | 185 | bus->ops->wowl_config(bus->dev, enabled); |
189 | } | 186 | } |
190 | 187 | ||
191 | static inline bool brcmf_bus_ready(struct brcmf_bus *bus) | ||
192 | { | ||
193 | return bus->state == BRCMF_BUS_LOAD || bus->state == BRCMF_BUS_DATA; | ||
194 | } | ||
195 | |||
196 | static inline void brcmf_bus_change_state(struct brcmf_bus *bus, | 188 | static inline void brcmf_bus_change_state(struct brcmf_bus *bus, |
197 | enum brcmf_bus_state new_state) | 189 | enum brcmf_bus_state new_state) |
198 | { | 190 | { |
199 | /* NOMEDIUM is permanent */ | ||
200 | if (bus->state == BRCMF_BUS_NOMEDIUM) | ||
201 | return; | ||
202 | |||
203 | brcmf_dbg(TRACE, "%d -> %d\n", bus->state, new_state); | 191 | brcmf_dbg(TRACE, "%d -> %d\n", bus->state, new_state); |
204 | bus->state = new_state; | 192 | bus->state = new_state; |
205 | } | 193 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/core.c b/drivers/net/wireless/brcm80211/brcmfmac/core.c index e2a9e33f71ab..ff8c97ba4bc5 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c | |||
@@ -197,7 +197,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, | |||
197 | brcmf_dbg(DATA, "Enter, idx=%d\n", ifp->bssidx); | 197 | brcmf_dbg(DATA, "Enter, idx=%d\n", ifp->bssidx); |
198 | 198 | ||
199 | /* Can the device send data? */ | 199 | /* Can the device send data? */ |
200 | if (drvr->bus_if->state != BRCMF_BUS_DATA) { | 200 | if (drvr->bus_if->state != BRCMF_BUS_UP) { |
201 | brcmf_err("xmit rejected state=%d\n", drvr->bus_if->state); | 201 | brcmf_err("xmit rejected state=%d\n", drvr->bus_if->state); |
202 | netif_stop_queue(ndev); | 202 | netif_stop_queue(ndev); |
203 | dev_kfree_skb(skb); | 203 | dev_kfree_skb(skb); |
@@ -637,7 +637,7 @@ static int brcmf_netdev_open(struct net_device *ndev) | |||
637 | brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx); | 637 | brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx); |
638 | 638 | ||
639 | /* If bus is not ready, can't continue */ | 639 | /* If bus is not ready, can't continue */ |
640 | if (bus_if->state != BRCMF_BUS_DATA) { | 640 | if (bus_if->state != BRCMF_BUS_UP) { |
641 | brcmf_err("failed bus is not ready\n"); | 641 | brcmf_err("failed bus is not ready\n"); |
642 | return -EAGAIN; | 642 | return -EAGAIN; |
643 | } | 643 | } |
@@ -964,7 +964,7 @@ int brcmf_bus_start(struct device *dev) | |||
964 | p2p_ifp = NULL; | 964 | p2p_ifp = NULL; |
965 | 965 | ||
966 | /* signal bus ready */ | 966 | /* signal bus ready */ |
967 | brcmf_bus_change_state(bus_if, BRCMF_BUS_DATA); | 967 | brcmf_bus_change_state(bus_if, BRCMF_BUS_UP); |
968 | 968 | ||
969 | /* Bus is ready, do any initialization */ | 969 | /* Bus is ready, do any initialization */ |
970 | ret = brcmf_c_preinit_dcmds(ifp); | 970 | ret = brcmf_c_preinit_dcmds(ifp); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c index 03f2c406a17b..dcfa0bb149ce 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c | |||
@@ -109,7 +109,7 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set) | |||
109 | struct brcmf_pub *drvr = ifp->drvr; | 109 | struct brcmf_pub *drvr = ifp->drvr; |
110 | s32 err; | 110 | s32 err; |
111 | 111 | ||
112 | if (drvr->bus_if->state != BRCMF_BUS_DATA) { | 112 | if (drvr->bus_if->state != BRCMF_BUS_UP) { |
113 | brcmf_err("bus is down. we have nothing to do.\n"); | 113 | brcmf_err("bus is down. we have nothing to do.\n"); |
114 | return -EIO; | 114 | return -EIO; |
115 | } | 115 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c index e91fa9a2c885..61c053a729be 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c | |||
@@ -1828,7 +1828,7 @@ static int brcmf_pcie_resume(struct pci_dev *pdev) | |||
1828 | goto cleanup; | 1828 | goto cleanup; |
1829 | brcmf_dbg(PCIE, "Hot resume, continue....\n"); | 1829 | brcmf_dbg(PCIE, "Hot resume, continue....\n"); |
1830 | brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); | 1830 | brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); |
1831 | brcmf_bus_change_state(bus, BRCMF_BUS_DATA); | 1831 | brcmf_bus_change_state(bus, BRCMF_BUS_UP); |
1832 | brcmf_pcie_intr_enable(devinfo); | 1832 | brcmf_pcie_intr_enable(devinfo); |
1833 | return 0; | 1833 | return 0; |
1834 | } | 1834 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c index 488a0f648e18..5e9d20853bbb 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c | |||
@@ -1909,7 +1909,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1909 | bus->rxpending = true; | 1909 | bus->rxpending = true; |
1910 | 1910 | ||
1911 | for (rd->seq_num = bus->rx_seq, rxleft = maxframes; | 1911 | for (rd->seq_num = bus->rx_seq, rxleft = maxframes; |
1912 | !bus->rxskip && rxleft && brcmf_bus_ready(bus->sdiodev->bus_if); | 1912 | !bus->rxskip && rxleft && bus->sdiodev->state == BRCMF_STATE_DATA; |
1913 | rd->seq_num++, rxleft--) { | 1913 | rd->seq_num++, rxleft--) { |
1914 | 1914 | ||
1915 | /* Handle glomming separately */ | 1915 | /* Handle glomming separately */ |
@@ -2415,7 +2415,7 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes) | |||
2415 | } | 2415 | } |
2416 | 2416 | ||
2417 | /* Deflow-control stack if needed */ | 2417 | /* Deflow-control stack if needed */ |
2418 | if ((bus->sdiodev->bus_if->state == BRCMF_BUS_DATA) && | 2418 | if ((bus->sdiodev->state == BRCMF_STATE_DATA) && |
2419 | bus->txoff && (pktq_len(&bus->txq) < TXLOW)) { | 2419 | bus->txoff && (pktq_len(&bus->txq) < TXLOW)) { |
2420 | bus->txoff = false; | 2420 | bus->txoff = false; |
2421 | brcmf_txflowblock(bus->sdiodev->dev, false); | 2421 | brcmf_txflowblock(bus->sdiodev->dev, false); |
@@ -2503,7 +2503,7 @@ static void brcmf_sdio_bus_stop(struct device *dev) | |||
2503 | bus->watchdog_tsk = NULL; | 2503 | bus->watchdog_tsk = NULL; |
2504 | } | 2504 | } |
2505 | 2505 | ||
2506 | if (bus_if->state == BRCMF_BUS_DOWN) { | 2506 | if (sdiodev->state != BRCMF_STATE_NOMEDIUM) { |
2507 | sdio_claim_host(sdiodev->func[1]); | 2507 | sdio_claim_host(sdiodev->func[1]); |
2508 | 2508 | ||
2509 | /* Enable clock for device interrupts */ | 2509 | /* Enable clock for device interrupts */ |
@@ -2756,7 +2756,7 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus) | |||
2756 | brcmf_sdio_sendfromq(bus, framecnt); | 2756 | brcmf_sdio_sendfromq(bus, framecnt); |
2757 | } | 2757 | } |
2758 | 2758 | ||
2759 | if (!brcmf_bus_ready(bus->sdiodev->bus_if) || (err != 0)) { | 2759 | if ((bus->sdiodev->state != BRCMF_STATE_DATA) || (err != 0)) { |
2760 | brcmf_err("failed backplane access over SDIO, halting operation\n"); | 2760 | brcmf_err("failed backplane access over SDIO, halting operation\n"); |
2761 | atomic_set(&bus->intstatus, 0); | 2761 | atomic_set(&bus->intstatus, 0); |
2762 | } else if (atomic_read(&bus->intstatus) || | 2762 | } else if (atomic_read(&bus->intstatus) || |
@@ -3411,8 +3411,8 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus, | |||
3411 | goto err; | 3411 | goto err; |
3412 | } | 3412 | } |
3413 | 3413 | ||
3414 | /* Allow HT Clock now that the ARM is running. */ | 3414 | /* Allow full data communication using DPC from now on. */ |
3415 | brcmf_bus_change_state(bus->sdiodev->bus_if, BRCMF_BUS_LOAD); | 3415 | bus->sdiodev->state = BRCMF_STATE_DATA; |
3416 | bcmerror = 0; | 3416 | bcmerror = 0; |
3417 | 3417 | ||
3418 | err: | 3418 | err: |
@@ -3558,7 +3558,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus) | |||
3558 | return; | 3558 | return; |
3559 | } | 3559 | } |
3560 | 3560 | ||
3561 | if (!brcmf_bus_ready(bus->sdiodev->bus_if)) { | 3561 | if (bus->sdiodev->state != BRCMF_STATE_DATA) { |
3562 | brcmf_err("bus is down. we have nothing to do\n"); | 3562 | brcmf_err("bus is down. we have nothing to do\n"); |
3563 | return; | 3563 | return; |
3564 | } | 3564 | } |
@@ -3581,10 +3581,6 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus) | |||
3581 | 3581 | ||
3582 | static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus) | 3582 | static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus) |
3583 | { | 3583 | { |
3584 | #ifdef DEBUG | ||
3585 | struct brcmf_bus *bus_if = dev_get_drvdata(bus->sdiodev->dev); | ||
3586 | #endif /* DEBUG */ | ||
3587 | |||
3588 | brcmf_dbg(TIMER, "Enter\n"); | 3584 | brcmf_dbg(TIMER, "Enter\n"); |
3589 | 3585 | ||
3590 | /* Poll period: check device if appropriate. */ | 3586 | /* Poll period: check device if appropriate. */ |
@@ -3628,7 +3624,7 @@ static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus) | |||
3628 | } | 3624 | } |
3629 | #ifdef DEBUG | 3625 | #ifdef DEBUG |
3630 | /* Poll for console output periodically */ | 3626 | /* Poll for console output periodically */ |
3631 | if (bus_if && bus_if->state == BRCMF_BUS_DATA && | 3627 | if (bus->sdiodev->state == BRCMF_STATE_DATA && |
3632 | bus->console_interval != 0) { | 3628 | bus->console_interval != 0) { |
3633 | bus->console.count += BRCMF_WD_POLL_MS; | 3629 | bus->console.count += BRCMF_WD_POLL_MS; |
3634 | if (bus->console.count >= bus->console_interval) { | 3630 | if (bus->console.count >= bus->console_interval) { |
@@ -3869,11 +3865,6 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus) | |||
3869 | goto fail; | 3865 | goto fail; |
3870 | } | 3866 | } |
3871 | 3867 | ||
3872 | /* SDIO register access works so moving | ||
3873 | * state from UNKNOWN to DOWN. | ||
3874 | */ | ||
3875 | brcmf_bus_change_state(bus->sdiodev->bus_if, BRCMF_BUS_DOWN); | ||
3876 | |||
3877 | bus->ci = brcmf_chip_attach(bus->sdiodev, &brcmf_sdio_buscore_ops); | 3868 | bus->ci = brcmf_chip_attach(bus->sdiodev, &brcmf_sdio_buscore_ops); |
3878 | if (IS_ERR(bus->ci)) { | 3869 | if (IS_ERR(bus->ci)) { |
3879 | brcmf_err("brcmf_chip_attach failed!\n"); | 3870 | brcmf_err("brcmf_chip_attach failed!\n"); |
@@ -4007,18 +3998,16 @@ static void brcmf_sdio_firmware_callback(struct device *dev, | |||
4007 | 3998 | ||
4008 | brcmf_dbg(TRACE, "Enter: dev=%s\n", dev_name(dev)); | 3999 | brcmf_dbg(TRACE, "Enter: dev=%s\n", dev_name(dev)); |
4009 | 4000 | ||
4010 | /* try to download image and nvram to the dongle */ | ||
4011 | if (bus_if->state == BRCMF_BUS_DOWN) { | ||
4012 | bus->alp_only = true; | ||
4013 | err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len); | ||
4014 | if (err) | ||
4015 | goto fail; | ||
4016 | bus->alp_only = false; | ||
4017 | } | ||
4018 | |||
4019 | if (!bus_if->drvr) | 4001 | if (!bus_if->drvr) |
4020 | return; | 4002 | return; |
4021 | 4003 | ||
4004 | /* try to download image and nvram to the dongle */ | ||
4005 | bus->alp_only = true; | ||
4006 | err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len); | ||
4007 | if (err) | ||
4008 | goto fail; | ||
4009 | bus->alp_only = false; | ||
4010 | |||
4022 | /* Start the watchdog timer */ | 4011 | /* Start the watchdog timer */ |
4023 | bus->sdcnt.tickcnt = 0; | 4012 | bus->sdcnt.tickcnt = 0; |
4024 | brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS); | 4013 | brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS); |
@@ -4254,7 +4243,7 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus) | |||
4254 | destroy_workqueue(bus->brcmf_wq); | 4243 | destroy_workqueue(bus->brcmf_wq); |
4255 | 4244 | ||
4256 | if (bus->ci) { | 4245 | if (bus->ci) { |
4257 | if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) { | 4246 | if (bus->sdiodev->state != BRCMF_STATE_NOMEDIUM) { |
4258 | sdio_claim_host(bus->sdiodev->func[1]); | 4247 | sdio_claim_host(bus->sdiodev->func[1]); |
4259 | brcmf_sdio_clkctl(bus, CLK_AVAIL, false); | 4248 | brcmf_sdio_clkctl(bus, CLK_AVAIL, false); |
4260 | /* Leave the device in state where it is | 4249 | /* Leave the device in state where it is |
@@ -4289,7 +4278,7 @@ void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick) | |||
4289 | } | 4278 | } |
4290 | 4279 | ||
4291 | /* don't start the wd until fw is loaded */ | 4280 | /* don't start the wd until fw is loaded */ |
4292 | if (bus->sdiodev->bus_if->state != BRCMF_BUS_DATA) | 4281 | if (bus->sdiodev->state != BRCMF_STATE_DATA) |
4293 | return; | 4282 | return; |
4294 | 4283 | ||
4295 | if (wdtick) { | 4284 | if (wdtick) { |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio.h index 9c5d42d20b48..ec2586a8425c 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.h | |||
@@ -155,6 +155,13 @@ | |||
155 | /* watchdog polling interval in ms */ | 155 | /* watchdog polling interval in ms */ |
156 | #define BRCMF_WD_POLL_MS 10 | 156 | #define BRCMF_WD_POLL_MS 10 |
157 | 157 | ||
158 | /* The state of the bus */ | ||
159 | enum brcmf_sdio_state { | ||
160 | BRCMF_STATE_DOWN, /* Device available, still initialising */ | ||
161 | BRCMF_STATE_DATA, /* Ready for data transfers, DPC enabled */ | ||
162 | BRCMF_STATE_NOMEDIUM /* No medium access to dongle possible */ | ||
163 | }; | ||
164 | |||
158 | struct brcmf_sdreg { | 165 | struct brcmf_sdreg { |
159 | int func; | 166 | int func; |
160 | int offset; | 167 | int offset; |
@@ -187,6 +194,7 @@ struct brcmf_sdio_dev { | |||
187 | char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; | 194 | char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; |
188 | char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; | 195 | char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; |
189 | bool wowl_enabled; | 196 | bool wowl_enabled; |
197 | enum brcmf_sdio_state state; | ||
190 | }; | 198 | }; |
191 | 199 | ||
192 | /* sdio core registers */ | 200 | /* sdio core registers */ |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index 4572defc280f..7e0c9e2fa7f6 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c | |||
@@ -576,7 +576,7 @@ brcmf_usb_state_change(struct brcmf_usbdev_info *devinfo, int state) | |||
576 | brcmf_bus_change_state(bcmf_bus, BRCMF_BUS_DOWN); | 576 | brcmf_bus_change_state(bcmf_bus, BRCMF_BUS_DOWN); |
577 | } else if (state == BRCMFMAC_USB_STATE_UP) { | 577 | } else if (state == BRCMFMAC_USB_STATE_UP) { |
578 | brcmf_dbg(USB, "DBUS is up\n"); | 578 | brcmf_dbg(USB, "DBUS is up\n"); |
579 | brcmf_bus_change_state(bcmf_bus, BRCMF_BUS_DATA); | 579 | brcmf_bus_change_state(bcmf_bus, BRCMF_BUS_UP); |
580 | } else { | 580 | } else { |
581 | brcmf_dbg(USB, "DBUS current state=%d\n", state); | 581 | brcmf_dbg(USB, "DBUS current state=%d\n", state); |
582 | } | 582 | } |