aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHante Meuleman <meuleman@broadcom.com>2014-02-25 14:30:35 -0500
committerJohn W. Linville <linville@tuxdriver.com>2014-02-28 14:33:43 -0500
commit81c7883c46fddd53b7a98c3659ffae21189ae4ab (patch)
treea5c10566d276aee988eefbdc47ccba802092e11e
parent848819f43878a3a3f7c659fee3b6e16c334c3062 (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.c112
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
1240static 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 */
1241static uint brcmf_sdio_glom_len(struct brcmf_sdio *bus) 1263static 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
2292done: 2294done:
@@ -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
2794static int brcmf_sdio_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len) 2771static 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}