aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c97
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 */
208static int
209brcmf_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
207static int 232static int
208brcmf_sdioh_request_packet(struct brcmf_sdio_dev *sdiodev, uint fix_inc, 233brcmf_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
270int
271brcmf_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 */