mac80211: uapsd_queues is in QoS IE order
The uapsd_queue field is in QoS IE order and not in IEEE80211_AC_*'s order. This means that mac80211 would get confused between BK and BE which is certainly not such a big deal but needs to be fixed. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
		
							parent
							
								
									f3fe4e93dd
								
							
						
					
					
						commit
						f438ceb81d
					
				| @ -4574,7 +4574,8 @@ void cfg80211_auth_timeout(struct net_device *dev, const u8 *addr); | ||||
|  *	moves to cfg80211 in this call | ||||
|  * @buf: authentication frame (header + body) | ||||
|  * @len: length of the frame data | ||||
|  * @uapsd_queues: bitmap of ACs configured to uapsd. -1 if n/a. | ||||
|  * @uapsd_queues: bitmap of queues configured for uapsd. Same format | ||||
|  *	as the AC bitmap in the QoS info field | ||||
|  * | ||||
|  * After being asked to associate via cfg80211_ops::assoc() the driver must | ||||
|  * call either this function or cfg80211_auth_timeout(). | ||||
|  | ||||
| @ -1745,7 +1745,8 @@ struct ieee80211_sta_rates { | ||||
|  * @drv_priv: data area for driver use, will always be aligned to | ||||
|  *	sizeof(void *), size is determined in hw information. | ||||
|  * @uapsd_queues: bitmap of queues configured for uapsd. Only valid | ||||
|  *	if wme is supported. | ||||
|  *	if wme is supported. The bits order is like in | ||||
|  *	IEEE80211_WMM_IE_STA_QOSINFO_AC_*. | ||||
|  * @max_sp: max Service Period. Only valid if wme is supported. | ||||
|  * @bandwidth: current bandwidth the station can receive with | ||||
|  * @rx_nss: in HT/VHT, the maximum number of spatial streams the | ||||
|  | ||||
| @ -84,6 +84,8 @@ struct ieee80211_local; | ||||
| #define IEEE80211_DEFAULT_MAX_SP_LEN		\ | ||||
| 	IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL | ||||
| 
 | ||||
| extern const u8 ieee80211_ac_to_qos_mask[IEEE80211_NUM_ACS]; | ||||
| 
 | ||||
| #define IEEE80211_DEAUTH_FRAME_LEN	(24 /* hdr */ + 2 /* reason */) | ||||
| 
 | ||||
| #define IEEE80211_MAX_NAN_INSTANCE_ID 255 | ||||
|  | ||||
| @ -3193,7 +3193,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | ||||
| 		uapsd_queues = 0; | ||||
| 		for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | ||||
| 			if (sdata->tx_conf[ac].uapsd) | ||||
| 				uapsd_queues |= BIT(ac); | ||||
| 				uapsd_queues |= ieee80211_ac_to_qos_mask[ac]; | ||||
| 	} | ||||
| 
 | ||||
| 	cfg80211_rx_assoc_resp(sdata->dev, bss, (u8 *)mgmt, len, uapsd_queues); | ||||
|  | ||||
| @ -1401,7 +1401,8 @@ void ieee80211_sta_uapsd_trigger(struct ieee80211_sta *pubsta, u8 tid) | ||||
| 	 * enabled queues, but for now we only implement uAPSD w/o | ||||
| 	 * TSPEC changes to the ACs, so they're always the same. | ||||
| 	 */ | ||||
| 	if (!(sta->sta.uapsd_queues & BIT(ac)) && tid != IEEE80211_NUM_TIDS) | ||||
| 	if (!(sta->sta.uapsd_queues & ieee80211_ac_to_qos_mask[ac]) && | ||||
| 	    tid != IEEE80211_NUM_TIDS) | ||||
| 		return; | ||||
| 
 | ||||
| 	/* if we are in a service period, do nothing */ | ||||
|  | ||||
| @ -709,7 +709,7 @@ static void __sta_info_recalc_tim(struct sta_info *sta, bool ignore_pending) | ||||
| 	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | ||||
| 		unsigned long tids; | ||||
| 
 | ||||
| 		if (ignore_for_tim & BIT(ac)) | ||||
| 		if (ignore_for_tim & ieee80211_ac_to_qos_mask[ac]) | ||||
| 			continue; | ||||
| 
 | ||||
| 		indicate_tim |= !skb_queue_empty(&sta->tx_filtered[ac]) || | ||||
| @ -1389,7 +1389,7 @@ ieee80211_sta_ps_more_data(struct sta_info *sta, u8 ignored_acs, | ||||
| 		return true; | ||||
| 
 | ||||
| 	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | ||||
| 		if (ignored_acs & BIT(ac)) | ||||
| 		if (ignored_acs & ieee80211_ac_to_qos_mask[ac]) | ||||
| 			continue; | ||||
| 
 | ||||
| 		if (!skb_queue_empty(&sta->tx_filtered[ac]) || | ||||
| @ -1414,7 +1414,7 @@ ieee80211_sta_ps_get_frames(struct sta_info *sta, int n_frames, u8 ignored_acs, | ||||
| 	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | ||||
| 		unsigned long tids; | ||||
| 
 | ||||
| 		if (ignored_acs & BIT(ac)) | ||||
| 		if (ignored_acs & ieee80211_ac_to_qos_mask[ac]) | ||||
| 			continue; | ||||
| 
 | ||||
| 		tids = ieee80211_tids_for_ac(ac); | ||||
| @ -1482,7 +1482,7 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta, | ||||
| 			BIT(find_highest_prio_tid(driver_release_tids)); | ||||
| 
 | ||||
| 	if (skb_queue_empty(&frames) && !driver_release_tids) { | ||||
| 		int tid; | ||||
| 		int tid, ac; | ||||
| 
 | ||||
| 		/*
 | ||||
| 		 * For PS-Poll, this can only happen due to a race condition | ||||
| @ -1500,7 +1500,10 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta, | ||||
| 		 */ | ||||
| 
 | ||||
| 		/* This will evaluate to 1, 3, 5 or 7. */ | ||||
| 		tid = 7 - ((ffs(~ignored_acs) - 1) << 1); | ||||
| 		for (ac = IEEE80211_AC_VO; ac < IEEE80211_NUM_ACS; ac++) | ||||
| 			if (ignored_acs & BIT(ac)) | ||||
| 				continue; | ||||
| 		tid = 7 - 2 * ac; | ||||
| 
 | ||||
| 		ieee80211_send_null_response(sta, tid, reason, true, false); | ||||
| 	} else if (!driver_release_tids) { | ||||
|  | ||||
| @ -3452,3 +3452,10 @@ void ieee80211_txq_get_depth(struct ieee80211_txq *txq, | ||||
| 		*byte_cnt = txqi->tin.backlog_bytes + frag_bytes; | ||||
| } | ||||
| EXPORT_SYMBOL(ieee80211_txq_get_depth); | ||||
| 
 | ||||
| const u8 ieee80211_ac_to_qos_mask[IEEE80211_NUM_ACS] = { | ||||
| 	IEEE80211_WMM_IE_STA_QOSINFO_AC_VO, | ||||
| 	IEEE80211_WMM_IE_STA_QOSINFO_AC_VI, | ||||
| 	IEEE80211_WMM_IE_STA_QOSINFO_AC_BE, | ||||
| 	IEEE80211_WMM_IE_STA_QOSINFO_AC_BK | ||||
| }; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user