aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex
diff options
context:
space:
mode:
authorZhaoyang Liu <liuzy@marvell.com>2015-03-13 08:07:59 -0400
committerKalle Valo <kvalo@codeaurora.org>2015-03-16 12:12:41 -0400
commit960d6d08e395d5441d53caa21083c0b6d38995f9 (patch)
tree547cc80e8509e9c37289412c0acc2a8be38810d1 /drivers/net/wireless/mwifiex
parent92263a841b1502d2ef19199deaa669fe4c0102e9 (diff)
mwifiex: delay skb allocation for RX until cmd53 over
This patch moves SKB allocation for RX packets from current place i.e. after reading MP regs to place where we already have read data from SDIO bus ie after cmd53. mp_rx_aggr_setup has been modified accordingly to set skb_arr to NULL. Signed-off-by: Zhaoyang Liu <liuzy@marvell.com> Signed-off-by: Shengzhen Li <szli@marvell.com> Reviewed-by: Amitkumar Karwar <akarwar@marvell.com> Reviewed-by: Cathy Luo <cluo@marvell.com> Reviewed-by: Avinash Patil <patila@marvell.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/mwifiex')
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c59
-rw-r--r--drivers/net/wireless/mwifiex/sdio.h8
2 files changed, 33 insertions, 34 deletions
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index fdeeb67f790a..330e9d06729d 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -1197,7 +1197,7 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter,
1197 * provided there is space left, processed and finally uploaded. 1197 * provided there is space left, processed and finally uploaded.
1198 */ 1198 */
1199static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, 1199static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1200 struct sk_buff *skb, u8 port) 1200 u16 rx_len, u8 port)
1201{ 1201{
1202 struct sdio_mmc_card *card = adapter->card; 1202 struct sdio_mmc_card *card = adapter->card;
1203 s32 f_do_rx_aggr = 0; 1203 s32 f_do_rx_aggr = 0;
@@ -1205,10 +1205,9 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1205 s32 f_aggr_cur = 0; 1205 s32 f_aggr_cur = 0;
1206 s32 f_post_aggr_cur = 0; 1206 s32 f_post_aggr_cur = 0;
1207 struct sk_buff *skb_deaggr; 1207 struct sk_buff *skb_deaggr;
1208 u32 pind; 1208 struct sk_buff *skb = NULL;
1209 u32 pkt_len, pkt_type, mport; 1209 u32 pkt_len, pkt_type, mport, pind;
1210 u8 *curr_ptr; 1210 u8 *curr_ptr;
1211 u32 rx_len = skb->len;
1212 1211
1213 if ((card->has_control_mask) && (port == CTRL_PORT)) { 1212 if ((card->has_control_mask) && (port == CTRL_PORT)) {
1214 /* Read the command Resp without aggr */ 1213 /* Read the command Resp without aggr */
@@ -1235,7 +1234,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1235 dev_dbg(adapter->dev, "info: %s: not last packet\n", __func__); 1234 dev_dbg(adapter->dev, "info: %s: not last packet\n", __func__);
1236 1235
1237 if (MP_RX_AGGR_IN_PROGRESS(card)) { 1236 if (MP_RX_AGGR_IN_PROGRESS(card)) {
1238 if (MP_RX_AGGR_BUF_HAS_ROOM(card, skb->len)) { 1237 if (MP_RX_AGGR_BUF_HAS_ROOM(card, rx_len)) {
1239 f_aggr_cur = 1; 1238 f_aggr_cur = 1;
1240 } else { 1239 } else {
1241 /* No room in Aggr buf, do rx aggr now */ 1240 /* No room in Aggr buf, do rx aggr now */
@@ -1253,7 +1252,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1253 1252
1254 if (MP_RX_AGGR_IN_PROGRESS(card)) { 1253 if (MP_RX_AGGR_IN_PROGRESS(card)) {
1255 f_do_rx_aggr = 1; 1254 f_do_rx_aggr = 1;
1256 if (MP_RX_AGGR_BUF_HAS_ROOM(card, skb->len)) 1255 if (MP_RX_AGGR_BUF_HAS_ROOM(card, rx_len))
1257 f_aggr_cur = 1; 1256 f_aggr_cur = 1;
1258 else 1257 else
1259 /* No room in Aggr buf, do rx aggr now */ 1258 /* No room in Aggr buf, do rx aggr now */
@@ -1266,7 +1265,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1266 if (f_aggr_cur) { 1265 if (f_aggr_cur) {
1267 dev_dbg(adapter->dev, "info: current packet aggregation\n"); 1266 dev_dbg(adapter->dev, "info: current packet aggregation\n");
1268 /* Curr pkt can be aggregated */ 1267 /* Curr pkt can be aggregated */
1269 mp_rx_aggr_setup(card, skb, port); 1268 mp_rx_aggr_setup(card, rx_len, port);
1270 1269
1271 if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) || 1270 if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) ||
1272 mp_rx_aggr_port_limit_reached(card)) { 1271 mp_rx_aggr_port_limit_reached(card)) {
@@ -1309,18 +1308,25 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1309 curr_ptr = card->mpa_rx.buf; 1308 curr_ptr = card->mpa_rx.buf;
1310 1309
1311 for (pind = 0; pind < card->mpa_rx.pkt_cnt; pind++) { 1310 for (pind = 0; pind < card->mpa_rx.pkt_cnt; pind++) {
1311 u32 *len_arr = card->mpa_rx.len_arr;
1312 1312
1313 /* get curr PKT len & type */ 1313 /* get curr PKT len & type */
1314 pkt_len = le16_to_cpu(*(__le16 *) &curr_ptr[0]); 1314 pkt_len = le16_to_cpu(*(__le16 *) &curr_ptr[0]);
1315 pkt_type = le16_to_cpu(*(__le16 *) &curr_ptr[2]); 1315 pkt_type = le16_to_cpu(*(__le16 *) &curr_ptr[2]);
1316 1316
1317 /* copy pkt to deaggr buf */ 1317 /* copy pkt to deaggr buf */
1318 skb_deaggr = card->mpa_rx.skb_arr[pind]; 1318 skb_deaggr = mwifiex_alloc_dma_align_buf(len_arr[pind],
1319 GFP_KERNEL |
1320 GFP_DMA);
1321 if (!skb_deaggr)
1322 goto error;
1323 skb_put(skb_deaggr, len_arr[pind]);
1324 card->mpa_rx.skb_arr[pind] = skb_deaggr;
1319 1325
1320 if ((pkt_type == MWIFIEX_TYPE_DATA || 1326 if ((pkt_type == MWIFIEX_TYPE_DATA ||
1321 (pkt_type == MWIFIEX_TYPE_AGGR_DATA && 1327 (pkt_type == MWIFIEX_TYPE_AGGR_DATA &&
1322 adapter->sdio_rx_aggr_enable)) && 1328 adapter->sdio_rx_aggr_enable)) &&
1323 (pkt_len <= card->mpa_rx.len_arr[pind])) { 1329 (pkt_len <= len_arr[pind])) {
1324 1330
1325 memcpy(skb_deaggr->data, curr_ptr, pkt_len); 1331 memcpy(skb_deaggr->data, curr_ptr, pkt_len);
1326 1332
@@ -1335,10 +1341,10 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1335 "type=%d len=%d max_len=%d\n", 1341 "type=%d len=%d max_len=%d\n",
1336 adapter->sdio_rx_aggr_enable, 1342 adapter->sdio_rx_aggr_enable,
1337 pkt_type, pkt_len, 1343 pkt_type, pkt_len,
1338 card->mpa_rx.len_arr[pind]); 1344 len_arr[pind]);
1339 dev_kfree_skb_any(skb_deaggr); 1345 dev_kfree_skb_any(skb_deaggr);
1340 } 1346 }
1341 curr_ptr += card->mpa_rx.len_arr[pind]; 1347 curr_ptr += len_arr[pind];
1342 } 1348 }
1343 MP_RX_AGGR_BUF_RESET(card); 1349 MP_RX_AGGR_BUF_RESET(card);
1344 } 1350 }
@@ -1347,6 +1353,10 @@ rx_curr_single:
1347 if (f_do_rx_cur) { 1353 if (f_do_rx_cur) {
1348 dev_dbg(adapter->dev, "info: RX: port: %d, rx_len: %d\n", 1354 dev_dbg(adapter->dev, "info: RX: port: %d, rx_len: %d\n",
1349 port, rx_len); 1355 port, rx_len);
1356 skb = mwifiex_alloc_dma_align_buf(rx_len, GFP_KERNEL | GFP_DMA);
1357 if (!skb)
1358 goto error;
1359 skb_put(skb, rx_len);
1350 1360
1351 if (mwifiex_sdio_card_to_host(adapter, &pkt_type, 1361 if (mwifiex_sdio_card_to_host(adapter, &pkt_type,
1352 skb->data, skb->len, 1362 skb->data, skb->len,
@@ -1365,7 +1375,7 @@ rx_curr_single:
1365 if (f_post_aggr_cur) { 1375 if (f_post_aggr_cur) {
1366 dev_dbg(adapter->dev, "info: current packet aggregation\n"); 1376 dev_dbg(adapter->dev, "info: current packet aggregation\n");
1367 /* Curr pkt can be aggregated */ 1377 /* Curr pkt can be aggregated */
1368 mp_rx_aggr_setup(card, skb, port); 1378 mp_rx_aggr_setup(card, skb->len, port);
1369 } 1379 }
1370 1380
1371 return 0; 1381 return 0;
@@ -1375,12 +1385,13 @@ error:
1375 for (pind = 0; pind < card->mpa_rx.pkt_cnt; pind++) { 1385 for (pind = 0; pind < card->mpa_rx.pkt_cnt; pind++) {
1376 /* copy pkt to deaggr buf */ 1386 /* copy pkt to deaggr buf */
1377 skb_deaggr = card->mpa_rx.skb_arr[pind]; 1387 skb_deaggr = card->mpa_rx.skb_arr[pind];
1378 dev_kfree_skb_any(skb_deaggr); 1388 if (skb_deaggr)
1389 dev_kfree_skb_any(skb_deaggr);
1379 } 1390 }
1380 MP_RX_AGGR_BUF_RESET(card); 1391 MP_RX_AGGR_BUF_RESET(card);
1381 } 1392 }
1382 1393
1383 if (f_do_rx_cur) 1394 if (f_do_rx_cur && skb)
1384 /* Single transfer pending. Free curr buff also */ 1395 /* Single transfer pending. Free curr buff also */
1385 dev_kfree_skb_any(skb); 1396 dev_kfree_skb_any(skb);
1386 1397
@@ -1442,6 +1453,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1442 MWIFIEX_RX_DATA_BUF_SIZE) 1453 MWIFIEX_RX_DATA_BUF_SIZE)
1443 return -1; 1454 return -1;
1444 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE); 1455 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
1456 dev_dbg(adapter->dev, "info: rx_len = %d\n", rx_len);
1445 1457
1446 skb = mwifiex_alloc_dma_align_buf(rx_len, GFP_KERNEL | GFP_DMA); 1458 skb = mwifiex_alloc_dma_align_buf(rx_len, GFP_KERNEL | GFP_DMA);
1447 if (!skb) 1459 if (!skb)
@@ -1538,24 +1550,11 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1538 rx_len); 1550 rx_len);
1539 return -1; 1551 return -1;
1540 } 1552 }
1541 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
1542 1553
1543 skb = mwifiex_alloc_dma_align_buf(rx_len, 1554 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
1544 GFP_KERNEL | 1555 dev_dbg(adapter->dev, "info: rx_len = %d\n", rx_len);
1545 GFP_DMA);
1546
1547 if (!skb) {
1548 dev_err(adapter->dev, "%s: failed to alloc skb",
1549 __func__);
1550 return -1;
1551 }
1552
1553 skb_put(skb, rx_len);
1554
1555 dev_dbg(adapter->dev, "info: rx_len = %d skb->len = %d\n",
1556 rx_len, skb->len);
1557 1556
1558 if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb, 1557 if (mwifiex_sdio_card_to_host_mp_aggr(adapter, rx_len,
1559 port)) { 1558 port)) {
1560 dev_err(adapter->dev, "card_to_host_mpa failed:" 1559 dev_err(adapter->dev, "card_to_host_mpa failed:"
1561 " int status=%#x\n", sdio_ireg); 1560 " int status=%#x\n", sdio_ireg);
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
index 264bc9b9e02a..6f645cf47369 100644
--- a/drivers/net/wireless/mwifiex/sdio.h
+++ b/drivers/net/wireless/mwifiex/sdio.h
@@ -573,9 +573,9 @@ mp_tx_aggr_port_limit_reached(struct sdio_mmc_card *card)
573 573
574/* Prepare to copy current packet from card to SDIO Rx aggregation buffer */ 574/* Prepare to copy current packet from card to SDIO Rx aggregation buffer */
575static inline void mp_rx_aggr_setup(struct sdio_mmc_card *card, 575static inline void mp_rx_aggr_setup(struct sdio_mmc_card *card,
576 struct sk_buff *skb, u8 port) 576 u16 rx_len, u8 port)
577{ 577{
578 card->mpa_rx.buf_len += skb->len; 578 card->mpa_rx.buf_len += rx_len;
579 579
580 if (!card->mpa_rx.pkt_cnt) 580 if (!card->mpa_rx.pkt_cnt)
581 card->mpa_rx.start_port = port; 581 card->mpa_rx.start_port = port;
@@ -588,8 +588,8 @@ static inline void mp_rx_aggr_setup(struct sdio_mmc_card *card,
588 else 588 else
589 card->mpa_rx.ports |= 1 << (card->mpa_rx.pkt_cnt + 1); 589 card->mpa_rx.ports |= 1 << (card->mpa_rx.pkt_cnt + 1);
590 } 590 }
591 card->mpa_rx.skb_arr[card->mpa_rx.pkt_cnt] = skb; 591 card->mpa_rx.skb_arr[card->mpa_rx.pkt_cnt] = NULL;
592 card->mpa_rx.len_arr[card->mpa_rx.pkt_cnt] = skb->len; 592 card->mpa_rx.len_arr[card->mpa_rx.pkt_cnt] = rx_len;
593 card->mpa_rx.pkt_cnt++; 593 card->mpa_rx.pkt_cnt++;
594} 594}
595#endif /* _MWIFIEX_SDIO_H */ 595#endif /* _MWIFIEX_SDIO_H */