mac80211.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  1. /*
  2. * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include <linux/of.h>
  17. #include "mt76.h"
  18. #define CHAN2G(_idx, _freq) { \
  19. .band = NL80211_BAND_2GHZ, \
  20. .center_freq = (_freq), \
  21. .hw_value = (_idx), \
  22. .max_power = 30, \
  23. }
  24. #define CHAN5G(_idx, _freq) { \
  25. .band = NL80211_BAND_5GHZ, \
  26. .center_freq = (_freq), \
  27. .hw_value = (_idx), \
  28. .max_power = 30, \
  29. }
  30. static const struct ieee80211_channel mt76_channels_2ghz[] = {
  31. CHAN2G(1, 2412),
  32. CHAN2G(2, 2417),
  33. CHAN2G(3, 2422),
  34. CHAN2G(4, 2427),
  35. CHAN2G(5, 2432),
  36. CHAN2G(6, 2437),
  37. CHAN2G(7, 2442),
  38. CHAN2G(8, 2447),
  39. CHAN2G(9, 2452),
  40. CHAN2G(10, 2457),
  41. CHAN2G(11, 2462),
  42. CHAN2G(12, 2467),
  43. CHAN2G(13, 2472),
  44. CHAN2G(14, 2484),
  45. };
  46. static const struct ieee80211_channel mt76_channels_5ghz[] = {
  47. CHAN5G(36, 5180),
  48. CHAN5G(40, 5200),
  49. CHAN5G(44, 5220),
  50. CHAN5G(48, 5240),
  51. CHAN5G(52, 5260),
  52. CHAN5G(56, 5280),
  53. CHAN5G(60, 5300),
  54. CHAN5G(64, 5320),
  55. CHAN5G(100, 5500),
  56. CHAN5G(104, 5520),
  57. CHAN5G(108, 5540),
  58. CHAN5G(112, 5560),
  59. CHAN5G(116, 5580),
  60. CHAN5G(120, 5600),
  61. CHAN5G(124, 5620),
  62. CHAN5G(128, 5640),
  63. CHAN5G(132, 5660),
  64. CHAN5G(136, 5680),
  65. CHAN5G(140, 5700),
  66. CHAN5G(149, 5745),
  67. CHAN5G(153, 5765),
  68. CHAN5G(157, 5785),
  69. CHAN5G(161, 5805),
  70. CHAN5G(165, 5825),
  71. };
  72. static const struct ieee80211_tpt_blink mt76_tpt_blink[] = {
  73. { .throughput = 0 * 1024, .blink_time = 334 },
  74. { .throughput = 1 * 1024, .blink_time = 260 },
  75. { .throughput = 5 * 1024, .blink_time = 220 },
  76. { .throughput = 10 * 1024, .blink_time = 190 },
  77. { .throughput = 20 * 1024, .blink_time = 170 },
  78. { .throughput = 50 * 1024, .blink_time = 150 },
  79. { .throughput = 70 * 1024, .blink_time = 130 },
  80. { .throughput = 100 * 1024, .blink_time = 110 },
  81. { .throughput = 200 * 1024, .blink_time = 80 },
  82. { .throughput = 300 * 1024, .blink_time = 50 },
  83. };
  84. static int mt76_led_init(struct mt76_dev *dev)
  85. {
  86. struct device_node *np = dev->dev->of_node;
  87. struct ieee80211_hw *hw = dev->hw;
  88. int led_pin;
  89. if (!dev->led_cdev.brightness_set && !dev->led_cdev.blink_set)
  90. return 0;
  91. snprintf(dev->led_name, sizeof(dev->led_name),
  92. "mt76-%s", wiphy_name(hw->wiphy));
  93. dev->led_cdev.name = dev->led_name;
  94. dev->led_cdev.default_trigger =
  95. ieee80211_create_tpt_led_trigger(hw,
  96. IEEE80211_TPT_LEDTRIG_FL_RADIO,
  97. mt76_tpt_blink,
  98. ARRAY_SIZE(mt76_tpt_blink));
  99. np = of_get_child_by_name(np, "led");
  100. if (np) {
  101. if (!of_property_read_u32(np, "led-sources", &led_pin))
  102. dev->led_pin = led_pin;
  103. dev->led_al = of_property_read_bool(np, "led-active-low");
  104. }
  105. return devm_led_classdev_register(dev->dev, &dev->led_cdev);
  106. }
  107. static void mt76_init_stream_cap(struct mt76_dev *dev,
  108. struct ieee80211_supported_band *sband,
  109. bool vht)
  110. {
  111. struct ieee80211_sta_ht_cap *ht_cap = &sband->ht_cap;
  112. int i, nstream = __sw_hweight8(dev->antenna_mask);
  113. struct ieee80211_sta_vht_cap *vht_cap;
  114. u16 mcs_map = 0;
  115. if (nstream > 1)
  116. ht_cap->cap |= IEEE80211_HT_CAP_TX_STBC;
  117. else
  118. ht_cap->cap &= ~IEEE80211_HT_CAP_TX_STBC;
  119. for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
  120. ht_cap->mcs.rx_mask[i] = i < nstream ? 0xff : 0;
  121. if (!vht)
  122. return;
  123. vht_cap = &sband->vht_cap;
  124. if (nstream > 1)
  125. vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC;
  126. else
  127. vht_cap->cap &= ~IEEE80211_VHT_CAP_TXSTBC;
  128. for (i = 0; i < 8; i++) {
  129. if (i < nstream)
  130. mcs_map |= (IEEE80211_VHT_MCS_SUPPORT_0_9 << (i * 2));
  131. else
  132. mcs_map |=
  133. (IEEE80211_VHT_MCS_NOT_SUPPORTED << (i * 2));
  134. }
  135. vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map);
  136. vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map);
  137. }
  138. void mt76_set_stream_caps(struct mt76_dev *dev, bool vht)
  139. {
  140. if (dev->cap.has_2ghz)
  141. mt76_init_stream_cap(dev, &dev->sband_2g.sband, false);
  142. if (dev->cap.has_5ghz)
  143. mt76_init_stream_cap(dev, &dev->sband_5g.sband, vht);
  144. }
  145. EXPORT_SYMBOL_GPL(mt76_set_stream_caps);
  146. static int
  147. mt76_init_sband(struct mt76_dev *dev, struct mt76_sband *msband,
  148. const struct ieee80211_channel *chan, int n_chan,
  149. struct ieee80211_rate *rates, int n_rates, bool vht)
  150. {
  151. struct ieee80211_supported_band *sband = &msband->sband;
  152. struct ieee80211_sta_ht_cap *ht_cap;
  153. struct ieee80211_sta_vht_cap *vht_cap;
  154. void *chanlist;
  155. int size;
  156. size = n_chan * sizeof(*chan);
  157. chanlist = devm_kmemdup(dev->dev, chan, size, GFP_KERNEL);
  158. if (!chanlist)
  159. return -ENOMEM;
  160. msband->chan = devm_kzalloc(dev->dev, n_chan * sizeof(*msband->chan),
  161. GFP_KERNEL);
  162. if (!msband->chan)
  163. return -ENOMEM;
  164. sband->channels = chanlist;
  165. sband->n_channels = n_chan;
  166. sband->bitrates = rates;
  167. sband->n_bitrates = n_rates;
  168. dev->chandef.chan = &sband->channels[0];
  169. ht_cap = &sband->ht_cap;
  170. ht_cap->ht_supported = true;
  171. ht_cap->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
  172. IEEE80211_HT_CAP_GRN_FLD |
  173. IEEE80211_HT_CAP_SGI_20 |
  174. IEEE80211_HT_CAP_SGI_40 |
  175. (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
  176. ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
  177. ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
  178. ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_4;
  179. mt76_init_stream_cap(dev, sband, vht);
  180. if (!vht)
  181. return 0;
  182. vht_cap = &sband->vht_cap;
  183. vht_cap->vht_supported = true;
  184. vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC |
  185. IEEE80211_VHT_CAP_RXSTBC_1 |
  186. IEEE80211_VHT_CAP_SHORT_GI_80;
  187. return 0;
  188. }
  189. static int
  190. mt76_init_sband_2g(struct mt76_dev *dev, struct ieee80211_rate *rates,
  191. int n_rates)
  192. {
  193. dev->hw->wiphy->bands[NL80211_BAND_2GHZ] = &dev->sband_2g.sband;
  194. return mt76_init_sband(dev, &dev->sband_2g,
  195. mt76_channels_2ghz,
  196. ARRAY_SIZE(mt76_channels_2ghz),
  197. rates, n_rates, false);
  198. }
  199. static int
  200. mt76_init_sband_5g(struct mt76_dev *dev, struct ieee80211_rate *rates,
  201. int n_rates, bool vht)
  202. {
  203. dev->hw->wiphy->bands[NL80211_BAND_5GHZ] = &dev->sband_5g.sband;
  204. return mt76_init_sband(dev, &dev->sband_5g,
  205. mt76_channels_5ghz,
  206. ARRAY_SIZE(mt76_channels_5ghz),
  207. rates, n_rates, vht);
  208. }
  209. static void
  210. mt76_check_sband(struct mt76_dev *dev, int band)
  211. {
  212. struct ieee80211_supported_band *sband = dev->hw->wiphy->bands[band];
  213. bool found = false;
  214. int i;
  215. if (!sband)
  216. return;
  217. for (i = 0; i < sband->n_channels; i++) {
  218. if (sband->channels[i].flags & IEEE80211_CHAN_DISABLED)
  219. continue;
  220. found = true;
  221. break;
  222. }
  223. if (found)
  224. return;
  225. sband->n_channels = 0;
  226. dev->hw->wiphy->bands[band] = NULL;
  227. }
  228. int mt76_register_device(struct mt76_dev *dev, bool vht,
  229. struct ieee80211_rate *rates, int n_rates)
  230. {
  231. struct ieee80211_hw *hw = dev->hw;
  232. struct wiphy *wiphy = hw->wiphy;
  233. int ret;
  234. dev_set_drvdata(dev->dev, dev);
  235. spin_lock_init(&dev->lock);
  236. spin_lock_init(&dev->cc_lock);
  237. INIT_LIST_HEAD(&dev->txwi_cache);
  238. SET_IEEE80211_DEV(hw, dev->dev);
  239. SET_IEEE80211_PERM_ADDR(hw, dev->macaddr);
  240. wiphy->interface_modes =
  241. BIT(NL80211_IFTYPE_STATION) |
  242. BIT(NL80211_IFTYPE_AP) |
  243. #ifdef CONFIG_MAC80211_MESH
  244. BIT(NL80211_IFTYPE_MESH_POINT) |
  245. #endif
  246. BIT(NL80211_IFTYPE_ADHOC);
  247. wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;
  248. wiphy->available_antennas_tx = dev->antenna_mask;
  249. wiphy->available_antennas_rx = dev->antenna_mask;
  250. hw->txq_data_size = sizeof(struct mt76_txq);
  251. hw->max_tx_fragments = 16;
  252. ieee80211_hw_set(hw, SIGNAL_DBM);
  253. ieee80211_hw_set(hw, PS_NULLFUNC_STACK);
  254. ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING);
  255. ieee80211_hw_set(hw, AMPDU_AGGREGATION);
  256. ieee80211_hw_set(hw, SUPPORTS_RC_TABLE);
  257. ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
  258. ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS);
  259. ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
  260. ieee80211_hw_set(hw, TX_AMSDU);
  261. ieee80211_hw_set(hw, TX_FRAG_LIST);
  262. ieee80211_hw_set(hw, MFP_CAPABLE);
  263. ieee80211_hw_set(hw, AP_LINK_PS);
  264. wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
  265. if (dev->cap.has_2ghz) {
  266. ret = mt76_init_sband_2g(dev, rates, n_rates);
  267. if (ret)
  268. return ret;
  269. }
  270. if (dev->cap.has_5ghz) {
  271. ret = mt76_init_sband_5g(dev, rates + 4, n_rates - 4, vht);
  272. if (ret)
  273. return ret;
  274. }
  275. wiphy_read_of_freq_limits(dev->hw->wiphy);
  276. mt76_check_sband(dev, NL80211_BAND_2GHZ);
  277. mt76_check_sband(dev, NL80211_BAND_5GHZ);
  278. ret = mt76_led_init(dev);
  279. if (ret)
  280. return ret;
  281. return ieee80211_register_hw(hw);
  282. }
  283. EXPORT_SYMBOL_GPL(mt76_register_device);
  284. void mt76_unregister_device(struct mt76_dev *dev)
  285. {
  286. struct ieee80211_hw *hw = dev->hw;
  287. ieee80211_unregister_hw(hw);
  288. mt76_tx_free(dev);
  289. }
  290. EXPORT_SYMBOL_GPL(mt76_unregister_device);
  291. void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb)
  292. {
  293. if (!test_bit(MT76_STATE_RUNNING, &dev->state)) {
  294. dev_kfree_skb(skb);
  295. return;
  296. }
  297. __skb_queue_tail(&dev->rx_skb[q], skb);
  298. }
  299. EXPORT_SYMBOL_GPL(mt76_rx);
  300. void mt76_set_channel(struct mt76_dev *dev)
  301. {
  302. struct ieee80211_hw *hw = dev->hw;
  303. struct cfg80211_chan_def *chandef = &hw->conf.chandef;
  304. struct mt76_channel_state *state;
  305. bool offchannel = hw->conf.flags & IEEE80211_CONF_OFFCHANNEL;
  306. if (dev->drv->update_survey)
  307. dev->drv->update_survey(dev);
  308. dev->chandef = *chandef;
  309. if (!offchannel)
  310. dev->main_chan = chandef->chan;
  311. if (chandef->chan != dev->main_chan) {
  312. state = mt76_channel_state(dev, chandef->chan);
  313. memset(state, 0, sizeof(*state));
  314. }
  315. }
  316. EXPORT_SYMBOL_GPL(mt76_set_channel);
  317. int mt76_get_survey(struct ieee80211_hw *hw, int idx,
  318. struct survey_info *survey)
  319. {
  320. struct mt76_dev *dev = hw->priv;
  321. struct mt76_sband *sband;
  322. struct ieee80211_channel *chan;
  323. struct mt76_channel_state *state;
  324. int ret = 0;
  325. if (idx == 0 && dev->drv->update_survey)
  326. dev->drv->update_survey(dev);
  327. sband = &dev->sband_2g;
  328. if (idx >= sband->sband.n_channels) {
  329. idx -= sband->sband.n_channels;
  330. sband = &dev->sband_5g;
  331. }
  332. if (idx >= sband->sband.n_channels)
  333. return -ENOENT;
  334. chan = &sband->sband.channels[idx];
  335. state = mt76_channel_state(dev, chan);
  336. memset(survey, 0, sizeof(*survey));
  337. survey->channel = chan;
  338. survey->filled = SURVEY_INFO_TIME | SURVEY_INFO_TIME_BUSY;
  339. if (chan == dev->main_chan)
  340. survey->filled |= SURVEY_INFO_IN_USE;
  341. spin_lock_bh(&dev->cc_lock);
  342. survey->time = div_u64(state->cc_active, 1000);
  343. survey->time_busy = div_u64(state->cc_busy, 1000);
  344. spin_unlock_bh(&dev->cc_lock);
  345. return ret;
  346. }
  347. EXPORT_SYMBOL_GPL(mt76_get_survey);
  348. void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid,
  349. struct ieee80211_key_conf *key)
  350. {
  351. struct ieee80211_key_seq seq;
  352. int i;
  353. wcid->rx_check_pn = false;
  354. if (!key)
  355. return;
  356. if (key->cipher == WLAN_CIPHER_SUITE_CCMP)
  357. wcid->rx_check_pn = true;
  358. for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
  359. ieee80211_get_key_rx_seq(key, i, &seq);
  360. memcpy(wcid->rx_key_pn[i], seq.ccmp.pn, sizeof(seq.ccmp.pn));
  361. }
  362. }
  363. EXPORT_SYMBOL(mt76_wcid_key_setup);
  364. static struct ieee80211_sta *mt76_rx_convert(struct sk_buff *skb)
  365. {
  366. struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
  367. struct mt76_rx_status mstat;
  368. mstat = *((struct mt76_rx_status *) skb->cb);
  369. memset(status, 0, sizeof(*status));
  370. status->flag = mstat.flag;
  371. status->freq = mstat.freq;
  372. status->enc_flags = mstat.enc_flags;
  373. status->encoding = mstat.encoding;
  374. status->bw = mstat.bw;
  375. status->rate_idx = mstat.rate_idx;
  376. status->nss = mstat.nss;
  377. status->band = mstat.band;
  378. status->signal = mstat.signal;
  379. status->chains = mstat.chains;
  380. BUILD_BUG_ON(sizeof(mstat) > sizeof(skb->cb));
  381. BUILD_BUG_ON(sizeof(status->chain_signal) != sizeof(mstat.chain_signal));
  382. memcpy(status->chain_signal, mstat.chain_signal, sizeof(mstat.chain_signal));
  383. return wcid_to_sta(mstat.wcid);
  384. }
  385. static int
  386. mt76_check_ccmp_pn(struct sk_buff *skb)
  387. {
  388. struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
  389. struct mt76_wcid *wcid = status->wcid;
  390. struct ieee80211_hdr *hdr;
  391. int ret;
  392. if (!(status->flag & RX_FLAG_DECRYPTED))
  393. return 0;
  394. if (!wcid || !wcid->rx_check_pn)
  395. return 0;
  396. if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
  397. /*
  398. * Validate the first fragment both here and in mac80211
  399. * All further fragments will be validated by mac80211 only.
  400. */
  401. hdr = (struct ieee80211_hdr *) skb->data;
  402. if (ieee80211_is_frag(hdr) &&
  403. !ieee80211_is_first_frag(hdr->frame_control))
  404. return 0;
  405. }
  406. BUILD_BUG_ON(sizeof(status->iv) != sizeof(wcid->rx_key_pn[0]));
  407. ret = memcmp(status->iv, wcid->rx_key_pn[status->tid],
  408. sizeof(status->iv));
  409. if (ret <= 0)
  410. return -EINVAL; /* replay */
  411. memcpy(wcid->rx_key_pn[status->tid], status->iv, sizeof(status->iv));
  412. if (status->flag & RX_FLAG_IV_STRIPPED)
  413. status->flag |= RX_FLAG_PN_VALIDATED;
  414. return 0;
  415. }
  416. static void
  417. mt76_check_ps(struct mt76_dev *dev, struct sk_buff *skb)
  418. {
  419. struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
  420. struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
  421. struct ieee80211_sta *sta;
  422. struct mt76_wcid *wcid = status->wcid;
  423. bool ps;
  424. if (!wcid || !wcid->sta)
  425. return;
  426. sta = container_of((void *) wcid, struct ieee80211_sta, drv_priv);
  427. if (!test_bit(MT_WCID_FLAG_CHECK_PS, &wcid->flags))
  428. return;
  429. if (ieee80211_is_pspoll(hdr->frame_control)) {
  430. ieee80211_sta_pspoll(sta);
  431. return;
  432. }
  433. if (ieee80211_has_morefrags(hdr->frame_control) ||
  434. !(ieee80211_is_mgmt(hdr->frame_control) ||
  435. ieee80211_is_data(hdr->frame_control)))
  436. return;
  437. ps = ieee80211_has_pm(hdr->frame_control);
  438. if (ps && (ieee80211_is_data_qos(hdr->frame_control) ||
  439. ieee80211_is_qos_nullfunc(hdr->frame_control)))
  440. ieee80211_sta_uapsd_trigger(sta, status->tid);
  441. if (!!test_bit(MT_WCID_FLAG_PS, &wcid->flags) == ps)
  442. return;
  443. if (ps) {
  444. set_bit(MT_WCID_FLAG_PS, &wcid->flags);
  445. mt76_stop_tx_queues(dev, sta, true);
  446. } else {
  447. clear_bit(MT_WCID_FLAG_PS, &wcid->flags);
  448. }
  449. ieee80211_sta_ps_transition(sta, ps);
  450. dev->drv->sta_ps(dev, sta, ps);
  451. }
  452. void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
  453. int queue)
  454. {
  455. struct napi_struct *napi = NULL;
  456. struct ieee80211_sta *sta;
  457. struct sk_buff *skb;
  458. if (queue >= 0)
  459. napi = &dev->napi[queue];
  460. while ((skb = __skb_dequeue(frames)) != NULL) {
  461. if (mt76_check_ccmp_pn(skb)) {
  462. dev_kfree_skb(skb);
  463. continue;
  464. }
  465. sta = mt76_rx_convert(skb);
  466. ieee80211_rx_napi(dev->hw, sta, skb, napi);
  467. }
  468. }
  469. void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q)
  470. {
  471. struct sk_buff_head frames;
  472. struct sk_buff *skb;
  473. __skb_queue_head_init(&frames);
  474. while ((skb = __skb_dequeue(&dev->rx_skb[q])) != NULL) {
  475. mt76_check_ps(dev, skb);
  476. mt76_rx_aggr_reorder(skb, &frames);
  477. }
  478. mt76_rx_complete(dev, &frames, q);
  479. }