root/drivers/net/wireless/mediatek/mt76/mt7615/main.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mt7615_start
  2. mt7615_stop
  3. get_omac_idx
  4. mt7615_add_interface
  5. mt7615_remove_interface
  6. mt7615_set_channel
  7. mt7615_set_key
  8. mt7615_config
  9. mt7615_conf_tx
  10. mt7615_configure_filter
  11. mt7615_bss_info_changed
  12. mt7615_channel_switch_beacon
  13. mt7615_sta_add
  14. mt7615_sta_assoc
  15. mt7615_sta_remove
  16. mt7615_sta_rate_tbl_update
  17. mt7615_tx
  18. mt7615_set_rts_threshold
  19. mt7615_ampdu_action

   1 // SPDX-License-Identifier: ISC
   2 /* Copyright (C) 2019 MediaTek Inc.
   3  *
   4  * Author: Roy Luo <royluo@google.com>
   5  *         Ryder Lee <ryder.lee@mediatek.com>
   6  *         Felix Fietkau <nbd@nbd.name>
   7  */
   8 
   9 #include <linux/etherdevice.h>
  10 #include <linux/platform_device.h>
  11 #include <linux/pci.h>
  12 #include <linux/module.h>
  13 #include "mt7615.h"
  14 
  15 static int mt7615_start(struct ieee80211_hw *hw)
  16 {
  17         struct mt7615_dev *dev = hw->priv;
  18 
  19         dev->mt76.survey_time = ktime_get_boottime();
  20         set_bit(MT76_STATE_RUNNING, &dev->mt76.state);
  21         ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
  22                                      MT7615_WATCHDOG_TIME);
  23 
  24         return 0;
  25 }
  26 
  27 static void mt7615_stop(struct ieee80211_hw *hw)
  28 {
  29         struct mt7615_dev *dev = hw->priv;
  30 
  31         clear_bit(MT76_STATE_RUNNING, &dev->mt76.state);
  32         cancel_delayed_work_sync(&dev->mt76.mac_work);
  33 }
  34 
  35 static int get_omac_idx(enum nl80211_iftype type, u32 mask)
  36 {
  37         int i;
  38 
  39         switch (type) {
  40         case NL80211_IFTYPE_AP:
  41         case NL80211_IFTYPE_MESH_POINT:
  42                 /* ap use hw bssid 0 and ext bssid */
  43                 if (~mask & BIT(HW_BSSID_0))
  44                         return HW_BSSID_0;
  45 
  46                 for (i = EXT_BSSID_1; i < EXT_BSSID_END; i++)
  47                         if (~mask & BIT(i))
  48                                 return i;
  49 
  50                 break;
  51         case NL80211_IFTYPE_STATION:
  52                 /* sta use hw bssid other than 0 */
  53                 for (i = HW_BSSID_1; i < HW_BSSID_MAX; i++)
  54                         if (~mask & BIT(i))
  55                                 return i;
  56 
  57                 break;
  58         default:
  59                 WARN_ON(1);
  60                 break;
  61         };
  62 
  63         return -1;
  64 }
  65 
  66 static int mt7615_add_interface(struct ieee80211_hw *hw,
  67                                 struct ieee80211_vif *vif)
  68 {
  69         struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
  70         struct mt7615_dev *dev = hw->priv;
  71         struct mt76_txq *mtxq;
  72         int idx, ret = 0;
  73 
  74         mutex_lock(&dev->mt76.mutex);
  75 
  76         mvif->idx = ffs(~dev->vif_mask) - 1;
  77         if (mvif->idx >= MT7615_MAX_INTERFACES) {
  78                 ret = -ENOSPC;
  79                 goto out;
  80         }
  81 
  82         idx = get_omac_idx(vif->type, dev->omac_mask);
  83         if (idx < 0) {
  84                 ret = -ENOSPC;
  85                 goto out;
  86         }
  87         mvif->omac_idx = idx;
  88 
  89         /* TODO: DBDC support. Use band 0 for now */
  90         mvif->band_idx = 0;
  91         mvif->wmm_idx = mvif->idx % MT7615_MAX_WMM_SETS;
  92 
  93         ret = mt7615_mcu_set_dev_info(dev, vif, 1);
  94         if (ret)
  95                 goto out;
  96 
  97         dev->vif_mask |= BIT(mvif->idx);
  98         dev->omac_mask |= BIT(mvif->omac_idx);
  99         idx = MT7615_WTBL_RESERVED - mvif->idx;
 100         mvif->sta.wcid.idx = idx;
 101         mvif->sta.wcid.hw_key_idx = -1;
 102 
 103         rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid);
 104         mtxq = (struct mt76_txq *)vif->txq->drv_priv;
 105         mtxq->wcid = &mvif->sta.wcid;
 106         mt76_txq_init(&dev->mt76, vif->txq);
 107 
 108 out:
 109         mutex_unlock(&dev->mt76.mutex);
 110 
 111         return ret;
 112 }
 113 
 114 static void mt7615_remove_interface(struct ieee80211_hw *hw,
 115                                     struct ieee80211_vif *vif)
 116 {
 117         struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
 118         struct mt7615_dev *dev = hw->priv;
 119         int idx = mvif->sta.wcid.idx;
 120 
 121         /* TODO: disable beacon for the bss */
 122 
 123         mt7615_mcu_set_dev_info(dev, vif, 0);
 124 
 125         rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
 126         mt76_txq_remove(&dev->mt76, vif->txq);
 127 
 128         mutex_lock(&dev->mt76.mutex);
 129         dev->vif_mask &= ~BIT(mvif->idx);
 130         dev->omac_mask &= ~BIT(mvif->omac_idx);
 131         mutex_unlock(&dev->mt76.mutex);
 132 }
 133 
 134 static int mt7615_set_channel(struct mt7615_dev *dev)
 135 {
 136         int ret;
 137 
 138         cancel_delayed_work_sync(&dev->mt76.mac_work);
 139 
 140         mutex_lock(&dev->mt76.mutex);
 141         set_bit(MT76_RESET, &dev->mt76.state);
 142 
 143         mt7615_dfs_check_channel(dev);
 144 
 145         mt76_set_channel(&dev->mt76);
 146 
 147         ret = mt7615_mcu_set_channel(dev);
 148         if (ret)
 149                 goto out;
 150 
 151         ret = mt7615_dfs_init_radar_detector(dev);
 152         mt7615_mac_cca_stats_reset(dev);
 153         dev->mt76.survey_time = ktime_get_boottime();
 154         /* TODO: add DBDC support */
 155         mt76_rr(dev, MT_MIB_SDR16(0));
 156 
 157 out:
 158         clear_bit(MT76_RESET, &dev->mt76.state);
 159         mutex_unlock(&dev->mt76.mutex);
 160 
 161         mt76_txq_schedule_all(&dev->mt76);
 162         ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
 163                                      MT7615_WATCHDOG_TIME);
 164         return ret;
 165 }
 166 
 167 static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 168                           struct ieee80211_vif *vif, struct ieee80211_sta *sta,
 169                           struct ieee80211_key_conf *key)
 170 {
 171         struct mt7615_dev *dev = hw->priv;
 172         struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
 173         struct mt7615_sta *msta = sta ? (struct mt7615_sta *)sta->drv_priv :
 174                                   &mvif->sta;
 175         struct mt76_wcid *wcid = &msta->wcid;
 176         int idx = key->keyidx;
 177 
 178         /* The hardware does not support per-STA RX GTK, fallback
 179          * to software mode for these.
 180          */
 181         if ((vif->type == NL80211_IFTYPE_ADHOC ||
 182              vif->type == NL80211_IFTYPE_MESH_POINT) &&
 183             (key->cipher == WLAN_CIPHER_SUITE_TKIP ||
 184              key->cipher == WLAN_CIPHER_SUITE_CCMP) &&
 185             !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
 186                 return -EOPNOTSUPP;
 187 
 188         /* fall back to sw encryption for unsupported ciphers */
 189         switch (key->cipher) {
 190         case WLAN_CIPHER_SUITE_AES_CMAC:
 191                 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIE;
 192                 break;
 193         case WLAN_CIPHER_SUITE_WEP40:
 194         case WLAN_CIPHER_SUITE_WEP104:
 195         case WLAN_CIPHER_SUITE_TKIP:
 196         case WLAN_CIPHER_SUITE_CCMP:
 197         case WLAN_CIPHER_SUITE_CCMP_256:
 198         case WLAN_CIPHER_SUITE_GCMP:
 199         case WLAN_CIPHER_SUITE_GCMP_256:
 200         case WLAN_CIPHER_SUITE_SMS4:
 201                 break;
 202         default:
 203                 return -EOPNOTSUPP;
 204         }
 205 
 206         if (cmd == SET_KEY) {
 207                 key->hw_key_idx = wcid->idx;
 208                 wcid->hw_key_idx = idx;
 209         } else if (idx == wcid->hw_key_idx) {
 210                 wcid->hw_key_idx = -1;
 211         }
 212         mt76_wcid_key_setup(&dev->mt76, wcid,
 213                             cmd == SET_KEY ? key : NULL);
 214 
 215         return mt7615_mac_wtbl_set_key(dev, wcid, key, cmd);
 216 }
 217 
 218 static int mt7615_config(struct ieee80211_hw *hw, u32 changed)
 219 {
 220         struct mt7615_dev *dev = hw->priv;
 221         int ret = 0;
 222 
 223         if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
 224                 ieee80211_stop_queues(hw);
 225                 ret = mt7615_set_channel(dev);
 226                 ieee80211_wake_queues(hw);
 227         }
 228 
 229         mutex_lock(&dev->mt76.mutex);
 230 
 231         if (changed & IEEE80211_CONF_CHANGE_POWER)
 232                 ret = mt7615_mcu_set_tx_power(dev);
 233 
 234         if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
 235                 if (!(hw->conf.flags & IEEE80211_CONF_MONITOR))
 236                         dev->mt76.rxfilter |= MT_WF_RFCR_DROP_OTHER_UC;
 237                 else
 238                         dev->mt76.rxfilter &= ~MT_WF_RFCR_DROP_OTHER_UC;
 239 
 240                 mt76_wr(dev, MT_WF_RFCR, dev->mt76.rxfilter);
 241         }
 242 
 243         mutex_unlock(&dev->mt76.mutex);
 244 
 245         return ret;
 246 }
 247 
 248 static int
 249 mt7615_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
 250                const struct ieee80211_tx_queue_params *params)
 251 {
 252         struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
 253         struct mt7615_dev *dev = hw->priv;
 254 
 255         queue += mvif->wmm_idx * MT7615_MAX_WMM_SETS;
 256 
 257         return mt7615_mcu_set_wmm(dev, queue, params);
 258 }
 259 
 260 static void mt7615_configure_filter(struct ieee80211_hw *hw,
 261                                     unsigned int changed_flags,
 262                                     unsigned int *total_flags,
 263                                     u64 multicast)
 264 {
 265         struct mt7615_dev *dev = hw->priv;
 266         u32 flags = 0;
 267 
 268 #define MT76_FILTER(_flag, _hw) do { \
 269                 flags |= *total_flags & FIF_##_flag;                    \
 270                 dev->mt76.rxfilter &= ~(_hw);                           \
 271                 dev->mt76.rxfilter |= !(flags & FIF_##_flag) * (_hw);   \
 272         } while (0)
 273 
 274         dev->mt76.rxfilter &= ~(MT_WF_RFCR_DROP_OTHER_BSS |
 275                                 MT_WF_RFCR_DROP_OTHER_BEACON |
 276                                 MT_WF_RFCR_DROP_FRAME_REPORT |
 277                                 MT_WF_RFCR_DROP_PROBEREQ |
 278                                 MT_WF_RFCR_DROP_MCAST_FILTERED |
 279                                 MT_WF_RFCR_DROP_MCAST |
 280                                 MT_WF_RFCR_DROP_BCAST |
 281                                 MT_WF_RFCR_DROP_DUPLICATE |
 282                                 MT_WF_RFCR_DROP_A2_BSSID |
 283                                 MT_WF_RFCR_DROP_UNWANTED_CTL |
 284                                 MT_WF_RFCR_DROP_STBC_MULTI);
 285 
 286         MT76_FILTER(OTHER_BSS, MT_WF_RFCR_DROP_OTHER_TIM |
 287                                MT_WF_RFCR_DROP_A3_MAC |
 288                                MT_WF_RFCR_DROP_A3_BSSID);
 289 
 290         MT76_FILTER(FCSFAIL, MT_WF_RFCR_DROP_FCSFAIL);
 291 
 292         MT76_FILTER(CONTROL, MT_WF_RFCR_DROP_CTS |
 293                              MT_WF_RFCR_DROP_RTS |
 294                              MT_WF_RFCR_DROP_CTL_RSV |
 295                              MT_WF_RFCR_DROP_NDPA);
 296 
 297         *total_flags = flags;
 298         mt76_wr(dev, MT_WF_RFCR, dev->mt76.rxfilter);
 299 }
 300 
 301 static void mt7615_bss_info_changed(struct ieee80211_hw *hw,
 302                                     struct ieee80211_vif *vif,
 303                                     struct ieee80211_bss_conf *info,
 304                                     u32 changed)
 305 {
 306         struct mt7615_dev *dev = hw->priv;
 307 
 308         mutex_lock(&dev->mt76.mutex);
 309 
 310         if (changed & BSS_CHANGED_ASSOC)
 311                 mt7615_mcu_set_bss_info(dev, vif, info->assoc);
 312 
 313         /* TODO: update beacon content
 314          * BSS_CHANGED_BEACON
 315          */
 316 
 317         if (changed & BSS_CHANGED_BEACON_ENABLED) {
 318                 mt7615_mcu_set_bss_info(dev, vif, info->enable_beacon);
 319                 mt7615_mcu_wtbl_bmc(dev, vif, info->enable_beacon);
 320                 mt7615_mcu_set_sta_rec_bmc(dev, vif, info->enable_beacon);
 321                 mt7615_mcu_set_bcn(dev, vif, info->enable_beacon);
 322         }
 323 
 324         mutex_unlock(&dev->mt76.mutex);
 325 }
 326 
 327 static void
 328 mt7615_channel_switch_beacon(struct ieee80211_hw *hw,
 329                              struct ieee80211_vif *vif,
 330                              struct cfg80211_chan_def *chandef)
 331 {
 332         struct mt7615_dev *dev = hw->priv;
 333 
 334         mutex_lock(&dev->mt76.mutex);
 335         mt7615_mcu_set_bcn(dev, vif, true);
 336         mutex_unlock(&dev->mt76.mutex);
 337 }
 338 
 339 int mt7615_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
 340                    struct ieee80211_sta *sta)
 341 {
 342         struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
 343         struct mt7615_sta *msta = (struct mt7615_sta *)sta->drv_priv;
 344         struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
 345         int idx;
 346 
 347         idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7615_WTBL_STA - 1);
 348         if (idx < 0)
 349                 return -ENOSPC;
 350 
 351         msta->vif = mvif;
 352         msta->wcid.sta = 1;
 353         msta->wcid.idx = idx;
 354 
 355         mt7615_mcu_add_wtbl(dev, vif, sta);
 356         mt7615_mcu_set_sta_rec(dev, vif, sta, 1);
 357 
 358         return 0;
 359 }
 360 
 361 void mt7615_sta_assoc(struct mt76_dev *mdev, struct ieee80211_vif *vif,
 362                       struct ieee80211_sta *sta)
 363 {
 364         struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
 365 
 366         if (sta->ht_cap.ht_supported)
 367                 mt7615_mcu_set_ht_cap(dev, vif, sta);
 368 }
 369 
 370 void mt7615_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
 371                        struct ieee80211_sta *sta)
 372 {
 373         struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
 374 
 375         mt7615_mcu_set_sta_rec(dev, vif, sta, 0);
 376         mt7615_mcu_del_wtbl(dev, sta);
 377 }
 378 
 379 static void mt7615_sta_rate_tbl_update(struct ieee80211_hw *hw,
 380                                        struct ieee80211_vif *vif,
 381                                        struct ieee80211_sta *sta)
 382 {
 383         struct mt7615_dev *dev = hw->priv;
 384         struct mt7615_sta *msta = (struct mt7615_sta *)sta->drv_priv;
 385         struct ieee80211_sta_rates *sta_rates = rcu_dereference(sta->rates);
 386         int i;
 387 
 388         spin_lock_bh(&dev->mt76.lock);
 389         for (i = 0; i < ARRAY_SIZE(msta->rates); i++) {
 390                 msta->rates[i].idx = sta_rates->rate[i].idx;
 391                 msta->rates[i].count = sta_rates->rate[i].count;
 392                 msta->rates[i].flags = sta_rates->rate[i].flags;
 393 
 394                 if (msta->rates[i].idx < 0 || !msta->rates[i].count)
 395                         break;
 396         }
 397         msta->n_rates = i;
 398         mt7615_mac_set_rates(dev, msta, NULL, msta->rates);
 399         msta->rate_probe = false;
 400         spin_unlock_bh(&dev->mt76.lock);
 401 }
 402 
 403 static void mt7615_tx(struct ieee80211_hw *hw,
 404                       struct ieee80211_tx_control *control,
 405                       struct sk_buff *skb)
 406 {
 407         struct mt7615_dev *dev = hw->priv;
 408         struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 409         struct ieee80211_vif *vif = info->control.vif;
 410         struct mt76_wcid *wcid = &dev->mt76.global_wcid;
 411 
 412         if (control->sta) {
 413                 struct mt7615_sta *sta;
 414 
 415                 sta = (struct mt7615_sta *)control->sta->drv_priv;
 416                 wcid = &sta->wcid;
 417         }
 418 
 419         if (vif && !control->sta) {
 420                 struct mt7615_vif *mvif;
 421 
 422                 mvif = (struct mt7615_vif *)vif->drv_priv;
 423                 wcid = &mvif->sta.wcid;
 424         }
 425 
 426         mt76_tx(&dev->mt76, control->sta, wcid, skb);
 427 }
 428 
 429 static int mt7615_set_rts_threshold(struct ieee80211_hw *hw, u32 val)
 430 {
 431         struct mt7615_dev *dev = hw->priv;
 432 
 433         mutex_lock(&dev->mt76.mutex);
 434         mt7615_mcu_set_rts_thresh(dev, val);
 435         mutex_unlock(&dev->mt76.mutex);
 436 
 437         return 0;
 438 }
 439 
 440 static int
 441 mt7615_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 442                     struct ieee80211_ampdu_params *params)
 443 {
 444         enum ieee80211_ampdu_mlme_action action = params->action;
 445         struct mt7615_dev *dev = hw->priv;
 446         struct ieee80211_sta *sta = params->sta;
 447         struct ieee80211_txq *txq = sta->txq[params->tid];
 448         struct mt7615_sta *msta = (struct mt7615_sta *)sta->drv_priv;
 449         u16 tid = params->tid;
 450         u16 ssn = params->ssn;
 451         struct mt76_txq *mtxq;
 452 
 453         if (!txq)
 454                 return -EINVAL;
 455 
 456         mtxq = (struct mt76_txq *)txq->drv_priv;
 457 
 458         switch (action) {
 459         case IEEE80211_AMPDU_RX_START:
 460                 mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid, ssn,
 461                                    params->buf_size);
 462                 mt7615_mcu_set_rx_ba(dev, params, 1);
 463                 break;
 464         case IEEE80211_AMPDU_RX_STOP:
 465                 mt76_rx_aggr_stop(&dev->mt76, &msta->wcid, tid);
 466                 mt7615_mcu_set_rx_ba(dev, params, 0);
 467                 break;
 468         case IEEE80211_AMPDU_TX_OPERATIONAL:
 469                 mtxq->aggr = true;
 470                 mtxq->send_bar = false;
 471                 mt7615_mcu_set_tx_ba(dev, params, 1);
 472                 break;
 473         case IEEE80211_AMPDU_TX_STOP_FLUSH:
 474         case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
 475                 mtxq->aggr = false;
 476                 mt7615_mcu_set_tx_ba(dev, params, 0);
 477                 break;
 478         case IEEE80211_AMPDU_TX_START:
 479                 mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(ssn);
 480                 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
 481                 break;
 482         case IEEE80211_AMPDU_TX_STOP_CONT:
 483                 mtxq->aggr = false;
 484                 mt7615_mcu_set_tx_ba(dev, params, 0);
 485                 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
 486                 break;
 487         }
 488 
 489         return 0;
 490 }
 491 
 492 const struct ieee80211_ops mt7615_ops = {
 493         .tx = mt7615_tx,
 494         .start = mt7615_start,
 495         .stop = mt7615_stop,
 496         .add_interface = mt7615_add_interface,
 497         .remove_interface = mt7615_remove_interface,
 498         .config = mt7615_config,
 499         .conf_tx = mt7615_conf_tx,
 500         .configure_filter = mt7615_configure_filter,
 501         .bss_info_changed = mt7615_bss_info_changed,
 502         .sta_state = mt76_sta_state,
 503         .set_key = mt7615_set_key,
 504         .ampdu_action = mt7615_ampdu_action,
 505         .set_rts_threshold = mt7615_set_rts_threshold,
 506         .wake_tx_queue = mt76_wake_tx_queue,
 507         .sta_rate_tbl_update = mt7615_sta_rate_tbl_update,
 508         .sw_scan_start = mt76_sw_scan,
 509         .sw_scan_complete = mt76_sw_scan_complete,
 510         .release_buffered_frames = mt76_release_buffered_frames,
 511         .get_txpower = mt76_get_txpower,
 512         .channel_switch_beacon = mt7615_channel_switch_beacon,
 513         .get_survey = mt76_get_survey,
 514 };

/* [<][>][^][v][top][bottom][index][help] */