Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Implementation of mac80211 API.
0004  *
0005  * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
0006  * Copyright (c) 2010, ST-Ericsson
0007  */
0008 #include <linux/etherdevice.h>
0009 #include <net/mac80211.h>
0010 
0011 #include "sta.h"
0012 #include "wfx.h"
0013 #include "fwio.h"
0014 #include "bh.h"
0015 #include "key.h"
0016 #include "scan.h"
0017 #include "debug.h"
0018 #include "hif_tx.h"
0019 #include "hif_tx_mib.h"
0020 
0021 #define HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES 2
0022 
0023 u32 wfx_rate_mask_to_hw(struct wfx_dev *wdev, u32 rates)
0024 {
0025     int i;
0026     u32 ret = 0;
0027     /* The device only supports 2GHz */
0028     struct ieee80211_supported_band *sband = wdev->hw->wiphy->bands[NL80211_BAND_2GHZ];
0029 
0030     for (i = 0; i < sband->n_bitrates; i++) {
0031         if (rates & BIT(i)) {
0032             if (i >= sband->n_bitrates)
0033                 dev_warn(wdev->dev, "unsupported basic rate\n");
0034             else
0035                 ret |= BIT(sband->bitrates[i].hw_value);
0036         }
0037     }
0038     return ret;
0039 }
0040 
0041 void wfx_cooling_timeout_work(struct work_struct *work)
0042 {
0043     struct wfx_dev *wdev = container_of(to_delayed_work(work), struct wfx_dev,
0044                         cooling_timeout_work);
0045 
0046     wdev->chip_frozen = true;
0047     wfx_tx_unlock(wdev);
0048 }
0049 
0050 void wfx_suspend_hot_dev(struct wfx_dev *wdev, enum sta_notify_cmd cmd)
0051 {
0052     if (cmd == STA_NOTIFY_AWAKE) {
0053         /* Device recover normal temperature */
0054         if (cancel_delayed_work(&wdev->cooling_timeout_work))
0055             wfx_tx_unlock(wdev);
0056     } else {
0057         /* Device is too hot */
0058         schedule_delayed_work(&wdev->cooling_timeout_work, 10 * HZ);
0059         wfx_tx_lock(wdev);
0060     }
0061 }
0062 
0063 static void wfx_filter_beacon(struct wfx_vif *wvif, bool filter_beacon)
0064 {
0065     static const struct wfx_hif_ie_table_entry filter_ies[] = {
0066         {
0067             .ie_id        = WLAN_EID_VENDOR_SPECIFIC,
0068             .has_changed  = 1,
0069             .no_longer    = 1,
0070             .has_appeared = 1,
0071             .oui          = { 0x50, 0x6F, 0x9A },
0072         }, {
0073             .ie_id        = WLAN_EID_HT_OPERATION,
0074             .has_changed  = 1,
0075             .no_longer    = 1,
0076             .has_appeared = 1,
0077         }, {
0078             .ie_id        = WLAN_EID_ERP_INFO,
0079             .has_changed  = 1,
0080             .no_longer    = 1,
0081             .has_appeared = 1,
0082         }, {
0083             .ie_id        = WLAN_EID_CHANNEL_SWITCH,
0084             .has_changed  = 1,
0085             .no_longer    = 1,
0086             .has_appeared = 1,
0087         }
0088     };
0089 
0090     if (!filter_beacon) {
0091         wfx_hif_beacon_filter_control(wvif, 0, 1);
0092     } else {
0093         wfx_hif_set_beacon_filter_table(wvif, ARRAY_SIZE(filter_ies), filter_ies);
0094         wfx_hif_beacon_filter_control(wvif, HIF_BEACON_FILTER_ENABLE, 0);
0095     }
0096 }
0097 
0098 void wfx_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
0099               unsigned int *total_flags, u64 unused)
0100 {
0101     bool filter_bssid, filter_prbreq, filter_beacon;
0102     struct ieee80211_vif *vif = NULL;
0103     struct wfx_dev *wdev = hw->priv;
0104     struct wfx_vif *wvif = NULL;
0105 
0106     /* Notes:
0107      *   - Probe responses (FIF_BCN_PRBRESP_PROMISC) are never filtered
0108      *   - PS-Poll (FIF_PSPOLL) are never filtered
0109      *   - RTS, CTS and Ack (FIF_CONTROL) are always filtered
0110      *   - Broken frames (FIF_FCSFAIL and FIF_PLCPFAIL) are always filtered
0111      *   - Firmware does (yet) allow to forward unicast traffic sent to other stations (aka.
0112      *     promiscuous mode)
0113      */
0114     *total_flags &= FIF_BCN_PRBRESP_PROMISC | FIF_ALLMULTI | FIF_OTHER_BSS |
0115             FIF_PROBE_REQ | FIF_PSPOLL;
0116 
0117     mutex_lock(&wdev->conf_mutex);
0118     while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
0119         mutex_lock(&wvif->scan_lock);
0120 
0121         /* Note: FIF_BCN_PRBRESP_PROMISC covers probe response and
0122          * beacons from other BSS
0123          */
0124         if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
0125             filter_beacon = false;
0126         else
0127             filter_beacon = true;
0128         wfx_filter_beacon(wvif, filter_beacon);
0129 
0130         if (*total_flags & FIF_OTHER_BSS)
0131             filter_bssid = false;
0132         else
0133             filter_bssid = true;
0134 
0135         vif = wvif_to_vif(wvif);
0136         /* In AP mode, chip can reply to probe request itself */
0137         if (*total_flags & FIF_PROBE_REQ && vif->type == NL80211_IFTYPE_AP) {
0138             dev_dbg(wdev->dev, "do not forward probe request in AP mode\n");
0139             *total_flags &= ~FIF_PROBE_REQ;
0140         }
0141 
0142         if (*total_flags & FIF_PROBE_REQ)
0143             filter_prbreq = false;
0144         else
0145             filter_prbreq = true;
0146         wfx_hif_set_rx_filter(wvif, filter_bssid, filter_prbreq);
0147 
0148         mutex_unlock(&wvif->scan_lock);
0149     }
0150     mutex_unlock(&wdev->conf_mutex);
0151 }
0152 
0153 static int wfx_get_ps_timeout(struct wfx_vif *wvif, bool *enable_ps)
0154 {
0155     struct ieee80211_channel *chan0 = NULL, *chan1 = NULL;
0156     struct ieee80211_conf *conf = &wvif->wdev->hw->conf;
0157     struct ieee80211_vif *vif = wvif_to_vif(wvif);
0158 
0159     WARN(!vif->cfg.assoc && enable_ps,
0160          "enable_ps is reliable only if associated");
0161     if (wdev_to_wvif(wvif->wdev, 0)) {
0162         struct wfx_vif *wvif_ch0 = wdev_to_wvif(wvif->wdev, 0);
0163         struct ieee80211_vif *vif_ch0 = wvif_to_vif(wvif_ch0);
0164 
0165         chan0 = vif_ch0->bss_conf.chandef.chan;
0166     }
0167     if (wdev_to_wvif(wvif->wdev, 1)) {
0168         struct wfx_vif *wvif_ch1 = wdev_to_wvif(wvif->wdev, 1);
0169         struct ieee80211_vif *vif_ch1 = wvif_to_vif(wvif_ch1);
0170 
0171         chan1 = vif_ch1->bss_conf.chandef.chan;
0172     }
0173     if (chan0 && chan1 && vif->type != NL80211_IFTYPE_AP) {
0174         if (chan0->hw_value == chan1->hw_value) {
0175             /* It is useless to enable PS if channels are the same. */
0176             if (enable_ps)
0177                 *enable_ps = false;
0178             if (vif->cfg.assoc && vif->cfg.ps)
0179                 dev_info(wvif->wdev->dev, "ignoring requested PS mode");
0180             return -1;
0181         }
0182         /* It is necessary to enable PS if channels are different. */
0183         if (enable_ps)
0184             *enable_ps = true;
0185         if (wfx_api_older_than(wvif->wdev, 3, 2))
0186             return 0;
0187         else
0188             return 30;
0189     }
0190     if (enable_ps)
0191         *enable_ps = vif->cfg.ps;
0192     if (vif->cfg.assoc && vif->cfg.ps)
0193         return conf->dynamic_ps_timeout;
0194     else
0195         return -1;
0196 }
0197 
0198 int wfx_update_pm(struct wfx_vif *wvif)
0199 {
0200     struct ieee80211_vif *vif = wvif_to_vif(wvif);
0201     int ps_timeout;
0202     bool ps;
0203 
0204     if (!vif->cfg.assoc)
0205         return 0;
0206     ps_timeout = wfx_get_ps_timeout(wvif, &ps);
0207     if (!ps)
0208         ps_timeout = 0;
0209     WARN_ON(ps_timeout < 0);
0210     if (wvif->uapsd_mask)
0211         ps_timeout = 0;
0212 
0213     if (!wait_for_completion_timeout(&wvif->set_pm_mode_complete, TU_TO_JIFFIES(512)))
0214         dev_warn(wvif->wdev->dev, "timeout while waiting of set_pm_mode_complete\n");
0215     return wfx_hif_set_pm(wvif, ps, ps_timeout);
0216 }
0217 
0218 int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
0219         unsigned int link_id, u16 queue,
0220         const struct ieee80211_tx_queue_params *params)
0221 {
0222     struct wfx_dev *wdev = hw->priv;
0223     struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
0224     int old_uapsd = wvif->uapsd_mask;
0225 
0226     WARN_ON(queue >= hw->queues);
0227 
0228     mutex_lock(&wdev->conf_mutex);
0229     assign_bit(queue, &wvif->uapsd_mask, params->uapsd);
0230     wfx_hif_set_edca_queue_params(wvif, queue, params);
0231     if (vif->type == NL80211_IFTYPE_STATION &&
0232         old_uapsd != wvif->uapsd_mask) {
0233         wfx_hif_set_uapsd_info(wvif, wvif->uapsd_mask);
0234         wfx_update_pm(wvif);
0235     }
0236     mutex_unlock(&wdev->conf_mutex);
0237     return 0;
0238 }
0239 
0240 int wfx_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
0241 {
0242     struct wfx_dev *wdev = hw->priv;
0243     struct wfx_vif *wvif = NULL;
0244 
0245     while ((wvif = wvif_iterate(wdev, wvif)) != NULL)
0246         wfx_hif_rts_threshold(wvif, value);
0247     return 0;
0248 }
0249 
0250 void wfx_event_report_rssi(struct wfx_vif *wvif, u8 raw_rcpi_rssi)
0251 {
0252     /* RSSI: signed Q8.0, RCPI: unsigned Q7.1
0253      * RSSI = RCPI / 2 - 110
0254      */
0255     struct ieee80211_vif *vif = wvif_to_vif(wvif);
0256     int rcpi_rssi;
0257     int cqm_evt;
0258 
0259     rcpi_rssi = raw_rcpi_rssi / 2 - 110;
0260     if (rcpi_rssi <= vif->bss_conf.cqm_rssi_thold)
0261         cqm_evt = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW;
0262     else
0263         cqm_evt = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
0264     ieee80211_cqm_rssi_notify(vif, cqm_evt, rcpi_rssi, GFP_KERNEL);
0265 }
0266 
0267 static void wfx_beacon_loss_work(struct work_struct *work)
0268 {
0269     struct wfx_vif *wvif = container_of(to_delayed_work(work), struct wfx_vif,
0270                         beacon_loss_work);
0271     struct ieee80211_vif *vif = wvif_to_vif(wvif);
0272     struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
0273 
0274     ieee80211_beacon_loss(vif);
0275     schedule_delayed_work(to_delayed_work(work), msecs_to_jiffies(bss_conf->beacon_int));
0276 }
0277 
0278 void wfx_set_default_unicast_key(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int idx)
0279 {
0280     struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
0281 
0282     wfx_hif_wep_default_key_id(wvif, idx);
0283 }
0284 
0285 void wfx_reset(struct wfx_vif *wvif)
0286 {
0287     struct wfx_dev *wdev = wvif->wdev;
0288 
0289     wfx_tx_lock_flush(wdev);
0290     wfx_hif_reset(wvif, false);
0291     wfx_tx_policy_init(wvif);
0292     if (wvif_count(wdev) <= 1)
0293         wfx_hif_set_block_ack_policy(wvif, 0xFF, 0xFF);
0294     wfx_tx_unlock(wdev);
0295     wvif->join_in_progress = false;
0296     cancel_delayed_work_sync(&wvif->beacon_loss_work);
0297     wvif =  NULL;
0298     while ((wvif = wvif_iterate(wdev, wvif)) != NULL)
0299         wfx_update_pm(wvif);
0300 }
0301 
0302 int wfx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta)
0303 {
0304     struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
0305     struct wfx_sta_priv *sta_priv = (struct wfx_sta_priv *)&sta->drv_priv;
0306 
0307     sta_priv->vif_id = wvif->id;
0308 
0309     if (vif->type == NL80211_IFTYPE_STATION)
0310         wfx_hif_set_mfp(wvif, sta->mfp, sta->mfp);
0311 
0312     /* In station mode, the firmware interprets new link-id as a TDLS peer */
0313     if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
0314         return 0;
0315     sta_priv->link_id = ffz(wvif->link_id_map);
0316     wvif->link_id_map |= BIT(sta_priv->link_id);
0317     WARN_ON(!sta_priv->link_id);
0318     WARN_ON(sta_priv->link_id >= HIF_LINK_ID_MAX);
0319     wfx_hif_map_link(wvif, false, sta->addr, sta_priv->link_id, sta->mfp);
0320 
0321     return 0;
0322 }
0323 
0324 int wfx_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta)
0325 {
0326     struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
0327     struct wfx_sta_priv *sta_priv = (struct wfx_sta_priv *)&sta->drv_priv;
0328 
0329     /* See note in wfx_sta_add() */
0330     if (!sta_priv->link_id)
0331         return 0;
0332     /* FIXME add a mutex? */
0333     wfx_hif_map_link(wvif, true, sta->addr, sta_priv->link_id, false);
0334     wvif->link_id_map &= ~BIT(sta_priv->link_id);
0335     return 0;
0336 }
0337 
0338 static int wfx_upload_ap_templates(struct wfx_vif *wvif)
0339 {
0340     struct ieee80211_vif *vif = wvif_to_vif(wvif);
0341     struct sk_buff *skb;
0342 
0343     skb = ieee80211_beacon_get(wvif->wdev->hw, vif, 0);
0344     if (!skb)
0345         return -ENOMEM;
0346     wfx_hif_set_template_frame(wvif, skb, HIF_TMPLT_BCN, API_RATE_INDEX_B_1MBPS);
0347     dev_kfree_skb(skb);
0348 
0349     skb = ieee80211_proberesp_get(wvif->wdev->hw, vif);
0350     if (!skb)
0351         return -ENOMEM;
0352     wfx_hif_set_template_frame(wvif, skb, HIF_TMPLT_PRBRES, API_RATE_INDEX_B_1MBPS);
0353     dev_kfree_skb(skb);
0354     return 0;
0355 }
0356 
0357 static void wfx_set_mfp_ap(struct wfx_vif *wvif)
0358 {
0359     struct ieee80211_vif *vif = wvif_to_vif(wvif);
0360     struct sk_buff *skb = ieee80211_beacon_get(wvif->wdev->hw, vif, 0);
0361     const int ieoffset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
0362     const u16 *ptr = (u16 *)cfg80211_find_ie(WLAN_EID_RSN, skb->data + ieoffset,
0363                          skb->len - ieoffset);
0364     const int pairwise_cipher_suite_count_offset = 8 / sizeof(u16);
0365     const int pairwise_cipher_suite_size = 4 / sizeof(u16);
0366     const int akm_suite_size = 4 / sizeof(u16);
0367 
0368     if (ptr) {
0369         ptr += pairwise_cipher_suite_count_offset;
0370         if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb)))
0371             return;
0372         ptr += 1 + pairwise_cipher_suite_size * *ptr;
0373         if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb)))
0374             return;
0375         ptr += 1 + akm_suite_size * *ptr;
0376         if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb)))
0377             return;
0378         wfx_hif_set_mfp(wvif, *ptr & BIT(7), *ptr & BIT(6));
0379     }
0380 }
0381 
0382 int wfx_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
0383          struct ieee80211_bss_conf *link_conf)
0384 {
0385     struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
0386     struct wfx_dev *wdev = wvif->wdev;
0387     int ret;
0388 
0389     wvif =  NULL;
0390     while ((wvif = wvif_iterate(wdev, wvif)) != NULL)
0391         wfx_update_pm(wvif);
0392     wvif = (struct wfx_vif *)vif->drv_priv;
0393     wfx_upload_ap_templates(wvif);
0394     ret = wfx_hif_start(wvif, &vif->bss_conf, wvif->channel);
0395     if (ret > 0)
0396         return -EIO;
0397     wfx_set_mfp_ap(wvif);
0398     return ret;
0399 }
0400 
0401 void wfx_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
0402          struct ieee80211_bss_conf *link_conf)
0403 {
0404     struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
0405 
0406     wfx_reset(wvif);
0407 }
0408 
0409 static void wfx_join(struct wfx_vif *wvif)
0410 {
0411     struct ieee80211_vif *vif = wvif_to_vif(wvif);
0412     struct ieee80211_bss_conf *conf = &vif->bss_conf;
0413     struct cfg80211_bss *bss = NULL;
0414     u8 ssid[IEEE80211_MAX_SSID_LEN];
0415     const u8 *ssid_ie = NULL;
0416     int ssid_len = 0;
0417     int ret;
0418 
0419     wfx_tx_lock_flush(wvif->wdev);
0420 
0421     bss = cfg80211_get_bss(wvif->wdev->hw->wiphy, wvif->channel, conf->bssid, NULL, 0,
0422                    IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
0423     if (!bss && !vif->cfg.ibss_joined) {
0424         wfx_tx_unlock(wvif->wdev);
0425         return;
0426     }
0427 
0428     rcu_read_lock(); /* protect ssid_ie */
0429     if (bss)
0430         ssid_ie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
0431     if (ssid_ie) {
0432         ssid_len = ssid_ie[1];
0433         if (ssid_len > IEEE80211_MAX_SSID_LEN)
0434             ssid_len = IEEE80211_MAX_SSID_LEN;
0435         memcpy(ssid, &ssid_ie[2], ssid_len);
0436     }
0437     rcu_read_unlock();
0438 
0439     cfg80211_put_bss(wvif->wdev->hw->wiphy, bss);
0440 
0441     wvif->join_in_progress = true;
0442     ret = wfx_hif_join(wvif, conf, wvif->channel, ssid, ssid_len);
0443     if (ret) {
0444         ieee80211_connection_loss(vif);
0445         wfx_reset(wvif);
0446     } else {
0447         /* Due to beacon filtering it is possible that the AP's beacon is not known for the
0448          * mac80211 stack.  Disable filtering temporary to make sure the stack receives at
0449          * least one
0450          */
0451         wfx_filter_beacon(wvif, false);
0452     }
0453     wfx_tx_unlock(wvif->wdev);
0454 }
0455 
0456 static void wfx_join_finalize(struct wfx_vif *wvif, struct ieee80211_bss_conf *info)
0457 {
0458     struct ieee80211_vif *vif = wvif_to_vif(wvif);
0459     struct ieee80211_sta *sta = NULL;
0460     int ampdu_density = 0;
0461     bool greenfield = false;
0462 
0463     rcu_read_lock(); /* protect sta */
0464     if (info->bssid && !vif->cfg.ibss_joined)
0465         sta = ieee80211_find_sta(vif, info->bssid);
0466     if (sta && sta->deflink.ht_cap.ht_supported)
0467         ampdu_density = sta->deflink.ht_cap.ampdu_density;
0468     if (sta && sta->deflink.ht_cap.ht_supported &&
0469         !(info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT))
0470         greenfield = !!(sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD);
0471     rcu_read_unlock();
0472 
0473     wvif->join_in_progress = false;
0474     wfx_hif_set_association_mode(wvif, ampdu_density, greenfield, info->use_short_preamble);
0475     wfx_hif_keep_alive_period(wvif, 0);
0476     /* beacon_loss_count is defined to 7 in net/mac80211/mlme.c. Let's use the same value. */
0477     wfx_hif_set_bss_params(wvif, vif->cfg.aid, 7);
0478     wfx_hif_set_beacon_wakeup_period(wvif, 1, 1);
0479     wfx_update_pm(wvif);
0480 }
0481 
0482 int wfx_join_ibss(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
0483 {
0484     struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
0485 
0486     wfx_upload_ap_templates(wvif);
0487     wfx_join(wvif);
0488     return 0;
0489 }
0490 
0491 void wfx_leave_ibss(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
0492 {
0493     struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
0494 
0495     wfx_reset(wvif);
0496 }
0497 
0498 static void wfx_enable_beacon(struct wfx_vif *wvif, bool enable)
0499 {
0500     /* Driver has Content After DTIM Beacon in queue. Driver is waiting for a signal from the
0501      * firmware. Since we are going to stop to send beacons, this signal will never happens. See
0502      * also wfx_suspend_resume_mc()
0503      */
0504     if (!enable && wfx_tx_queues_has_cab(wvif)) {
0505         wvif->after_dtim_tx_allowed = true;
0506         wfx_bh_request_tx(wvif->wdev);
0507     }
0508     wfx_hif_beacon_transmit(wvif, enable);
0509 }
0510 
0511 void wfx_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
0512               struct ieee80211_bss_conf *info, u64 changed)
0513 {
0514     struct wfx_dev *wdev = hw->priv;
0515     struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
0516     int i;
0517 
0518     mutex_lock(&wdev->conf_mutex);
0519 
0520     if (changed & BSS_CHANGED_BASIC_RATES ||
0521         changed & BSS_CHANGED_BEACON_INT ||
0522         changed & BSS_CHANGED_BSSID) {
0523         if (vif->type == NL80211_IFTYPE_STATION)
0524             wfx_join(wvif);
0525     }
0526 
0527     if (changed & BSS_CHANGED_ASSOC) {
0528         if (vif->cfg.assoc || vif->cfg.ibss_joined)
0529             wfx_join_finalize(wvif, info);
0530         else if (!vif->cfg.assoc && vif->type == NL80211_IFTYPE_STATION)
0531             wfx_reset(wvif);
0532         else
0533             dev_warn(wdev->dev, "misunderstood change: ASSOC\n");
0534     }
0535 
0536     if (changed & BSS_CHANGED_BEACON_INFO) {
0537         if (vif->type != NL80211_IFTYPE_STATION)
0538             dev_warn(wdev->dev, "misunderstood change: BEACON_INFO\n");
0539         wfx_hif_set_beacon_wakeup_period(wvif, info->dtim_period, info->dtim_period);
0540         /* We temporary forwarded beacon for join process. It is now no more necessary. */
0541         wfx_filter_beacon(wvif, true);
0542     }
0543 
0544     if (changed & BSS_CHANGED_ARP_FILTER) {
0545         for (i = 0; i < HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES; i++) {
0546             __be32 *arp_addr = &vif->cfg.arp_addr_list[i];
0547 
0548             if (vif->cfg.arp_addr_cnt > HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES)
0549                 arp_addr = NULL;
0550             if (i >= vif->cfg.arp_addr_cnt)
0551                 arp_addr = NULL;
0552             wfx_hif_set_arp_ipv4_filter(wvif, i, arp_addr);
0553         }
0554     }
0555 
0556     if (changed & BSS_CHANGED_AP_PROBE_RESP || changed & BSS_CHANGED_BEACON)
0557         wfx_upload_ap_templates(wvif);
0558 
0559     if (changed & BSS_CHANGED_BEACON_ENABLED)
0560         wfx_enable_beacon(wvif, info->enable_beacon);
0561 
0562     if (changed & BSS_CHANGED_KEEP_ALIVE)
0563         wfx_hif_keep_alive_period(wvif,
0564                       info->max_idle_period * USEC_PER_TU / USEC_PER_MSEC);
0565 
0566     if (changed & BSS_CHANGED_ERP_CTS_PROT)
0567         wfx_hif_erp_use_protection(wvif, info->use_cts_prot);
0568 
0569     if (changed & BSS_CHANGED_ERP_SLOT)
0570         wfx_hif_slot_time(wvif, info->use_short_slot ? 9 : 20);
0571 
0572     if (changed & BSS_CHANGED_CQM)
0573         wfx_hif_set_rcpi_rssi_threshold(wvif, info->cqm_rssi_thold, info->cqm_rssi_hyst);
0574 
0575     if (changed & BSS_CHANGED_TXPOWER)
0576         wfx_hif_set_output_power(wvif, info->txpower);
0577 
0578     if (changed & BSS_CHANGED_PS)
0579         wfx_update_pm(wvif);
0580 
0581     mutex_unlock(&wdev->conf_mutex);
0582 }
0583 
0584 static int wfx_update_tim(struct wfx_vif *wvif)
0585 {
0586     struct ieee80211_vif *vif = wvif_to_vif(wvif);
0587     struct sk_buff *skb;
0588     u16 tim_offset, tim_length;
0589     u8 *tim_ptr;
0590 
0591     skb = ieee80211_beacon_get_tim(wvif->wdev->hw, vif, &tim_offset,
0592                        &tim_length, 0);
0593     if (!skb)
0594         return -ENOENT;
0595     tim_ptr = skb->data + tim_offset;
0596 
0597     if (tim_offset && tim_length >= 6) {
0598         /* Firmware handles DTIM counter internally */
0599         tim_ptr[2] = 0;
0600 
0601         /* Set/reset aid0 bit */
0602         if (wfx_tx_queues_has_cab(wvif))
0603             tim_ptr[4] |= 1;
0604         else
0605             tim_ptr[4] &= ~1;
0606     }
0607 
0608     wfx_hif_update_ie_beacon(wvif, tim_ptr, tim_length);
0609     dev_kfree_skb(skb);
0610 
0611     return 0;
0612 }
0613 
0614 static void wfx_update_tim_work(struct work_struct *work)
0615 {
0616     struct wfx_vif *wvif = container_of(work, struct wfx_vif, update_tim_work);
0617 
0618     wfx_update_tim(wvif);
0619 }
0620 
0621 int wfx_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
0622 {
0623     struct wfx_dev *wdev = hw->priv;
0624     struct wfx_sta_priv *sta_dev = (struct wfx_sta_priv *)&sta->drv_priv;
0625     struct wfx_vif *wvif = wdev_to_wvif(wdev, sta_dev->vif_id);
0626 
0627     if (!wvif) {
0628         dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__);
0629         return -EIO;
0630     }
0631     schedule_work(&wvif->update_tim_work);
0632     return 0;
0633 }
0634 
0635 void wfx_suspend_resume_mc(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd)
0636 {
0637     struct wfx_vif *wvif_it;
0638 
0639     if (notify_cmd != STA_NOTIFY_AWAKE)
0640         return;
0641 
0642     /* Device won't be able to honor CAB if a scan is in progress on any interface. Prefer to
0643      * skip this DTIM and wait for the next one.
0644      */
0645     wvif_it = NULL;
0646     while ((wvif_it = wvif_iterate(wvif->wdev, wvif_it)) != NULL)
0647         if (mutex_is_locked(&wvif_it->scan_lock))
0648             return;
0649 
0650     if (!wfx_tx_queues_has_cab(wvif) || wvif->after_dtim_tx_allowed)
0651         dev_warn(wvif->wdev->dev, "incorrect sequence (%d CAB in queue)",
0652              wfx_tx_queues_has_cab(wvif));
0653     wvif->after_dtim_tx_allowed = true;
0654     wfx_bh_request_tx(wvif->wdev);
0655 }
0656 
0657 int wfx_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
0658              struct ieee80211_ampdu_params *params)
0659 {
0660     /* Aggregation is implemented fully in firmware */
0661     switch (params->action) {
0662     case IEEE80211_AMPDU_RX_START:
0663     case IEEE80211_AMPDU_RX_STOP:
0664         /* Just acknowledge it to enable frame re-ordering */
0665         return 0;
0666     default:
0667         /* Leave the firmware doing its business for tx aggregation */
0668         return -EOPNOTSUPP;
0669     }
0670 }
0671 
0672 int wfx_add_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *conf)
0673 {
0674     return 0;
0675 }
0676 
0677 void wfx_remove_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *conf)
0678 {
0679 }
0680 
0681 void wfx_change_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *conf, u32 changed)
0682 {
0683 }
0684 
0685 int wfx_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
0686                struct ieee80211_bss_conf *link_conf,
0687                struct ieee80211_chanctx_conf *conf)
0688 {
0689     struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
0690     struct ieee80211_channel *ch = conf->def.chan;
0691 
0692     WARN(wvif->channel, "channel overwrite");
0693     wvif->channel = ch;
0694 
0695     return 0;
0696 }
0697 
0698 void wfx_unassign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
0699                   struct ieee80211_bss_conf *link_conf,
0700                   struct ieee80211_chanctx_conf *conf)
0701 {
0702     struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
0703     struct ieee80211_channel *ch = conf->def.chan;
0704 
0705     WARN(wvif->channel != ch, "channel mismatch");
0706     wvif->channel = NULL;
0707 }
0708 
0709 int wfx_config(struct ieee80211_hw *hw, u32 changed)
0710 {
0711     return 0;
0712 }
0713 
0714 int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
0715 {
0716     int i;
0717     struct wfx_dev *wdev = hw->priv;
0718     struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
0719 
0720     vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
0721                  IEEE80211_VIF_SUPPORTS_UAPSD |
0722                  IEEE80211_VIF_SUPPORTS_CQM_RSSI;
0723 
0724     mutex_lock(&wdev->conf_mutex);
0725 
0726     switch (vif->type) {
0727     case NL80211_IFTYPE_STATION:
0728     case NL80211_IFTYPE_ADHOC:
0729     case NL80211_IFTYPE_AP:
0730         break;
0731     default:
0732         mutex_unlock(&wdev->conf_mutex);
0733         return -EOPNOTSUPP;
0734     }
0735 
0736     wvif->wdev = wdev;
0737 
0738     wvif->link_id_map = 1; /* link-id 0 is reserved for multicast */
0739     INIT_WORK(&wvif->update_tim_work, wfx_update_tim_work);
0740     INIT_DELAYED_WORK(&wvif->beacon_loss_work, wfx_beacon_loss_work);
0741 
0742     init_completion(&wvif->set_pm_mode_complete);
0743     complete(&wvif->set_pm_mode_complete);
0744     INIT_WORK(&wvif->tx_policy_upload_work, wfx_tx_policy_upload_work);
0745 
0746     mutex_init(&wvif->scan_lock);
0747     init_completion(&wvif->scan_complete);
0748     INIT_WORK(&wvif->scan_work, wfx_hw_scan_work);
0749 
0750     wfx_tx_queues_init(wvif);
0751     wfx_tx_policy_init(wvif);
0752 
0753     for (i = 0; i < ARRAY_SIZE(wdev->vif); i++) {
0754         if (!wdev->vif[i]) {
0755             wdev->vif[i] = vif;
0756             wvif->id = i;
0757             break;
0758         }
0759     }
0760     WARN(i == ARRAY_SIZE(wdev->vif), "try to instantiate more vif than supported");
0761 
0762     wfx_hif_set_macaddr(wvif, vif->addr);
0763 
0764     mutex_unlock(&wdev->conf_mutex);
0765 
0766     wvif = NULL;
0767     while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
0768         /* Combo mode does not support Block Acks. We can re-enable them */
0769         if (wvif_count(wdev) == 1)
0770             wfx_hif_set_block_ack_policy(wvif, 0xFF, 0xFF);
0771         else
0772             wfx_hif_set_block_ack_policy(wvif, 0x00, 0x00);
0773     }
0774     return 0;
0775 }
0776 
0777 void wfx_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
0778 {
0779     struct wfx_dev *wdev = hw->priv;
0780     struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
0781 
0782     wait_for_completion_timeout(&wvif->set_pm_mode_complete, msecs_to_jiffies(300));
0783     wfx_tx_queues_check_empty(wvif);
0784 
0785     mutex_lock(&wdev->conf_mutex);
0786     WARN(wvif->link_id_map != 1, "corrupted state");
0787 
0788     wfx_hif_reset(wvif, false);
0789     wfx_hif_set_macaddr(wvif, NULL);
0790     wfx_tx_policy_init(wvif);
0791 
0792     cancel_delayed_work_sync(&wvif->beacon_loss_work);
0793     wdev->vif[wvif->id] = NULL;
0794 
0795     mutex_unlock(&wdev->conf_mutex);
0796 
0797     wvif = NULL;
0798     while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
0799         /* Combo mode does not support Block Acks. We can re-enable them */
0800         if (wvif_count(wdev) == 1)
0801             wfx_hif_set_block_ack_policy(wvif, 0xFF, 0xFF);
0802         else
0803             wfx_hif_set_block_ack_policy(wvif, 0x00, 0x00);
0804     }
0805 }
0806 
0807 int wfx_start(struct ieee80211_hw *hw)
0808 {
0809     return 0;
0810 }
0811 
0812 void wfx_stop(struct ieee80211_hw *hw)
0813 {
0814     struct wfx_dev *wdev = hw->priv;
0815 
0816     WARN_ON(!skb_queue_empty_lockless(&wdev->tx_pending));
0817 }