mt76_connac_mcu.c 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850
  1. // SPDX-License-Identifier: ISC
  2. /* Copyright (C) 2020 MediaTek Inc. */
  3. #include "mt76_connac_mcu.h"
  4. int mt76_connac_mcu_start_firmware(struct mt76_dev *dev, u32 addr, u32 option)
  5. {
  6. struct {
  7. __le32 option;
  8. __le32 addr;
  9. } req = {
  10. .option = cpu_to_le32(option),
  11. .addr = cpu_to_le32(addr),
  12. };
  13. return mt76_mcu_send_msg(dev, MCU_CMD_FW_START_REQ, &req, sizeof(req),
  14. true);
  15. }
  16. EXPORT_SYMBOL_GPL(mt76_connac_mcu_start_firmware);
  17. int mt76_connac_mcu_patch_sem_ctrl(struct mt76_dev *dev, bool get)
  18. {
  19. u32 op = get ? PATCH_SEM_GET : PATCH_SEM_RELEASE;
  20. struct {
  21. __le32 op;
  22. } req = {
  23. .op = cpu_to_le32(op),
  24. };
  25. return mt76_mcu_send_msg(dev, MCU_CMD_PATCH_SEM_CONTROL, &req,
  26. sizeof(req), true);
  27. }
  28. EXPORT_SYMBOL_GPL(mt76_connac_mcu_patch_sem_ctrl);
  29. int mt76_connac_mcu_start_patch(struct mt76_dev *dev)
  30. {
  31. struct {
  32. u8 check_crc;
  33. u8 reserved[3];
  34. } req = {
  35. .check_crc = 0,
  36. };
  37. return mt76_mcu_send_msg(dev, MCU_CMD_PATCH_FINISH_REQ, &req,
  38. sizeof(req), true);
  39. }
  40. EXPORT_SYMBOL_GPL(mt76_connac_mcu_start_patch);
  41. #define MCU_PATCH_ADDRESS 0x200000
  42. int mt76_connac_mcu_init_download(struct mt76_dev *dev, u32 addr, u32 len,
  43. u32 mode)
  44. {
  45. struct {
  46. __le32 addr;
  47. __le32 len;
  48. __le32 mode;
  49. } req = {
  50. .addr = cpu_to_le32(addr),
  51. .len = cpu_to_le32(len),
  52. .mode = cpu_to_le32(mode),
  53. };
  54. int cmd;
  55. if (is_mt7921(dev) &&
  56. (req.addr == cpu_to_le32(MCU_PATCH_ADDRESS) || addr == 0x900000))
  57. cmd = MCU_CMD_PATCH_START_REQ;
  58. else
  59. cmd = MCU_CMD_TARGET_ADDRESS_LEN_REQ;
  60. return mt76_mcu_send_msg(dev, cmd, &req, sizeof(req), true);
  61. }
  62. EXPORT_SYMBOL_GPL(mt76_connac_mcu_init_download);
  63. int mt76_connac_mcu_set_channel_domain(struct mt76_phy *phy)
  64. {
  65. struct mt76_dev *dev = phy->dev;
  66. struct mt76_connac_mcu_channel_domain {
  67. u8 alpha2[4]; /* regulatory_request.alpha2 */
  68. u8 bw_2g; /* BW_20_40M 0
  69. * BW_20M 1
  70. * BW_20_40_80M 2
  71. * BW_20_40_80_160M 3
  72. * BW_20_40_80_8080M 4
  73. */
  74. u8 bw_5g;
  75. __le16 pad;
  76. u8 n_2ch;
  77. u8 n_5ch;
  78. __le16 pad2;
  79. } __packed hdr = {
  80. .bw_2g = 0,
  81. .bw_5g = 3,
  82. };
  83. struct mt76_connac_mcu_chan {
  84. __le16 hw_value;
  85. __le16 pad;
  86. __le32 flags;
  87. } __packed channel;
  88. int len, i, n_max_channels, n_2ch = 0, n_5ch = 0;
  89. struct ieee80211_channel *chan;
  90. struct sk_buff *skb;
  91. n_max_channels = phy->sband_2g.sband.n_channels +
  92. phy->sband_5g.sband.n_channels;
  93. len = sizeof(hdr) + n_max_channels * sizeof(channel);
  94. skb = mt76_mcu_msg_alloc(dev, NULL, len);
  95. if (!skb)
  96. return -ENOMEM;
  97. skb_reserve(skb, sizeof(hdr));
  98. for (i = 0; i < phy->sband_2g.sband.n_channels; i++) {
  99. chan = &phy->sband_2g.sband.channels[i];
  100. if (chan->flags & IEEE80211_CHAN_DISABLED)
  101. continue;
  102. channel.hw_value = cpu_to_le16(chan->hw_value);
  103. channel.flags = cpu_to_le32(chan->flags);
  104. channel.pad = 0;
  105. skb_put_data(skb, &channel, sizeof(channel));
  106. n_2ch++;
  107. }
  108. for (i = 0; i < phy->sband_5g.sband.n_channels; i++) {
  109. chan = &phy->sband_5g.sband.channels[i];
  110. if (chan->flags & IEEE80211_CHAN_DISABLED)
  111. continue;
  112. channel.hw_value = cpu_to_le16(chan->hw_value);
  113. channel.flags = cpu_to_le32(chan->flags);
  114. channel.pad = 0;
  115. skb_put_data(skb, &channel, sizeof(channel));
  116. n_5ch++;
  117. }
  118. BUILD_BUG_ON(sizeof(dev->alpha2) > sizeof(hdr.alpha2));
  119. memcpy(hdr.alpha2, dev->alpha2, sizeof(dev->alpha2));
  120. hdr.n_2ch = n_2ch;
  121. hdr.n_5ch = n_5ch;
  122. memcpy(__skb_push(skb, sizeof(hdr)), &hdr, sizeof(hdr));
  123. return mt76_mcu_skb_send_msg(dev, skb, MCU_CMD_SET_CHAN_DOMAIN, false);
  124. }
  125. EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_channel_domain);
  126. int mt76_connac_mcu_set_mac_enable(struct mt76_dev *dev, int band, bool enable,
  127. bool hdr_trans)
  128. {
  129. struct {
  130. u8 enable;
  131. u8 band;
  132. u8 rsv[2];
  133. } __packed req_mac = {
  134. .enable = enable,
  135. .band = band,
  136. };
  137. return mt76_mcu_send_msg(dev, MCU_EXT_CMD_MAC_INIT_CTRL, &req_mac,
  138. sizeof(req_mac), true);
  139. }
  140. EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_mac_enable);
  141. int mt76_connac_mcu_set_vif_ps(struct mt76_dev *dev, struct ieee80211_vif *vif)
  142. {
  143. struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
  144. struct {
  145. u8 bss_idx;
  146. u8 ps_state; /* 0: device awake
  147. * 1: static power save
  148. * 2: dynamic power saving
  149. */
  150. } req = {
  151. .bss_idx = mvif->idx,
  152. .ps_state = vif->bss_conf.ps ? 2 : 0,
  153. };
  154. if (vif->type != NL80211_IFTYPE_STATION)
  155. return -EOPNOTSUPP;
  156. return mt76_mcu_send_msg(dev, MCU_CMD_SET_PS_PROFILE, &req,
  157. sizeof(req), false);
  158. }
  159. EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_vif_ps);
  160. int mt76_connac_mcu_set_rts_thresh(struct mt76_dev *dev, u32 val, u8 band)
  161. {
  162. struct {
  163. u8 prot_idx;
  164. u8 band;
  165. u8 rsv[2];
  166. __le32 len_thresh;
  167. __le32 pkt_thresh;
  168. } __packed req = {
  169. .prot_idx = 1,
  170. .band = band,
  171. .len_thresh = cpu_to_le32(val),
  172. .pkt_thresh = cpu_to_le32(0x2),
  173. };
  174. return mt76_mcu_send_msg(dev, MCU_EXT_CMD_PROTECT_CTRL, &req,
  175. sizeof(req), true);
  176. }
  177. EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_rts_thresh);
  178. void mt76_connac_mcu_beacon_loss_iter(void *priv, u8 *mac,
  179. struct ieee80211_vif *vif)
  180. {
  181. struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
  182. struct mt76_connac_beacon_loss_event *event = priv;
  183. if (mvif->idx != event->bss_idx)
  184. return;
  185. if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER))
  186. return;
  187. ieee80211_beacon_loss(vif);
  188. }
  189. EXPORT_SYMBOL_GPL(mt76_connac_mcu_beacon_loss_iter);
  190. struct tlv *
  191. mt76_connac_mcu_add_nested_tlv(struct sk_buff *skb, int tag, int len,
  192. void *sta_ntlv, void *sta_wtbl)
  193. {
  194. struct sta_ntlv_hdr *ntlv_hdr = sta_ntlv;
  195. struct tlv *sta_hdr = sta_wtbl;
  196. struct tlv *ptlv, tlv = {
  197. .tag = cpu_to_le16(tag),
  198. .len = cpu_to_le16(len),
  199. };
  200. u16 ntlv;
  201. ptlv = skb_put(skb, len);
  202. memcpy(ptlv, &tlv, sizeof(tlv));
  203. ntlv = le16_to_cpu(ntlv_hdr->tlv_num);
  204. ntlv_hdr->tlv_num = cpu_to_le16(ntlv + 1);
  205. if (sta_hdr) {
  206. u16 size = le16_to_cpu(sta_hdr->len);
  207. sta_hdr->len = cpu_to_le16(size + len);
  208. }
  209. return ptlv;
  210. }
  211. EXPORT_SYMBOL_GPL(mt76_connac_mcu_add_nested_tlv);
  212. struct sk_buff *
  213. mt76_connac_mcu_alloc_sta_req(struct mt76_dev *dev, struct mt76_vif *mvif,
  214. struct mt76_wcid *wcid)
  215. {
  216. struct sta_req_hdr hdr = {
  217. .bss_idx = mvif->idx,
  218. .muar_idx = wcid ? mvif->omac_idx : 0,
  219. .is_tlv_append = 1,
  220. };
  221. struct sk_buff *skb;
  222. mt76_connac_mcu_get_wlan_idx(dev, wcid, &hdr.wlan_idx_lo,
  223. &hdr.wlan_idx_hi);
  224. skb = mt76_mcu_msg_alloc(dev, NULL, MT76_CONNAC_STA_UPDATE_MAX_SIZE);
  225. if (!skb)
  226. return ERR_PTR(-ENOMEM);
  227. skb_put_data(skb, &hdr, sizeof(hdr));
  228. return skb;
  229. }
  230. EXPORT_SYMBOL_GPL(mt76_connac_mcu_alloc_sta_req);
  231. struct wtbl_req_hdr *
  232. mt76_connac_mcu_alloc_wtbl_req(struct mt76_dev *dev, struct mt76_wcid *wcid,
  233. int cmd, void *sta_wtbl, struct sk_buff **skb)
  234. {
  235. struct tlv *sta_hdr = sta_wtbl;
  236. struct wtbl_req_hdr hdr = {
  237. .operation = cmd,
  238. };
  239. struct sk_buff *nskb = *skb;
  240. mt76_connac_mcu_get_wlan_idx(dev, wcid, &hdr.wlan_idx_lo,
  241. &hdr.wlan_idx_hi);
  242. if (!nskb) {
  243. nskb = mt76_mcu_msg_alloc(dev, NULL,
  244. MT76_CONNAC_WTBL_UPDATE_MAX_SIZE);
  245. if (!nskb)
  246. return ERR_PTR(-ENOMEM);
  247. *skb = nskb;
  248. }
  249. if (sta_hdr)
  250. sta_hdr->len = cpu_to_le16(sizeof(hdr));
  251. return skb_put_data(nskb, &hdr, sizeof(hdr));
  252. }
  253. EXPORT_SYMBOL_GPL(mt76_connac_mcu_alloc_wtbl_req);
  254. void mt76_connac_mcu_sta_basic_tlv(struct sk_buff *skb,
  255. struct ieee80211_vif *vif,
  256. struct ieee80211_sta *sta,
  257. bool enable)
  258. {
  259. struct sta_rec_basic *basic;
  260. struct tlv *tlv;
  261. int conn_type;
  262. tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BASIC, sizeof(*basic));
  263. basic = (struct sta_rec_basic *)tlv;
  264. basic->extra_info = cpu_to_le16(EXTRA_INFO_VER);
  265. if (enable) {
  266. basic->extra_info |= cpu_to_le16(EXTRA_INFO_NEW);
  267. basic->conn_state = CONN_STATE_PORT_SECURE;
  268. } else {
  269. basic->conn_state = CONN_STATE_DISCONNECT;
  270. }
  271. if (!sta) {
  272. basic->conn_type = cpu_to_le32(CONNECTION_INFRA_BC);
  273. eth_broadcast_addr(basic->peer_addr);
  274. return;
  275. }
  276. switch (vif->type) {
  277. case NL80211_IFTYPE_MESH_POINT:
  278. case NL80211_IFTYPE_AP:
  279. if (vif->p2p)
  280. conn_type = CONNECTION_P2P_GC;
  281. else
  282. conn_type = CONNECTION_INFRA_STA;
  283. basic->conn_type = cpu_to_le32(conn_type);
  284. basic->aid = cpu_to_le16(sta->aid);
  285. break;
  286. case NL80211_IFTYPE_STATION:
  287. if (vif->p2p)
  288. conn_type = CONNECTION_P2P_GO;
  289. else
  290. conn_type = CONNECTION_INFRA_AP;
  291. basic->conn_type = cpu_to_le32(conn_type);
  292. basic->aid = cpu_to_le16(vif->bss_conf.aid);
  293. break;
  294. case NL80211_IFTYPE_ADHOC:
  295. basic->conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC);
  296. basic->aid = cpu_to_le16(sta->aid);
  297. break;
  298. default:
  299. WARN_ON(1);
  300. break;
  301. }
  302. memcpy(basic->peer_addr, sta->addr, ETH_ALEN);
  303. basic->qos = sta->wme;
  304. }
  305. EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_basic_tlv);
  306. static void
  307. mt76_connac_mcu_sta_uapsd(struct sk_buff *skb, struct ieee80211_vif *vif,
  308. struct ieee80211_sta *sta)
  309. {
  310. struct sta_rec_uapsd *uapsd;
  311. struct tlv *tlv;
  312. if (vif->type != NL80211_IFTYPE_AP || !sta->wme)
  313. return;
  314. tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_APPS, sizeof(*uapsd));
  315. uapsd = (struct sta_rec_uapsd *)tlv;
  316. if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) {
  317. uapsd->dac_map |= BIT(3);
  318. uapsd->tac_map |= BIT(3);
  319. }
  320. if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI) {
  321. uapsd->dac_map |= BIT(2);
  322. uapsd->tac_map |= BIT(2);
  323. }
  324. if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE) {
  325. uapsd->dac_map |= BIT(1);
  326. uapsd->tac_map |= BIT(1);
  327. }
  328. if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK) {
  329. uapsd->dac_map |= BIT(0);
  330. uapsd->tac_map |= BIT(0);
  331. }
  332. uapsd->max_sp = sta->max_sp;
  333. }
  334. void mt76_connac_mcu_wtbl_generic_tlv(struct mt76_dev *dev,
  335. struct sk_buff *skb,
  336. struct ieee80211_vif *vif,
  337. struct ieee80211_sta *sta,
  338. void *sta_wtbl, void *wtbl_tlv)
  339. {
  340. struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
  341. struct wtbl_generic *generic;
  342. struct wtbl_rx *rx;
  343. struct wtbl_spe *spe;
  344. struct tlv *tlv;
  345. tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_GENERIC,
  346. sizeof(*generic),
  347. wtbl_tlv, sta_wtbl);
  348. generic = (struct wtbl_generic *)tlv;
  349. if (sta) {
  350. if (vif->type == NL80211_IFTYPE_STATION)
  351. generic->partial_aid = cpu_to_le16(vif->bss_conf.aid);
  352. else
  353. generic->partial_aid = cpu_to_le16(sta->aid);
  354. memcpy(generic->peer_addr, sta->addr, ETH_ALEN);
  355. generic->muar_idx = mvif->omac_idx;
  356. generic->qos = sta->wme;
  357. } else {
  358. if (is_mt7921(dev) &&
  359. vif->type == NL80211_IFTYPE_STATION)
  360. memcpy(generic->peer_addr, vif->bss_conf.bssid,
  361. ETH_ALEN);
  362. else
  363. eth_broadcast_addr(generic->peer_addr);
  364. generic->muar_idx = 0xe;
  365. }
  366. tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_RX, sizeof(*rx),
  367. wtbl_tlv, sta_wtbl);
  368. rx = (struct wtbl_rx *)tlv;
  369. rx->rca1 = sta ? vif->type != NL80211_IFTYPE_AP : 1;
  370. rx->rca2 = 1;
  371. rx->rv = 1;
  372. if (is_mt7921(dev))
  373. return;
  374. tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_SPE, sizeof(*spe),
  375. wtbl_tlv, sta_wtbl);
  376. spe = (struct wtbl_spe *)tlv;
  377. spe->spe_idx = 24;
  378. }
  379. EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_generic_tlv);
  380. static void
  381. mt76_connac_mcu_sta_amsdu_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
  382. struct ieee80211_vif *vif)
  383. {
  384. struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
  385. struct sta_rec_amsdu *amsdu;
  386. struct tlv *tlv;
  387. if (vif->type != NL80211_IFTYPE_AP &&
  388. vif->type != NL80211_IFTYPE_STATION)
  389. return;
  390. if (!sta->max_amsdu_len)
  391. return;
  392. tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HW_AMSDU, sizeof(*amsdu));
  393. amsdu = (struct sta_rec_amsdu *)tlv;
  394. amsdu->max_amsdu_num = 8;
  395. amsdu->amsdu_en = true;
  396. amsdu->max_mpdu_size = sta->max_amsdu_len >=
  397. IEEE80211_MAX_MPDU_LEN_VHT_7991;
  398. wcid->amsdu = true;
  399. }
  400. #define HE_PHY(p, c) u8_get_bits(c, IEEE80211_HE_PHY_##p)
  401. #define HE_MAC(m, c) u8_get_bits(c, IEEE80211_HE_MAC_##m)
  402. static void
  403. mt76_connac_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
  404. {
  405. struct ieee80211_sta_he_cap *he_cap = &sta->he_cap;
  406. struct ieee80211_he_cap_elem *elem = &he_cap->he_cap_elem;
  407. struct sta_rec_he *he;
  408. struct tlv *tlv;
  409. u32 cap = 0;
  410. tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE, sizeof(*he));
  411. he = (struct sta_rec_he *)tlv;
  412. if (elem->mac_cap_info[0] & IEEE80211_HE_MAC_CAP0_HTC_HE)
  413. cap |= STA_REC_HE_CAP_HTC;
  414. if (elem->mac_cap_info[2] & IEEE80211_HE_MAC_CAP2_BSR)
  415. cap |= STA_REC_HE_CAP_BSR;
  416. if (elem->mac_cap_info[3] & IEEE80211_HE_MAC_CAP3_OMI_CONTROL)
  417. cap |= STA_REC_HE_CAP_OM;
  418. if (elem->mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU)
  419. cap |= STA_REC_HE_CAP_AMSDU_IN_AMPDU;
  420. if (elem->mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_BQR)
  421. cap |= STA_REC_HE_CAP_BQR;
  422. if (elem->phy_cap_info[0] &
  423. (IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_2G |
  424. IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_5G))
  425. cap |= STA_REC_HE_CAP_BW20_RU242_SUPPORT;
  426. if (elem->phy_cap_info[1] &
  427. IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)
  428. cap |= STA_REC_HE_CAP_LDPC;
  429. if (elem->phy_cap_info[1] &
  430. IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US)
  431. cap |= STA_REC_HE_CAP_SU_PPDU_1LTF_8US_GI;
  432. if (elem->phy_cap_info[2] &
  433. IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US)
  434. cap |= STA_REC_HE_CAP_NDP_4LTF_3DOT2MS_GI;
  435. if (elem->phy_cap_info[2] &
  436. IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ)
  437. cap |= STA_REC_HE_CAP_LE_EQ_80M_TX_STBC;
  438. if (elem->phy_cap_info[2] &
  439. IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ)
  440. cap |= STA_REC_HE_CAP_LE_EQ_80M_RX_STBC;
  441. if (elem->phy_cap_info[6] &
  442. IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE)
  443. cap |= STA_REC_HE_CAP_PARTIAL_BW_EXT_RANGE;
  444. if (elem->phy_cap_info[7] &
  445. IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI)
  446. cap |= STA_REC_HE_CAP_SU_MU_PPDU_4LTF_8US_GI;
  447. if (elem->phy_cap_info[7] &
  448. IEEE80211_HE_PHY_CAP7_STBC_TX_ABOVE_80MHZ)
  449. cap |= STA_REC_HE_CAP_GT_80M_TX_STBC;
  450. if (elem->phy_cap_info[7] &
  451. IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ)
  452. cap |= STA_REC_HE_CAP_GT_80M_RX_STBC;
  453. if (elem->phy_cap_info[8] &
  454. IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI)
  455. cap |= STA_REC_HE_CAP_ER_SU_PPDU_4LTF_8US_GI;
  456. if (elem->phy_cap_info[8] &
  457. IEEE80211_HE_PHY_CAP8_HE_ER_SU_1XLTF_AND_08_US_GI)
  458. cap |= STA_REC_HE_CAP_ER_SU_PPDU_1LTF_8US_GI;
  459. if (elem->phy_cap_info[9] &
  460. IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK)
  461. cap |= STA_REC_HE_CAP_TRIG_CQI_FK;
  462. if (elem->phy_cap_info[9] &
  463. IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU)
  464. cap |= STA_REC_HE_CAP_TX_1024QAM_UNDER_RU242;
  465. if (elem->phy_cap_info[9] &
  466. IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU)
  467. cap |= STA_REC_HE_CAP_RX_1024QAM_UNDER_RU242;
  468. he->he_cap = cpu_to_le32(cap);
  469. switch (sta->bandwidth) {
  470. case IEEE80211_STA_RX_BW_160:
  471. if (elem->phy_cap_info[0] &
  472. IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
  473. he->max_nss_mcs[CMD_HE_MCS_BW8080] =
  474. he_cap->he_mcs_nss_supp.rx_mcs_80p80;
  475. he->max_nss_mcs[CMD_HE_MCS_BW160] =
  476. he_cap->he_mcs_nss_supp.rx_mcs_160;
  477. fallthrough;
  478. default:
  479. he->max_nss_mcs[CMD_HE_MCS_BW80] =
  480. he_cap->he_mcs_nss_supp.rx_mcs_80;
  481. break;
  482. }
  483. he->t_frame_dur =
  484. HE_MAC(CAP1_TF_MAC_PAD_DUR_MASK, elem->mac_cap_info[1]);
  485. he->max_ampdu_exp =
  486. HE_MAC(CAP3_MAX_AMPDU_LEN_EXP_MASK, elem->mac_cap_info[3]);
  487. he->bw_set =
  488. HE_PHY(CAP0_CHANNEL_WIDTH_SET_MASK, elem->phy_cap_info[0]);
  489. he->device_class =
  490. HE_PHY(CAP1_DEVICE_CLASS_A, elem->phy_cap_info[1]);
  491. he->punc_pream_rx =
  492. HE_PHY(CAP1_PREAMBLE_PUNC_RX_MASK, elem->phy_cap_info[1]);
  493. he->dcm_tx_mode =
  494. HE_PHY(CAP3_DCM_MAX_CONST_TX_MASK, elem->phy_cap_info[3]);
  495. he->dcm_tx_max_nss =
  496. HE_PHY(CAP3_DCM_MAX_TX_NSS_2, elem->phy_cap_info[3]);
  497. he->dcm_rx_mode =
  498. HE_PHY(CAP3_DCM_MAX_CONST_RX_MASK, elem->phy_cap_info[3]);
  499. he->dcm_rx_max_nss =
  500. HE_PHY(CAP3_DCM_MAX_RX_NSS_2, elem->phy_cap_info[3]);
  501. he->dcm_rx_max_nss =
  502. HE_PHY(CAP8_DCM_MAX_RU_MASK, elem->phy_cap_info[8]);
  503. he->pkt_ext = 2;
  504. }
  505. static u8
  506. mt76_connac_get_phy_mode_v2(struct mt76_phy *mphy, struct ieee80211_vif *vif,
  507. enum nl80211_band band, struct ieee80211_sta *sta)
  508. {
  509. struct ieee80211_sta_ht_cap *ht_cap;
  510. struct ieee80211_sta_vht_cap *vht_cap;
  511. const struct ieee80211_sta_he_cap *he_cap;
  512. u8 mode = 0;
  513. if (sta) {
  514. ht_cap = &sta->ht_cap;
  515. vht_cap = &sta->vht_cap;
  516. he_cap = &sta->he_cap;
  517. } else {
  518. struct ieee80211_supported_band *sband;
  519. sband = mphy->hw->wiphy->bands[band];
  520. ht_cap = &sband->ht_cap;
  521. vht_cap = &sband->vht_cap;
  522. he_cap = ieee80211_get_he_iftype_cap(sband, vif->type);
  523. }
  524. if (band == NL80211_BAND_2GHZ) {
  525. mode |= PHY_TYPE_BIT_HR_DSSS | PHY_TYPE_BIT_ERP;
  526. if (ht_cap->ht_supported)
  527. mode |= PHY_TYPE_BIT_HT;
  528. if (he_cap->has_he)
  529. mode |= PHY_TYPE_BIT_HE;
  530. } else if (band == NL80211_BAND_5GHZ) {
  531. mode |= PHY_TYPE_BIT_OFDM;
  532. if (ht_cap->ht_supported)
  533. mode |= PHY_TYPE_BIT_HT;
  534. if (vht_cap->vht_supported)
  535. mode |= PHY_TYPE_BIT_VHT;
  536. if (he_cap->has_he)
  537. mode |= PHY_TYPE_BIT_HE;
  538. }
  539. return mode;
  540. }
  541. void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
  542. struct ieee80211_sta *sta,
  543. struct ieee80211_vif *vif)
  544. {
  545. struct cfg80211_chan_def *chandef = &mphy->chandef;
  546. enum nl80211_band band = chandef->chan->band;
  547. struct mt76_dev *dev = mphy->dev;
  548. struct sta_rec_ra_info *ra_info;
  549. struct sta_rec_state *state;
  550. struct sta_rec_phy *phy;
  551. struct tlv *tlv;
  552. /* starec ht */
  553. if (sta->ht_cap.ht_supported) {
  554. struct sta_rec_ht *ht;
  555. tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HT, sizeof(*ht));
  556. ht = (struct sta_rec_ht *)tlv;
  557. ht->ht_cap = cpu_to_le16(sta->ht_cap.cap);
  558. }
  559. /* starec vht */
  560. if (sta->vht_cap.vht_supported) {
  561. struct sta_rec_vht *vht;
  562. int len;
  563. len = is_mt7921(dev) ? sizeof(*vht) : sizeof(*vht) - 4;
  564. tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_VHT, len);
  565. vht = (struct sta_rec_vht *)tlv;
  566. vht->vht_cap = cpu_to_le32(sta->vht_cap.cap);
  567. vht->vht_rx_mcs_map = sta->vht_cap.vht_mcs.rx_mcs_map;
  568. vht->vht_tx_mcs_map = sta->vht_cap.vht_mcs.tx_mcs_map;
  569. }
  570. /* starec uapsd */
  571. mt76_connac_mcu_sta_uapsd(skb, vif, sta);
  572. if (!is_mt7921(dev))
  573. return;
  574. if (sta->ht_cap.ht_supported)
  575. mt76_connac_mcu_sta_amsdu_tlv(skb, sta, vif);
  576. /* starec he */
  577. if (sta->he_cap.has_he)
  578. mt76_connac_mcu_sta_he_tlv(skb, sta);
  579. tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_PHY, sizeof(*phy));
  580. phy = (struct sta_rec_phy *)tlv;
  581. phy->phy_type = mt76_connac_get_phy_mode_v2(mphy, vif, band, sta);
  582. phy->basic_rate = cpu_to_le16((u16)vif->bss_conf.basic_rates);
  583. tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA, sizeof(*ra_info));
  584. ra_info = (struct sta_rec_ra_info *)tlv;
  585. ra_info->legacy = cpu_to_le16((u16)sta->supp_rates[band]);
  586. if (sta->ht_cap.ht_supported)
  587. memcpy(ra_info->rx_mcs_bitmask, sta->ht_cap.mcs.rx_mask,
  588. HT_MCS_MASK_NUM);
  589. tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_STATE, sizeof(*state));
  590. state = (struct sta_rec_state *)tlv;
  591. state->state = 2;
  592. if (sta->vht_cap.vht_supported) {
  593. state->vht_opmode = sta->bandwidth;
  594. state->vht_opmode |= (sta->rx_nss - 1) <<
  595. IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT;
  596. }
  597. }
  598. EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_tlv);
  599. static void
  600. mt76_connac_mcu_wtbl_smps_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
  601. void *sta_wtbl, void *wtbl_tlv)
  602. {
  603. struct wtbl_smps *smps;
  604. struct tlv *tlv;
  605. tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_SMPS, sizeof(*smps),
  606. wtbl_tlv, sta_wtbl);
  607. smps = (struct wtbl_smps *)tlv;
  608. if (sta->smps_mode == IEEE80211_SMPS_DYNAMIC)
  609. smps->smps = true;
  610. }
  611. void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb,
  612. struct ieee80211_sta *sta, void *sta_wtbl,
  613. void *wtbl_tlv)
  614. {
  615. struct wtbl_ht *ht = NULL;
  616. struct tlv *tlv;
  617. u32 flags = 0;
  618. if (sta->ht_cap.ht_supported) {
  619. tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_HT, sizeof(*ht),
  620. wtbl_tlv, sta_wtbl);
  621. ht = (struct wtbl_ht *)tlv;
  622. ht->ldpc = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING);
  623. ht->af = sta->ht_cap.ampdu_factor;
  624. ht->mm = sta->ht_cap.ampdu_density;
  625. ht->ht = true;
  626. }
  627. if (sta->vht_cap.vht_supported) {
  628. struct wtbl_vht *vht;
  629. u8 af;
  630. tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_VHT,
  631. sizeof(*vht), wtbl_tlv,
  632. sta_wtbl);
  633. vht = (struct wtbl_vht *)tlv;
  634. vht->ldpc = !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC);
  635. vht->vht = true;
  636. af = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK,
  637. sta->vht_cap.cap);
  638. if (ht)
  639. ht->af = max(ht->af, af);
  640. }
  641. mt76_connac_mcu_wtbl_smps_tlv(skb, sta, sta_wtbl, wtbl_tlv);
  642. if (!is_mt7921(dev) && sta->ht_cap.ht_supported) {
  643. /* sgi */
  644. u32 msk = MT_WTBL_W5_SHORT_GI_20 | MT_WTBL_W5_SHORT_GI_40 |
  645. MT_WTBL_W5_SHORT_GI_80 | MT_WTBL_W5_SHORT_GI_160;
  646. struct wtbl_raw *raw;
  647. tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_RAW_DATA,
  648. sizeof(*raw), wtbl_tlv,
  649. sta_wtbl);
  650. if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20)
  651. flags |= MT_WTBL_W5_SHORT_GI_20;
  652. if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)
  653. flags |= MT_WTBL_W5_SHORT_GI_40;
  654. if (sta->vht_cap.vht_supported) {
  655. if (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80)
  656. flags |= MT_WTBL_W5_SHORT_GI_80;
  657. if (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160)
  658. flags |= MT_WTBL_W5_SHORT_GI_160;
  659. }
  660. raw = (struct wtbl_raw *)tlv;
  661. raw->val = cpu_to_le32(flags);
  662. raw->msk = cpu_to_le32(~msk);
  663. raw->wtbl_idx = 1;
  664. raw->dw = 5;
  665. }
  666. }
  667. EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_ht_tlv);
  668. int mt76_connac_mcu_add_sta_cmd(struct mt76_phy *phy,
  669. struct ieee80211_vif *vif,
  670. struct ieee80211_sta *sta,
  671. struct mt76_wcid *wcid,
  672. bool enable, int cmd)
  673. {
  674. struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
  675. struct mt76_dev *dev = phy->dev;
  676. struct wtbl_req_hdr *wtbl_hdr;
  677. struct tlv *sta_wtbl;
  678. struct sk_buff *skb;
  679. skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
  680. if (IS_ERR(skb))
  681. return PTR_ERR(skb);
  682. mt76_connac_mcu_sta_basic_tlv(skb, vif, sta, enable);
  683. if (enable && sta)
  684. mt76_connac_mcu_sta_tlv(phy, skb, sta, vif);
  685. sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL,
  686. sizeof(struct tlv));
  687. wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, wcid,
  688. WTBL_RESET_AND_SET,
  689. sta_wtbl, &skb);
  690. if (IS_ERR(wtbl_hdr))
  691. return PTR_ERR(wtbl_hdr);
  692. if (enable) {
  693. mt76_connac_mcu_wtbl_generic_tlv(dev, skb, vif, sta, sta_wtbl,
  694. wtbl_hdr);
  695. if (sta)
  696. mt76_connac_mcu_wtbl_ht_tlv(dev, skb, sta, sta_wtbl,
  697. wtbl_hdr);
  698. }
  699. return mt76_mcu_skb_send_msg(dev, skb, cmd, true);
  700. }
  701. EXPORT_SYMBOL_GPL(mt76_connac_mcu_add_sta_cmd);
  702. void mt76_connac_mcu_wtbl_ba_tlv(struct mt76_dev *dev, struct sk_buff *skb,
  703. struct ieee80211_ampdu_params *params,
  704. bool enable, bool tx, void *sta_wtbl,
  705. void *wtbl_tlv)
  706. {
  707. struct wtbl_ba *ba;
  708. struct tlv *tlv;
  709. tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_BA, sizeof(*ba),
  710. wtbl_tlv, sta_wtbl);
  711. ba = (struct wtbl_ba *)tlv;
  712. ba->tid = params->tid;
  713. if (tx) {
  714. ba->ba_type = MT_BA_TYPE_ORIGINATOR;
  715. ba->sn = enable ? cpu_to_le16(params->ssn) : 0;
  716. ba->ba_winsize = enable ? cpu_to_le16(params->buf_size) : 0;
  717. ba->ba_en = enable;
  718. } else {
  719. memcpy(ba->peer_addr, params->sta->addr, ETH_ALEN);
  720. ba->ba_type = MT_BA_TYPE_RECIPIENT;
  721. ba->rst_ba_tid = params->tid;
  722. ba->rst_ba_sel = RST_BA_MAC_TID_MATCH;
  723. ba->rst_ba_sb = 1;
  724. }
  725. if (is_mt7921(dev))
  726. return;
  727. if (enable && tx) {
  728. u8 ba_range[] = { 4, 8, 12, 24, 36, 48, 54, 64 };
  729. int i;
  730. for (i = 7; i > 0; i--) {
  731. if (params->buf_size >= ba_range[i])
  732. break;
  733. }
  734. ba->ba_winsize_idx = i;
  735. }
  736. }
  737. EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_ba_tlv);
  738. int mt76_connac_mcu_uni_add_dev(struct mt76_phy *phy,
  739. struct ieee80211_vif *vif,
  740. struct mt76_wcid *wcid,
  741. bool enable)
  742. {
  743. struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
  744. struct mt76_dev *dev = phy->dev;
  745. struct {
  746. struct {
  747. u8 omac_idx;
  748. u8 band_idx;
  749. __le16 pad;
  750. } __packed hdr;
  751. struct req_tlv {
  752. __le16 tag;
  753. __le16 len;
  754. u8 active;
  755. u8 pad;
  756. u8 omac_addr[ETH_ALEN];
  757. } __packed tlv;
  758. } dev_req = {
  759. .hdr = {
  760. .omac_idx = mvif->omac_idx,
  761. .band_idx = mvif->band_idx,
  762. },
  763. .tlv = {
  764. .tag = cpu_to_le16(DEV_INFO_ACTIVE),
  765. .len = cpu_to_le16(sizeof(struct req_tlv)),
  766. .active = enable,
  767. },
  768. };
  769. struct {
  770. struct {
  771. u8 bss_idx;
  772. u8 pad[3];
  773. } __packed hdr;
  774. struct mt76_connac_bss_basic_tlv basic;
  775. } basic_req = {
  776. .hdr = {
  777. .bss_idx = mvif->idx,
  778. },
  779. .basic = {
  780. .tag = cpu_to_le16(UNI_BSS_INFO_BASIC),
  781. .len = cpu_to_le16(sizeof(struct mt76_connac_bss_basic_tlv)),
  782. .omac_idx = mvif->omac_idx,
  783. .band_idx = mvif->band_idx,
  784. .wmm_idx = mvif->wmm_idx,
  785. .active = enable,
  786. .bmc_tx_wlan_idx = cpu_to_le16(wcid->idx),
  787. .sta_idx = cpu_to_le16(wcid->idx),
  788. .conn_state = 1,
  789. },
  790. };
  791. int err, idx, cmd, len;
  792. void *data;
  793. switch (vif->type) {
  794. case NL80211_IFTYPE_MESH_POINT:
  795. case NL80211_IFTYPE_AP:
  796. basic_req.basic.conn_type = cpu_to_le32(CONNECTION_INFRA_AP);
  797. break;
  798. case NL80211_IFTYPE_STATION:
  799. basic_req.basic.conn_type = cpu_to_le32(CONNECTION_INFRA_STA);
  800. break;
  801. case NL80211_IFTYPE_ADHOC:
  802. basic_req.basic.conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC);
  803. break;
  804. default:
  805. WARN_ON(1);
  806. break;
  807. }
  808. idx = mvif->omac_idx > EXT_BSSID_START ? HW_BSSID_0 : mvif->omac_idx;
  809. basic_req.basic.hw_bss_idx = idx;
  810. memcpy(dev_req.tlv.omac_addr, vif->addr, ETH_ALEN);
  811. cmd = enable ? MCU_UNI_CMD_DEV_INFO_UPDATE : MCU_UNI_CMD_BSS_INFO_UPDATE;
  812. data = enable ? (void *)&dev_req : (void *)&basic_req;
  813. len = enable ? sizeof(dev_req) : sizeof(basic_req);
  814. err = mt76_mcu_send_msg(dev, cmd, data, len, true);
  815. if (err < 0)
  816. return err;
  817. cmd = enable ? MCU_UNI_CMD_BSS_INFO_UPDATE : MCU_UNI_CMD_DEV_INFO_UPDATE;
  818. data = enable ? (void *)&basic_req : (void *)&dev_req;
  819. len = enable ? sizeof(basic_req) : sizeof(dev_req);
  820. return mt76_mcu_send_msg(dev, cmd, data, len, true);
  821. }
  822. EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_dev);
  823. void mt76_connac_mcu_sta_ba_tlv(struct sk_buff *skb,
  824. struct ieee80211_ampdu_params *params,
  825. bool enable, bool tx)
  826. {
  827. struct sta_rec_ba *ba;
  828. struct tlv *tlv;
  829. tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BA, sizeof(*ba));
  830. ba = (struct sta_rec_ba *)tlv;
  831. ba->ba_type = tx ? MT_BA_TYPE_ORIGINATOR : MT_BA_TYPE_RECIPIENT;
  832. ba->winsize = cpu_to_le16(params->buf_size);
  833. ba->ssn = cpu_to_le16(params->ssn);
  834. ba->ba_en = enable << params->tid;
  835. ba->amsdu = params->amsdu;
  836. ba->tid = params->tid;
  837. }
  838. EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba_tlv);
  839. int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
  840. struct ieee80211_ampdu_params *params,
  841. bool enable, bool tx)
  842. {
  843. struct mt76_wcid *wcid = (struct mt76_wcid *)params->sta->drv_priv;
  844. struct wtbl_req_hdr *wtbl_hdr;
  845. struct tlv *sta_wtbl;
  846. struct sk_buff *skb;
  847. int ret;
  848. skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
  849. if (IS_ERR(skb))
  850. return PTR_ERR(skb);
  851. sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL,
  852. sizeof(struct tlv));
  853. wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, wcid, WTBL_SET,
  854. sta_wtbl, &skb);
  855. if (IS_ERR(wtbl_hdr))
  856. return PTR_ERR(wtbl_hdr);
  857. mt76_connac_mcu_wtbl_ba_tlv(dev, skb, params, enable, tx, sta_wtbl,
  858. wtbl_hdr);
  859. ret = mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD_STA_REC_UPDATE, true);
  860. if (ret)
  861. return ret;
  862. skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
  863. if (IS_ERR(skb))
  864. return PTR_ERR(skb);
  865. mt76_connac_mcu_sta_ba_tlv(skb, params, enable, tx);
  866. return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD_STA_REC_UPDATE,
  867. true);
  868. }
  869. EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba);
  870. static u8
  871. mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,
  872. enum nl80211_band band,
  873. struct ieee80211_sta *sta)
  874. {
  875. struct mt76_dev *dev = phy->dev;
  876. const struct ieee80211_sta_he_cap *he_cap;
  877. struct ieee80211_sta_vht_cap *vht_cap;
  878. struct ieee80211_sta_ht_cap *ht_cap;
  879. u8 mode = 0;
  880. if (!is_mt7921(dev))
  881. return 0x38;
  882. if (sta) {
  883. ht_cap = &sta->ht_cap;
  884. vht_cap = &sta->vht_cap;
  885. he_cap = &sta->he_cap;
  886. } else {
  887. struct ieee80211_supported_band *sband;
  888. sband = phy->hw->wiphy->bands[band];
  889. ht_cap = &sband->ht_cap;
  890. vht_cap = &sband->vht_cap;
  891. he_cap = ieee80211_get_he_iftype_cap(sband, vif->type);
  892. }
  893. if (band == NL80211_BAND_2GHZ) {
  894. mode |= PHY_MODE_B | PHY_MODE_G;
  895. if (ht_cap->ht_supported)
  896. mode |= PHY_MODE_GN;
  897. if (he_cap->has_he)
  898. mode |= PHY_MODE_AX_24G;
  899. } else if (band == NL80211_BAND_5GHZ) {
  900. mode |= PHY_MODE_A;
  901. if (ht_cap->ht_supported)
  902. mode |= PHY_MODE_AN;
  903. if (vht_cap->vht_supported)
  904. mode |= PHY_MODE_AC;
  905. if (he_cap->has_he)
  906. mode |= PHY_MODE_AX_5G;
  907. }
  908. return mode;
  909. }
  910. static const struct ieee80211_sta_he_cap *
  911. mt76_connac_get_he_phy_cap(struct mt76_phy *phy, struct ieee80211_vif *vif)
  912. {
  913. enum nl80211_band band = phy->chandef.chan->band;
  914. struct ieee80211_supported_band *sband;
  915. sband = phy->hw->wiphy->bands[band];
  916. return ieee80211_get_he_iftype_cap(sband, vif->type);
  917. }
  918. #define DEFAULT_HE_PE_DURATION 4
  919. #define DEFAULT_HE_DURATION_RTS_THRES 1023
  920. static void
  921. mt76_connac_mcu_uni_bss_he_tlv(struct mt76_phy *phy, struct ieee80211_vif *vif,
  922. struct tlv *tlv)
  923. {
  924. const struct ieee80211_sta_he_cap *cap;
  925. struct bss_info_uni_he *he;
  926. cap = mt76_connac_get_he_phy_cap(phy, vif);
  927. he = (struct bss_info_uni_he *)tlv;
  928. he->he_pe_duration = vif->bss_conf.htc_trig_based_pkt_ext;
  929. if (!he->he_pe_duration)
  930. he->he_pe_duration = DEFAULT_HE_PE_DURATION;
  931. he->he_rts_thres = cpu_to_le16(vif->bss_conf.frame_time_rts_th);
  932. if (!he->he_rts_thres)
  933. he->he_rts_thres = cpu_to_le16(DEFAULT_HE_DURATION_RTS_THRES);
  934. he->max_nss_mcs[CMD_HE_MCS_BW80] = cap->he_mcs_nss_supp.tx_mcs_80;
  935. he->max_nss_mcs[CMD_HE_MCS_BW160] = cap->he_mcs_nss_supp.tx_mcs_160;
  936. he->max_nss_mcs[CMD_HE_MCS_BW8080] = cap->he_mcs_nss_supp.tx_mcs_80p80;
  937. }
  938. int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,
  939. struct ieee80211_vif *vif,
  940. struct mt76_wcid *wcid,
  941. bool enable)
  942. {
  943. struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
  944. struct cfg80211_chan_def *chandef = &phy->chandef;
  945. int freq1 = chandef->center_freq1, freq2 = chandef->center_freq2;
  946. enum nl80211_band band = chandef->chan->band;
  947. struct mt76_dev *mdev = phy->dev;
  948. struct {
  949. struct {
  950. u8 bss_idx;
  951. u8 pad[3];
  952. } __packed hdr;
  953. struct mt76_connac_bss_basic_tlv basic;
  954. struct mt76_connac_bss_qos_tlv qos;
  955. } basic_req = {
  956. .hdr = {
  957. .bss_idx = mvif->idx,
  958. },
  959. .basic = {
  960. .tag = cpu_to_le16(UNI_BSS_INFO_BASIC),
  961. .len = cpu_to_le16(sizeof(struct mt76_connac_bss_basic_tlv)),
  962. .bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int),
  963. .dtim_period = vif->bss_conf.dtim_period,
  964. .omac_idx = mvif->omac_idx,
  965. .band_idx = mvif->band_idx,
  966. .wmm_idx = mvif->wmm_idx,
  967. .active = true, /* keep bss deactivated */
  968. .phymode = mt76_connac_get_phy_mode(phy, vif, band, NULL),
  969. },
  970. .qos = {
  971. .tag = cpu_to_le16(UNI_BSS_INFO_QBSS),
  972. .len = cpu_to_le16(sizeof(struct mt76_connac_bss_qos_tlv)),
  973. .qos = vif->bss_conf.qos,
  974. },
  975. };
  976. struct {
  977. struct {
  978. u8 bss_idx;
  979. u8 pad[3];
  980. } __packed hdr;
  981. struct rlm_tlv {
  982. __le16 tag;
  983. __le16 len;
  984. u8 control_channel;
  985. u8 center_chan;
  986. u8 center_chan2;
  987. u8 bw;
  988. u8 tx_streams;
  989. u8 rx_streams;
  990. u8 short_st;
  991. u8 ht_op_info;
  992. u8 sco;
  993. u8 pad[3];
  994. } __packed rlm;
  995. } __packed rlm_req = {
  996. .hdr = {
  997. .bss_idx = mvif->idx,
  998. },
  999. .rlm = {
  1000. .tag = cpu_to_le16(UNI_BSS_INFO_RLM),
  1001. .len = cpu_to_le16(sizeof(struct rlm_tlv)),
  1002. .control_channel = chandef->chan->hw_value,
  1003. .center_chan = ieee80211_frequency_to_channel(freq1),
  1004. .center_chan2 = ieee80211_frequency_to_channel(freq2),
  1005. .tx_streams = hweight8(phy->antenna_mask),
  1006. .ht_op_info = 4, /* set HT 40M allowed */
  1007. .rx_streams = phy->chainmask,
  1008. .short_st = true,
  1009. },
  1010. };
  1011. int err, conn_type;
  1012. u8 idx;
  1013. idx = mvif->omac_idx > EXT_BSSID_START ? HW_BSSID_0 : mvif->omac_idx;
  1014. basic_req.basic.hw_bss_idx = idx;
  1015. switch (vif->type) {
  1016. case NL80211_IFTYPE_MESH_POINT:
  1017. case NL80211_IFTYPE_AP:
  1018. if (vif->p2p)
  1019. conn_type = CONNECTION_P2P_GO;
  1020. else
  1021. conn_type = CONNECTION_INFRA_AP;
  1022. basic_req.basic.conn_type = cpu_to_le32(conn_type);
  1023. break;
  1024. case NL80211_IFTYPE_STATION:
  1025. if (vif->p2p)
  1026. conn_type = CONNECTION_P2P_GC;
  1027. else
  1028. conn_type = CONNECTION_INFRA_STA;
  1029. basic_req.basic.conn_type = cpu_to_le32(conn_type);
  1030. break;
  1031. case NL80211_IFTYPE_ADHOC:
  1032. basic_req.basic.conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC);
  1033. break;
  1034. default:
  1035. WARN_ON(1);
  1036. break;
  1037. }
  1038. memcpy(basic_req.basic.bssid, vif->bss_conf.bssid, ETH_ALEN);
  1039. basic_req.basic.bmc_tx_wlan_idx = cpu_to_le16(wcid->idx);
  1040. basic_req.basic.sta_idx = cpu_to_le16(wcid->idx);
  1041. basic_req.basic.conn_state = !enable;
  1042. err = mt76_mcu_send_msg(mdev, MCU_UNI_CMD_BSS_INFO_UPDATE, &basic_req,
  1043. sizeof(basic_req), true);
  1044. if (err < 0)
  1045. return err;
  1046. if (vif->bss_conf.he_support) {
  1047. struct {
  1048. struct {
  1049. u8 bss_idx;
  1050. u8 pad[3];
  1051. } __packed hdr;
  1052. struct bss_info_uni_he he;
  1053. } he_req = {
  1054. .hdr = {
  1055. .bss_idx = mvif->idx,
  1056. },
  1057. .he = {
  1058. .tag = cpu_to_le16(UNI_BSS_INFO_HE_BASIC),
  1059. .len = cpu_to_le16(sizeof(struct bss_info_uni_he)),
  1060. },
  1061. };
  1062. mt76_connac_mcu_uni_bss_he_tlv(phy, vif,
  1063. (struct tlv *)&he_req.he);
  1064. err = mt76_mcu_send_msg(mdev, MCU_UNI_CMD_BSS_INFO_UPDATE,
  1065. &he_req, sizeof(he_req), true);
  1066. if (err < 0)
  1067. return err;
  1068. }
  1069. switch (chandef->width) {
  1070. case NL80211_CHAN_WIDTH_40:
  1071. rlm_req.rlm.bw = CMD_CBW_40MHZ;
  1072. break;
  1073. case NL80211_CHAN_WIDTH_80:
  1074. rlm_req.rlm.bw = CMD_CBW_80MHZ;
  1075. break;
  1076. case NL80211_CHAN_WIDTH_80P80:
  1077. rlm_req.rlm.bw = CMD_CBW_8080MHZ;
  1078. break;
  1079. case NL80211_CHAN_WIDTH_160:
  1080. rlm_req.rlm.bw = CMD_CBW_160MHZ;
  1081. break;
  1082. case NL80211_CHAN_WIDTH_5:
  1083. rlm_req.rlm.bw = CMD_CBW_5MHZ;
  1084. break;
  1085. case NL80211_CHAN_WIDTH_10:
  1086. rlm_req.rlm.bw = CMD_CBW_10MHZ;
  1087. break;
  1088. case NL80211_CHAN_WIDTH_20_NOHT:
  1089. case NL80211_CHAN_WIDTH_20:
  1090. default:
  1091. rlm_req.rlm.bw = CMD_CBW_20MHZ;
  1092. rlm_req.rlm.ht_op_info = 0;
  1093. break;
  1094. }
  1095. if (rlm_req.rlm.control_channel < rlm_req.rlm.center_chan)
  1096. rlm_req.rlm.sco = 1; /* SCA */
  1097. else if (rlm_req.rlm.control_channel > rlm_req.rlm.center_chan)
  1098. rlm_req.rlm.sco = 3; /* SCB */
  1099. return mt76_mcu_send_msg(mdev, MCU_UNI_CMD_BSS_INFO_UPDATE, &rlm_req,
  1100. sizeof(rlm_req), true);
  1101. }
  1102. EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_bss);
  1103. #define MT76_CONNAC_SCAN_CHANNEL_TIME 60
  1104. int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
  1105. struct ieee80211_scan_request *scan_req)
  1106. {
  1107. struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
  1108. struct cfg80211_scan_request *sreq = &scan_req->req;
  1109. int n_ssids = 0, err, i, duration = MT76_CONNAC_SCAN_CHANNEL_TIME;
  1110. int ext_channels_num = max_t(int, sreq->n_channels - 32, 0);
  1111. struct ieee80211_channel **scan_list = sreq->channels;
  1112. struct mt76_dev *mdev = phy->dev;
  1113. bool ext_phy = phy == mdev->phy2;
  1114. struct mt76_connac_mcu_scan_channel *chan;
  1115. struct mt76_connac_hw_scan_req *req;
  1116. struct sk_buff *skb;
  1117. skb = mt76_mcu_msg_alloc(mdev, NULL, sizeof(*req));
  1118. if (!skb)
  1119. return -ENOMEM;
  1120. set_bit(MT76_HW_SCANNING, &phy->state);
  1121. mvif->scan_seq_num = (mvif->scan_seq_num + 1) & 0x7f;
  1122. req = (struct mt76_connac_hw_scan_req *)skb_put(skb, sizeof(*req));
  1123. req->seq_num = mvif->scan_seq_num | ext_phy << 7;
  1124. req->bss_idx = mvif->idx;
  1125. req->scan_type = sreq->n_ssids ? 1 : 0;
  1126. req->probe_req_num = sreq->n_ssids ? 2 : 0;
  1127. req->version = 1;
  1128. for (i = 0; i < sreq->n_ssids; i++) {
  1129. if (!sreq->ssids[i].ssid_len)
  1130. continue;
  1131. req->ssids[i].ssid_len = cpu_to_le32(sreq->ssids[i].ssid_len);
  1132. memcpy(req->ssids[i].ssid, sreq->ssids[i].ssid,
  1133. sreq->ssids[i].ssid_len);
  1134. n_ssids++;
  1135. }
  1136. req->ssid_type = n_ssids ? BIT(2) : BIT(0);
  1137. req->ssid_type_ext = n_ssids ? BIT(0) : 0;
  1138. req->ssids_num = n_ssids;
  1139. /* increase channel time for passive scan */
  1140. if (!sreq->n_ssids)
  1141. duration *= 2;
  1142. req->timeout_value = cpu_to_le16(sreq->n_channels * duration);
  1143. req->channel_min_dwell_time = cpu_to_le16(duration);
  1144. req->channel_dwell_time = cpu_to_le16(duration);
  1145. req->channels_num = min_t(u8, sreq->n_channels, 32);
  1146. req->ext_channels_num = min_t(u8, ext_channels_num, 32);
  1147. for (i = 0; i < req->channels_num + req->ext_channels_num; i++) {
  1148. if (i >= 32)
  1149. chan = &req->ext_channels[i - 32];
  1150. else
  1151. chan = &req->channels[i];
  1152. chan->band = scan_list[i]->band == NL80211_BAND_2GHZ ? 1 : 2;
  1153. chan->channel_num = scan_list[i]->hw_value;
  1154. }
  1155. req->channel_type = sreq->n_channels ? 4 : 0;
  1156. if (sreq->ie_len > 0) {
  1157. memcpy(req->ies, sreq->ie, sreq->ie_len);
  1158. req->ies_len = cpu_to_le16(sreq->ie_len);
  1159. }
  1160. memcpy(req->bssid, sreq->bssid, ETH_ALEN);
  1161. if (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
  1162. get_random_mask_addr(req->random_mac, sreq->mac_addr,
  1163. sreq->mac_addr_mask);
  1164. req->scan_func = 1;
  1165. }
  1166. err = mt76_mcu_skb_send_msg(mdev, skb, MCU_CMD_START_HW_SCAN, false);
  1167. if (err < 0)
  1168. clear_bit(MT76_HW_SCANNING, &phy->state);
  1169. return err;
  1170. }
  1171. EXPORT_SYMBOL_GPL(mt76_connac_mcu_hw_scan);
  1172. int mt76_connac_mcu_cancel_hw_scan(struct mt76_phy *phy,
  1173. struct ieee80211_vif *vif)
  1174. {
  1175. struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
  1176. struct {
  1177. u8 seq_num;
  1178. u8 is_ext_channel;
  1179. u8 rsv[2];
  1180. } __packed req = {
  1181. .seq_num = mvif->scan_seq_num,
  1182. };
  1183. if (test_and_clear_bit(MT76_HW_SCANNING, &phy->state)) {
  1184. struct cfg80211_scan_info info = {
  1185. .aborted = true,
  1186. };
  1187. ieee80211_scan_completed(phy->hw, &info);
  1188. }
  1189. return mt76_mcu_send_msg(phy->dev, MCU_CMD_CANCEL_HW_SCAN, &req,
  1190. sizeof(req), false);
  1191. }
  1192. EXPORT_SYMBOL_GPL(mt76_connac_mcu_cancel_hw_scan);
  1193. int mt76_connac_mcu_sched_scan_req(struct mt76_phy *phy,
  1194. struct ieee80211_vif *vif,
  1195. struct cfg80211_sched_scan_request *sreq)
  1196. {
  1197. struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
  1198. struct ieee80211_channel **scan_list = sreq->channels;
  1199. struct mt76_connac_mcu_scan_channel *chan;
  1200. struct mt76_connac_sched_scan_req *req;
  1201. struct mt76_dev *mdev = phy->dev;
  1202. bool ext_phy = phy == mdev->phy2;
  1203. struct cfg80211_match_set *match;
  1204. struct cfg80211_ssid *ssid;
  1205. struct sk_buff *skb;
  1206. int i;
  1207. skb = mt76_mcu_msg_alloc(mdev, NULL, sizeof(*req) + sreq->ie_len);
  1208. if (!skb)
  1209. return -ENOMEM;
  1210. mvif->scan_seq_num = (mvif->scan_seq_num + 1) & 0x7f;
  1211. req = (struct mt76_connac_sched_scan_req *)skb_put(skb, sizeof(*req));
  1212. req->version = 1;
  1213. req->seq_num = mvif->scan_seq_num | ext_phy << 7;
  1214. if (is_mt7663(phy->dev) &&
  1215. (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)) {
  1216. get_random_mask_addr(req->mt7663.random_mac, sreq->mac_addr,
  1217. sreq->mac_addr_mask);
  1218. req->scan_func = 1;
  1219. } else if (is_mt7921(phy->dev)) {
  1220. req->mt7921.bss_idx = mvif->idx;
  1221. }
  1222. req->ssids_num = sreq->n_ssids;
  1223. for (i = 0; i < req->ssids_num; i++) {
  1224. ssid = &sreq->ssids[i];
  1225. memcpy(req->ssids[i].ssid, ssid->ssid, ssid->ssid_len);
  1226. req->ssids[i].ssid_len = cpu_to_le32(ssid->ssid_len);
  1227. }
  1228. req->match_num = sreq->n_match_sets;
  1229. for (i = 0; i < req->match_num; i++) {
  1230. match = &sreq->match_sets[i];
  1231. memcpy(req->match[i].ssid, match->ssid.ssid,
  1232. match->ssid.ssid_len);
  1233. req->match[i].rssi_th = cpu_to_le32(match->rssi_thold);
  1234. req->match[i].ssid_len = match->ssid.ssid_len;
  1235. }
  1236. req->channel_type = sreq->n_channels ? 4 : 0;
  1237. req->channels_num = min_t(u8, sreq->n_channels, 64);
  1238. for (i = 0; i < req->channels_num; i++) {
  1239. chan = &req->channels[i];
  1240. chan->band = scan_list[i]->band == NL80211_BAND_2GHZ ? 1 : 2;
  1241. chan->channel_num = scan_list[i]->hw_value;
  1242. }
  1243. req->intervals_num = sreq->n_scan_plans;
  1244. for (i = 0; i < req->intervals_num; i++)
  1245. req->intervals[i] = cpu_to_le16(sreq->scan_plans[i].interval);
  1246. if (sreq->ie_len > 0) {
  1247. req->ie_len = cpu_to_le16(sreq->ie_len);
  1248. memcpy(skb_put(skb, sreq->ie_len), sreq->ie, sreq->ie_len);
  1249. }
  1250. return mt76_mcu_skb_send_msg(mdev, skb, MCU_CMD_SCHED_SCAN_REQ, false);
  1251. }
  1252. EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_req);
  1253. int mt76_connac_mcu_sched_scan_enable(struct mt76_phy *phy,
  1254. struct ieee80211_vif *vif,
  1255. bool enable)
  1256. {
  1257. struct {
  1258. u8 active; /* 0: enabled 1: disabled */
  1259. u8 rsv[3];
  1260. } __packed req = {
  1261. .active = !enable,
  1262. };
  1263. if (enable)
  1264. set_bit(MT76_HW_SCHED_SCANNING, &phy->state);
  1265. else
  1266. clear_bit(MT76_HW_SCHED_SCANNING, &phy->state);
  1267. return mt76_mcu_send_msg(phy->dev, MCU_CMD_SCHED_SCAN_ENABLE, &req,
  1268. sizeof(req), false);
  1269. }
  1270. EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_enable);
  1271. int mt76_connac_mcu_chip_config(struct mt76_dev *dev)
  1272. {
  1273. struct {
  1274. __le16 id;
  1275. u8 type;
  1276. u8 resp_type;
  1277. __le16 data_size;
  1278. __le16 resv;
  1279. u8 data[320];
  1280. } req = {
  1281. .resp_type = 0,
  1282. };
  1283. memcpy(req.data, "assert", 7);
  1284. return mt76_mcu_send_msg(dev, MCU_CMD_CHIP_CONFIG, &req, sizeof(req),
  1285. false);
  1286. }
  1287. EXPORT_SYMBOL_GPL(mt76_connac_mcu_chip_config);
  1288. void mt76_connac_mcu_coredump_event(struct mt76_dev *dev, struct sk_buff *skb,
  1289. struct mt76_connac_coredump *coredump)
  1290. {
  1291. spin_lock_bh(&dev->lock);
  1292. __skb_queue_tail(&coredump->msg_list, skb);
  1293. spin_unlock_bh(&dev->lock);
  1294. coredump->last_activity = jiffies;
  1295. queue_delayed_work(dev->wq, &coredump->work,
  1296. MT76_CONNAC_COREDUMP_TIMEOUT);
  1297. }
  1298. EXPORT_SYMBOL_GPL(mt76_connac_mcu_coredump_event);
  1299. #ifdef CONFIG_PM
  1300. const struct wiphy_wowlan_support mt76_connac_wowlan_support = {
  1301. .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT |
  1302. WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | WIPHY_WOWLAN_NET_DETECT,
  1303. .n_patterns = 1,
  1304. .pattern_min_len = 1,
  1305. .pattern_max_len = MT76_CONNAC_WOW_PATTEN_MAX_LEN,
  1306. .max_nd_match_sets = 10,
  1307. };
  1308. EXPORT_SYMBOL_GPL(mt76_connac_wowlan_support);
  1309. static void
  1310. mt76_connac_mcu_key_iter(struct ieee80211_hw *hw,
  1311. struct ieee80211_vif *vif,
  1312. struct ieee80211_sta *sta,
  1313. struct ieee80211_key_conf *key,
  1314. void *data)
  1315. {
  1316. struct mt76_connac_gtk_rekey_tlv *gtk_tlv = data;
  1317. u32 cipher;
  1318. if (key->cipher != WLAN_CIPHER_SUITE_AES_CMAC &&
  1319. key->cipher != WLAN_CIPHER_SUITE_CCMP &&
  1320. key->cipher != WLAN_CIPHER_SUITE_TKIP)
  1321. return;
  1322. if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
  1323. gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_1);
  1324. cipher = BIT(3);
  1325. } else {
  1326. gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_2);
  1327. cipher = BIT(4);
  1328. }
  1329. /* we are assuming here to have a single pairwise key */
  1330. if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
  1331. gtk_tlv->pairwise_cipher = cpu_to_le32(cipher);
  1332. gtk_tlv->group_cipher = cpu_to_le32(cipher);
  1333. gtk_tlv->keyid = key->keyidx;
  1334. }
  1335. }
  1336. int mt76_connac_mcu_update_gtk_rekey(struct ieee80211_hw *hw,
  1337. struct ieee80211_vif *vif,
  1338. struct cfg80211_gtk_rekey_data *key)
  1339. {
  1340. struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
  1341. struct mt76_connac_gtk_rekey_tlv *gtk_tlv;
  1342. struct mt76_phy *phy = hw->priv;
  1343. struct sk_buff *skb;
  1344. struct {
  1345. u8 bss_idx;
  1346. u8 pad[3];
  1347. } __packed hdr = {
  1348. .bss_idx = mvif->idx,
  1349. };
  1350. skb = mt76_mcu_msg_alloc(phy->dev, NULL,
  1351. sizeof(hdr) + sizeof(*gtk_tlv));
  1352. if (!skb)
  1353. return -ENOMEM;
  1354. skb_put_data(skb, &hdr, sizeof(hdr));
  1355. gtk_tlv = (struct mt76_connac_gtk_rekey_tlv *)skb_put(skb,
  1356. sizeof(*gtk_tlv));
  1357. gtk_tlv->tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_GTK_REKEY);
  1358. gtk_tlv->len = cpu_to_le16(sizeof(*gtk_tlv));
  1359. gtk_tlv->rekey_mode = 2;
  1360. gtk_tlv->option = 1;
  1361. rcu_read_lock();
  1362. ieee80211_iter_keys_rcu(hw, vif, mt76_connac_mcu_key_iter, gtk_tlv);
  1363. rcu_read_unlock();
  1364. memcpy(gtk_tlv->kek, key->kek, NL80211_KEK_LEN);
  1365. memcpy(gtk_tlv->kck, key->kck, NL80211_KCK_LEN);
  1366. memcpy(gtk_tlv->replay_ctr, key->replay_ctr, NL80211_REPLAY_CTR_LEN);
  1367. return mt76_mcu_skb_send_msg(phy->dev, skb, MCU_UNI_CMD_OFFLOAD, true);
  1368. }
  1369. EXPORT_SYMBOL_GPL(mt76_connac_mcu_update_gtk_rekey);
  1370. static int
  1371. mt76_connac_mcu_set_arp_filter(struct mt76_dev *dev, struct ieee80211_vif *vif,
  1372. bool suspend)
  1373. {
  1374. struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
  1375. struct {
  1376. struct {
  1377. u8 bss_idx;
  1378. u8 pad[3];
  1379. } __packed hdr;
  1380. struct mt76_connac_arpns_tlv arpns;
  1381. } req = {
  1382. .hdr = {
  1383. .bss_idx = mvif->idx,
  1384. },
  1385. .arpns = {
  1386. .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP),
  1387. .len = cpu_to_le16(sizeof(struct mt76_connac_arpns_tlv)),
  1388. .mode = suspend,
  1389. },
  1390. };
  1391. return mt76_mcu_send_msg(dev, MCU_UNI_CMD_OFFLOAD, &req, sizeof(req),
  1392. true);
  1393. }
  1394. static int
  1395. mt76_connac_mcu_set_gtk_rekey(struct mt76_dev *dev, struct ieee80211_vif *vif,
  1396. bool suspend)
  1397. {
  1398. struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
  1399. struct {
  1400. struct {
  1401. u8 bss_idx;
  1402. u8 pad[3];
  1403. } __packed hdr;
  1404. struct mt76_connac_gtk_rekey_tlv gtk_tlv;
  1405. } __packed req = {
  1406. .hdr = {
  1407. .bss_idx = mvif->idx,
  1408. },
  1409. .gtk_tlv = {
  1410. .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_GTK_REKEY),
  1411. .len = cpu_to_le16(sizeof(struct mt76_connac_gtk_rekey_tlv)),
  1412. .rekey_mode = !suspend,
  1413. },
  1414. };
  1415. return mt76_mcu_send_msg(dev, MCU_UNI_CMD_OFFLOAD, &req, sizeof(req),
  1416. true);
  1417. }
  1418. static int
  1419. mt76_connac_mcu_set_suspend_mode(struct mt76_dev *dev,
  1420. struct ieee80211_vif *vif,
  1421. bool enable, u8 mdtim,
  1422. bool wow_suspend)
  1423. {
  1424. struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
  1425. struct {
  1426. struct {
  1427. u8 bss_idx;
  1428. u8 pad[3];
  1429. } __packed hdr;
  1430. struct mt76_connac_suspend_tlv suspend_tlv;
  1431. } req = {
  1432. .hdr = {
  1433. .bss_idx = mvif->idx,
  1434. },
  1435. .suspend_tlv = {
  1436. .tag = cpu_to_le16(UNI_SUSPEND_MODE_SETTING),
  1437. .len = cpu_to_le16(sizeof(struct mt76_connac_suspend_tlv)),
  1438. .enable = enable,
  1439. .mdtim = mdtim,
  1440. .wow_suspend = wow_suspend,
  1441. },
  1442. };
  1443. return mt76_mcu_send_msg(dev, MCU_UNI_CMD_SUSPEND, &req, sizeof(req),
  1444. true);
  1445. }
  1446. static int
  1447. mt76_connac_mcu_set_wow_pattern(struct mt76_dev *dev,
  1448. struct ieee80211_vif *vif,
  1449. u8 index, bool enable,
  1450. struct cfg80211_pkt_pattern *pattern)
  1451. {
  1452. struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
  1453. struct mt76_connac_wow_pattern_tlv *ptlv;
  1454. struct sk_buff *skb;
  1455. struct req_hdr {
  1456. u8 bss_idx;
  1457. u8 pad[3];
  1458. } __packed hdr = {
  1459. .bss_idx = mvif->idx,
  1460. };
  1461. skb = mt76_mcu_msg_alloc(dev, NULL, sizeof(hdr) + sizeof(*ptlv));
  1462. if (!skb)
  1463. return -ENOMEM;
  1464. skb_put_data(skb, &hdr, sizeof(hdr));
  1465. ptlv = (struct mt76_connac_wow_pattern_tlv *)skb_put(skb, sizeof(*ptlv));
  1466. ptlv->tag = cpu_to_le16(UNI_SUSPEND_WOW_PATTERN);
  1467. ptlv->len = cpu_to_le16(sizeof(*ptlv));
  1468. ptlv->data_len = pattern->pattern_len;
  1469. ptlv->enable = enable;
  1470. ptlv->index = index;
  1471. memcpy(ptlv->pattern, pattern->pattern, pattern->pattern_len);
  1472. memcpy(ptlv->mask, pattern->mask, pattern->pattern_len / 8);
  1473. return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD_SUSPEND, true);
  1474. }
  1475. static int
  1476. mt76_connac_mcu_set_wow_ctrl(struct mt76_phy *phy, struct ieee80211_vif *vif,
  1477. bool suspend, struct cfg80211_wowlan *wowlan)
  1478. {
  1479. struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
  1480. struct mt76_dev *dev = phy->dev;
  1481. struct {
  1482. struct {
  1483. u8 bss_idx;
  1484. u8 pad[3];
  1485. } __packed hdr;
  1486. struct mt76_connac_wow_ctrl_tlv wow_ctrl_tlv;
  1487. struct mt76_connac_wow_gpio_param_tlv gpio_tlv;
  1488. } req = {
  1489. .hdr = {
  1490. .bss_idx = mvif->idx,
  1491. },
  1492. .wow_ctrl_tlv = {
  1493. .tag = cpu_to_le16(UNI_SUSPEND_WOW_CTRL),
  1494. .len = cpu_to_le16(sizeof(struct mt76_connac_wow_ctrl_tlv)),
  1495. .cmd = suspend ? 1 : 2,
  1496. },
  1497. .gpio_tlv = {
  1498. .tag = cpu_to_le16(UNI_SUSPEND_WOW_GPIO_PARAM),
  1499. .len = cpu_to_le16(sizeof(struct mt76_connac_wow_gpio_param_tlv)),
  1500. .gpio_pin = 0xff, /* follow fw about GPIO pin */
  1501. },
  1502. };
  1503. if (wowlan->magic_pkt)
  1504. req.wow_ctrl_tlv.trigger |= BIT(0);
  1505. if (wowlan->disconnect)
  1506. req.wow_ctrl_tlv.trigger |= BIT(2);
  1507. if (wowlan->nd_config) {
  1508. mt76_connac_mcu_sched_scan_req(phy, vif, wowlan->nd_config);
  1509. req.wow_ctrl_tlv.trigger |= BIT(5);
  1510. mt76_connac_mcu_sched_scan_enable(phy, vif, suspend);
  1511. }
  1512. if (mt76_is_mmio(dev))
  1513. req.wow_ctrl_tlv.wakeup_hif = WOW_PCIE;
  1514. else if (mt76_is_usb(dev))
  1515. req.wow_ctrl_tlv.wakeup_hif = WOW_USB;
  1516. else if (mt76_is_sdio(dev))
  1517. req.wow_ctrl_tlv.wakeup_hif = WOW_GPIO;
  1518. return mt76_mcu_send_msg(dev, MCU_UNI_CMD_SUSPEND, &req, sizeof(req),
  1519. true);
  1520. }
  1521. int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend)
  1522. {
  1523. struct {
  1524. struct {
  1525. u8 hif_type; /* 0x0: HIF_SDIO
  1526. * 0x1: HIF_USB
  1527. * 0x2: HIF_PCIE
  1528. */
  1529. u8 pad[3];
  1530. } __packed hdr;
  1531. struct hif_suspend_tlv {
  1532. __le16 tag;
  1533. __le16 len;
  1534. u8 suspend;
  1535. } __packed hif_suspend;
  1536. } req = {
  1537. .hif_suspend = {
  1538. .tag = cpu_to_le16(0), /* 0: UNI_HIF_CTRL_BASIC */
  1539. .len = cpu_to_le16(sizeof(struct hif_suspend_tlv)),
  1540. .suspend = suspend,
  1541. },
  1542. };
  1543. if (mt76_is_mmio(dev))
  1544. req.hdr.hif_type = 2;
  1545. else if (mt76_is_usb(dev))
  1546. req.hdr.hif_type = 1;
  1547. else if (mt76_is_sdio(dev))
  1548. req.hdr.hif_type = 0;
  1549. return mt76_mcu_send_msg(dev, MCU_UNI_CMD_HIF_CTRL, &req, sizeof(req),
  1550. true);
  1551. }
  1552. EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_hif_suspend);
  1553. void mt76_connac_mcu_set_suspend_iter(void *priv, u8 *mac,
  1554. struct ieee80211_vif *vif)
  1555. {
  1556. struct mt76_phy *phy = priv;
  1557. bool suspend = test_bit(MT76_STATE_SUSPEND, &phy->state);
  1558. struct ieee80211_hw *hw = phy->hw;
  1559. struct cfg80211_wowlan *wowlan = hw->wiphy->wowlan_config;
  1560. int i;
  1561. mt76_connac_mcu_set_gtk_rekey(phy->dev, vif, suspend);
  1562. mt76_connac_mcu_set_arp_filter(phy->dev, vif, suspend);
  1563. mt76_connac_mcu_set_suspend_mode(phy->dev, vif, suspend, 1, true);
  1564. for (i = 0; i < wowlan->n_patterns; i++)
  1565. mt76_connac_mcu_set_wow_pattern(phy->dev, vif, i, suspend,
  1566. &wowlan->patterns[i]);
  1567. mt76_connac_mcu_set_wow_ctrl(phy, vif, suspend, wowlan);
  1568. }
  1569. EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_suspend_iter);
  1570. #endif /* CONFIG_PM */
  1571. MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
  1572. MODULE_LICENSE("Dual BSD/GPL");