Search Linux Wireless

Re: [patch 3/5] A-MSDU Rx aggregation support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 26 Mar 2007 04:40:00 -0700 mohamed wrote:

> Add A-MSDU Rx aggregation support.
> 
> To support IEEE 802.11n, we need to be able to process A-MSDU frames. 
> The present of the HT control field indicates it is A-MSDU frame. 
> This patch adds support to discover and process A-MSDU frames.
> 
> Signed-off-by: Mohamed Abbas <mabbas@xxxxxxxxxxxxxxx>
> 
> diff -Nupr wireless-dev/net/mac80211/ieee80211.c
> wireless-dev-new/net/mac80211/ieee80211.c
> --- wireless-dev/net/mac80211/ieee80211.c	2007-03-27 00:36:24.000000000
> -0700
> +++ wireless-dev-new/net/mac80211/ieee80211.c	2007-03-27
> 01:54:48.000000000 -0700
> @@ -2446,6 +2446,143 @@ static inline int ieee80211_bssid_match(
>  }
>  
>  
> +inline static unsigned int calc_pad_len(unsigned int len) 
> +{ 
> +	return (4 - len % 4) % 4; 

Oops, line ends with a space.  Please, no lines that end with
space or tab.

Is gcc doing shifts for these % operations?  Hope so.

> +}
> +
> +inline static int is_agg_frame(struct sk_buff *skb, u16 fc)
> +{
> +	u8 *p = skb->data + ieee80211_get_hdrlen(fc) - 2;
> +
> +	if (!(fc & IEEE80211_STYPE_QOS_DATA));

line ends with ';' ???

> +		return 0;
> +
> +	if (*p & QOS_CONTROL_A_MSDU_PRESENT)
> +		return 1;
> +	else

'else' not needed (just a style thing)

> +		return 0;
> +}
> +
> +static ieee80211_txrx_result
> +ieee80211_rx_h_data_agg(struct ieee80211_txrx_data *rx)
> +{
> +	struct net_device *dev = rx->dev;
> +	struct ieee80211_local *local = rx->local;
> +	u16 fc, hdrlen, ethertype;
> +	u8 *payload;
> +	struct sk_buff *skb = rx->skb, *skb2, *frame;
> +	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
> +	const struct ethhdr* eth;
> +
> +	fc = rx->fc;
> +	if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA))
> +		return TXRX_CONTINUE;
> +
> +	if (unlikely(!WLAN_FC_DATA_PRESENT(fc)))
> +		return TXRX_DROP;
> +
> +	if (!is_agg_frame(skb, fc))
> +		return TXRX_CONTINUE;
> +
> +	hdrlen = ieee80211_get_hdrlen(fc);
> +
> +	payload = skb->data + hdrlen;
> +
> +	if (unlikely(skb->len - hdrlen < 8)) {
> +		if (net_ratelimit()) {
> +			printk(KERN_DEBUG "%s: RX too short data frame "
> +				"payload\n", dev->name);
> +		}
> +		return TXRX_DROP;
> +	}
> +
> +	ethertype = (payload[6] << 8) | payload[7];
> +
> +	if (likely((memcmp(payload, rfc1042_header, 6) == 0 &&
> +		ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
> +		memcmp(payload, bridge_tunnel_header, 6) == 0)) {
> +		/* remove RFC1042 or Bridge-Tunnel encapsulation and
> +		* replace EtherType */	
> +		skb_pull(skb, hdrlen + 6);
> +	} else {
> +		skb_pull(skb, hdrlen);
> +	}

No braces on single-statement "blocks".  (happens elsewhere also)

> +
> +	eth = (struct ethhdr*)skb->data;
> +
> +	while ((u8*)eth < skb->data + skb->len) {
> +        	unsigned int eth_len = sizeof(struct ethhdr) + 
> +						ntohs(eth->h_proto);
> +        
> +		frame = dev_alloc_skb(3000);

Why 3000?  can it be a well-defined #define??

> +
> +		if (frame == NULL) 
> +			return TXRX_DROP;
> +
> +		frame->mac.raw = frame->data;
> +		memcpy(skb_put(frame, eth_len), (u8*)eth, eth_len);
> +
> +		frame->dev = dev;
> +
> +		skb2 = NULL;
> +
> +		sdata->stats.rx_packets++;
> +		sdata->stats.rx_bytes += frame->len;
> +
> +		if (local->bridge_packets && 
> +		    (sdata->type == IEEE80211_IF_TYPE_AP ||
> +		     sdata->type == IEEE80211_IF_TYPE_VLAN) && 
> +                    rx->u.rx.ra_match) {
> +			if (is_multicast_ether_addr(frame->data)) {
> +				/* send multicast frames both to higher layers
> +				* in local net stack and back to the wireless 
> +				* media */
> +				skb2 = skb_copy(frame, GFP_ATOMIC);
> +				if (!skb2)
> +					printk(KERN_DEBUG "%s: failed to clone "
> +					"multicast frame\n", dev->name);

more indentation on last part.

> +			} else {
> +				struct sta_info *dsta;
> +				dsta = sta_info_get(local, frame->data);
> +				if (dsta && !dsta->dev) {
> +					printk(KERN_DEBUG "Station with null "
> +					"dev structure!\n");

Indentation.  no braces.

> +                        	} else if (dsta && dsta->dev == dev) {
> +                                	/* Destination station is associated 
> +					* to this AP, so send the frame
> +					* directly to it and do not pass 
> +					* the frame to local net stack.
> +					*/
> +					skb2 = skb;
> +					skb = NULL;
> +				}
> +				if (dsta)
> +					sta_info_put(dsta);
> +			}
> +		}
> +		if (frame) {
> +			/* deliver to local stack */
> +			frame->protocol = eth_type_trans(frame, dev);
> +			memset(frame->cb, 0, sizeof(frame->cb));
> +			netif_rx(frame);
> +		}
> +
> +		if (skb2) {
> +			/* send to wireless media */
> +			skb2->protocol = __constant_htons(ETH_P_802_3);
> +			skb2->mac.raw = skb2->nh.raw = skb2->data;
> +			dev_queue_xmit(skb2);
> +		}
> +
> +		eth = (struct ethhdr*)((u8*)eth + eth_len 
> +					+ calc_pad_len(eth_len));
> +	}
> +
> +	dev_kfree_skb(skb);
> +        return TXRX_QUEUED;

Inconsisten indentation above.  'return' line is using spaces
instead of a tab.

> +}
> +
>  static ieee80211_txrx_result
>  ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
>  {


---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
-
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux