1 /* 2 * Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl> 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <linux/module.h> 19 #include "mt76x02.h" 20 21 #define CCK_RATE(_idx, _rate) { \ 22 .bitrate = _rate, \ 23 .flags = IEEE80211_RATE_SHORT_PREAMBLE, \ 24 .hw_value = (MT_PHY_TYPE_CCK << 8) | _idx, \ 25 .hw_value_short = (MT_PHY_TYPE_CCK << 8) | (8 + _idx), \ 26 } 27 28 #define OFDM_RATE(_idx, _rate) { \ 29 .bitrate = _rate, \ 30 .hw_value = (MT_PHY_TYPE_OFDM << 8) | _idx, \ 31 .hw_value_short = (MT_PHY_TYPE_OFDM << 8) | _idx, \ 32 } 33 34 struct ieee80211_rate mt76x02_rates[] = { 35 CCK_RATE(0, 10), 36 CCK_RATE(1, 20), 37 CCK_RATE(2, 55), 38 CCK_RATE(3, 110), 39 OFDM_RATE(0, 60), 40 OFDM_RATE(1, 90), 41 OFDM_RATE(2, 120), 42 OFDM_RATE(3, 180), 43 OFDM_RATE(4, 240), 44 OFDM_RATE(5, 360), 45 OFDM_RATE(6, 480), 46 OFDM_RATE(7, 540), 47 }; 48 EXPORT_SYMBOL_GPL(mt76x02_rates); 49 50 static const struct ieee80211_iface_limit mt76x02_if_limits[] = { 51 { 52 .max = 1, 53 .types = BIT(NL80211_IFTYPE_ADHOC) 54 }, { 55 .max = 8, 56 .types = BIT(NL80211_IFTYPE_STATION) | 57 #ifdef CONFIG_MAC80211_MESH 58 BIT(NL80211_IFTYPE_MESH_POINT) | 59 #endif 60 BIT(NL80211_IFTYPE_AP) 61 }, 62 }; 63 64 static const struct ieee80211_iface_combination mt76x02_if_comb[] = { 65 { 66 .limits = mt76x02_if_limits, 67 .n_limits = ARRAY_SIZE(mt76x02_if_limits), 68 .max_interfaces = 8, 69 .num_different_channels = 1, 70 .beacon_int_infra_match = true, 71 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | 72 BIT(NL80211_CHAN_WIDTH_20) | 73 BIT(NL80211_CHAN_WIDTH_40) | 74 BIT(NL80211_CHAN_WIDTH_80), 75 } 76 }; 77 78 void mt76x02_init_device(struct mt76x02_dev *dev) 79 { 80 struct ieee80211_hw *hw = mt76_hw(dev); 81 struct wiphy *wiphy = hw->wiphy; 82 83 INIT_DELAYED_WORK(&dev->mac_work, mt76x02_mac_work); 84 85 hw->queues = 4; 86 hw->max_rates = 1; 87 hw->max_report_rates = 7; 88 hw->max_rate_tries = 1; 89 hw->extra_tx_headroom = 2; 90 91 if (mt76_is_usb(dev)) { 92 hw->extra_tx_headroom += sizeof(struct mt76x02_txwi) + 93 MT_DMA_HDR_LEN; 94 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); 95 } else { 96 mt76x02_dfs_init_detector(dev); 97 98 wiphy->reg_notifier = mt76x02_regd_notifier; 99 wiphy->iface_combinations = mt76x02_if_comb; 100 wiphy->n_iface_combinations = ARRAY_SIZE(mt76x02_if_comb); 101 wiphy->interface_modes = 102 BIT(NL80211_IFTYPE_STATION) | 103 BIT(NL80211_IFTYPE_AP) | 104 #ifdef CONFIG_MAC80211_MESH 105 BIT(NL80211_IFTYPE_MESH_POINT) | 106 #endif 107 BIT(NL80211_IFTYPE_ADHOC); 108 109 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS); 110 } 111 112 hw->sta_data_size = sizeof(struct mt76x02_sta); 113 hw->vif_data_size = sizeof(struct mt76x02_vif); 114 115 ieee80211_hw_set(hw, SUPPORTS_HT_CCK_RATES); 116 ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER); 117 118 dev->mt76.global_wcid.idx = 255; 119 dev->mt76.global_wcid.hw_key_idx = -1; 120 dev->slottime = 9; 121 122 if (is_mt76x2(dev)) { 123 dev->mt76.sband_2g.sband.ht_cap.cap |= 124 IEEE80211_HT_CAP_LDPC_CODING; 125 dev->mt76.sband_5g.sband.ht_cap.cap |= 126 IEEE80211_HT_CAP_LDPC_CODING; 127 dev->mt76.chainmask = 0x202; 128 dev->mt76.antenna_mask = 3; 129 } else { 130 dev->mt76.chainmask = 0x101; 131 dev->mt76.antenna_mask = 1; 132 } 133 } 134 EXPORT_SYMBOL_GPL(mt76x02_init_device); 135 136 void mt76x02_configure_filter(struct ieee80211_hw *hw, 137 unsigned int changed_flags, 138 unsigned int *total_flags, u64 multicast) 139 { 140 struct mt76x02_dev *dev = hw->priv; 141 u32 flags = 0; 142 143 #define MT76_FILTER(_flag, _hw) do { \ 144 flags |= *total_flags & FIF_##_flag; \ 145 dev->mt76.rxfilter &= ~(_hw); \ 146 dev->mt76.rxfilter |= !(flags & FIF_##_flag) * (_hw); \ 147 } while (0) 148 149 mutex_lock(&dev->mt76.mutex); 150 151 dev->mt76.rxfilter &= ~MT_RX_FILTR_CFG_OTHER_BSS; 152 153 MT76_FILTER(FCSFAIL, MT_RX_FILTR_CFG_CRC_ERR); 154 MT76_FILTER(PLCPFAIL, MT_RX_FILTR_CFG_PHY_ERR); 155 MT76_FILTER(CONTROL, MT_RX_FILTR_CFG_ACK | 156 MT_RX_FILTR_CFG_CTS | 157 MT_RX_FILTR_CFG_CFEND | 158 MT_RX_FILTR_CFG_CFACK | 159 MT_RX_FILTR_CFG_BA | 160 MT_RX_FILTR_CFG_CTRL_RSV); 161 MT76_FILTER(PSPOLL, MT_RX_FILTR_CFG_PSPOLL); 162 163 *total_flags = flags; 164 mt76_wr(dev, MT_RX_FILTR_CFG, dev->mt76.rxfilter); 165 166 mutex_unlock(&dev->mt76.mutex); 167 } 168 EXPORT_SYMBOL_GPL(mt76x02_configure_filter); 169 170 int mt76x02_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, 171 struct ieee80211_sta *sta) 172 { 173 struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76); 174 struct mt76x02_sta *msta = (struct mt76x02_sta *)sta->drv_priv; 175 struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv; 176 int idx = 0; 177 178 idx = mt76_wcid_alloc(dev->mt76.wcid_mask, ARRAY_SIZE(dev->mt76.wcid)); 179 if (idx < 0) 180 return -ENOSPC; 181 182 msta->vif = mvif; 183 msta->wcid.sta = 1; 184 msta->wcid.idx = idx; 185 msta->wcid.hw_key_idx = -1; 186 mt76x02_mac_wcid_setup(dev, idx, mvif->idx, sta->addr); 187 mt76x02_mac_wcid_set_drop(dev, idx, false); 188 189 if (vif->type == NL80211_IFTYPE_AP) 190 set_bit(MT_WCID_FLAG_CHECK_PS, &msta->wcid.flags); 191 192 ewma_signal_init(&msta->rssi); 193 194 return 0; 195 } 196 EXPORT_SYMBOL_GPL(mt76x02_sta_add); 197 198 void mt76x02_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, 199 struct ieee80211_sta *sta) 200 { 201 struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76); 202 struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv; 203 int idx = wcid->idx; 204 205 mt76x02_mac_wcid_set_drop(dev, idx, true); 206 mt76x02_mac_wcid_setup(dev, idx, 0, NULL); 207 } 208 EXPORT_SYMBOL_GPL(mt76x02_sta_remove); 209 210 void mt76x02_vif_init(struct mt76x02_dev *dev, struct ieee80211_vif *vif, 211 unsigned int idx) 212 { 213 struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv; 214 struct mt76_txq *mtxq; 215 216 mvif->idx = idx; 217 mvif->group_wcid.idx = MT_VIF_WCID(idx); 218 mvif->group_wcid.hw_key_idx = -1; 219 mtxq = (struct mt76_txq *) vif->txq->drv_priv; 220 mtxq->wcid = &mvif->group_wcid; 221 222 mt76_txq_init(&dev->mt76, vif->txq); 223 } 224 EXPORT_SYMBOL_GPL(mt76x02_vif_init); 225 226 int 227 mt76x02_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 228 { 229 struct mt76x02_dev *dev = hw->priv; 230 unsigned int idx = 0; 231 232 if (vif->addr[0] & BIT(1)) 233 idx = 1 + (((dev->mt76.macaddr[0] ^ vif->addr[0]) >> 2) & 7); 234 235 /* 236 * Client mode typically only has one configurable BSSID register, 237 * which is used for bssidx=0. This is linked to the MAC address. 238 * Since mac80211 allows changing interface types, and we cannot 239 * force the use of the primary MAC address for a station mode 240 * interface, we need some other way of configuring a per-interface 241 * remote BSSID. 242 * The hardware provides an AP-Client feature, where bssidx 0-7 are 243 * used for AP mode and bssidx 8-15 for client mode. 244 * We shift the station interface bss index by 8 to force the 245 * hardware to recognize the BSSID. 246 * The resulting bssidx mismatch for unicast frames is ignored by hw. 247 */ 248 if (vif->type == NL80211_IFTYPE_STATION) 249 idx += 8; 250 251 mt76x02_vif_init(dev, vif, idx); 252 return 0; 253 } 254 EXPORT_SYMBOL_GPL(mt76x02_add_interface); 255 256 void mt76x02_remove_interface(struct ieee80211_hw *hw, 257 struct ieee80211_vif *vif) 258 { 259 struct mt76x02_dev *dev = hw->priv; 260 261 mt76_txq_remove(&dev->mt76, vif->txq); 262 } 263 EXPORT_SYMBOL_GPL(mt76x02_remove_interface); 264 265 int mt76x02_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 266 struct ieee80211_ampdu_params *params) 267 { 268 enum ieee80211_ampdu_mlme_action action = params->action; 269 struct ieee80211_sta *sta = params->sta; 270 struct mt76x02_dev *dev = hw->priv; 271 struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; 272 struct ieee80211_txq *txq = sta->txq[params->tid]; 273 u16 tid = params->tid; 274 u16 *ssn = ¶ms->ssn; 275 struct mt76_txq *mtxq; 276 277 if (!txq) 278 return -EINVAL; 279 280 mtxq = (struct mt76_txq *)txq->drv_priv; 281 282 switch (action) { 283 case IEEE80211_AMPDU_RX_START: 284 mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid, 285 *ssn, params->buf_size); 286 mt76_set(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid)); 287 break; 288 case IEEE80211_AMPDU_RX_STOP: 289 mt76_rx_aggr_stop(&dev->mt76, &msta->wcid, tid); 290 mt76_clear(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, 291 BIT(16 + tid)); 292 break; 293 case IEEE80211_AMPDU_TX_OPERATIONAL: 294 mtxq->aggr = true; 295 mtxq->send_bar = false; 296 ieee80211_send_bar(vif, sta->addr, tid, mtxq->agg_ssn); 297 break; 298 case IEEE80211_AMPDU_TX_STOP_FLUSH: 299 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: 300 mtxq->aggr = false; 301 ieee80211_send_bar(vif, sta->addr, tid, mtxq->agg_ssn); 302 break; 303 case IEEE80211_AMPDU_TX_START: 304 mtxq->agg_ssn = *ssn << 4; 305 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); 306 break; 307 case IEEE80211_AMPDU_TX_STOP_CONT: 308 mtxq->aggr = false; 309 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); 310 break; 311 } 312 313 return 0; 314 } 315 EXPORT_SYMBOL_GPL(mt76x02_ampdu_action); 316 317 int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 318 struct ieee80211_vif *vif, struct ieee80211_sta *sta, 319 struct ieee80211_key_conf *key) 320 { 321 struct mt76x02_dev *dev = hw->priv; 322 struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv; 323 struct mt76x02_sta *msta; 324 struct mt76_wcid *wcid; 325 int idx = key->keyidx; 326 int ret; 327 328 /* fall back to sw encryption for unsupported ciphers */ 329 switch (key->cipher) { 330 case WLAN_CIPHER_SUITE_WEP40: 331 case WLAN_CIPHER_SUITE_WEP104: 332 case WLAN_CIPHER_SUITE_TKIP: 333 case WLAN_CIPHER_SUITE_CCMP: 334 break; 335 default: 336 return -EOPNOTSUPP; 337 } 338 339 /* 340 * The hardware does not support per-STA RX GTK, fall back 341 * to software mode for these. 342 */ 343 if ((vif->type == NL80211_IFTYPE_ADHOC || 344 vif->type == NL80211_IFTYPE_MESH_POINT) && 345 (key->cipher == WLAN_CIPHER_SUITE_TKIP || 346 key->cipher == WLAN_CIPHER_SUITE_CCMP) && 347 !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) 348 return -EOPNOTSUPP; 349 350 msta = sta ? (struct mt76x02_sta *) sta->drv_priv : NULL; 351 wcid = msta ? &msta->wcid : &mvif->group_wcid; 352 353 if (cmd == SET_KEY) { 354 key->hw_key_idx = wcid->idx; 355 wcid->hw_key_idx = idx; 356 if (key->flags & IEEE80211_KEY_FLAG_RX_MGMT) { 357 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; 358 wcid->sw_iv = true; 359 } 360 } else { 361 if (idx == wcid->hw_key_idx) { 362 wcid->hw_key_idx = -1; 363 wcid->sw_iv = true; 364 } 365 366 key = NULL; 367 } 368 mt76_wcid_key_setup(&dev->mt76, wcid, key); 369 370 if (!msta) { 371 if (key || wcid->hw_key_idx == idx) { 372 ret = mt76x02_mac_wcid_set_key(dev, wcid->idx, key); 373 if (ret) 374 return ret; 375 } 376 377 return mt76x02_mac_shared_key_setup(dev, mvif->idx, idx, key); 378 } 379 380 return mt76x02_mac_wcid_set_key(dev, msta->wcid.idx, key); 381 } 382 EXPORT_SYMBOL_GPL(mt76x02_set_key); 383 384 int mt76x02_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 385 u16 queue, const struct ieee80211_tx_queue_params *params) 386 { 387 struct mt76x02_dev *dev = hw->priv; 388 u8 cw_min = 5, cw_max = 10, qid; 389 u32 val; 390 391 qid = dev->mt76.q_tx[queue].hw_idx; 392 393 if (params->cw_min) 394 cw_min = fls(params->cw_min); 395 if (params->cw_max) 396 cw_max = fls(params->cw_max); 397 398 val = FIELD_PREP(MT_EDCA_CFG_TXOP, params->txop) | 399 FIELD_PREP(MT_EDCA_CFG_AIFSN, params->aifs) | 400 FIELD_PREP(MT_EDCA_CFG_CWMIN, cw_min) | 401 FIELD_PREP(MT_EDCA_CFG_CWMAX, cw_max); 402 mt76_wr(dev, MT_EDCA_CFG_AC(qid), val); 403 404 val = mt76_rr(dev, MT_WMM_TXOP(qid)); 405 val &= ~(MT_WMM_TXOP_MASK << MT_WMM_TXOP_SHIFT(qid)); 406 val |= params->txop << MT_WMM_TXOP_SHIFT(qid); 407 mt76_wr(dev, MT_WMM_TXOP(qid), val); 408 409 val = mt76_rr(dev, MT_WMM_AIFSN); 410 val &= ~(MT_WMM_AIFSN_MASK << MT_WMM_AIFSN_SHIFT(qid)); 411 val |= params->aifs << MT_WMM_AIFSN_SHIFT(qid); 412 mt76_wr(dev, MT_WMM_AIFSN, val); 413 414 val = mt76_rr(dev, MT_WMM_CWMIN); 415 val &= ~(MT_WMM_CWMIN_MASK << MT_WMM_CWMIN_SHIFT(qid)); 416 val |= cw_min << MT_WMM_CWMIN_SHIFT(qid); 417 mt76_wr(dev, MT_WMM_CWMIN, val); 418 419 val = mt76_rr(dev, MT_WMM_CWMAX); 420 val &= ~(MT_WMM_CWMAX_MASK << MT_WMM_CWMAX_SHIFT(qid)); 421 val |= cw_max << MT_WMM_CWMAX_SHIFT(qid); 422 mt76_wr(dev, MT_WMM_CWMAX, val); 423 424 return 0; 425 } 426 EXPORT_SYMBOL_GPL(mt76x02_conf_tx); 427 428 void mt76x02_set_tx_ackto(struct mt76x02_dev *dev) 429 { 430 u8 ackto, sifs, slottime = dev->slottime; 431 432 /* As defined by IEEE 802.11-2007 17.3.8.6 */ 433 slottime += 3 * dev->coverage_class; 434 mt76_rmw_field(dev, MT_BKOFF_SLOT_CFG, 435 MT_BKOFF_SLOT_CFG_SLOTTIME, slottime); 436 437 sifs = mt76_get_field(dev, MT_XIFS_TIME_CFG, 438 MT_XIFS_TIME_CFG_OFDM_SIFS); 439 440 ackto = slottime + sifs; 441 mt76_rmw_field(dev, MT_TX_TIMEOUT_CFG, 442 MT_TX_TIMEOUT_CFG_ACKTO, ackto); 443 } 444 EXPORT_SYMBOL_GPL(mt76x02_set_tx_ackto); 445 446 void mt76x02_set_coverage_class(struct ieee80211_hw *hw, 447 s16 coverage_class) 448 { 449 struct mt76x02_dev *dev = hw->priv; 450 451 mutex_lock(&dev->mt76.mutex); 452 dev->coverage_class = coverage_class; 453 mt76x02_set_tx_ackto(dev); 454 mutex_unlock(&dev->mt76.mutex); 455 } 456 EXPORT_SYMBOL_GPL(mt76x02_set_coverage_class); 457 458 int mt76x02_set_rts_threshold(struct ieee80211_hw *hw, u32 val) 459 { 460 struct mt76x02_dev *dev = hw->priv; 461 462 if (val != ~0 && val > 0xffff) 463 return -EINVAL; 464 465 mutex_lock(&dev->mt76.mutex); 466 mt76x02_mac_set_tx_protection(dev, val); 467 mutex_unlock(&dev->mt76.mutex); 468 469 return 0; 470 } 471 EXPORT_SYMBOL_GPL(mt76x02_set_rts_threshold); 472 473 void mt76x02_sta_rate_tbl_update(struct ieee80211_hw *hw, 474 struct ieee80211_vif *vif, 475 struct ieee80211_sta *sta) 476 { 477 struct mt76x02_dev *dev = hw->priv; 478 struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv; 479 struct ieee80211_sta_rates *rates = rcu_dereference(sta->rates); 480 struct ieee80211_tx_rate rate = {}; 481 482 if (!rates) 483 return; 484 485 rate.idx = rates->rate[0].idx; 486 rate.flags = rates->rate[0].flags; 487 mt76x02_mac_wcid_set_rate(dev, &msta->wcid, &rate); 488 msta->wcid.max_txpwr_adj = mt76x02_tx_get_max_txpwr_adj(dev, &rate); 489 } 490 EXPORT_SYMBOL_GPL(mt76x02_sta_rate_tbl_update); 491 492 int mt76x02_insert_hdr_pad(struct sk_buff *skb) 493 { 494 int len = ieee80211_get_hdrlen_from_skb(skb); 495 496 if (len % 4 == 0) 497 return 0; 498 499 skb_push(skb, 2); 500 memmove(skb->data, skb->data + 2, len); 501 502 skb->data[len] = 0; 503 skb->data[len + 1] = 0; 504 return 2; 505 } 506 EXPORT_SYMBOL_GPL(mt76x02_insert_hdr_pad); 507 508 void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len) 509 { 510 int hdrlen; 511 512 if (!len) 513 return; 514 515 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 516 memmove(skb->data + len, skb->data, hdrlen); 517 skb_pull(skb, len); 518 } 519 EXPORT_SYMBOL_GPL(mt76x02_remove_hdr_pad); 520 521 void mt76x02_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 522 const u8 *mac) 523 { 524 struct mt76x02_dev *dev = hw->priv; 525 526 if (mt76_is_mmio(dev)) 527 tasklet_disable(&dev->pre_tbtt_tasklet); 528 set_bit(MT76_SCANNING, &dev->mt76.state); 529 } 530 EXPORT_SYMBOL_GPL(mt76x02_sw_scan); 531 532 void mt76x02_sw_scan_complete(struct ieee80211_hw *hw, 533 struct ieee80211_vif *vif) 534 { 535 struct mt76x02_dev *dev = hw->priv; 536 537 clear_bit(MT76_SCANNING, &dev->mt76.state); 538 if (mt76_is_mmio(dev)) 539 tasklet_enable(&dev->pre_tbtt_tasklet); 540 541 if (dev->cal.gain_init_done) { 542 /* Restore AGC gain and resume calibration after scanning. */ 543 dev->cal.low_gain = -1; 544 ieee80211_queue_delayed_work(hw, &dev->cal_work, 0); 545 } 546 } 547 EXPORT_SYMBOL_GPL(mt76x02_sw_scan_complete); 548 549 int mt76x02_get_txpower(struct ieee80211_hw *hw, 550 struct ieee80211_vif *vif, int *dbm) 551 { 552 struct mt76x02_dev *dev = hw->priv; 553 u8 nstreams = dev->mt76.chainmask & 0xf; 554 555 *dbm = dev->mt76.txpower_cur / 2; 556 557 /* convert from per-chain power to combined 558 * output on 2x2 devices 559 */ 560 if (nstreams > 1) 561 *dbm += 3; 562 563 return 0; 564 } 565 EXPORT_SYMBOL_GPL(mt76x02_get_txpower); 566 567 void mt76x02_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, 568 bool ps) 569 { 570 struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76); 571 struct mt76x02_sta *msta = (struct mt76x02_sta *)sta->drv_priv; 572 int idx = msta->wcid.idx; 573 574 mt76_stop_tx_queues(&dev->mt76, sta, true); 575 mt76x02_mac_wcid_set_drop(dev, idx, ps); 576 } 577 EXPORT_SYMBOL_GPL(mt76x02_sta_ps); 578 579 const u16 mt76x02_beacon_offsets[16] = { 580 /* 1024 byte per beacon */ 581 0xc000, 582 0xc400, 583 0xc800, 584 0xcc00, 585 0xd000, 586 0xd400, 587 0xd800, 588 0xdc00, 589 /* BSS idx 8-15 not used for beacons */ 590 0xc000, 591 0xc000, 592 0xc000, 593 0xc000, 594 0xc000, 595 0xc000, 596 0xc000, 597 0xc000, 598 }; 599 600 static void mt76x02_set_beacon_offsets(struct mt76x02_dev *dev) 601 { 602 u16 val, base = MT_BEACON_BASE; 603 u32 regs[4] = {}; 604 int i; 605 606 for (i = 0; i < 16; i++) { 607 val = mt76x02_beacon_offsets[i] - base; 608 regs[i / 4] |= (val / 64) << (8 * (i % 4)); 609 } 610 611 for (i = 0; i < 4; i++) 612 mt76_wr(dev, MT_BCN_OFFSET(i), regs[i]); 613 } 614 615 void mt76x02_init_beacon_config(struct mt76x02_dev *dev) 616 { 617 static const u8 null_addr[ETH_ALEN] = {}; 618 int i; 619 620 mt76_wr(dev, MT_MAC_BSSID_DW0, 621 get_unaligned_le32(dev->mt76.macaddr)); 622 mt76_wr(dev, MT_MAC_BSSID_DW1, 623 get_unaligned_le16(dev->mt76.macaddr + 4) | 624 FIELD_PREP(MT_MAC_BSSID_DW1_MBSS_MODE, 3) | /* 8 beacons */ 625 MT_MAC_BSSID_DW1_MBSS_LOCAL_BIT); 626 627 /* Fire a pre-TBTT interrupt 8 ms before TBTT */ 628 mt76_rmw_field(dev, MT_INT_TIMER_CFG, MT_INT_TIMER_CFG_PRE_TBTT, 629 8 << 4); 630 mt76_rmw_field(dev, MT_INT_TIMER_CFG, MT_INT_TIMER_CFG_GP_TIMER, 631 MT_DFS_GP_INTERVAL); 632 mt76_wr(dev, MT_INT_TIMER_EN, 0); 633 634 mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xffff); 635 636 for (i = 0; i < 8; i++) { 637 mt76x02_mac_set_bssid(dev, i, null_addr); 638 mt76x02_mac_set_beacon(dev, i, NULL); 639 } 640 mt76x02_set_beacon_offsets(dev); 641 } 642 EXPORT_SYMBOL_GPL(mt76x02_init_beacon_config); 643 644 void mt76x02_bss_info_changed(struct ieee80211_hw *hw, 645 struct ieee80211_vif *vif, 646 struct ieee80211_bss_conf *info, 647 u32 changed) 648 { 649 struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv; 650 struct mt76x02_dev *dev = hw->priv; 651 652 mutex_lock(&dev->mt76.mutex); 653 654 if (changed & BSS_CHANGED_BSSID) 655 mt76x02_mac_set_bssid(dev, mvif->idx, info->bssid); 656 657 if (changed & BSS_CHANGED_BEACON_ENABLED) { 658 tasklet_disable(&dev->pre_tbtt_tasklet); 659 mt76x02_mac_set_beacon_enable(dev, mvif->idx, 660 info->enable_beacon); 661 tasklet_enable(&dev->pre_tbtt_tasklet); 662 } 663 664 if (changed & BSS_CHANGED_BEACON_INT) { 665 mt76_rmw_field(dev, MT_BEACON_TIME_CFG, 666 MT_BEACON_TIME_CFG_INTVAL, 667 info->beacon_int << 4); 668 dev->beacon_int = info->beacon_int; 669 dev->tbtt_count = 0; 670 } 671 672 if (changed & BSS_CHANGED_ERP_PREAMBLE) 673 mt76x02_mac_set_short_preamble(dev, info->use_short_preamble); 674 675 if (changed & BSS_CHANGED_ERP_SLOT) { 676 int slottime = info->use_short_slot ? 9 : 20; 677 678 dev->slottime = slottime; 679 mt76x02_set_tx_ackto(dev); 680 } 681 682 mutex_unlock(&dev->mt76.mutex); 683 } 684 EXPORT_SYMBOL_GPL(mt76x02_bss_info_changed); 685 686 void mt76x02_config_mac_addr_list(struct mt76x02_dev *dev) 687 { 688 struct ieee80211_hw *hw = mt76_hw(dev); 689 struct wiphy *wiphy = hw->wiphy; 690 int i; 691 692 for (i = 0; i < ARRAY_SIZE(dev->macaddr_list); i++) { 693 u8 *addr = dev->macaddr_list[i].addr; 694 695 memcpy(addr, dev->mt76.macaddr, ETH_ALEN); 696 697 if (!i) 698 continue; 699 700 addr[0] |= BIT(1); 701 addr[0] ^= ((i - 1) << 2); 702 } 703 wiphy->addresses = dev->macaddr_list; 704 wiphy->n_addresses = ARRAY_SIZE(dev->macaddr_list); 705 } 706 EXPORT_SYMBOL_GPL(mt76x02_config_mac_addr_list); 707 708 MODULE_LICENSE("Dual BSD/GPL"); 709