Skip to content

Commit

Permalink
mwifiex: use ieee80211_amsdu_to_8023s routine
Browse files Browse the repository at this point in the history
mwifiex was using its own implementation of converting 802.11n
AMSDU to 802.3s.  This patch removes mwifiex specific
implementation and uses existing ieee80211_amsdu_to_8023s
routine.

Signed-off-by: Yogesh Ashok Powar <yogeshp@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Yogesh Ashok Powar authored and John W. Linville committed May 16, 2011
1 parent 8b3beca commit 3b8ab88
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 127 deletions.
125 changes: 0 additions & 125 deletions drivers/net/wireless/mwifiex/11n_aggr.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,131 +135,6 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv,
}
}

/*
* Counts the number of subframes in an aggregate packet.
*
* This function parses an aggregate packet buffer, looking for
* subframes and counting the number of such subframe found. The
* function automatically skips the DA/SA fields at the beginning
* of each subframe and padding at the end.
*/
static int
mwifiex_11n_get_num_aggr_pkts(u8 *data, int total_pkt_len)
{
int pkt_count = 0, pkt_len, pad;

while (total_pkt_len > 0) {
/* Length will be in network format, change it to host */
pkt_len = ntohs((*(__be16 *)(data + 2 * ETH_ALEN)));
pad = (((pkt_len + sizeof(struct ethhdr)) & 3)) ?
(4 - ((pkt_len + sizeof(struct ethhdr)) & 3)) : 0;
data += pkt_len + pad + sizeof(struct ethhdr);
total_pkt_len -= pkt_len + pad + sizeof(struct ethhdr);
++pkt_count;
}

return pkt_count;
}

/*
* De-aggregate received packets.
*
* This function parses the received aggregate buffer, extracts each subframe,
* strips off the SNAP header from them and sends the data portion for further
* processing.
*
* Each subframe body is copied onto a separate buffer, which are freed by
* upper layer after processing. The function also performs sanity tests on
* the received buffer.
*/
int mwifiex_11n_deaggregate_pkt(struct mwifiex_private *priv,
struct sk_buff *skb)
{
u16 pkt_len;
int total_pkt_len;
u8 *data;
int pad;
struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
struct rxpd *local_rx_pd = (struct rxpd *) skb->data;
struct sk_buff *skb_daggr;
struct mwifiex_rxinfo *rx_info_daggr;
int ret = -1;
struct rx_packet_hdr *rx_pkt_hdr;
struct mwifiex_adapter *adapter = priv->adapter;
u8 rfc1042_eth_hdr[ETH_ALEN] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};

data = (u8 *) (local_rx_pd + local_rx_pd->rx_pkt_offset);
total_pkt_len = local_rx_pd->rx_pkt_length;

/* Sanity test */
if (total_pkt_len > MWIFIEX_RX_DATA_BUF_SIZE) {
dev_err(adapter->dev, "total pkt len greater than buffer"
" size %d\n", total_pkt_len);
return -1;
}

rx_info->use_count = mwifiex_11n_get_num_aggr_pkts(data, total_pkt_len);

while (total_pkt_len > 0) {
rx_pkt_hdr = (struct rx_packet_hdr *) data;
/* Length will be in network format, change it to host */
pkt_len = ntohs((*(__be16 *) (data + 2 * ETH_ALEN)));
if (pkt_len > total_pkt_len) {
dev_err(adapter->dev, "pkt_len %d > total_pkt_len %d\n",
total_pkt_len, pkt_len);
break;
}

pad = (((pkt_len + sizeof(struct ethhdr)) & 3)) ?
(4 - ((pkt_len + sizeof(struct ethhdr)) & 3)) : 0;

total_pkt_len -= pkt_len + pad + sizeof(struct ethhdr);

if (memcmp(&rx_pkt_hdr->rfc1042_hdr,
rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr)) == 0) {
memmove(data + LLC_SNAP_LEN, data, 2 * ETH_ALEN);
data += LLC_SNAP_LEN;
pkt_len += sizeof(struct ethhdr) - LLC_SNAP_LEN;
} else {
*(u16 *) (data + 2 * ETH_ALEN) = (u16) 0;
pkt_len += sizeof(struct ethhdr);
}

skb_daggr = dev_alloc_skb(pkt_len);
if (!skb_daggr) {
dev_err(adapter->dev, "%s: failed to alloc skb_daggr\n",
__func__);
return -1;
}
rx_info_daggr = MWIFIEX_SKB_RXCB(skb_daggr);

rx_info_daggr->bss_index = rx_info->bss_index;
skb_daggr->tstamp = skb->tstamp;
rx_info_daggr->parent = skb;
skb_daggr->priority = skb->priority;
skb_put(skb_daggr, pkt_len);
memcpy(skb_daggr->data, data, pkt_len);

ret = mwifiex_recv_packet(adapter, skb_daggr);

switch (ret) {
case -EINPROGRESS:
break;
case -1:
dev_err(adapter->dev, "deaggr: host_to_card failed\n");
case 0:
mwifiex_recv_packet_complete(adapter, skb_daggr, ret);
break;
default:
break;
}

data += pkt_len + pad;
}

return ret;
}

/*
* Create aggregated packet.
*
Expand Down
22 changes: 20 additions & 2 deletions drivers/net/wireless/mwifiex/sta_rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,28 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter,
dev_kfree_skb_any(skb);
return ret;
}

if (local_rx_pd->rx_pkt_type == PKT_TYPE_AMSDU) {
mwifiex_11n_deaggregate_pkt(priv, skb);
return ret;
struct sk_buff_head list;
struct sk_buff *rx_skb;

__skb_queue_head_init(&list);

skb_pull(skb, local_rx_pd->rx_pkt_offset);
skb_trim(skb, local_rx_pd->rx_pkt_length);

ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr,
priv->wdev->iftype, 0, false);

while (!skb_queue_empty(&list)) {
rx_skb = __skb_dequeue(&list);
ret = mwifiex_recv_packet(adapter, rx_skb);
if (ret == -1)
dev_err(adapter->dev, "Rx of A-MSDU failed");
}
return 0;
}

/*
* If the packet is not an unicast packet then send the packet
* directly to os. Don't pass thru rx reordering
Expand Down

0 comments on commit 3b8ab88

Please sign in to comment.