aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwmc3200wifi
diff options
context:
space:
mode:
authorZhu Yi <yi.zhu@intel.com>2009-11-30 21:18:38 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-12-22 13:31:16 -0500
commit18974b5b0b5e758d416c550553b143e5c8038281 (patch)
tree58a50707ace9a9be37c525e6fd72cba18b90fde3 /drivers/net/wireless/iwmc3200wifi
parenteaf85ca7fecb218fc41ff57c1642ca73b097aabb (diff)
iwmc3200wifi: rx aggregation support
When the device receives an A-MSDU frame (indicated by flag IWM_RX_TICKET_AMSDU_MSK), use ieee80211_amsdu_to_8023s to convert it to a list of 802.3 frames and handled them to upper layer. Cc: Johannes Berg <johannes@sipsolutions.net> Acked-by: Samuel Ortiz <samuel@sortiz.org> Signed-off-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwmc3200wifi')
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.c46
1 files changed, 41 insertions, 5 deletions
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index 72c27a3e5528..6bd253ac533f 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -1534,6 +1534,33 @@ static void classify8023(struct sk_buff *skb)
1534 } 1534 }
1535} 1535}
1536 1536
1537static void iwm_rx_process_amsdu(struct iwm_priv *iwm, struct sk_buff *skb)
1538{
1539 struct wireless_dev *wdev = iwm_to_wdev(iwm);
1540 struct net_device *ndev = iwm_to_ndev(iwm);
1541 struct sk_buff_head list;
1542 struct sk_buff *frame;
1543
1544 IWM_HEXDUMP(iwm, DBG, RX, "A-MSDU: ", skb->data, skb->len);
1545
1546 __skb_queue_head_init(&list);
1547 ieee80211_amsdu_to_8023s(skb, &list, ndev->dev_addr, wdev->iftype, 0);
1548
1549 while ((frame = __skb_dequeue(&list))) {
1550 ndev->stats.rx_packets++;
1551 ndev->stats.rx_bytes += frame->len;
1552
1553 frame->protocol = eth_type_trans(frame, ndev);
1554 frame->ip_summed = CHECKSUM_NONE;
1555 memset(frame->cb, 0, sizeof(frame->cb));
1556
1557 if (netif_rx_ni(frame) == NET_RX_DROP) {
1558 IWM_ERR(iwm, "Packet dropped\n");
1559 ndev->stats.rx_dropped++;
1560 }
1561 }
1562}
1563
1537static void iwm_rx_process_packet(struct iwm_priv *iwm, 1564static void iwm_rx_process_packet(struct iwm_priv *iwm,
1538 struct iwm_rx_packet *packet, 1565 struct iwm_rx_packet *packet,
1539 struct iwm_rx_ticket_node *ticket_node) 1566 struct iwm_rx_ticket_node *ticket_node)
@@ -1548,25 +1575,34 @@ static void iwm_rx_process_packet(struct iwm_priv *iwm,
1548 switch (le16_to_cpu(ticket_node->ticket->action)) { 1575 switch (le16_to_cpu(ticket_node->ticket->action)) {
1549 case IWM_RX_TICKET_RELEASE: 1576 case IWM_RX_TICKET_RELEASE:
1550 IWM_DBG_RX(iwm, DBG, "RELEASE packet\n"); 1577 IWM_DBG_RX(iwm, DBG, "RELEASE packet\n");
1551 classify8023(skb); 1578
1552 iwm_rx_adjust_packet(iwm, packet, ticket_node); 1579 iwm_rx_adjust_packet(iwm, packet, ticket_node);
1580 skb->dev = iwm_to_ndev(iwm);
1581 classify8023(skb);
1582
1583 if (le16_to_cpu(ticket_node->ticket->flags) &
1584 IWM_RX_TICKET_AMSDU_MSK) {
1585 iwm_rx_process_amsdu(iwm, skb);
1586 break;
1587 }
1588
1553 ret = ieee80211_data_to_8023(skb, ndev->dev_addr, wdev->iftype); 1589 ret = ieee80211_data_to_8023(skb, ndev->dev_addr, wdev->iftype);
1554 if (ret < 0) { 1590 if (ret < 0) {
1555 IWM_DBG_RX(iwm, DBG, "Couldn't convert 802.11 header - " 1591 IWM_DBG_RX(iwm, DBG, "Couldn't convert 802.11 header - "
1556 "%d\n", ret); 1592 "%d\n", ret);
1593 kfree_skb(packet->skb);
1557 break; 1594 break;
1558 } 1595 }
1559 1596
1560 IWM_HEXDUMP(iwm, DBG, RX, "802.3: ", skb->data, skb->len); 1597 IWM_HEXDUMP(iwm, DBG, RX, "802.3: ", skb->data, skb->len);
1561 1598
1562 skb->dev = iwm_to_ndev(iwm); 1599 ndev->stats.rx_packets++;
1600 ndev->stats.rx_bytes += skb->len;
1601
1563 skb->protocol = eth_type_trans(skb, ndev); 1602 skb->protocol = eth_type_trans(skb, ndev);
1564 skb->ip_summed = CHECKSUM_NONE; 1603 skb->ip_summed = CHECKSUM_NONE;
1565 memset(skb->cb, 0, sizeof(skb->cb)); 1604 memset(skb->cb, 0, sizeof(skb->cb));
1566 1605
1567 ndev->stats.rx_packets++;
1568 ndev->stats.rx_bytes += skb->len;
1569
1570 if (netif_rx_ni(skb) == NET_RX_DROP) { 1606 if (netif_rx_ni(skb) == NET_RX_DROP) {
1571 IWM_ERR(iwm, "Packet dropped\n"); 1607 IWM_ERR(iwm, "Packet dropped\n");
1572 ndev->stats.rx_dropped++; 1608 ndev->stats.rx_dropped++;