aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211/brcmfmac
diff options
context:
space:
mode:
authorArend van Spriel <arend@broadcom.com>2015-02-06 12:36:42 -0500
committerKalle Valo <kvalo@codeaurora.org>2015-02-26 08:14:14 -0500
commita1ce7a0d6a4f1ed178c075c9dc02a06f0c68ab70 (patch)
tree8eab1cd47968a44baf23a8f38c24bb2ff63e070c /drivers/net/wireless/brcm80211/brcmfmac
parentffdcad05968ccb9ca2bb66f0e72467aa87baf2c2 (diff)
brcmfmac: use helper function for changing SDIO state
Changing the SDIO state of the driver involves changing the bus interface state. Adding a helper function makes sure that knowledge is in one place. Reviewed-by: Hante Meuleman <meuleman@broadcom.com> Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com> Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@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/brcmfmac')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c41
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio.c18
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio.h21
3 files changed, 54 insertions, 26 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 7944224e3fc9..1f7e2f245e9e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -197,6 +197,30 @@ int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
197 return 0; 197 return 0;
198} 198}
199 199
200void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev,
201 enum brcmf_sdiod_state state)
202{
203 if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM ||
204 state == sdiodev->state)
205 return;
206
207 brcmf_dbg(TRACE, "%d -> %d\n", sdiodev->state, state);
208 switch (sdiodev->state) {
209 case BRCMF_SDIOD_DATA:
210 /* any other state means bus interface is down */
211 brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_DOWN);
212 break;
213 case BRCMF_SDIOD_DOWN:
214 /* transition from DOWN to DATA means bus interface is up */
215 if (state == BRCMF_SDIOD_DATA)
216 brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_UP);
217 break;
218 default:
219 break;
220 }
221 sdiodev->state = state;
222}
223
200static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, 224static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func,
201 uint regaddr, u8 byte) 225 uint regaddr, u8 byte)
202{ 226{
@@ -269,12 +293,6 @@ static int brcmf_sdiod_request_data(struct brcmf_sdio_dev *sdiodev, u8 fn,
269 return ret; 293 return ret;
270} 294}
271 295
272static 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
278static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, 296static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
279 u8 regsz, void *data, bool write) 297 u8 regsz, void *data, bool write)
280{ 298{
@@ -282,7 +300,7 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
282 s32 retry = 0; 300 s32 retry = 0;
283 int ret; 301 int ret;
284 302
285 if (sdiodev->state == BRCMF_STATE_NOMEDIUM) 303 if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
286 return -ENOMEDIUM; 304 return -ENOMEDIUM;
287 305
288 /* 306 /*
@@ -308,7 +326,7 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
308 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); 326 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
309 327
310 if (ret == -ENOMEDIUM) 328 if (ret == -ENOMEDIUM)
311 brcmf_sdiod_nomedium_state(sdiodev); 329 brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
312 else if (ret != 0) { 330 else if (ret != 0) {
313 /* 331 /*
314 * SleepCSR register access can fail when 332 * SleepCSR register access can fail when
@@ -331,7 +349,7 @@ brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
331 int err = 0, i; 349 int err = 0, i;
332 u8 addr[3]; 350 u8 addr[3];
333 351
334 if (sdiodev->state == BRCMF_STATE_NOMEDIUM) 352 if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
335 return -ENOMEDIUM; 353 return -ENOMEDIUM;
336 354
337 addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK; 355 addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK;
@@ -460,7 +478,7 @@ static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
460 err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr, 478 err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr,
461 req_sz); 479 req_sz);
462 if (err == -ENOMEDIUM) 480 if (err == -ENOMEDIUM)
463 brcmf_sdiod_nomedium_state(sdiodev); 481 brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
464 return err; 482 return err;
465} 483}
466 484
@@ -595,7 +613,7 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
595 613
596 ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error; 614 ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error;
597 if (ret == -ENOMEDIUM) { 615 if (ret == -ENOMEDIUM) {
598 brcmf_sdiod_nomedium_state(sdiodev); 616 brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
599 break; 617 break;
600 } else if (ret != 0) { 618 } else if (ret != 0) {
601 brcmf_err("CMD53 sg block %s failed %d\n", 619 brcmf_err("CMD53 sg block %s failed %d\n",
@@ -1050,6 +1068,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
1050 bus_if->wowl_supported = true; 1068 bus_if->wowl_supported = true;
1051#endif 1069#endif
1052 1070
1071 brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_DOWN);
1053 sdiodev->sleeping = false; 1072 sdiodev->sleeping = false;
1054 atomic_set(&sdiodev->suspend, false); 1073 atomic_set(&sdiodev->suspend, false);
1055 init_waitqueue_head(&sdiodev->idle_wait); 1074 init_waitqueue_head(&sdiodev->idle_wait);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
index 314ab0391867..f3c49c4201e9 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 && bus->sdiodev->state == BRCMF_STATE_DATA; 1912 !bus->rxskip && rxleft && bus->sdiodev->state == BRCMF_SDIOD_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->state == BRCMF_STATE_DATA) && 2418 if ((bus->sdiodev->state == BRCMF_SDIOD_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 (sdiodev->state != BRCMF_STATE_NOMEDIUM) { 2506 if (sdiodev->state != BRCMF_SDIOD_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 */
@@ -2755,7 +2755,7 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2755 brcmf_sdio_sendfromq(bus, framecnt); 2755 brcmf_sdio_sendfromq(bus, framecnt);
2756 } 2756 }
2757 2757
2758 if ((bus->sdiodev->state != BRCMF_STATE_DATA) || (err != 0)) { 2758 if ((bus->sdiodev->state != BRCMF_SDIOD_DATA) || (err != 0)) {
2759 brcmf_err("failed backplane access over SDIO, halting operation\n"); 2759 brcmf_err("failed backplane access over SDIO, halting operation\n");
2760 atomic_set(&bus->intstatus, 0); 2760 atomic_set(&bus->intstatus, 0);
2761 } else if (atomic_read(&bus->intstatus) || 2761 } else if (atomic_read(&bus->intstatus) ||
@@ -3411,7 +3411,7 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus,
3411 } 3411 }
3412 3412
3413 /* Allow full data communication using DPC from now on. */ 3413 /* Allow full data communication using DPC from now on. */
3414 bus->sdiodev->state = BRCMF_STATE_DATA; 3414 brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA);
3415 bcmerror = 0; 3415 bcmerror = 0;
3416 3416
3417err: 3417err:
@@ -3557,7 +3557,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus)
3557 return; 3557 return;
3558 } 3558 }
3559 3559
3560 if (bus->sdiodev->state != BRCMF_STATE_DATA) { 3560 if (bus->sdiodev->state != BRCMF_SDIOD_DATA) {
3561 brcmf_err("bus is down. we have nothing to do\n"); 3561 brcmf_err("bus is down. we have nothing to do\n");
3562 return; 3562 return;
3563 } 3563 }
@@ -3623,7 +3623,7 @@ static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
3623 } 3623 }
3624#ifdef DEBUG 3624#ifdef DEBUG
3625 /* Poll for console output periodically */ 3625 /* Poll for console output periodically */
3626 if (bus->sdiodev->state == BRCMF_STATE_DATA && 3626 if (bus->sdiodev->state == BRCMF_SDIOD_DATA &&
3627 bus->console_interval != 0) { 3627 bus->console_interval != 0) {
3628 bus->console.count += BRCMF_WD_POLL_MS; 3628 bus->console.count += BRCMF_WD_POLL_MS;
3629 if (bus->console.count >= bus->console_interval) { 3629 if (bus->console.count >= bus->console_interval) {
@@ -4242,7 +4242,7 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus)
4242 destroy_workqueue(bus->brcmf_wq); 4242 destroy_workqueue(bus->brcmf_wq);
4243 4243
4244 if (bus->ci) { 4244 if (bus->ci) {
4245 if (bus->sdiodev->state != BRCMF_STATE_NOMEDIUM) { 4245 if (bus->sdiodev->state != BRCMF_SDIOD_NOMEDIUM) {
4246 sdio_claim_host(bus->sdiodev->func[1]); 4246 sdio_claim_host(bus->sdiodev->func[1]);
4247 brcmf_sdio_clkctl(bus, CLK_AVAIL, false); 4247 brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
4248 /* Leave the device in state where it is 4248 /* Leave the device in state where it is
@@ -4277,7 +4277,7 @@ void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick)
4277 } 4277 }
4278 4278
4279 /* don't start the wd until fw is loaded */ 4279 /* don't start the wd until fw is loaded */
4280 if (bus->sdiodev->state != BRCMF_STATE_DATA) 4280 if (bus->sdiodev->state != BRCMF_SDIOD_DATA)
4281 return; 4281 return;
4282 4282
4283 if (wdtick) { 4283 if (wdtick) {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio.h
index ec2586a8425c..a6cdc6061c3a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.h
@@ -155,11 +155,17 @@
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 */ 158/**
159enum brcmf_sdio_state { 159 * enum brcmf_sdiod_state - the state of the bus.
160 BRCMF_STATE_DOWN, /* Device available, still initialising */ 160 *
161 BRCMF_STATE_DATA, /* Ready for data transfers, DPC enabled */ 161 * @BRCMF_SDIOD_DOWN: Device can be accessed, no DPC.
162 BRCMF_STATE_NOMEDIUM /* No medium access to dongle possible */ 162 * @BRCMF_SDIOD_DATA: Ready for data transfers, DPC enabled.
163 * @BRCMF_SDIOD_NOMEDIUM: No medium access to dongle possible.
164 */
165enum brcmf_sdiod_state {
166 BRCMF_SDIOD_DOWN,
167 BRCMF_SDIOD_DATA,
168 BRCMF_SDIOD_NOMEDIUM
163}; 169};
164 170
165struct brcmf_sdreg { 171struct brcmf_sdreg {
@@ -194,7 +200,7 @@ struct brcmf_sdio_dev {
194 char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; 200 char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
195 char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; 201 char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
196 bool wowl_enabled; 202 bool wowl_enabled;
197 enum brcmf_sdio_state state; 203 enum brcmf_sdiod_state state;
198}; 204};
199 205
200/* sdio core registers */ 206/* sdio core registers */
@@ -345,4 +351,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus);
345void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick); 351void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick);
346void brcmf_sdio_wowl_config(struct device *dev, bool enabled); 352void brcmf_sdio_wowl_config(struct device *dev, bool enabled);
347 353
354void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev,
355 enum brcmf_sdiod_state state);
356
348#endif /* BRCMFMAC_SDIO_H */ 357#endif /* BRCMFMAC_SDIO_H */