diff options
author | Hante Meuleman <meuleman@broadcom.com> | 2014-02-25 14:30:35 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-02-28 14:33:43 -0500 |
commit | 81c7883c46fddd53b7a98c3659ffae21189ae4ab (patch) | |
tree | a5c10566d276aee988eefbdc47ccba802092e11e | |
parent | 848819f43878a3a3f7c659fee3b6e16c334c3062 (diff) |
brcmfmac: Put frame sdio tx error handling in sub function.
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 112 |
1 files changed, 33 insertions, 79 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 0ccb7affeb04..c894ee358153 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | |||
@@ -1237,6 +1237,28 @@ static void brcmf_sdio_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx) | |||
1237 | bus->cur_read.len = 0; | 1237 | bus->cur_read.len = 0; |
1238 | } | 1238 | } |
1239 | 1239 | ||
1240 | static void brcmf_sdio_txfail(struct brcmf_sdio *bus) | ||
1241 | { | ||
1242 | struct brcmf_sdio_dev *sdiodev = bus->sdiodev; | ||
1243 | u8 i, hi, lo; | ||
1244 | |||
1245 | /* On failure, abort the command and terminate the frame */ | ||
1246 | brcmf_err("sdio error, abort command and terminate frame\n"); | ||
1247 | bus->sdcnt.tx_sderrs++; | ||
1248 | |||
1249 | brcmf_sdiod_abort(sdiodev, SDIO_FUNC_2); | ||
1250 | brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL); | ||
1251 | bus->sdcnt.f1regdata++; | ||
1252 | |||
1253 | for (i = 0; i < 3; i++) { | ||
1254 | hi = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_WFRAMEBCHI, NULL); | ||
1255 | lo = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_WFRAMEBCLO, NULL); | ||
1256 | bus->sdcnt.f1regdata += 2; | ||
1257 | if ((hi == 0) && (lo == 0)) | ||
1258 | break; | ||
1259 | } | ||
1260 | } | ||
1261 | |||
1240 | /* return total length of buffer chain */ | 1262 | /* return total length of buffer chain */ |
1241 | static uint brcmf_sdio_glom_len(struct brcmf_sdio *bus) | 1263 | static uint brcmf_sdio_glom_len(struct brcmf_sdio *bus) |
1242 | { | 1264 | { |
@@ -2252,7 +2274,6 @@ static int brcmf_sdio_txpkt(struct brcmf_sdio *bus, struct sk_buff_head *pktq, | |||
2252 | uint chan) | 2274 | uint chan) |
2253 | { | 2275 | { |
2254 | int ret; | 2276 | int ret; |
2255 | int i; | ||
2256 | struct sk_buff *pkt_next, *tmp; | 2277 | struct sk_buff *pkt_next, *tmp; |
2257 | 2278 | ||
2258 | brcmf_dbg(TRACE, "Enter\n"); | 2279 | brcmf_dbg(TRACE, "Enter\n"); |
@@ -2265,28 +2286,9 @@ static int brcmf_sdio_txpkt(struct brcmf_sdio *bus, struct sk_buff_head *pktq, | |||
2265 | ret = brcmf_sdiod_send_pkt(bus->sdiodev, pktq); | 2286 | ret = brcmf_sdiod_send_pkt(bus->sdiodev, pktq); |
2266 | bus->sdcnt.f2txdata++; | 2287 | bus->sdcnt.f2txdata++; |
2267 | 2288 | ||
2268 | if (ret < 0) { | 2289 | if (ret < 0) |
2269 | /* On failure, abort the command and terminate the frame */ | 2290 | brcmf_sdio_txfail(bus); |
2270 | brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n", | ||
2271 | ret); | ||
2272 | bus->sdcnt.tx_sderrs++; | ||
2273 | 2291 | ||
2274 | brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2); | ||
2275 | brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, | ||
2276 | SFC_WF_TERM, NULL); | ||
2277 | bus->sdcnt.f1regdata++; | ||
2278 | |||
2279 | for (i = 0; i < 3; i++) { | ||
2280 | u8 hi, lo; | ||
2281 | hi = brcmf_sdiod_regrb(bus->sdiodev, | ||
2282 | SBSDIO_FUNC1_WFRAMEBCHI, NULL); | ||
2283 | lo = brcmf_sdiod_regrb(bus->sdiodev, | ||
2284 | SBSDIO_FUNC1_WFRAMEBCLO, NULL); | ||
2285 | bus->sdcnt.f1regdata += 2; | ||
2286 | if ((hi == 0) && (lo == 0)) | ||
2287 | break; | ||
2288 | } | ||
2289 | } | ||
2290 | sdio_release_host(bus->sdiodev->func[1]); | 2292 | sdio_release_host(bus->sdiodev->func[1]); |
2291 | 2293 | ||
2292 | done: | 2294 | done: |
@@ -2588,42 +2590,17 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus) | |||
2588 | brcmf_sdio_clrintr(bus); | 2590 | brcmf_sdio_clrintr(bus); |
2589 | 2591 | ||
2590 | if (data_ok(bus) && bus->ctrl_frame_stat && | 2592 | if (data_ok(bus) && bus->ctrl_frame_stat && |
2591 | (bus->clkstate == CLK_AVAIL)) { | 2593 | (bus->clkstate == CLK_AVAIL)) { |
2592 | int i; | ||
2593 | 2594 | ||
2594 | sdio_claim_host(bus->sdiodev->func[1]); | 2595 | sdio_claim_host(bus->sdiodev->func[1]); |
2595 | err = brcmf_sdiod_send_buf(bus->sdiodev, bus->ctrl_frame_buf, | 2596 | err = brcmf_sdiod_send_buf(bus->sdiodev, bus->ctrl_frame_buf, |
2596 | (u32)bus->ctrl_frame_len); | 2597 | (u32)bus->ctrl_frame_len); |
2597 | 2598 | ||
2598 | if (err < 0) { | 2599 | if (err < 0) |
2599 | /* On failure, abort the command and | 2600 | brcmf_sdio_txfail(bus); |
2600 | terminate the frame */ | 2601 | else |
2601 | brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n", | ||
2602 | err); | ||
2603 | bus->sdcnt.tx_sderrs++; | ||
2604 | |||
2605 | brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2); | ||
2606 | |||
2607 | brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, | ||
2608 | SFC_WF_TERM, &err); | ||
2609 | bus->sdcnt.f1regdata++; | ||
2610 | |||
2611 | for (i = 0; i < 3; i++) { | ||
2612 | u8 hi, lo; | ||
2613 | hi = brcmf_sdiod_regrb(bus->sdiodev, | ||
2614 | SBSDIO_FUNC1_WFRAMEBCHI, | ||
2615 | &err); | ||
2616 | lo = brcmf_sdiod_regrb(bus->sdiodev, | ||
2617 | SBSDIO_FUNC1_WFRAMEBCLO, | ||
2618 | &err); | ||
2619 | bus->sdcnt.f1regdata += 2; | ||
2620 | if ((hi == 0) && (lo == 0)) | ||
2621 | break; | ||
2622 | } | ||
2623 | |||
2624 | } else { | ||
2625 | bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP; | 2602 | bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP; |
2626 | } | 2603 | |
2627 | sdio_release_host(bus->sdiodev->func[1]); | 2604 | sdio_release_host(bus->sdiodev->func[1]); |
2628 | bus->ctrl_frame_stat = false; | 2605 | bus->ctrl_frame_stat = false; |
2629 | brcmf_sdio_wait_event_wakeup(bus); | 2606 | brcmf_sdio_wait_event_wakeup(bus); |
@@ -2793,38 +2770,15 @@ break2: | |||
2793 | 2770 | ||
2794 | static int brcmf_sdio_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len) | 2771 | static int brcmf_sdio_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len) |
2795 | { | 2772 | { |
2796 | int i; | ||
2797 | int ret; | 2773 | int ret; |
2798 | 2774 | ||
2799 | bus->ctrl_frame_stat = false; | 2775 | bus->ctrl_frame_stat = false; |
2800 | ret = brcmf_sdiod_send_buf(bus->sdiodev, frame, len); | 2776 | ret = brcmf_sdiod_send_buf(bus->sdiodev, frame, len); |
2801 | 2777 | ||
2802 | if (ret < 0) { | 2778 | if (ret < 0) |
2803 | /* On failure, abort the command and terminate the frame */ | 2779 | brcmf_sdio_txfail(bus); |
2804 | brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n", | 2780 | else |
2805 | ret); | 2781 | bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP; |
2806 | bus->sdcnt.tx_sderrs++; | ||
2807 | |||
2808 | brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2); | ||
2809 | |||
2810 | brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, | ||
2811 | SFC_WF_TERM, NULL); | ||
2812 | bus->sdcnt.f1regdata++; | ||
2813 | |||
2814 | for (i = 0; i < 3; i++) { | ||
2815 | u8 hi, lo; | ||
2816 | hi = brcmf_sdiod_regrb(bus->sdiodev, | ||
2817 | SBSDIO_FUNC1_WFRAMEBCHI, NULL); | ||
2818 | lo = brcmf_sdiod_regrb(bus->sdiodev, | ||
2819 | SBSDIO_FUNC1_WFRAMEBCLO, NULL); | ||
2820 | bus->sdcnt.f1regdata += 2; | ||
2821 | if (hi == 0 && lo == 0) | ||
2822 | break; | ||
2823 | } | ||
2824 | return ret; | ||
2825 | } | ||
2826 | |||
2827 | bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP; | ||
2828 | 2782 | ||
2829 | return ret; | 2783 | return ret; |
2830 | } | 2784 | } |