diff options
Diffstat (limited to 'net/mac80211/wme.c')
| -rw-r--r-- | net/mac80211/wme.c | 82 | 
1 files changed, 44 insertions, 38 deletions
| diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 5f7c96368b11..6a3187883c4b 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c @@ -141,6 +141,42 @@ u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata,  	return ieee80211_downgrade_queue(sdata, NULL, skb);  } +u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, +			     struct sta_info *sta, struct sk_buff *skb) +{ +	struct mac80211_qos_map *qos_map; +	bool qos; + +	/* all mesh/ocb stations are required to support WME */ +	if (sdata->vif.type == NL80211_IFTYPE_MESH_POINT || +	    sdata->vif.type == NL80211_IFTYPE_OCB) +		qos = true; +	else if (sta) +		qos = sta->sta.wme; +	else +		qos = false; + +	if (!qos) { +		skb->priority = 0; /* required for correct WPA/11i MIC */ +		return IEEE80211_AC_BE; +	} + +	if (skb->protocol == sdata->control_port_protocol) { +		skb->priority = 7; +		goto downgrade; +	} + +	/* use the data classifier to determine what 802.1d tag the +	 * data frame has */ +	qos_map = rcu_dereference(sdata->qos_map); +	skb->priority = cfg80211_classify8021d(skb, qos_map ? +					       &qos_map->qos_map : NULL); + + downgrade: +	return ieee80211_downgrade_queue(sdata, sta, skb); +} + +  /* Indicate which queue to use. */  u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,  			   struct sk_buff *skb) @@ -148,10 +184,12 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,  	struct ieee80211_local *local = sdata->local;  	struct sta_info *sta = NULL;  	const u8 *ra = NULL; -	bool qos = false; -	struct mac80211_qos_map *qos_map;  	u16 ret; +	/* when using iTXQ, we can do this later */ +	if (local->ops->wake_tx_queue) +		return 0; +  	if (local->hw.queues < IEEE80211_NUM_ACS || skb->len < 6) {  		skb->priority = 0; /* required for correct WPA/11i MIC */  		return 0; @@ -161,10 +199,8 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,  	switch (sdata->vif.type) {  	case NL80211_IFTYPE_AP_VLAN:  		sta = rcu_dereference(sdata->u.vlan.sta); -		if (sta) { -			qos = sta->sta.wme; +		if (sta)  			break; -		}  		/* fall through */  	case NL80211_IFTYPE_AP:  		ra = skb->data; @@ -172,56 +208,26 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,  	case NL80211_IFTYPE_WDS:  		ra = sdata->u.wds.remote_addr;  		break; -#ifdef CONFIG_MAC80211_MESH -	case NL80211_IFTYPE_MESH_POINT: -		qos = true; -		break; -#endif  	case NL80211_IFTYPE_STATION:  		/* might be a TDLS station */  		sta = sta_info_get(sdata, skb->data);  		if (sta) -			qos = sta->sta.wme; +			break;  		ra = sdata->u.mgd.bssid;  		break;  	case NL80211_IFTYPE_ADHOC:  		ra = skb->data;  		break; -	case NL80211_IFTYPE_OCB: -		/* all stations are required to support WME */ -		qos = true; -		break;  	default:  		break;  	} -	if (!sta && ra && !is_multicast_ether_addr(ra)) { +	if (!sta && ra && !is_multicast_ether_addr(ra))  		sta = sta_info_get(sdata, ra); -		if (sta) -			qos = sta->sta.wme; -	} -	if (!qos) { -		skb->priority = 0; /* required for correct WPA/11i MIC */ -		ret = IEEE80211_AC_BE; -		goto out; -	} +	ret = __ieee80211_select_queue(sdata, sta, skb); -	if (skb->protocol == sdata->control_port_protocol) { -		skb->priority = 7; -		goto downgrade; -	} - -	/* use the data classifier to determine what 802.1d tag the -	 * data frame has */ -	qos_map = rcu_dereference(sdata->qos_map); -	skb->priority = cfg80211_classify8021d(skb, qos_map ? -					       &qos_map->qos_map : NULL); - - downgrade: -	ret = ieee80211_downgrade_queue(sdata, sta, skb); - out:  	rcu_read_unlock();  	return ret;  } |