diff options
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 97 |
1 files changed, 72 insertions, 25 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index bbaeb2d5c93a..4e75c191c290 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | |||
@@ -204,16 +204,79 @@ int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev, | |||
204 | return err_ret; | 204 | return err_ret; |
205 | } | 205 | } |
206 | 206 | ||
207 | /* precondition: host controller is claimed */ | ||
208 | static int | ||
209 | brcmf_sdioh_request_data(struct brcmf_sdio_dev *sdiodev, uint write, bool fifo, | ||
210 | uint func, uint addr, struct sk_buff *pkt, uint pktlen) | ||
211 | { | ||
212 | int err_ret = 0; | ||
213 | |||
214 | if ((write) && (!fifo)) { | ||
215 | err_ret = sdio_memcpy_toio(sdiodev->func[func], addr, | ||
216 | ((u8 *) (pkt->data)), pktlen); | ||
217 | } else if (write) { | ||
218 | err_ret = sdio_memcpy_toio(sdiodev->func[func], addr, | ||
219 | ((u8 *) (pkt->data)), pktlen); | ||
220 | } else if (fifo) { | ||
221 | err_ret = sdio_readsb(sdiodev->func[func], | ||
222 | ((u8 *) (pkt->data)), addr, pktlen); | ||
223 | } else { | ||
224 | err_ret = sdio_memcpy_fromio(sdiodev->func[func], | ||
225 | ((u8 *) (pkt->data)), | ||
226 | addr, pktlen); | ||
227 | } | ||
228 | |||
229 | return err_ret; | ||
230 | } | ||
231 | |||
207 | static int | 232 | static int |
208 | brcmf_sdioh_request_packet(struct brcmf_sdio_dev *sdiodev, uint fix_inc, | 233 | brcmf_sdioh_request_packet(struct brcmf_sdio_dev *sdiodev, uint fix_inc, |
209 | uint write, uint func, uint addr, | 234 | uint write, uint func, uint addr, |
210 | struct sk_buff *pkt) | 235 | struct sk_buff *pkt) |
211 | { | 236 | { |
212 | bool fifo = (fix_inc == SDIOH_DATA_FIX); | 237 | bool fifo = (fix_inc == SDIOH_DATA_FIX); |
238 | int err_ret = 0; | ||
239 | uint pkt_len = pkt->len; | ||
240 | |||
241 | brcmf_dbg(TRACE, "Enter\n"); | ||
242 | |||
243 | brcmf_pm_resume_wait(sdiodev, &sdiodev->request_packet_wait); | ||
244 | if (brcmf_pm_resume_error(sdiodev)) | ||
245 | return -EIO; | ||
246 | |||
247 | /* Claim host controller */ | ||
248 | sdio_claim_host(sdiodev->func[func]); | ||
249 | |||
250 | pkt_len += 3; | ||
251 | pkt_len &= 0xFFFFFFFC; | ||
252 | |||
253 | err_ret = brcmf_sdioh_request_data(sdiodev, write, fifo, func, | ||
254 | addr, pkt, pkt_len); | ||
255 | if (err_ret) { | ||
256 | brcmf_dbg(ERROR, "%s FAILED %p, addr=0x%05x, pkt_len=%d, ERR=0x%08x\n", | ||
257 | write ? "TX" : "RX", pkt, addr, pkt_len, err_ret); | ||
258 | } else { | ||
259 | brcmf_dbg(TRACE, "%s xfr'd %p, addr=0x%05x, len=%d\n", | ||
260 | write ? "TX" : "RX", pkt, addr, pkt_len); | ||
261 | } | ||
262 | |||
263 | /* Release host controller */ | ||
264 | sdio_release_host(sdiodev->func[func]); | ||
265 | |||
266 | brcmf_dbg(TRACE, "Exit\n"); | ||
267 | return err_ret; | ||
268 | } | ||
269 | |||
270 | int | ||
271 | brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc, | ||
272 | uint write, uint func, uint addr, | ||
273 | struct sk_buff_head *pktq) | ||
274 | { | ||
275 | bool fifo = (fix_inc == SDIOH_DATA_FIX); | ||
213 | u32 SGCount = 0; | 276 | u32 SGCount = 0; |
214 | int err_ret = 0; | 277 | int err_ret = 0; |
215 | 278 | ||
216 | struct sk_buff *pnext; | 279 | struct sk_buff *pkt; |
217 | 280 | ||
218 | brcmf_dbg(TRACE, "Enter\n"); | 281 | brcmf_dbg(TRACE, "Enter\n"); |
219 | 282 | ||
@@ -223,43 +286,27 @@ brcmf_sdioh_request_packet(struct brcmf_sdio_dev *sdiodev, uint fix_inc, | |||
223 | 286 | ||
224 | /* Claim host controller */ | 287 | /* Claim host controller */ |
225 | sdio_claim_host(sdiodev->func[func]); | 288 | sdio_claim_host(sdiodev->func[func]); |
226 | for (pnext = pkt; pnext; pnext = pnext->next) { | 289 | |
227 | uint pkt_len = pnext->len; | 290 | skb_queue_walk(pktq, pkt) { |
291 | uint pkt_len = pkt->len; | ||
228 | pkt_len += 3; | 292 | pkt_len += 3; |
229 | pkt_len &= 0xFFFFFFFC; | 293 | pkt_len &= 0xFFFFFFFC; |
230 | 294 | ||
231 | if ((write) && (!fifo)) { | 295 | err_ret = brcmf_sdioh_request_data(sdiodev, write, fifo, func, |
232 | err_ret = sdio_memcpy_toio(sdiodev->func[func], addr, | 296 | addr, pkt, pkt_len); |
233 | ((u8 *) (pnext->data)), | ||
234 | pkt_len); | ||
235 | } else if (write) { | ||
236 | err_ret = sdio_memcpy_toio(sdiodev->func[func], addr, | ||
237 | ((u8 *) (pnext->data)), | ||
238 | pkt_len); | ||
239 | } else if (fifo) { | ||
240 | err_ret = sdio_readsb(sdiodev->func[func], | ||
241 | ((u8 *) (pnext->data)), | ||
242 | addr, pkt_len); | ||
243 | } else { | ||
244 | err_ret = sdio_memcpy_fromio(sdiodev->func[func], | ||
245 | ((u8 *) (pnext->data)), | ||
246 | addr, pkt_len); | ||
247 | } | ||
248 | |||
249 | if (err_ret) { | 297 | if (err_ret) { |
250 | brcmf_dbg(ERROR, "%s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=0x%08x\n", | 298 | brcmf_dbg(ERROR, "%s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=0x%08x\n", |
251 | write ? "TX" : "RX", pnext, SGCount, addr, | 299 | write ? "TX" : "RX", pkt, SGCount, addr, |
252 | pkt_len, err_ret); | 300 | pkt_len, err_ret); |
253 | } else { | 301 | } else { |
254 | brcmf_dbg(TRACE, "%s xfr'd %p[%d], addr=0x%05x, len=%d\n", | 302 | brcmf_dbg(TRACE, "%s xfr'd %p[%d], addr=0x%05x, len=%d\n", |
255 | write ? "TX" : "RX", pnext, SGCount, addr, | 303 | write ? "TX" : "RX", pkt, SGCount, addr, |
256 | pkt_len); | 304 | pkt_len); |
257 | } | 305 | } |
258 | |||
259 | if (!fifo) | 306 | if (!fifo) |
260 | addr += pkt_len; | 307 | addr += pkt_len; |
261 | SGCount++; | ||
262 | 308 | ||
309 | SGCount++; | ||
263 | } | 310 | } |
264 | 311 | ||
265 | /* Release host controller */ | 312 | /* Release host controller */ |