diff options
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 110 |
1 files changed, 44 insertions, 66 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 2c644a93c5bc..5338f57620b4 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | |||
@@ -629,43 +629,29 @@ static bool data_ok(struct brcmf_sdio *bus) | |||
629 | * Reads a register in the SDIO hardware block. This block occupies a series of | 629 | * Reads a register in the SDIO hardware block. This block occupies a series of |
630 | * adresses on the 32 bit backplane bus. | 630 | * adresses on the 32 bit backplane bus. |
631 | */ | 631 | */ |
632 | static void | 632 | static int |
633 | r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset, u32 *retryvar) | 633 | r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset) |
634 | { | 634 | { |
635 | u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); | 635 | u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); |
636 | int ret; | 636 | int ret; |
637 | *retryvar = 0; | 637 | |
638 | do { | 638 | *regvar = brcmf_sdio_regrl(bus->sdiodev, |
639 | *regvar = brcmf_sdio_regrl(bus->sdiodev, | 639 | bus->ci->c_inf[idx].base + offset, &ret); |
640 | bus->ci->c_inf[idx].base + offset, | 640 | |
641 | &ret); | 641 | return ret; |
642 | } while ((ret != 0) && (++(*retryvar) <= retry_limit)); | ||
643 | if (*retryvar) { | ||
644 | bus->regfails += (*retryvar-1); | ||
645 | if (*retryvar > retry_limit) { | ||
646 | brcmf_dbg(ERROR, "FAILED READ %Xh\n", offset); | ||
647 | *regvar = 0; | ||
648 | } | ||
649 | } | ||
650 | } | 642 | } |
651 | 643 | ||
652 | static void | 644 | static int |
653 | w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset, u32 *retryvar) | 645 | w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset) |
654 | { | 646 | { |
655 | u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); | 647 | u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); |
656 | int ret; | 648 | int ret; |
657 | *retryvar = 0; | 649 | |
658 | do { | 650 | brcmf_sdio_regwl(bus->sdiodev, |
659 | brcmf_sdio_regwl(bus->sdiodev, | 651 | bus->ci->c_inf[idx].base + reg_offset, |
660 | bus->ci->c_inf[idx].base + reg_offset, | 652 | regval, &ret); |
661 | regval, &ret); | 653 | |
662 | } while ((ret != 0) && (++(*retryvar) <= retry_limit)); | 654 | return ret; |
663 | if (*retryvar) { | ||
664 | bus->regfails += (*retryvar-1); | ||
665 | if (*retryvar > retry_limit) | ||
666 | brcmf_dbg(ERROR, "FAILED REGISTER WRITE %Xh\n", | ||
667 | reg_offset); | ||
668 | } | ||
669 | } | 655 | } |
670 | 656 | ||
671 | #define PKT_AVAILABLE() (intstatus & I_HMB_FRAME_IND) | 657 | #define PKT_AVAILABLE() (intstatus & I_HMB_FRAME_IND) |
@@ -870,7 +856,7 @@ static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok) | |||
870 | 856 | ||
871 | static int brcmf_sdbrcm_bussleep(struct brcmf_sdio *bus, bool sleep) | 857 | static int brcmf_sdbrcm_bussleep(struct brcmf_sdio *bus, bool sleep) |
872 | { | 858 | { |
873 | uint retries = 0; | 859 | int ret; |
874 | 860 | ||
875 | brcmf_dbg(INFO, "request %s (currently %s)\n", | 861 | brcmf_dbg(INFO, "request %s (currently %s)\n", |
876 | sleep ? "SLEEP" : "WAKE", | 862 | sleep ? "SLEEP" : "WAKE", |
@@ -890,9 +876,9 @@ static int brcmf_sdbrcm_bussleep(struct brcmf_sdio *bus, bool sleep) | |||
890 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | 876 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); |
891 | 877 | ||
892 | /* Tell device to start using OOB wakeup */ | 878 | /* Tell device to start using OOB wakeup */ |
893 | w_sdreg32(bus, SMB_USE_OOB, | 879 | ret = w_sdreg32(bus, SMB_USE_OOB, |
894 | offsetof(struct sdpcmd_regs, tosbmailbox), &retries); | 880 | offsetof(struct sdpcmd_regs, tosbmailbox)); |
895 | if (retries > retry_limit) | 881 | if (ret != 0) |
896 | brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n"); | 882 | brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n"); |
897 | 883 | ||
898 | /* Turn off our contribution to the HT clock request */ | 884 | /* Turn off our contribution to the HT clock request */ |
@@ -918,14 +904,13 @@ static int brcmf_sdbrcm_bussleep(struct brcmf_sdio *bus, bool sleep) | |||
918 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | 904 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); |
919 | 905 | ||
920 | /* Send misc interrupt to indicate OOB not needed */ | 906 | /* Send misc interrupt to indicate OOB not needed */ |
921 | w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, tosbmailboxdata), | 907 | ret = w_sdreg32(bus, 0, |
922 | &retries); | 908 | offsetof(struct sdpcmd_regs, tosbmailboxdata)); |
923 | if (retries <= retry_limit) | 909 | if (ret == 0) |
924 | w_sdreg32(bus, SMB_DEV_INT, | 910 | ret = w_sdreg32(bus, SMB_DEV_INT, |
925 | offsetof(struct sdpcmd_regs, tosbmailbox), | 911 | offsetof(struct sdpcmd_regs, tosbmailbox)); |
926 | &retries); | 912 | |
927 | 913 | if (ret != 0) | |
928 | if (retries > retry_limit) | ||
929 | brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP TO CLEAR OOB!!\n"); | 914 | brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP TO CLEAR OOB!!\n"); |
930 | 915 | ||
931 | /* Make sure we have SD bus access */ | 916 | /* Make sure we have SD bus access */ |
@@ -949,17 +934,17 @@ static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus) | |||
949 | u32 intstatus = 0; | 934 | u32 intstatus = 0; |
950 | u32 hmb_data; | 935 | u32 hmb_data; |
951 | u8 fcbits; | 936 | u8 fcbits; |
952 | uint retries = 0; | 937 | int ret; |
953 | 938 | ||
954 | brcmf_dbg(TRACE, "Enter\n"); | 939 | brcmf_dbg(TRACE, "Enter\n"); |
955 | 940 | ||
956 | /* Read mailbox data and ack that we did so */ | 941 | /* Read mailbox data and ack that we did so */ |
957 | r_sdreg32(bus, &hmb_data, | 942 | ret = r_sdreg32(bus, &hmb_data, |
958 | offsetof(struct sdpcmd_regs, tohostmailboxdata), &retries); | 943 | offsetof(struct sdpcmd_regs, tohostmailboxdata)); |
959 | 944 | ||
960 | if (retries <= retry_limit) | 945 | if (ret == 0) |
961 | w_sdreg32(bus, SMB_INT_ACK, | 946 | w_sdreg32(bus, SMB_INT_ACK, |
962 | offsetof(struct sdpcmd_regs, tosbmailbox), &retries); | 947 | offsetof(struct sdpcmd_regs, tosbmailbox)); |
963 | bus->f1regdata += 2; | 948 | bus->f1regdata += 2; |
964 | 949 | ||
965 | /* Dongle recomposed rx frames, accept them again */ | 950 | /* Dongle recomposed rx frames, accept them again */ |
@@ -1063,11 +1048,11 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx) | |||
1063 | 1048 | ||
1064 | if (rtx) { | 1049 | if (rtx) { |
1065 | bus->rxrtx++; | 1050 | bus->rxrtx++; |
1066 | w_sdreg32(bus, SMB_NAK, | 1051 | err = w_sdreg32(bus, SMB_NAK, |
1067 | offsetof(struct sdpcmd_regs, tosbmailbox), &retries); | 1052 | offsetof(struct sdpcmd_regs, tosbmailbox)); |
1068 | 1053 | ||
1069 | bus->f1regdata++; | 1054 | bus->f1regdata++; |
1070 | if (retries <= retry_limit) | 1055 | if (err == 0) |
1071 | bus->rxskip = true; | 1056 | bus->rxskip = true; |
1072 | } | 1057 | } |
1073 | 1058 | ||
@@ -2207,7 +2192,6 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes) | |||
2207 | { | 2192 | { |
2208 | struct sk_buff *pkt; | 2193 | struct sk_buff *pkt; |
2209 | u32 intstatus = 0; | 2194 | u32 intstatus = 0; |
2210 | uint retries = 0; | ||
2211 | int ret = 0, prec_out; | 2195 | int ret = 0, prec_out; |
2212 | uint cnt = 0; | 2196 | uint cnt = 0; |
2213 | uint datalen; | 2197 | uint datalen; |
@@ -2238,8 +2222,7 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes) | |||
2238 | if (!bus->intr && cnt) { | 2222 | if (!bus->intr && cnt) { |
2239 | /* Check device status, signal pending interrupt */ | 2223 | /* Check device status, signal pending interrupt */ |
2240 | r_sdreg32(bus, &intstatus, | 2224 | r_sdreg32(bus, &intstatus, |
2241 | offsetof(struct sdpcmd_regs, intstatus), | 2225 | offsetof(struct sdpcmd_regs, intstatus)); |
2242 | &retries); | ||
2243 | bus->f2txdata++; | 2226 | bus->f2txdata++; |
2244 | if (brcmf_sdcard_regfail(bus->sdiodev)) | 2227 | if (brcmf_sdcard_regfail(bus->sdiodev)) |
2245 | break; | 2228 | break; |
@@ -2263,7 +2246,6 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) | |||
2263 | { | 2246 | { |
2264 | u32 local_hostintmask; | 2247 | u32 local_hostintmask; |
2265 | u8 saveclk; | 2248 | u8 saveclk; |
2266 | uint retries; | ||
2267 | int err; | 2249 | int err; |
2268 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | 2250 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); |
2269 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; | 2251 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; |
@@ -2291,7 +2273,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) | |||
2291 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | 2273 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); |
2292 | 2274 | ||
2293 | /* Disable and clear interrupts at the chip level also */ | 2275 | /* Disable and clear interrupts at the chip level also */ |
2294 | w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask), &retries); | 2276 | w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask)); |
2295 | local_hostintmask = bus->hostintmask; | 2277 | local_hostintmask = bus->hostintmask; |
2296 | bus->hostintmask = 0; | 2278 | bus->hostintmask = 0; |
2297 | 2279 | ||
@@ -2315,7 +2297,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) | |||
2315 | 2297 | ||
2316 | /* Clear any pending interrupts now that F2 is disabled */ | 2298 | /* Clear any pending interrupts now that F2 is disabled */ |
2317 | w_sdreg32(bus, local_hostintmask, | 2299 | w_sdreg32(bus, local_hostintmask, |
2318 | offsetof(struct sdpcmd_regs, intstatus), &retries); | 2300 | offsetof(struct sdpcmd_regs, intstatus)); |
2319 | 2301 | ||
2320 | /* Turn off the backplane clock (only) */ | 2302 | /* Turn off the backplane clock (only) */ |
2321 | brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); | 2303 | brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); |
@@ -2360,7 +2342,6 @@ static inline void brcmf_sdbrcm_clrintr(struct brcmf_sdio *bus) | |||
2360 | static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) | 2342 | static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) |
2361 | { | 2343 | { |
2362 | u32 intstatus, newstatus = 0; | 2344 | u32 intstatus, newstatus = 0; |
2363 | uint retries = 0; | ||
2364 | uint rxlimit = bus->rxbound; /* Rx frames to read before resched */ | 2345 | uint rxlimit = bus->rxbound; /* Rx frames to read before resched */ |
2365 | uint txlimit = bus->txbound; /* Tx frames to send before resched */ | 2346 | uint txlimit = bus->txbound; /* Tx frames to send before resched */ |
2366 | uint framecnt = 0; /* Temporary counter of tx/rx frames */ | 2347 | uint framecnt = 0; /* Temporary counter of tx/rx frames */ |
@@ -2434,7 +2415,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) | |||
2434 | if (bus->ipend) { | 2415 | if (bus->ipend) { |
2435 | bus->ipend = false; | 2416 | bus->ipend = false; |
2436 | r_sdreg32(bus, &newstatus, | 2417 | r_sdreg32(bus, &newstatus, |
2437 | offsetof(struct sdpcmd_regs, intstatus), &retries); | 2418 | offsetof(struct sdpcmd_regs, intstatus)); |
2438 | bus->f1regdata++; | 2419 | bus->f1regdata++; |
2439 | if (brcmf_sdcard_regfail(bus->sdiodev)) | 2420 | if (brcmf_sdcard_regfail(bus->sdiodev)) |
2440 | newstatus = 0; | 2421 | newstatus = 0; |
@@ -2442,8 +2423,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) | |||
2442 | bus->fcstate = !!(newstatus & I_HMB_FC_STATE); | 2423 | bus->fcstate = !!(newstatus & I_HMB_FC_STATE); |
2443 | if (newstatus) { | 2424 | if (newstatus) { |
2444 | w_sdreg32(bus, newstatus, | 2425 | w_sdreg32(bus, newstatus, |
2445 | offsetof(struct sdpcmd_regs, intstatus), | 2426 | offsetof(struct sdpcmd_regs, intstatus)); |
2446 | &retries); | ||
2447 | bus->f1regdata++; | 2427 | bus->f1regdata++; |
2448 | } | 2428 | } |
2449 | } | 2429 | } |
@@ -2459,10 +2439,10 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) | |||
2459 | if (intstatus & I_HMB_FC_CHANGE) { | 2439 | if (intstatus & I_HMB_FC_CHANGE) { |
2460 | intstatus &= ~I_HMB_FC_CHANGE; | 2440 | intstatus &= ~I_HMB_FC_CHANGE; |
2461 | w_sdreg32(bus, I_HMB_FC_CHANGE, | 2441 | w_sdreg32(bus, I_HMB_FC_CHANGE, |
2462 | offsetof(struct sdpcmd_regs, intstatus), &retries); | 2442 | offsetof(struct sdpcmd_regs, intstatus)); |
2463 | 2443 | ||
2464 | r_sdreg32(bus, &newstatus, | 2444 | r_sdreg32(bus, &newstatus, |
2465 | offsetof(struct sdpcmd_regs, intstatus), &retries); | 2445 | offsetof(struct sdpcmd_regs, intstatus)); |
2466 | bus->f1regdata += 2; | 2446 | bus->f1regdata += 2; |
2467 | bus->fcstate = | 2447 | bus->fcstate = |
2468 | !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE)); | 2448 | !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE)); |
@@ -3168,7 +3148,6 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus) | |||
3168 | 3148 | ||
3169 | static int brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter) | 3149 | static int brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter) |
3170 | { | 3150 | { |
3171 | uint retries; | ||
3172 | int bcmerror = 0; | 3151 | int bcmerror = 0; |
3173 | struct chip_info *ci = bus->ci; | 3152 | struct chip_info *ci = bus->ci; |
3174 | 3153 | ||
@@ -3202,7 +3181,7 @@ static int brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter) | |||
3202 | } | 3181 | } |
3203 | 3182 | ||
3204 | w_sdreg32(bus, 0xFFFFFFFF, | 3183 | w_sdreg32(bus, 0xFFFFFFFF, |
3205 | offsetof(struct sdpcmd_regs, intstatus), &retries); | 3184 | offsetof(struct sdpcmd_regs, intstatus)); |
3206 | 3185 | ||
3207 | ci->resetcore(bus->sdiodev, ci, BCMA_CORE_ARM_CM3); | 3186 | ci->resetcore(bus->sdiodev, ci, BCMA_CORE_ARM_CM3); |
3208 | 3187 | ||
@@ -3424,7 +3403,6 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) | |||
3424 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; | 3403 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; |
3425 | struct brcmf_sdio *bus = sdiodev->bus; | 3404 | struct brcmf_sdio *bus = sdiodev->bus; |
3426 | unsigned long timeout; | 3405 | unsigned long timeout; |
3427 | uint retries = 0; | ||
3428 | u8 ready, enable; | 3406 | u8 ready, enable; |
3429 | int err, ret = 0; | 3407 | int err, ret = 0; |
3430 | u8 saveclk; | 3408 | u8 saveclk; |
@@ -3465,7 +3443,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) | |||
3465 | 3443 | ||
3466 | /* Enable function 2 (frame transfers) */ | 3444 | /* Enable function 2 (frame transfers) */ |
3467 | w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT, | 3445 | w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT, |
3468 | offsetof(struct sdpcmd_regs, tosbmailboxdata), &retries); | 3446 | offsetof(struct sdpcmd_regs, tosbmailboxdata)); |
3469 | enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2); | 3447 | enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2); |
3470 | 3448 | ||
3471 | brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, enable, NULL); | 3449 | brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, enable, NULL); |
@@ -3489,7 +3467,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) | |||
3489 | /* Set up the interrupt mask and enable interrupts */ | 3467 | /* Set up the interrupt mask and enable interrupts */ |
3490 | bus->hostintmask = HOSTINTMASK; | 3468 | bus->hostintmask = HOSTINTMASK; |
3491 | w_sdreg32(bus, bus->hostintmask, | 3469 | w_sdreg32(bus, bus->hostintmask, |
3492 | offsetof(struct sdpcmd_regs, hostintmask), &retries); | 3470 | offsetof(struct sdpcmd_regs, hostintmask)); |
3493 | 3471 | ||
3494 | brcmf_sdio_regwb(bus->sdiodev, SBSDIO_WATERMARK, 8, &err); | 3472 | brcmf_sdio_regwb(bus->sdiodev, SBSDIO_WATERMARK, 8, &err); |
3495 | } else { | 3473 | } else { |