diff options
Diffstat (limited to 'net/mac80211/iface.c')
| -rw-r--r-- | net/mac80211/iface.c | 46 | 
1 files changed, 39 insertions, 7 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 388b863e821c..f75e5f132c5a 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -841,10 +841,11 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,  	sdata_lock(sdata);  	mutex_lock(&local->mtx);  	sdata->vif.csa_active = false; -	if (!ieee80211_csa_needs_block_tx(local)) -		ieee80211_wake_queues_by_reason(&local->hw, -					IEEE80211_MAX_QUEUE_MAP, -					IEEE80211_QUEUE_STOP_REASON_CSA); +	if (sdata->csa_block_tx) { +		ieee80211_wake_vif_queues(local, sdata, +					  IEEE80211_QUEUE_STOP_REASON_CSA); +		sdata->csa_block_tx = false; +	}  	mutex_unlock(&local->mtx);  	sdata_unlock(sdata); @@ -1139,6 +1140,7 @@ static void ieee80211_iface_work(struct work_struct *work)  	struct sk_buff *skb;  	struct sta_info *sta;  	struct ieee80211_ra_tid *ra_tid; +	struct ieee80211_rx_agg *rx_agg;  	if (!ieee80211_sdata_running(sdata))  		return; @@ -1166,6 +1168,34 @@ static void ieee80211_iface_work(struct work_struct *work)  			ra_tid = (void *)&skb->cb;  			ieee80211_stop_tx_ba_cb(&sdata->vif, ra_tid->ra,  						ra_tid->tid); +		} else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_START) { +			rx_agg = (void *)&skb->cb; +			mutex_lock(&local->sta_mtx); +			sta = sta_info_get_bss(sdata, rx_agg->addr); +			if (sta) { +				u16 last_seq; + +				last_seq = IEEE80211_SEQ_TO_SN(le16_to_cpu( +					sta->last_seq_ctrl[rx_agg->tid])); + +				__ieee80211_start_rx_ba_session(sta, +						0, 0, +						ieee80211_sn_inc(last_seq), +						1, rx_agg->tid, +						IEEE80211_MAX_AMPDU_BUF, +						false); +			} +			mutex_unlock(&local->sta_mtx); +		} else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_STOP) { +			rx_agg = (void *)&skb->cb; +			mutex_lock(&local->sta_mtx); +			sta = sta_info_get_bss(sdata, rx_agg->addr); +			if (sta) +				__ieee80211_stop_rx_ba_session(sta, +							rx_agg->tid, +							WLAN_BACK_RECIPIENT, 0, +							false); +			mutex_unlock(&local->sta_mtx);  		} else if (ieee80211_is_action(mgmt->frame_control) &&  			   mgmt->u.action.category == WLAN_CATEGORY_BACK) {  			int len = skb->len; @@ -1623,9 +1653,9 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,  		if (local->hw.queues >= IEEE80211_NUM_ACS)  			txqs = IEEE80211_NUM_ACS; -		ndev = alloc_netdev_mqs(sizeof(*sdata) + -					local->hw.vif_data_size, -					name, ieee80211_if_setup, txqs, 1); +		ndev = alloc_netdev_mqs(sizeof(*sdata) + local->hw.vif_data_size, +					name, NET_NAME_UNKNOWN, +					ieee80211_if_setup, txqs, 1);  		if (!ndev)  			return -ENOMEM;  		dev_net_set(ndev, wiphy_net(local->hw.wiphy)); @@ -1705,6 +1735,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,  		ndev->features |= local->hw.netdev_features; +		netdev_set_default_ethtool_ops(ndev, &ieee80211_ethtool_ops); +  		ret = register_netdevice(ndev);  		if (ret) {  			free_netdev(ndev);  |