Merge tag 'hsi-for-3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-hsi
[cascardo/linux.git] / net / mac80211 / iface.c
index 388b863..01eede7 100644 (file)
@@ -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 = 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);