0002-wifi.patch 87 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520
  1. From e963d9406f7c618d9210c45a901b284cf07c8379 Mon Sep 17 00:00:00 2001
  2. From: Tsuchiya Yuto <kitakar@gmail.com>
  3. Date: Mon, 28 Sep 2020 17:46:49 +0900
  4. Subject: [PATCH] mwifiex: pcie: add DMI-based quirk impl for Surface devices
  5. This commit adds quirk implementation based on DMI matching with DMI
  6. table for Surface devices.
  7. This implementation can be used for quirks later.
  8. Signed-off-by: Tsuchiya Yuto <kitakar@gmail.com>
  9. Patchset: wifi
  10. ---
  11. drivers/net/wireless/marvell/mwifiex/Makefile | 1 +
  12. drivers/net/wireless/marvell/mwifiex/pcie.c | 4 +
  13. drivers/net/wireless/marvell/mwifiex/pcie.h | 1 +
  14. .../wireless/marvell/mwifiex/pcie_quirks.c | 114 ++++++++++++++++++
  15. .../wireless/marvell/mwifiex/pcie_quirks.h | 11 ++
  16. 5 files changed, 131 insertions(+)
  17. create mode 100644 drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
  18. create mode 100644 drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
  19. diff --git a/drivers/net/wireless/marvell/mwifiex/Makefile b/drivers/net/wireless/marvell/mwifiex/Makefile
  20. index fdfd9bf15ed4..8a1e7c5b9c6e 100644
  21. --- a/drivers/net/wireless/marvell/mwifiex/Makefile
  22. +++ b/drivers/net/wireless/marvell/mwifiex/Makefile
  23. @@ -49,6 +49,7 @@ mwifiex_sdio-y += sdio.o
  24. obj-$(CONFIG_MWIFIEX_SDIO) += mwifiex_sdio.o
  25. mwifiex_pcie-y += pcie.o
  26. +mwifiex_pcie-y += pcie_quirks.o
  27. obj-$(CONFIG_MWIFIEX_PCIE) += mwifiex_pcie.o
  28. mwifiex_usb-y += usb.o
  29. diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
  30. index b2de8d03c5fa..4c375ad6a078 100644
  31. --- a/drivers/net/wireless/marvell/mwifiex/pcie.c
  32. +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
  33. @@ -27,6 +27,7 @@
  34. #include "wmm.h"
  35. #include "11n.h"
  36. #include "pcie.h"
  37. +#include "pcie_quirks.h"
  38. #define PCIE_VERSION "1.0"
  39. #define DRV_NAME "Marvell mwifiex PCIe"
  40. @@ -410,6 +411,9 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
  41. return ret;
  42. }
  43. + /* check quirks */
  44. + mwifiex_initialize_quirks(card);
  45. +
  46. if (mwifiex_add_card(card, &card->fw_done, &pcie_ops,
  47. MWIFIEX_PCIE, &pdev->dev)) {
  48. pr_err("%s failed\n", __func__);
  49. diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.h b/drivers/net/wireless/marvell/mwifiex/pcie.h
  50. index 5ed613d65709..981e330c77d7 100644
  51. --- a/drivers/net/wireless/marvell/mwifiex/pcie.h
  52. +++ b/drivers/net/wireless/marvell/mwifiex/pcie.h
  53. @@ -244,6 +244,7 @@ struct pcie_service_card {
  54. unsigned long work_flags;
  55. bool pci_reset_ongoing;
  56. + unsigned long quirks;
  57. };
  58. static inline int
  59. diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
  60. new file mode 100644
  61. index 000000000000..929aee2b0a60
  62. --- /dev/null
  63. +++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
  64. @@ -0,0 +1,114 @@
  65. +// SPDX-License-Identifier: GPL-2.0
  66. +/*
  67. + * File for PCIe quirks.
  68. + */
  69. +
  70. +/* The low-level PCI operations will be performed in this file. Therefore,
  71. + * let's use dev_*() instead of mwifiex_dbg() here to avoid troubles (e.g.
  72. + * to avoid using mwifiex_adapter struct before init or wifi is powered
  73. + * down, or causes NULL ptr deref).
  74. + */
  75. +
  76. +#include <linux/dmi.h>
  77. +
  78. +#include "pcie_quirks.h"
  79. +
  80. +/* quirk table based on DMI matching */
  81. +static const struct dmi_system_id mwifiex_quirk_table[] = {
  82. + {
  83. + .ident = "Surface Pro 4",
  84. + .matches = {
  85. + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  86. + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 4"),
  87. + },
  88. + .driver_data = 0,
  89. + },
  90. + {
  91. + .ident = "Surface Pro 5",
  92. + .matches = {
  93. + /* match for SKU here due to generic product name "Surface Pro" */
  94. + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  95. + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1796"),
  96. + },
  97. + .driver_data = 0,
  98. + },
  99. + {
  100. + .ident = "Surface Pro 5 (LTE)",
  101. + .matches = {
  102. + /* match for SKU here due to generic product name "Surface Pro" */
  103. + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  104. + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1807"),
  105. + },
  106. + .driver_data = 0,
  107. + },
  108. + {
  109. + .ident = "Surface Pro 6",
  110. + .matches = {
  111. + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  112. + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 6"),
  113. + },
  114. + .driver_data = 0,
  115. + },
  116. + {
  117. + .ident = "Surface Book 1",
  118. + .matches = {
  119. + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  120. + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book"),
  121. + },
  122. + .driver_data = 0,
  123. + },
  124. + {
  125. + .ident = "Surface Book 2",
  126. + .matches = {
  127. + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  128. + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book 2"),
  129. + },
  130. + .driver_data = 0,
  131. + },
  132. + {
  133. + .ident = "Surface Laptop 1",
  134. + .matches = {
  135. + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  136. + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop"),
  137. + },
  138. + .driver_data = 0,
  139. + },
  140. + {
  141. + .ident = "Surface Laptop 2",
  142. + .matches = {
  143. + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  144. + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop 2"),
  145. + },
  146. + .driver_data = 0,
  147. + },
  148. + {
  149. + .ident = "Surface 3",
  150. + .matches = {
  151. + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  152. + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface 3"),
  153. + },
  154. + .driver_data = 0,
  155. + },
  156. + {
  157. + .ident = "Surface Pro 3",
  158. + .matches = {
  159. + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  160. + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 3"),
  161. + },
  162. + .driver_data = 0,
  163. + },
  164. + {}
  165. +};
  166. +
  167. +void mwifiex_initialize_quirks(struct pcie_service_card *card)
  168. +{
  169. + struct pci_dev *pdev = card->dev;
  170. + const struct dmi_system_id *dmi_id;
  171. +
  172. + dmi_id = dmi_first_match(mwifiex_quirk_table);
  173. + if (dmi_id)
  174. + card->quirks = (uintptr_t)dmi_id->driver_data;
  175. +
  176. + if (!card->quirks)
  177. + dev_info(&pdev->dev, "no quirks enabled\n");
  178. +}
  179. diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
  180. new file mode 100644
  181. index 000000000000..5326ae7e5671
  182. --- /dev/null
  183. +++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
  184. @@ -0,0 +1,11 @@
  185. +/* SPDX-License-Identifier: GPL-2.0 */
  186. +/*
  187. + * Header file for PCIe quirks.
  188. + */
  189. +
  190. +#include "pcie.h"
  191. +
  192. +/* quirks */
  193. +// quirk flags can be added here
  194. +
  195. +void mwifiex_initialize_quirks(struct pcie_service_card *card);
  196. --
  197. 2.33.0
  198. From 6d8f2fa840634998f2baf1a9ab17dbc175e80d54 Mon Sep 17 00:00:00 2001
  199. From: Tsuchiya Yuto <kitakar@gmail.com>
  200. Date: Tue, 29 Sep 2020 17:25:22 +0900
  201. Subject: [PATCH] mwifiex: pcie: add reset_d3cold quirk for Surface gen4+
  202. devices
  203. To reset mwifiex on Surface gen4+ (Pro 4 or later gen) devices, it
  204. seems that putting the wifi device into D3cold is required according
  205. to errata.inf file on Windows installation (Windows/INF/errata.inf).
  206. This patch adds a function that performs power-cycle (put into D3cold
  207. then D0) and call the function at the end of reset_prepare().
  208. Note: Need to also reset the parent device (bridge) of wifi on SB1;
  209. it might be because the bridge of wifi always reports it's in D3hot.
  210. When I tried to reset only the wifi device (not touching parent), it gave
  211. the following error and the reset failed:
  212. acpi device:4b: Cannot transition to power state D0 for parent in D3hot
  213. mwifiex_pcie 0000:03:00.0: can't change power state from D3cold to D0 (config space inaccessible)
  214. Signed-off-by: Tsuchiya Yuto <kitakar@gmail.com>
  215. Patchset: wifi
  216. ---
  217. drivers/net/wireless/marvell/mwifiex/pcie.c | 7 ++
  218. .../wireless/marvell/mwifiex/pcie_quirks.c | 73 +++++++++++++++++--
  219. .../wireless/marvell/mwifiex/pcie_quirks.h | 3 +-
  220. 3 files changed, 74 insertions(+), 9 deletions(-)
  221. diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
  222. index 4c375ad6a078..ccb4b54c9067 100644
  223. --- a/drivers/net/wireless/marvell/mwifiex/pcie.c
  224. +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
  225. @@ -529,6 +529,13 @@ static void mwifiex_pcie_reset_prepare(struct pci_dev *pdev)
  226. mwifiex_shutdown_sw(adapter);
  227. clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags);
  228. clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags);
  229. +
  230. + /* For Surface gen4+ devices, we need to put wifi into D3cold right
  231. + * before performing FLR
  232. + */
  233. + if (card->quirks & QUIRK_FW_RST_D3COLD)
  234. + mwifiex_pcie_reset_d3cold_quirk(pdev);
  235. +
  236. mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
  237. card->pci_reset_ongoing = true;
  238. diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
  239. index 929aee2b0a60..edc739c542fe 100644
  240. --- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
  241. +++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
  242. @@ -21,7 +21,7 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  243. DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  244. DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 4"),
  245. },
  246. - .driver_data = 0,
  247. + .driver_data = (void *)QUIRK_FW_RST_D3COLD,
  248. },
  249. {
  250. .ident = "Surface Pro 5",
  251. @@ -30,7 +30,7 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  252. DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  253. DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1796"),
  254. },
  255. - .driver_data = 0,
  256. + .driver_data = (void *)QUIRK_FW_RST_D3COLD,
  257. },
  258. {
  259. .ident = "Surface Pro 5 (LTE)",
  260. @@ -39,7 +39,7 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  261. DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  262. DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1807"),
  263. },
  264. - .driver_data = 0,
  265. + .driver_data = (void *)QUIRK_FW_RST_D3COLD,
  266. },
  267. {
  268. .ident = "Surface Pro 6",
  269. @@ -47,7 +47,7 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  270. DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  271. DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 6"),
  272. },
  273. - .driver_data = 0,
  274. + .driver_data = (void *)QUIRK_FW_RST_D3COLD,
  275. },
  276. {
  277. .ident = "Surface Book 1",
  278. @@ -55,7 +55,7 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  279. DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  280. DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book"),
  281. },
  282. - .driver_data = 0,
  283. + .driver_data = (void *)QUIRK_FW_RST_D3COLD,
  284. },
  285. {
  286. .ident = "Surface Book 2",
  287. @@ -63,7 +63,7 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  288. DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  289. DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book 2"),
  290. },
  291. - .driver_data = 0,
  292. + .driver_data = (void *)QUIRK_FW_RST_D3COLD,
  293. },
  294. {
  295. .ident = "Surface Laptop 1",
  296. @@ -71,7 +71,7 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  297. DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  298. DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop"),
  299. },
  300. - .driver_data = 0,
  301. + .driver_data = (void *)QUIRK_FW_RST_D3COLD,
  302. },
  303. {
  304. .ident = "Surface Laptop 2",
  305. @@ -79,7 +79,7 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  306. DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  307. DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop 2"),
  308. },
  309. - .driver_data = 0,
  310. + .driver_data = (void *)QUIRK_FW_RST_D3COLD,
  311. },
  312. {
  313. .ident = "Surface 3",
  314. @@ -111,4 +111,61 @@ void mwifiex_initialize_quirks(struct pcie_service_card *card)
  315. if (!card->quirks)
  316. dev_info(&pdev->dev, "no quirks enabled\n");
  317. + if (card->quirks & QUIRK_FW_RST_D3COLD)
  318. + dev_info(&pdev->dev, "quirk reset_d3cold enabled\n");
  319. +}
  320. +
  321. +static void mwifiex_pcie_set_power_d3cold(struct pci_dev *pdev)
  322. +{
  323. + dev_info(&pdev->dev, "putting into D3cold...\n");
  324. +
  325. + pci_save_state(pdev);
  326. + if (pci_is_enabled(pdev))
  327. + pci_disable_device(pdev);
  328. + pci_set_power_state(pdev, PCI_D3cold);
  329. +}
  330. +
  331. +static int mwifiex_pcie_set_power_d0(struct pci_dev *pdev)
  332. +{
  333. + int ret;
  334. +
  335. + dev_info(&pdev->dev, "putting into D0...\n");
  336. +
  337. + pci_set_power_state(pdev, PCI_D0);
  338. + ret = pci_enable_device(pdev);
  339. + if (ret) {
  340. + dev_err(&pdev->dev, "pci_enable_device failed\n");
  341. + return ret;
  342. + }
  343. + pci_restore_state(pdev);
  344. +
  345. + return 0;
  346. +}
  347. +
  348. +int mwifiex_pcie_reset_d3cold_quirk(struct pci_dev *pdev)
  349. +{
  350. + struct pci_dev *parent_pdev = pci_upstream_bridge(pdev);
  351. + int ret;
  352. +
  353. + /* Power-cycle (put into D3cold then D0) */
  354. + dev_info(&pdev->dev, "Using reset_d3cold quirk to perform FW reset\n");
  355. +
  356. + /* We need to perform power-cycle also for bridge of wifi because
  357. + * on some devices (e.g. Surface Book 1), the OS for some reasons
  358. + * can't know the real power state of the bridge.
  359. + * When tried to power-cycle only wifi, the reset failed with the
  360. + * following dmesg log:
  361. + * "Cannot transition to power state D0 for parent in D3hot".
  362. + */
  363. + mwifiex_pcie_set_power_d3cold(pdev);
  364. + mwifiex_pcie_set_power_d3cold(parent_pdev);
  365. +
  366. + ret = mwifiex_pcie_set_power_d0(parent_pdev);
  367. + if (ret)
  368. + return ret;
  369. + ret = mwifiex_pcie_set_power_d0(pdev);
  370. + if (ret)
  371. + return ret;
  372. +
  373. + return 0;
  374. }
  375. diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
  376. index 5326ae7e5671..8b9dcb5070d8 100644
  377. --- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
  378. +++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
  379. @@ -6,6 +6,7 @@
  380. #include "pcie.h"
  381. /* quirks */
  382. -// quirk flags can be added here
  383. +#define QUIRK_FW_RST_D3COLD BIT(0)
  384. void mwifiex_initialize_quirks(struct pcie_service_card *card);
  385. +int mwifiex_pcie_reset_d3cold_quirk(struct pci_dev *pdev);
  386. --
  387. 2.33.0
  388. From eeb7f040697ceefc7b98f09fb0d3918bd82bcd02 Mon Sep 17 00:00:00 2001
  389. From: Tsuchiya Yuto <kitakar@gmail.com>
  390. Date: Tue, 29 Sep 2020 17:32:22 +0900
  391. Subject: [PATCH] mwifiex: pcie: add reset_wsid quirk for Surface 3
  392. This commit adds reset_wsid quirk and uses this quirk for Surface 3 on
  393. card reset.
  394. To reset mwifiex on Surface 3, it seems that calling the _DSM method
  395. exists in \_SB.WSID [1] device is required.
  396. On Surface 3, calling the _DSM method removes/re-probes the card by
  397. itself. So, need to place the reset function before performing FLR and
  398. skip performing any other reset-related works.
  399. Note that Surface Pro 3 also has the WSID device [2], but it seems to need
  400. more work. This commit only supports Surface 3 yet.
  401. [1] https://github.com/linux-surface/acpidumps/blob/05cba925f3a515f222acb5b3551a032ddde958fe/surface_3/dsdt.dsl#L11947-L12011
  402. [2] https://github.com/linux-surface/acpidumps/blob/05cba925f3a515f222acb5b3551a032ddde958fe/surface_pro_3/dsdt.dsl#L12164-L12216
  403. Signed-off-by: Tsuchiya Yuto <kitakar@gmail.com>
  404. Patchset: wifi
  405. ---
  406. drivers/net/wireless/marvell/mwifiex/pcie.c | 10 +++
  407. .../wireless/marvell/mwifiex/pcie_quirks.c | 77 ++++++++++++++++++-
  408. .../wireless/marvell/mwifiex/pcie_quirks.h | 5 ++
  409. 3 files changed, 91 insertions(+), 1 deletion(-)
  410. diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
  411. index ccb4b54c9067..8d5cc3c1cf38 100644
  412. --- a/drivers/net/wireless/marvell/mwifiex/pcie.c
  413. +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
  414. @@ -2968,6 +2968,16 @@ static void mwifiex_pcie_card_reset_work(struct mwifiex_adapter *adapter)
  415. {
  416. struct pcie_service_card *card = adapter->card;
  417. + /* On Surface 3, reset_wsid method removes then re-probes card by
  418. + * itself. So, need to place it here and skip performing any other
  419. + * reset-related works.
  420. + */
  421. + if (card->quirks & QUIRK_FW_RST_WSID_S3) {
  422. + mwifiex_pcie_reset_wsid_quirk(card->dev);
  423. + /* skip performing any other reset-related works */
  424. + return;
  425. + }
  426. +
  427. /* We can't afford to wait here; remove() might be waiting on us. If we
  428. * can't grab the device lock, maybe we'll get another chance later.
  429. */
  430. diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
  431. index edc739c542fe..f0a6fa0a7ae5 100644
  432. --- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
  433. +++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
  434. @@ -9,10 +9,21 @@
  435. * down, or causes NULL ptr deref).
  436. */
  437. +#include <linux/acpi.h>
  438. #include <linux/dmi.h>
  439. #include "pcie_quirks.h"
  440. +/* For reset_wsid quirk */
  441. +#define ACPI_WSID_PATH "\\_SB.WSID"
  442. +#define WSID_REV 0x0
  443. +#define WSID_FUNC_WIFI_PWR_OFF 0x1
  444. +#define WSID_FUNC_WIFI_PWR_ON 0x2
  445. +/* WSID _DSM UUID: "534ea3bf-fcc2-4e7a-908f-a13978f0c7ef" */
  446. +static const guid_t wsid_dsm_guid =
  447. + GUID_INIT(0x534ea3bf, 0xfcc2, 0x4e7a,
  448. + 0x90, 0x8f, 0xa1, 0x39, 0x78, 0xf0, 0xc7, 0xef);
  449. +
  450. /* quirk table based on DMI matching */
  451. static const struct dmi_system_id mwifiex_quirk_table[] = {
  452. {
  453. @@ -87,7 +98,7 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  454. DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  455. DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface 3"),
  456. },
  457. - .driver_data = 0,
  458. + .driver_data = (void *)QUIRK_FW_RST_WSID_S3,
  459. },
  460. {
  461. .ident = "Surface Pro 3",
  462. @@ -113,6 +124,9 @@ void mwifiex_initialize_quirks(struct pcie_service_card *card)
  463. dev_info(&pdev->dev, "no quirks enabled\n");
  464. if (card->quirks & QUIRK_FW_RST_D3COLD)
  465. dev_info(&pdev->dev, "quirk reset_d3cold enabled\n");
  466. + if (card->quirks & QUIRK_FW_RST_WSID_S3)
  467. + dev_info(&pdev->dev,
  468. + "quirk reset_wsid for Surface 3 enabled\n");
  469. }
  470. static void mwifiex_pcie_set_power_d3cold(struct pci_dev *pdev)
  471. @@ -169,3 +183,64 @@ int mwifiex_pcie_reset_d3cold_quirk(struct pci_dev *pdev)
  472. return 0;
  473. }
  474. +
  475. +int mwifiex_pcie_reset_wsid_quirk(struct pci_dev *pdev)
  476. +{
  477. + acpi_handle handle;
  478. + union acpi_object *obj;
  479. + acpi_status status;
  480. +
  481. + dev_info(&pdev->dev, "Using reset_wsid quirk to perform FW reset\n");
  482. +
  483. + status = acpi_get_handle(NULL, ACPI_WSID_PATH, &handle);
  484. + if (ACPI_FAILURE(status)) {
  485. + dev_err(&pdev->dev, "No ACPI handle for path %s\n",
  486. + ACPI_WSID_PATH);
  487. + return -ENODEV;
  488. + }
  489. +
  490. + if (!acpi_has_method(handle, "_DSM")) {
  491. + dev_err(&pdev->dev, "_DSM method not found\n");
  492. + return -ENODEV;
  493. + }
  494. +
  495. + if (!acpi_check_dsm(handle, &wsid_dsm_guid,
  496. + WSID_REV, WSID_FUNC_WIFI_PWR_OFF)) {
  497. + dev_err(&pdev->dev,
  498. + "_DSM method doesn't support wifi power off func\n");
  499. + return -ENODEV;
  500. + }
  501. +
  502. + if (!acpi_check_dsm(handle, &wsid_dsm_guid,
  503. + WSID_REV, WSID_FUNC_WIFI_PWR_ON)) {
  504. + dev_err(&pdev->dev,
  505. + "_DSM method doesn't support wifi power on func\n");
  506. + return -ENODEV;
  507. + }
  508. +
  509. + /* card will be removed immediately after this call on Surface 3 */
  510. + dev_info(&pdev->dev, "turning wifi off...\n");
  511. + obj = acpi_evaluate_dsm(handle, &wsid_dsm_guid,
  512. + WSID_REV, WSID_FUNC_WIFI_PWR_OFF,
  513. + NULL);
  514. + if (!obj) {
  515. + dev_err(&pdev->dev,
  516. + "device _DSM execution failed for turning wifi off\n");
  517. + return -EIO;
  518. + }
  519. + ACPI_FREE(obj);
  520. +
  521. + /* card will be re-probed immediately after this call on Surface 3 */
  522. + dev_info(&pdev->dev, "turning wifi on...\n");
  523. + obj = acpi_evaluate_dsm(handle, &wsid_dsm_guid,
  524. + WSID_REV, WSID_FUNC_WIFI_PWR_ON,
  525. + NULL);
  526. + if (!obj) {
  527. + dev_err(&pdev->dev,
  528. + "device _DSM execution failed for turning wifi on\n");
  529. + return -EIO;
  530. + }
  531. + ACPI_FREE(obj);
  532. +
  533. + return 0;
  534. +}
  535. diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
  536. index 8b9dcb5070d8..3ef7440418e3 100644
  537. --- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
  538. +++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
  539. @@ -7,6 +7,11 @@
  540. /* quirks */
  541. #define QUIRK_FW_RST_D3COLD BIT(0)
  542. +/* Surface 3 and Surface Pro 3 have the same _DSM method but need to
  543. + * be handled differently. Currently, only S3 is supported.
  544. + */
  545. +#define QUIRK_FW_RST_WSID_S3 BIT(1)
  546. void mwifiex_initialize_quirks(struct pcie_service_card *card);
  547. int mwifiex_pcie_reset_d3cold_quirk(struct pci_dev *pdev);
  548. +int mwifiex_pcie_reset_wsid_quirk(struct pci_dev *pdev);
  549. --
  550. 2.33.0
  551. From 6e4d13d95aa201fbb6b307b67b7620f7c0c58111 Mon Sep 17 00:00:00 2001
  552. From: Tsuchiya Yuto <kitakar@gmail.com>
  553. Date: Wed, 30 Sep 2020 18:08:24 +0900
  554. Subject: [PATCH] mwifiex: pcie: (OEMB) add quirk for Surface 3 with broken DMI
  555. table
  556. (made referring to http://git.osdn.net/view?p=android-x86/kernel.git;a=commitdiff;h=18e2e857c57633b25b3b4120f212224a108cd883)
  557. On some Surface 3, the DMI table gets corrupted for unknown reasons
  558. and breaks existing DMI matching used for device-specific quirks.
  559. This commit adds the (broken) DMI info for the affected Surface 3.
  560. On affected systems, DMI info will look like this:
  561. $ grep . /sys/devices/virtual/dmi/id/{bios_vendor,board_name,board_vendor,\
  562. chassis_vendor,product_name,sys_vendor}
  563. /sys/devices/virtual/dmi/id/bios_vendor:American Megatrends Inc.
  564. /sys/devices/virtual/dmi/id/board_name:OEMB
  565. /sys/devices/virtual/dmi/id/board_vendor:OEMB
  566. /sys/devices/virtual/dmi/id/chassis_vendor:OEMB
  567. /sys/devices/virtual/dmi/id/product_name:OEMB
  568. /sys/devices/virtual/dmi/id/sys_vendor:OEMB
  569. Expected:
  570. $ grep . /sys/devices/virtual/dmi/id/{bios_vendor,board_name,board_vendor,\
  571. chassis_vendor,product_name,sys_vendor}
  572. /sys/devices/virtual/dmi/id/bios_vendor:American Megatrends Inc.
  573. /sys/devices/virtual/dmi/id/board_name:Surface 3
  574. /sys/devices/virtual/dmi/id/board_vendor:Microsoft Corporation
  575. /sys/devices/virtual/dmi/id/chassis_vendor:Microsoft Corporation
  576. /sys/devices/virtual/dmi/id/product_name:Surface 3
  577. /sys/devices/virtual/dmi/id/sys_vendor:Microsoft Corporation
  578. Signed-off-by: Tsuchiya Yuto <kitakar@gmail.com>
  579. Patchset: wifi
  580. ---
  581. drivers/net/wireless/marvell/mwifiex/pcie_quirks.c | 9 +++++++++
  582. 1 file changed, 9 insertions(+)
  583. diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
  584. index f0a6fa0a7ae5..34dcd84f02a6 100644
  585. --- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
  586. +++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
  587. @@ -100,6 +100,15 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  588. },
  589. .driver_data = (void *)QUIRK_FW_RST_WSID_S3,
  590. },
  591. + {
  592. + .ident = "Surface 3",
  593. + .matches = {
  594. + DMI_EXACT_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
  595. + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "OEMB"),
  596. + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "OEMB"),
  597. + },
  598. + .driver_data = (void *)QUIRK_FW_RST_WSID_S3,
  599. + },
  600. {
  601. .ident = "Surface Pro 3",
  602. .matches = {
  603. --
  604. 2.33.0
  605. From 172acc5e1534698958af941a22fc8815486b5e4b Mon Sep 17 00:00:00 2001
  606. From: Tsuchiya Yuto <kitakar@gmail.com>
  607. Date: Sun, 4 Oct 2020 00:11:49 +0900
  608. Subject: [PATCH] mwifiex: pcie: disable bridge_d3 for Surface gen4+
  609. Currently, mwifiex fw will crash after suspend on recent kernel series.
  610. On Windows, it seems that the root port of wifi will never enter D3 state
  611. (stay on D0 state). And on Linux, disabling the D3 state for the
  612. bridge fixes fw crashing after suspend.
  613. This commit disables the D3 state of root port on driver initialization
  614. and fixes fw crashing after suspend.
  615. Signed-off-by: Tsuchiya Yuto <kitakar@gmail.com>
  616. Patchset: wifi
  617. ---
  618. drivers/net/wireless/marvell/mwifiex/pcie.c | 7 +++++
  619. .../wireless/marvell/mwifiex/pcie_quirks.c | 27 +++++++++++++------
  620. .../wireless/marvell/mwifiex/pcie_quirks.h | 1 +
  621. 3 files changed, 27 insertions(+), 8 deletions(-)
  622. diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
  623. index 8d5cc3c1cf38..0627a37deac8 100644
  624. --- a/drivers/net/wireless/marvell/mwifiex/pcie.c
  625. +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
  626. @@ -379,6 +379,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
  627. const struct pci_device_id *ent)
  628. {
  629. struct pcie_service_card *card;
  630. + struct pci_dev *parent_pdev = pci_upstream_bridge(pdev);
  631. int ret;
  632. pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
  633. @@ -420,6 +421,12 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
  634. return -1;
  635. }
  636. + /* disable bridge_d3 for Surface gen4+ devices to fix fw crashing
  637. + * after suspend
  638. + */
  639. + if (card->quirks & QUIRK_NO_BRIDGE_D3)
  640. + parent_pdev->bridge_d3 = false;
  641. +
  642. return 0;
  643. }
  644. diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
  645. index 34dcd84f02a6..a2aeb2af907e 100644
  646. --- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
  647. +++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
  648. @@ -32,7 +32,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  649. DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  650. DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 4"),
  651. },
  652. - .driver_data = (void *)QUIRK_FW_RST_D3COLD,
  653. + .driver_data = (void *)(QUIRK_FW_RST_D3COLD |
  654. + QUIRK_NO_BRIDGE_D3),
  655. },
  656. {
  657. .ident = "Surface Pro 5",
  658. @@ -41,7 +42,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  659. DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  660. DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1796"),
  661. },
  662. - .driver_data = (void *)QUIRK_FW_RST_D3COLD,
  663. + .driver_data = (void *)(QUIRK_FW_RST_D3COLD |
  664. + QUIRK_NO_BRIDGE_D3),
  665. },
  666. {
  667. .ident = "Surface Pro 5 (LTE)",
  668. @@ -50,7 +52,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  669. DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  670. DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1807"),
  671. },
  672. - .driver_data = (void *)QUIRK_FW_RST_D3COLD,
  673. + .driver_data = (void *)(QUIRK_FW_RST_D3COLD |
  674. + QUIRK_NO_BRIDGE_D3),
  675. },
  676. {
  677. .ident = "Surface Pro 6",
  678. @@ -58,7 +61,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  679. DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  680. DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 6"),
  681. },
  682. - .driver_data = (void *)QUIRK_FW_RST_D3COLD,
  683. + .driver_data = (void *)(QUIRK_FW_RST_D3COLD |
  684. + QUIRK_NO_BRIDGE_D3),
  685. },
  686. {
  687. .ident = "Surface Book 1",
  688. @@ -66,7 +70,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  689. DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  690. DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book"),
  691. },
  692. - .driver_data = (void *)QUIRK_FW_RST_D3COLD,
  693. + .driver_data = (void *)(QUIRK_FW_RST_D3COLD |
  694. + QUIRK_NO_BRIDGE_D3),
  695. },
  696. {
  697. .ident = "Surface Book 2",
  698. @@ -74,7 +79,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  699. DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  700. DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book 2"),
  701. },
  702. - .driver_data = (void *)QUIRK_FW_RST_D3COLD,
  703. + .driver_data = (void *)(QUIRK_FW_RST_D3COLD |
  704. + QUIRK_NO_BRIDGE_D3),
  705. },
  706. {
  707. .ident = "Surface Laptop 1",
  708. @@ -82,7 +88,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  709. DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  710. DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop"),
  711. },
  712. - .driver_data = (void *)QUIRK_FW_RST_D3COLD,
  713. + .driver_data = (void *)(QUIRK_FW_RST_D3COLD |
  714. + QUIRK_NO_BRIDGE_D3),
  715. },
  716. {
  717. .ident = "Surface Laptop 2",
  718. @@ -90,7 +97,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  719. DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
  720. DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop 2"),
  721. },
  722. - .driver_data = (void *)QUIRK_FW_RST_D3COLD,
  723. + .driver_data = (void *)(QUIRK_FW_RST_D3COLD |
  724. + QUIRK_NO_BRIDGE_D3),
  725. },
  726. {
  727. .ident = "Surface 3",
  728. @@ -136,6 +144,9 @@ void mwifiex_initialize_quirks(struct pcie_service_card *card)
  729. if (card->quirks & QUIRK_FW_RST_WSID_S3)
  730. dev_info(&pdev->dev,
  731. "quirk reset_wsid for Surface 3 enabled\n");
  732. + if (card->quirks & QUIRK_NO_BRIDGE_D3)
  733. + dev_info(&pdev->dev,
  734. + "quirk no_brigde_d3 enabled\n");
  735. }
  736. static void mwifiex_pcie_set_power_d3cold(struct pci_dev *pdev)
  737. diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
  738. index 3ef7440418e3..a95ebac06e13 100644
  739. --- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
  740. +++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
  741. @@ -11,6 +11,7 @@
  742. * be handled differently. Currently, only S3 is supported.
  743. */
  744. #define QUIRK_FW_RST_WSID_S3 BIT(1)
  745. +#define QUIRK_NO_BRIDGE_D3 BIT(2)
  746. void mwifiex_initialize_quirks(struct pcie_service_card *card);
  747. int mwifiex_pcie_reset_d3cold_quirk(struct pci_dev *pdev);
  748. --
  749. 2.33.0
  750. From 4e5394f910d705c8d749a15610f07224fcbe8383 Mon Sep 17 00:00:00 2001
  751. From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
  752. Date: Tue, 10 Nov 2020 12:49:56 +0100
  753. Subject: [PATCH] mwifiex: Use non-posted PCI register writes
  754. On the 88W8897 card it's very important the TX ring write pointer is
  755. updated correctly to its new value before setting the TX ready
  756. interrupt, otherwise the firmware appears to crash (probably because
  757. it's trying to DMA-read from the wrong place).
  758. Since PCI uses "posted writes" when writing to a register, it's not
  759. guaranteed that a write will happen immediately. That means the pointer
  760. might be outdated when setting the TX ready interrupt, leading to
  761. firmware crashes especially when ASPM L1 and L1 substates are enabled
  762. (because of the higher link latency, the write will probably take
  763. longer).
  764. So fix those firmware crashes by always forcing non-posted writes. We do
  765. that by simply reading back the register after writing it, just as a lot
  766. of other drivers do.
  767. There are two reproducers that are fixed with this patch:
  768. 1) During rx/tx traffic and with ASPM L1 substates enabled (the enabled
  769. substates are platform dependent), the firmware crashes and eventually a
  770. command timeout appears in the logs. That crash is fixed by using a
  771. non-posted write in mwifiex_pcie_send_data().
  772. 2) When sending lots of commands to the card, waking it up from sleep in
  773. very quick intervals, the firmware eventually crashes. That crash
  774. appears to be fixed by some other non-posted write included here.
  775. Patchset: wifi
  776. ---
  777. drivers/net/wireless/marvell/mwifiex/pcie.c | 6 ++++++
  778. 1 file changed, 6 insertions(+)
  779. diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
  780. index 0627a37deac8..95a0c436bc1c 100644
  781. --- a/drivers/net/wireless/marvell/mwifiex/pcie.c
  782. +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
  783. @@ -237,6 +237,12 @@ static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data)
  784. iowrite32(data, card->pci_mmap1 + reg);
  785. + /* Do a read-back, which makes the write non-posted, ensuring the
  786. + * completion before returning.
  787. + * The firmware of the 88W8897 card is buggy and this avoids crashes.
  788. + */
  789. + ioread32(card->pci_mmap1 + reg);
  790. +
  791. return 0;
  792. }
  793. --
  794. 2.33.0
  795. From 031afca1cdca9266d6a61d361bc14b8b4b7834e5 Mon Sep 17 00:00:00 2001
  796. From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
  797. Date: Tue, 3 Nov 2020 13:28:04 +0100
  798. Subject: [PATCH] mwifiex: Add quirk resetting the PCI bridge on MS Surface
  799. devices
  800. The most recent firmware of the 88W8897 card reports a hardcoded LTR
  801. value to the system during initialization, probably as an (unsuccessful)
  802. attempt of the developers to fix firmware crashes. This LTR value
  803. prevents most of the Microsoft Surface devices from entering deep
  804. powersaving states (either platform C-State 10 or S0ix state), because
  805. the exit latency of that state would be higher than what the card can
  806. tolerate.
  807. Turns out the card works just the same (including the firmware crashes)
  808. no matter if that hardcoded LTR value is reported or not, so it's kind
  809. of useless and only prevents us from saving power.
  810. To get rid of those hardcoded LTR reports, it's possible to reset the
  811. PCI bridge device after initializing the cards firmware. I'm not exactly
  812. sure why that works, maybe the power management subsystem of the PCH
  813. resets its stored LTR values when doing a function level reset of the
  814. bridge device. Doing the reset once after starting the wifi firmware
  815. works very well, probably because the firmware only reports that LTR
  816. value a single time during firmware startup.
  817. Patchset: wifi
  818. ---
  819. drivers/net/wireless/marvell/mwifiex/pcie.c | 12 +++++++++
  820. .../wireless/marvell/mwifiex/pcie_quirks.c | 26 +++++++++++++------
  821. .../wireless/marvell/mwifiex/pcie_quirks.h | 1 +
  822. 3 files changed, 31 insertions(+), 8 deletions(-)
  823. diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
  824. index 95a0c436bc1c..97e7787e88b0 100644
  825. --- a/drivers/net/wireless/marvell/mwifiex/pcie.c
  826. +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
  827. @@ -1762,9 +1762,21 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
  828. static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter)
  829. {
  830. struct pcie_service_card *card = adapter->card;
  831. + struct pci_dev *pdev = card->dev;
  832. + struct pci_dev *parent_pdev = pci_upstream_bridge(pdev);
  833. const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
  834. int tx_wrap = card->txbd_wrptr & reg->tx_wrap_mask;
  835. + /* Trigger a function level reset of the PCI bridge device, this makes
  836. + * the firmware of PCIe 88W8897 cards stop reporting a fixed LTR value
  837. + * that prevents the system from entering package C10 and S0ix powersaving
  838. + * states.
  839. + * We need to do it here because it must happen after firmware
  840. + * initialization and this function is called after that is done.
  841. + */
  842. + if (card->quirks & QUIRK_DO_FLR_ON_BRIDGE)
  843. + pci_reset_function(parent_pdev);
  844. +
  845. /* Write the RX ring read pointer in to reg->rx_rdptr */
  846. if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr |
  847. tx_wrap)) {
  848. diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
  849. index a2aeb2af907e..6885575826a6 100644
  850. --- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
  851. +++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.c
  852. @@ -33,7 +33,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  853. DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 4"),
  854. },
  855. .driver_data = (void *)(QUIRK_FW_RST_D3COLD |
  856. - QUIRK_NO_BRIDGE_D3),
  857. + QUIRK_NO_BRIDGE_D3 |
  858. + QUIRK_DO_FLR_ON_BRIDGE),
  859. },
  860. {
  861. .ident = "Surface Pro 5",
  862. @@ -43,7 +44,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  863. DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1796"),
  864. },
  865. .driver_data = (void *)(QUIRK_FW_RST_D3COLD |
  866. - QUIRK_NO_BRIDGE_D3),
  867. + QUIRK_NO_BRIDGE_D3 |
  868. + QUIRK_DO_FLR_ON_BRIDGE),
  869. },
  870. {
  871. .ident = "Surface Pro 5 (LTE)",
  872. @@ -53,7 +55,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  873. DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "Surface_Pro_1807"),
  874. },
  875. .driver_data = (void *)(QUIRK_FW_RST_D3COLD |
  876. - QUIRK_NO_BRIDGE_D3),
  877. + QUIRK_NO_BRIDGE_D3 |
  878. + QUIRK_DO_FLR_ON_BRIDGE),
  879. },
  880. {
  881. .ident = "Surface Pro 6",
  882. @@ -62,7 +65,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  883. DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 6"),
  884. },
  885. .driver_data = (void *)(QUIRK_FW_RST_D3COLD |
  886. - QUIRK_NO_BRIDGE_D3),
  887. + QUIRK_NO_BRIDGE_D3 |
  888. + QUIRK_DO_FLR_ON_BRIDGE),
  889. },
  890. {
  891. .ident = "Surface Book 1",
  892. @@ -71,7 +75,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  893. DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book"),
  894. },
  895. .driver_data = (void *)(QUIRK_FW_RST_D3COLD |
  896. - QUIRK_NO_BRIDGE_D3),
  897. + QUIRK_NO_BRIDGE_D3 |
  898. + QUIRK_DO_FLR_ON_BRIDGE),
  899. },
  900. {
  901. .ident = "Surface Book 2",
  902. @@ -80,7 +85,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  903. DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Book 2"),
  904. },
  905. .driver_data = (void *)(QUIRK_FW_RST_D3COLD |
  906. - QUIRK_NO_BRIDGE_D3),
  907. + QUIRK_NO_BRIDGE_D3 |
  908. + QUIRK_DO_FLR_ON_BRIDGE),
  909. },
  910. {
  911. .ident = "Surface Laptop 1",
  912. @@ -89,7 +95,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  913. DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop"),
  914. },
  915. .driver_data = (void *)(QUIRK_FW_RST_D3COLD |
  916. - QUIRK_NO_BRIDGE_D3),
  917. + QUIRK_NO_BRIDGE_D3 |
  918. + QUIRK_DO_FLR_ON_BRIDGE),
  919. },
  920. {
  921. .ident = "Surface Laptop 2",
  922. @@ -98,7 +105,8 @@ static const struct dmi_system_id mwifiex_quirk_table[] = {
  923. DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Laptop 2"),
  924. },
  925. .driver_data = (void *)(QUIRK_FW_RST_D3COLD |
  926. - QUIRK_NO_BRIDGE_D3),
  927. + QUIRK_NO_BRIDGE_D3 |
  928. + QUIRK_DO_FLR_ON_BRIDGE),
  929. },
  930. {
  931. .ident = "Surface 3",
  932. @@ -147,6 +155,8 @@ void mwifiex_initialize_quirks(struct pcie_service_card *card)
  933. if (card->quirks & QUIRK_NO_BRIDGE_D3)
  934. dev_info(&pdev->dev,
  935. "quirk no_brigde_d3 enabled\n");
  936. + if (card->quirks & QUIRK_DO_FLR_ON_BRIDGE)
  937. + dev_info(&pdev->dev, "quirk do_flr_on_bridge enabled\n");
  938. }
  939. static void mwifiex_pcie_set_power_d3cold(struct pci_dev *pdev)
  940. diff --git a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
  941. index a95ebac06e13..4ec2ae72f632 100644
  942. --- a/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
  943. +++ b/drivers/net/wireless/marvell/mwifiex/pcie_quirks.h
  944. @@ -12,6 +12,7 @@
  945. */
  946. #define QUIRK_FW_RST_WSID_S3 BIT(1)
  947. #define QUIRK_NO_BRIDGE_D3 BIT(2)
  948. +#define QUIRK_DO_FLR_ON_BRIDGE BIT(3)
  949. void mwifiex_initialize_quirks(struct pcie_service_card *card);
  950. int mwifiex_pcie_reset_d3cold_quirk(struct pci_dev *pdev);
  951. --
  952. 2.33.0
  953. From 432d62d512afb247aedd76f15e7e9f125b1b4dd5 Mon Sep 17 00:00:00 2001
  954. From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
  955. Date: Sun, 28 Mar 2021 21:10:06 +0200
  956. Subject: [PATCH] mwifiex: Try waking the firmware until we get an interrupt
  957. It seems that the firmware of the 88W8897 card sometimes ignores or
  958. misses when we try to wake it up by reading the firmware status
  959. register. This leads to the firmware wakeup timeout expiring and the
  960. driver resetting the card because we assume the firmware has hung up or
  961. crashed (unfortunately that's not unlikely with this card).
  962. Turns out that most of the time the firmware actually didn't hang up,
  963. but simply "missed" our wakeup request and doesn't send us an AWAKE
  964. event.
  965. Trying again to read the firmware status register after a short timeout
  966. usually makes the firmware wake we up as expected, so add a small retry
  967. loop to mwifiex_pm_wakeup_card() that looks at the interrupt status to
  968. check whether the card woke up.
  969. The number of tries and timeout lengths for this were determined
  970. experimentally: The firmware usually takes about 500 us to wake up
  971. after we attempt to read the status register. In some cases where the
  972. firmware is very busy (for example while doing a bluetooth scan) it
  973. might even miss our requests for multiple milliseconds, which is why
  974. after 15 tries the waiting time gets increased to 10 ms. The maximum
  975. number of tries it took to wake the firmware when testing this was
  976. around 20, so a maximum number of 50 tries should give us plenty of
  977. safety margin.
  978. A good reproducer for this issue is letting the firmware sleep and wake
  979. up in very short intervals, for example by pinging an device on the
  980. network every 0.1 seconds.
  981. Patchset: wifi
  982. ---
  983. drivers/net/wireless/marvell/mwifiex/pcie.c | 29 ++++++++++++++++-----
  984. 1 file changed, 23 insertions(+), 6 deletions(-)
  985. diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
  986. index 97e7787e88b0..a4713019b226 100644
  987. --- a/drivers/net/wireless/marvell/mwifiex/pcie.c
  988. +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
  989. @@ -666,6 +666,7 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
  990. {
  991. struct pcie_service_card *card = adapter->card;
  992. const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
  993. + int n_tries = 0;
  994. mwifiex_dbg(adapter, EVENT,
  995. "event: Wakeup device...\n");
  996. @@ -673,12 +674,28 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
  997. if (reg->sleep_cookie)
  998. mwifiex_pcie_dev_wakeup_delay(adapter);
  999. - /* Accessing fw_status register will wakeup device */
  1000. - if (mwifiex_write_reg(adapter, reg->fw_status, FIRMWARE_READY_PCIE)) {
  1001. - mwifiex_dbg(adapter, ERROR,
  1002. - "Writing fw_status register failed\n");
  1003. - return -1;
  1004. - }
  1005. + /* Access the fw_status register to wake up the device.
  1006. + * Since the 88W8897 firmware sometimes appears to ignore or miss
  1007. + * that wakeup request, we continue trying until we receive an
  1008. + * interrupt from the card.
  1009. + */
  1010. + do {
  1011. + if (mwifiex_write_reg(adapter, reg->fw_status, FIRMWARE_READY_PCIE)) {
  1012. + mwifiex_dbg(adapter, ERROR,
  1013. + "Writing fw_status register failed\n");
  1014. + return -1;
  1015. + }
  1016. +
  1017. + n_tries++;
  1018. +
  1019. + if (n_tries <= 15)
  1020. + usleep_range(400, 700);
  1021. + else
  1022. + msleep(10);
  1023. + } while (n_tries <= 50 && READ_ONCE(adapter->int_status) == 0);
  1024. +
  1025. + mwifiex_dbg(adapter, EVENT,
  1026. + "event: Tried %d times until firmware woke up\n", n_tries);
  1027. if (reg->sleep_cookie) {
  1028. mwifiex_pcie_dev_wakeup_delay(adapter);
  1029. --
  1030. 2.33.0
  1031. From bb21b6f05a27b98ea3212239a3d8ec1401448c0d Mon Sep 17 00:00:00 2001
  1032. From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
  1033. Date: Thu, 25 Mar 2021 11:33:02 +0100
  1034. Subject: [PATCH] Bluetooth: btusb: Lower passive lescan interval on Marvell
  1035. 88W8897
  1036. The Marvell 88W8897 combined wifi and bluetooth card (pcie+usb version)
  1037. is used in a lot of Microsoft Surface devices, and all those devices
  1038. suffer from very low 2.4GHz wifi connection speeds while bluetooth is
  1039. enabled. The reason for that is that the default passive scanning
  1040. interval for Bluetooth Low Energy devices is quite high in Linux
  1041. (interval of 60 msec and scan window of 30 msec, see hci_core.c), and
  1042. the Marvell chip is known for its bad bt+wifi coexisting performance.
  1043. So decrease that passive scan interval and make the scan window shorter
  1044. on this particular device to allow for spending more time transmitting
  1045. wifi signals: The new scan interval is 250 msec (0x190 * 0.625 msec) and
  1046. the new scan window is 6.25 msec (0xa * 0,625 msec).
  1047. This change has a very large impact on the 2.4GHz wifi speeds and gets
  1048. it up to performance comparable with the Windows driver, which seems to
  1049. apply a similar quirk.
  1050. The interval and window length were tested and found to work very well
  1051. with a lot of Bluetooth Low Energy devices, including the Surface Pen, a
  1052. Bluetooth Speaker and two modern Bluetooth headphones. All devices were
  1053. discovered immediately after turning them on. Even lower values were
  1054. also tested, but they introduced longer delays until devices get
  1055. discovered.
  1056. Patchset: wifi
  1057. ---
  1058. drivers/bluetooth/btusb.c | 15 +++++++++++++++
  1059. 1 file changed, 15 insertions(+)
  1060. diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
  1061. index e0859f4e2807..a6a3298c0178 100644
  1062. --- a/drivers/bluetooth/btusb.c
  1063. +++ b/drivers/bluetooth/btusb.c
  1064. @@ -60,6 +60,7 @@ static struct usb_driver btusb_driver;
  1065. #define BTUSB_WIDEBAND_SPEECH 0x400000
  1066. #define BTUSB_VALID_LE_STATES 0x800000
  1067. #define BTUSB_QCA_WCN6855 0x1000000
  1068. +#define BTUSB_LOWER_LESCAN_INTERVAL 0x2000000
  1069. static const struct usb_device_id btusb_table[] = {
  1070. /* Generic Bluetooth USB device */
  1071. @@ -358,6 +359,7 @@ static const struct usb_device_id blacklist_table[] = {
  1072. { USB_DEVICE(0x1286, 0x2044), .driver_info = BTUSB_MARVELL },
  1073. { USB_DEVICE(0x1286, 0x2046), .driver_info = BTUSB_MARVELL },
  1074. { USB_DEVICE(0x1286, 0x204e), .driver_info = BTUSB_MARVELL },
  1075. + { USB_DEVICE(0x1286, 0x204c), .driver_info = BTUSB_LOWER_LESCAN_INTERVAL },
  1076. /* Intel Bluetooth devices */
  1077. { USB_DEVICE(0x8087, 0x0025), .driver_info = BTUSB_INTEL_NEW |
  1078. @@ -4115,6 +4117,19 @@ static int btusb_probe(struct usb_interface *intf,
  1079. if (id->driver_info & BTUSB_MARVELL)
  1080. hdev->set_bdaddr = btusb_set_bdaddr_marvell;
  1081. + /* The Marvell 88W8897 combined wifi and bluetooth card is known for
  1082. + * very bad bt+wifi coexisting performance.
  1083. + *
  1084. + * Decrease the passive BT Low Energy scan interval a bit
  1085. + * (0x0190 * 0.625 msec = 250 msec) and make the scan window shorter
  1086. + * (0x000a * 0,625 msec = 6.25 msec). This allows for significantly
  1087. + * higher wifi throughput while passively scanning for BT LE devices.
  1088. + */
  1089. + if (id->driver_info & BTUSB_LOWER_LESCAN_INTERVAL) {
  1090. + hdev->le_scan_interval = 0x0190;
  1091. + hdev->le_scan_window = 0x000a;
  1092. + }
  1093. +
  1094. if (IS_ENABLED(CONFIG_BT_HCIBTUSB_MTK) &&
  1095. (id->driver_info & BTUSB_MEDIATEK)) {
  1096. hdev->setup = btusb_mtk_setup;
  1097. --
  1098. 2.33.0
  1099. From 7763c0ba58baca69827db1e6e85a739562ecd017 Mon Sep 17 00:00:00 2001
  1100. From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
  1101. Date: Wed, 11 Nov 2020 12:31:26 +0100
  1102. Subject: [PATCH] mwifiex: Small cleanup for handling virtual interface type
  1103. changes
  1104. Handle the obvious invalid virtual interface type changes with a general
  1105. check instead of looking at the individual change.
  1106. For type changes from P2P_CLIENT to P2P_GO and the other way round, this
  1107. changes the behavior slightly: We now still do nothing, but return
  1108. -EOPNOTSUPP instead of 0. Now that behavior was incorrect before and
  1109. still is, because type changes between these two types are actually
  1110. possible and supported, which we'll fix in a following commit.
  1111. Patchset: wifi
  1112. ---
  1113. .../net/wireless/marvell/mwifiex/cfg80211.c | 39 +++++++------------
  1114. 1 file changed, 14 insertions(+), 25 deletions(-)
  1115. diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1116. index a6b9dc6700b1..d50fd8570475 100644
  1117. --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1118. +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1119. @@ -1141,6 +1141,20 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
  1120. return -EBUSY;
  1121. }
  1122. + if (type == NL80211_IFTYPE_UNSPECIFIED) {
  1123. + mwifiex_dbg(priv->adapter, INFO,
  1124. + "%s: no new type specified, keeping old type %d\n",
  1125. + dev->name, curr_iftype);
  1126. + return 0;
  1127. + }
  1128. +
  1129. + if (curr_iftype == type) {
  1130. + mwifiex_dbg(priv->adapter, INFO,
  1131. + "%s: interface already is of type %d\n",
  1132. + dev->name, curr_iftype);
  1133. + return 0;
  1134. + }
  1135. +
  1136. switch (curr_iftype) {
  1137. case NL80211_IFTYPE_ADHOC:
  1138. switch (type) {
  1139. @@ -1160,12 +1174,6 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
  1140. case NL80211_IFTYPE_AP:
  1141. return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
  1142. params);
  1143. - case NL80211_IFTYPE_UNSPECIFIED:
  1144. - mwifiex_dbg(priv->adapter, INFO,
  1145. - "%s: kept type as IBSS\n", dev->name);
  1146. - fallthrough;
  1147. - case NL80211_IFTYPE_ADHOC: /* This shouldn't happen */
  1148. - return 0;
  1149. default:
  1150. mwifiex_dbg(priv->adapter, ERROR,
  1151. "%s: changing to %d not supported\n",
  1152. @@ -1191,12 +1199,6 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
  1153. case NL80211_IFTYPE_AP:
  1154. return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
  1155. params);
  1156. - case NL80211_IFTYPE_UNSPECIFIED:
  1157. - mwifiex_dbg(priv->adapter, INFO,
  1158. - "%s: kept type as STA\n", dev->name);
  1159. - fallthrough;
  1160. - case NL80211_IFTYPE_STATION: /* This shouldn't happen */
  1161. - return 0;
  1162. default:
  1163. mwifiex_dbg(priv->adapter, ERROR,
  1164. "%s: changing to %d not supported\n",
  1165. @@ -1214,12 +1216,6 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
  1166. case NL80211_IFTYPE_P2P_GO:
  1167. return mwifiex_change_vif_to_p2p(dev, curr_iftype,
  1168. type, params);
  1169. - case NL80211_IFTYPE_UNSPECIFIED:
  1170. - mwifiex_dbg(priv->adapter, INFO,
  1171. - "%s: kept type as AP\n", dev->name);
  1172. - fallthrough;
  1173. - case NL80211_IFTYPE_AP: /* This shouldn't happen */
  1174. - return 0;
  1175. default:
  1176. mwifiex_dbg(priv->adapter, ERROR,
  1177. "%s: changing to %d not supported\n",
  1178. @@ -1254,13 +1250,6 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
  1179. return -EFAULT;
  1180. return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
  1181. params);
  1182. - case NL80211_IFTYPE_UNSPECIFIED:
  1183. - mwifiex_dbg(priv->adapter, INFO,
  1184. - "%s: kept type as P2P\n", dev->name);
  1185. - fallthrough;
  1186. - case NL80211_IFTYPE_P2P_CLIENT:
  1187. - case NL80211_IFTYPE_P2P_GO:
  1188. - return 0;
  1189. default:
  1190. mwifiex_dbg(priv->adapter, ERROR,
  1191. "%s: changing to %d not supported\n",
  1192. --
  1193. 2.33.0
  1194. From e34bf670e3ce80661536cc88049724f9a58dba2f Mon Sep 17 00:00:00 2001
  1195. From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
  1196. Date: Wed, 11 Nov 2020 12:44:39 +0100
  1197. Subject: [PATCH] mwifiex: Use function to check whether interface type change
  1198. is allowed
  1199. Instead of bailing out in the function which is supposed to do the type
  1200. change, detect invalid changes beforehand using a generic function and
  1201. return an error if the change is not allowed.
  1202. Patchset: wifi
  1203. ---
  1204. .../net/wireless/marvell/mwifiex/cfg80211.c | 139 ++++++++++++------
  1205. 1 file changed, 92 insertions(+), 47 deletions(-)
  1206. diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1207. index d50fd8570475..3a79a55bbfd2 100644
  1208. --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1209. +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1210. @@ -939,6 +939,76 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv,
  1211. return 0;
  1212. }
  1213. +static bool
  1214. +is_vif_type_change_allowed(struct mwifiex_adapter *adapter,
  1215. + enum nl80211_iftype old_iftype,
  1216. + enum nl80211_iftype new_iftype)
  1217. +{
  1218. + switch (old_iftype) {
  1219. + case NL80211_IFTYPE_ADHOC:
  1220. + switch (new_iftype) {
  1221. + case NL80211_IFTYPE_STATION:
  1222. + return true;
  1223. + case NL80211_IFTYPE_P2P_CLIENT:
  1224. + case NL80211_IFTYPE_P2P_GO:
  1225. + return adapter->curr_iface_comb.p2p_intf !=
  1226. + adapter->iface_limit.p2p_intf;
  1227. + case NL80211_IFTYPE_AP:
  1228. + return adapter->curr_iface_comb.uap_intf !=
  1229. + adapter->iface_limit.uap_intf;
  1230. + default:
  1231. + return false;
  1232. + }
  1233. +
  1234. + case NL80211_IFTYPE_STATION:
  1235. + switch (new_iftype) {
  1236. + case NL80211_IFTYPE_ADHOC:
  1237. + return true;
  1238. + case NL80211_IFTYPE_P2P_CLIENT:
  1239. + case NL80211_IFTYPE_P2P_GO:
  1240. + return adapter->curr_iface_comb.p2p_intf !=
  1241. + adapter->iface_limit.p2p_intf;
  1242. + case NL80211_IFTYPE_AP:
  1243. + return adapter->curr_iface_comb.uap_intf !=
  1244. + adapter->iface_limit.uap_intf;
  1245. + default:
  1246. + return false;
  1247. + }
  1248. +
  1249. + case NL80211_IFTYPE_AP:
  1250. + switch (new_iftype) {
  1251. + case NL80211_IFTYPE_ADHOC:
  1252. + case NL80211_IFTYPE_STATION:
  1253. + return adapter->curr_iface_comb.sta_intf !=
  1254. + adapter->iface_limit.sta_intf;
  1255. + case NL80211_IFTYPE_P2P_CLIENT:
  1256. + case NL80211_IFTYPE_P2P_GO:
  1257. + return adapter->curr_iface_comb.p2p_intf !=
  1258. + adapter->iface_limit.p2p_intf;
  1259. + default:
  1260. + return false;
  1261. + }
  1262. +
  1263. + case NL80211_IFTYPE_P2P_CLIENT:
  1264. + case NL80211_IFTYPE_P2P_GO:
  1265. + switch (new_iftype) {
  1266. + case NL80211_IFTYPE_ADHOC:
  1267. + case NL80211_IFTYPE_STATION:
  1268. + return true;
  1269. + case NL80211_IFTYPE_AP:
  1270. + return adapter->curr_iface_comb.uap_intf !=
  1271. + adapter->iface_limit.uap_intf;
  1272. + default:
  1273. + return false;
  1274. + }
  1275. +
  1276. + default:
  1277. + break;
  1278. + }
  1279. +
  1280. + return false;
  1281. +}
  1282. +
  1283. static int
  1284. mwifiex_change_vif_to_p2p(struct net_device *dev,
  1285. enum nl80211_iftype curr_iftype,
  1286. @@ -955,13 +1025,6 @@ mwifiex_change_vif_to_p2p(struct net_device *dev,
  1287. adapter = priv->adapter;
  1288. - if (adapter->curr_iface_comb.p2p_intf ==
  1289. - adapter->iface_limit.p2p_intf) {
  1290. - mwifiex_dbg(adapter, ERROR,
  1291. - "cannot create multiple P2P ifaces\n");
  1292. - return -1;
  1293. - }
  1294. -
  1295. mwifiex_dbg(adapter, INFO,
  1296. "%s: changing role to p2p\n", dev->name);
  1297. @@ -1027,15 +1090,6 @@ mwifiex_change_vif_to_sta_adhoc(struct net_device *dev,
  1298. adapter = priv->adapter;
  1299. - if ((curr_iftype != NL80211_IFTYPE_P2P_CLIENT &&
  1300. - curr_iftype != NL80211_IFTYPE_P2P_GO) &&
  1301. - (adapter->curr_iface_comb.sta_intf ==
  1302. - adapter->iface_limit.sta_intf)) {
  1303. - mwifiex_dbg(adapter, ERROR,
  1304. - "cannot create multiple station/adhoc ifaces\n");
  1305. - return -1;
  1306. - }
  1307. -
  1308. if (type == NL80211_IFTYPE_STATION)
  1309. mwifiex_dbg(adapter, INFO,
  1310. "%s: changing role to station\n", dev->name);
  1311. @@ -1086,13 +1140,6 @@ mwifiex_change_vif_to_ap(struct net_device *dev,
  1312. adapter = priv->adapter;
  1313. - if (adapter->curr_iface_comb.uap_intf ==
  1314. - adapter->iface_limit.uap_intf) {
  1315. - mwifiex_dbg(adapter, ERROR,
  1316. - "cannot create multiple AP ifaces\n");
  1317. - return -1;
  1318. - }
  1319. -
  1320. mwifiex_dbg(adapter, INFO,
  1321. "%s: changing role to AP\n", dev->name);
  1322. @@ -1155,6 +1202,13 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
  1323. return 0;
  1324. }
  1325. + if (!is_vif_type_change_allowed(priv->adapter, curr_iftype, type)) {
  1326. + mwifiex_dbg(priv->adapter, ERROR,
  1327. + "%s: change from type %d to %d is not allowed\n",
  1328. + dev->name, curr_iftype, type);
  1329. + return -EOPNOTSUPP;
  1330. + }
  1331. +
  1332. switch (curr_iftype) {
  1333. case NL80211_IFTYPE_ADHOC:
  1334. switch (type) {
  1335. @@ -1175,12 +1229,9 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
  1336. return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
  1337. params);
  1338. default:
  1339. - mwifiex_dbg(priv->adapter, ERROR,
  1340. - "%s: changing to %d not supported\n",
  1341. - dev->name, type);
  1342. - return -EOPNOTSUPP;
  1343. + goto errnotsupp;
  1344. }
  1345. - break;
  1346. +
  1347. case NL80211_IFTYPE_STATION:
  1348. switch (type) {
  1349. case NL80211_IFTYPE_ADHOC:
  1350. @@ -1200,12 +1251,9 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
  1351. return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
  1352. params);
  1353. default:
  1354. - mwifiex_dbg(priv->adapter, ERROR,
  1355. - "%s: changing to %d not supported\n",
  1356. - dev->name, type);
  1357. - return -EOPNOTSUPP;
  1358. + goto errnotsupp;
  1359. }
  1360. - break;
  1361. +
  1362. case NL80211_IFTYPE_AP:
  1363. switch (type) {
  1364. case NL80211_IFTYPE_ADHOC:
  1365. @@ -1217,12 +1265,9 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
  1366. return mwifiex_change_vif_to_p2p(dev, curr_iftype,
  1367. type, params);
  1368. default:
  1369. - mwifiex_dbg(priv->adapter, ERROR,
  1370. - "%s: changing to %d not supported\n",
  1371. - dev->name, type);
  1372. - return -EOPNOTSUPP;
  1373. + goto errnotsupp;
  1374. }
  1375. - break;
  1376. +
  1377. case NL80211_IFTYPE_P2P_CLIENT:
  1378. case NL80211_IFTYPE_P2P_GO:
  1379. switch (type) {
  1380. @@ -1251,21 +1296,21 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
  1381. return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
  1382. params);
  1383. default:
  1384. - mwifiex_dbg(priv->adapter, ERROR,
  1385. - "%s: changing to %d not supported\n",
  1386. - dev->name, type);
  1387. - return -EOPNOTSUPP;
  1388. + goto errnotsupp;
  1389. }
  1390. - break;
  1391. +
  1392. default:
  1393. - mwifiex_dbg(priv->adapter, ERROR,
  1394. - "%s: unknown iftype: %d\n",
  1395. - dev->name, dev->ieee80211_ptr->iftype);
  1396. - return -EOPNOTSUPP;
  1397. + goto errnotsupp;
  1398. }
  1399. return 0;
  1400. +
  1401. +errnotsupp:
  1402. + mwifiex_dbg(priv->adapter, ERROR,
  1403. + "unsupported interface type transition: %d to %d\n",
  1404. + curr_iftype, type);
  1405. + return -EOPNOTSUPP;
  1406. }
  1407. static void
  1408. --
  1409. 2.33.0
  1410. From ede9773f9d8d9a0f65b5e17a4421e7f8862e5832 Mon Sep 17 00:00:00 2001
  1411. From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
  1412. Date: Wed, 11 Nov 2020 13:33:04 +0100
  1413. Subject: [PATCH] mwifiex: Run SET_BSS_MODE when changing from P2P to STATION
  1414. vif-type
  1415. We currently handle changing from the P2P to the STATION virtual
  1416. interface type slightly different than changing from P2P to ADHOC: When
  1417. changing to STATION, we don't send the SET_BSS_MODE command. We do send
  1418. that command on all other type-changes though, and it probably makes
  1419. sense to send the command since after all we just changed our BSS_MODE.
  1420. Looking at prior changes to this part of the code, it seems that this is
  1421. simply a leftover from old refactorings.
  1422. Since sending the SET_BSS_MODE command is the only difference between
  1423. mwifiex_change_vif_to_sta_adhoc() and the current code, we can now use
  1424. mwifiex_change_vif_to_sta_adhoc() for both switching to ADHOC and
  1425. STATION interface type.
  1426. This does not fix any particular bug and just "looked right", so there's
  1427. a small chance it might be a regression.
  1428. Patchset: wifi
  1429. ---
  1430. .../net/wireless/marvell/mwifiex/cfg80211.c | 22 ++++---------------
  1431. 1 file changed, 4 insertions(+), 18 deletions(-)
  1432. diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1433. index 3a79a55bbfd2..66e978088061 100644
  1434. --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1435. +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1436. @@ -1270,29 +1270,15 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
  1437. case NL80211_IFTYPE_P2P_CLIENT:
  1438. case NL80211_IFTYPE_P2P_GO:
  1439. + if (mwifiex_cfg80211_deinit_p2p(priv))
  1440. + return -EFAULT;
  1441. +
  1442. switch (type) {
  1443. - case NL80211_IFTYPE_STATION:
  1444. - if (mwifiex_cfg80211_deinit_p2p(priv))
  1445. - return -EFAULT;
  1446. - priv->adapter->curr_iface_comb.p2p_intf--;
  1447. - priv->adapter->curr_iface_comb.sta_intf++;
  1448. - dev->ieee80211_ptr->iftype = type;
  1449. - if (mwifiex_deinit_priv_params(priv))
  1450. - return -1;
  1451. - if (mwifiex_init_new_priv_params(priv, dev, type))
  1452. - return -1;
  1453. - if (mwifiex_sta_init_cmd(priv, false, false))
  1454. - return -1;
  1455. - break;
  1456. case NL80211_IFTYPE_ADHOC:
  1457. - if (mwifiex_cfg80211_deinit_p2p(priv))
  1458. - return -EFAULT;
  1459. + case NL80211_IFTYPE_STATION:
  1460. return mwifiex_change_vif_to_sta_adhoc(dev, curr_iftype,
  1461. type, params);
  1462. - break;
  1463. case NL80211_IFTYPE_AP:
  1464. - if (mwifiex_cfg80211_deinit_p2p(priv))
  1465. - return -EFAULT;
  1466. return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
  1467. params);
  1468. default:
  1469. --
  1470. 2.33.0
  1471. From 5f322ab7ea0d62a876f50ef4ca6f40b1b9c10a74 Mon Sep 17 00:00:00 2001
  1472. From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
  1473. Date: Wed, 11 Nov 2020 14:42:54 +0100
  1474. Subject: [PATCH] mwifiex: Use helper function for counting interface types
  1475. Use a small helper function to increment and decrement the counter of
  1476. the interface types we currently manage. This makes the code that
  1477. actually changes and sets up the interface type a bit less messy and
  1478. also helps avoiding mistakes in case someone increments/decrements a
  1479. counter wrongly.
  1480. Patchset: wifi
  1481. ---
  1482. .../net/wireless/marvell/mwifiex/cfg80211.c | 110 ++++++------------
  1483. 1 file changed, 35 insertions(+), 75 deletions(-)
  1484. diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1485. index 66e978088061..db30f595e9f9 100644
  1486. --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1487. +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1488. @@ -1009,6 +1009,32 @@ is_vif_type_change_allowed(struct mwifiex_adapter *adapter,
  1489. return false;
  1490. }
  1491. +static void
  1492. +update_vif_type_counter(struct mwifiex_adapter *adapter,
  1493. + enum nl80211_iftype iftype,
  1494. + int change)
  1495. +{
  1496. + switch (iftype) {
  1497. + case NL80211_IFTYPE_UNSPECIFIED:
  1498. + case NL80211_IFTYPE_ADHOC:
  1499. + case NL80211_IFTYPE_STATION:
  1500. + adapter->curr_iface_comb.sta_intf += change;
  1501. + break;
  1502. + case NL80211_IFTYPE_AP:
  1503. + adapter->curr_iface_comb.uap_intf += change;
  1504. + break;
  1505. + case NL80211_IFTYPE_P2P_CLIENT:
  1506. + case NL80211_IFTYPE_P2P_GO:
  1507. + adapter->curr_iface_comb.p2p_intf += change;
  1508. + break;
  1509. + default:
  1510. + mwifiex_dbg(adapter, ERROR,
  1511. + "%s: Unsupported iftype passed: %d\n",
  1512. + __func__, iftype);
  1513. + break;
  1514. + }
  1515. +}
  1516. +
  1517. static int
  1518. mwifiex_change_vif_to_p2p(struct net_device *dev,
  1519. enum nl80211_iftype curr_iftype,
  1520. @@ -1056,19 +1082,8 @@ mwifiex_change_vif_to_p2p(struct net_device *dev,
  1521. if (mwifiex_sta_init_cmd(priv, false, false))
  1522. return -1;
  1523. - switch (curr_iftype) {
  1524. - case NL80211_IFTYPE_STATION:
  1525. - case NL80211_IFTYPE_ADHOC:
  1526. - adapter->curr_iface_comb.sta_intf--;
  1527. - break;
  1528. - case NL80211_IFTYPE_AP:
  1529. - adapter->curr_iface_comb.uap_intf--;
  1530. - break;
  1531. - default:
  1532. - break;
  1533. - }
  1534. -
  1535. - adapter->curr_iface_comb.p2p_intf++;
  1536. + update_vif_type_counter(adapter, curr_iftype, -1);
  1537. + update_vif_type_counter(adapter, type, +1);
  1538. dev->ieee80211_ptr->iftype = type;
  1539. return 0;
  1540. @@ -1107,20 +1122,10 @@ mwifiex_change_vif_to_sta_adhoc(struct net_device *dev,
  1541. if (mwifiex_sta_init_cmd(priv, false, false))
  1542. return -1;
  1543. - switch (curr_iftype) {
  1544. - case NL80211_IFTYPE_P2P_CLIENT:
  1545. - case NL80211_IFTYPE_P2P_GO:
  1546. - adapter->curr_iface_comb.p2p_intf--;
  1547. - break;
  1548. - case NL80211_IFTYPE_AP:
  1549. - adapter->curr_iface_comb.uap_intf--;
  1550. - break;
  1551. - default:
  1552. - break;
  1553. - }
  1554. -
  1555. - adapter->curr_iface_comb.sta_intf++;
  1556. + update_vif_type_counter(adapter, curr_iftype, -1);
  1557. + update_vif_type_counter(adapter, type, +1);
  1558. dev->ieee80211_ptr->iftype = type;
  1559. +
  1560. return 0;
  1561. }
  1562. @@ -1153,20 +1158,8 @@ mwifiex_change_vif_to_ap(struct net_device *dev,
  1563. if (mwifiex_sta_init_cmd(priv, false, false))
  1564. return -1;
  1565. - switch (curr_iftype) {
  1566. - case NL80211_IFTYPE_P2P_CLIENT:
  1567. - case NL80211_IFTYPE_P2P_GO:
  1568. - adapter->curr_iface_comb.p2p_intf--;
  1569. - break;
  1570. - case NL80211_IFTYPE_STATION:
  1571. - case NL80211_IFTYPE_ADHOC:
  1572. - adapter->curr_iface_comb.sta_intf--;
  1573. - break;
  1574. - default:
  1575. - break;
  1576. - }
  1577. -
  1578. - adapter->curr_iface_comb.uap_intf++;
  1579. + update_vif_type_counter(adapter, curr_iftype, -1);
  1580. + update_vif_type_counter(adapter, type, +1);
  1581. dev->ieee80211_ptr->iftype = type;
  1582. return 0;
  1583. }
  1584. @@ -3114,23 +3107,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
  1585. mwifiex_dev_debugfs_init(priv);
  1586. #endif
  1587. - switch (type) {
  1588. - case NL80211_IFTYPE_UNSPECIFIED:
  1589. - case NL80211_IFTYPE_STATION:
  1590. - case NL80211_IFTYPE_ADHOC:
  1591. - adapter->curr_iface_comb.sta_intf++;
  1592. - break;
  1593. - case NL80211_IFTYPE_AP:
  1594. - adapter->curr_iface_comb.uap_intf++;
  1595. - break;
  1596. - case NL80211_IFTYPE_P2P_CLIENT:
  1597. - adapter->curr_iface_comb.p2p_intf++;
  1598. - break;
  1599. - default:
  1600. - /* This should be dead code; checked above */
  1601. - mwifiex_dbg(adapter, ERROR, "type not supported\n");
  1602. - return ERR_PTR(-EINVAL);
  1603. - }
  1604. + update_vif_type_counter(adapter, type, +1);
  1605. return &priv->wdev;
  1606. @@ -3196,24 +3173,7 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
  1607. /* Clear the priv in adapter */
  1608. priv->netdev = NULL;
  1609. - switch (priv->bss_mode) {
  1610. - case NL80211_IFTYPE_UNSPECIFIED:
  1611. - case NL80211_IFTYPE_STATION:
  1612. - case NL80211_IFTYPE_ADHOC:
  1613. - adapter->curr_iface_comb.sta_intf--;
  1614. - break;
  1615. - case NL80211_IFTYPE_AP:
  1616. - adapter->curr_iface_comb.uap_intf--;
  1617. - break;
  1618. - case NL80211_IFTYPE_P2P_CLIENT:
  1619. - case NL80211_IFTYPE_P2P_GO:
  1620. - adapter->curr_iface_comb.p2p_intf--;
  1621. - break;
  1622. - default:
  1623. - mwifiex_dbg(adapter, ERROR,
  1624. - "del_virtual_intf: type not supported\n");
  1625. - break;
  1626. - }
  1627. + update_vif_type_counter(adapter, priv->bss_mode, -1);
  1628. priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
  1629. --
  1630. 2.33.0
  1631. From ccf1a0c04da4ef3eec5848dd00ee71ecf70cd4c0 Mon Sep 17 00:00:00 2001
  1632. From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
  1633. Date: Fri, 26 Mar 2021 15:56:58 +0100
  1634. Subject: [PATCH] mwifiex: Update virtual interface counters right after
  1635. setting bss_type
  1636. In mwifiex_init_new_priv_params() we update our private driver state to
  1637. reflect the currently selected virtual interface type. Most notably we
  1638. set the bss_mode to the mode we're going to put the firmware in.
  1639. Now after we updated the driver state we actually start talking to the
  1640. firmware and instruct it to set up the new mode. Those commands can and
  1641. will sometimes fail, in which case we return with an error from
  1642. mwifiex_change_vif_to_*. We currently update our virtual interface type
  1643. counters after this return, which means the code is never reached when a
  1644. firmware error happens and we never update the counters. Since we have
  1645. updated our bss_mode earlier though, the counters now no longer reflect
  1646. the actual state of the driver.
  1647. This will break things on the next virtual interface change, because the
  1648. virtual interface type we're switching away from didn't get its counter
  1649. incremented, and we end up decrementing a 0-counter.
  1650. To fix this, simply update the virtual interface type counters right
  1651. after updating our driver structures, so that they are always in sync.
  1652. Patchset: wifi
  1653. ---
  1654. .../net/wireless/marvell/mwifiex/cfg80211.c | 25 +++++++++++--------
  1655. 1 file changed, 14 insertions(+), 11 deletions(-)
  1656. diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1657. index db30f595e9f9..60de1cec77c7 100644
  1658. --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1659. +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1660. @@ -1059,6 +1059,10 @@ mwifiex_change_vif_to_p2p(struct net_device *dev,
  1661. if (mwifiex_init_new_priv_params(priv, dev, type))
  1662. return -1;
  1663. + update_vif_type_counter(adapter, curr_iftype, -1);
  1664. + update_vif_type_counter(adapter, type, +1);
  1665. + dev->ieee80211_ptr->iftype = type;
  1666. +
  1667. switch (type) {
  1668. case NL80211_IFTYPE_P2P_CLIENT:
  1669. if (mwifiex_cfg80211_init_p2p_client(priv))
  1670. @@ -1082,10 +1086,6 @@ mwifiex_change_vif_to_p2p(struct net_device *dev,
  1671. if (mwifiex_sta_init_cmd(priv, false, false))
  1672. return -1;
  1673. - update_vif_type_counter(adapter, curr_iftype, -1);
  1674. - update_vif_type_counter(adapter, type, +1);
  1675. - dev->ieee80211_ptr->iftype = type;
  1676. -
  1677. return 0;
  1678. }
  1679. @@ -1116,16 +1116,17 @@ mwifiex_change_vif_to_sta_adhoc(struct net_device *dev,
  1680. return -1;
  1681. if (mwifiex_init_new_priv_params(priv, dev, type))
  1682. return -1;
  1683. +
  1684. + update_vif_type_counter(adapter, curr_iftype, -1);
  1685. + update_vif_type_counter(adapter, type, +1);
  1686. + dev->ieee80211_ptr->iftype = type;
  1687. +
  1688. if (mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
  1689. HostCmd_ACT_GEN_SET, 0, NULL, true))
  1690. return -1;
  1691. if (mwifiex_sta_init_cmd(priv, false, false))
  1692. return -1;
  1693. - update_vif_type_counter(adapter, curr_iftype, -1);
  1694. - update_vif_type_counter(adapter, type, +1);
  1695. - dev->ieee80211_ptr->iftype = type;
  1696. -
  1697. return 0;
  1698. }
  1699. @@ -1152,15 +1153,17 @@ mwifiex_change_vif_to_ap(struct net_device *dev,
  1700. return -1;
  1701. if (mwifiex_init_new_priv_params(priv, dev, type))
  1702. return -1;
  1703. +
  1704. + update_vif_type_counter(adapter, curr_iftype, -1);
  1705. + update_vif_type_counter(adapter, type, +1);
  1706. + dev->ieee80211_ptr->iftype = type;
  1707. +
  1708. if (mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
  1709. HostCmd_ACT_GEN_SET, 0, NULL, true))
  1710. return -1;
  1711. if (mwifiex_sta_init_cmd(priv, false, false))
  1712. return -1;
  1713. - update_vif_type_counter(adapter, curr_iftype, -1);
  1714. - update_vif_type_counter(adapter, type, +1);
  1715. - dev->ieee80211_ptr->iftype = type;
  1716. return 0;
  1717. }
  1718. /*
  1719. --
  1720. 2.33.0
  1721. From 4ed65a1a9ca878178854a444ddf8afeb1f5892c7 Mon Sep 17 00:00:00 2001
  1722. From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
  1723. Date: Wed, 11 Nov 2020 13:42:40 +0100
  1724. Subject: [PATCH] mwifiex: Allow switching interface type from P2P_CLIENT to
  1725. P2P_GO
  1726. It's possible to change virtual interface type between P2P_CLIENT and
  1727. P2P_GO, the card supports that just fine, and it happens for example
  1728. when using miracast with the miraclecast software.
  1729. So allow type changes between P2P_CLIENT and P2P_GO and simply call into
  1730. mwifiex_change_vif_to_p2p(), which handles this just fine. We have to
  1731. call mwifiex_cfg80211_deinit_p2p() before though to make sure the old
  1732. p2p mode is properly uninitialized.
  1733. Patchset: wifi
  1734. ---
  1735. .../net/wireless/marvell/mwifiex/cfg80211.c | 36 +++++++++++++++++++
  1736. 1 file changed, 36 insertions(+)
  1737. diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1738. index 60de1cec77c7..a37b504bd084 100644
  1739. --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1740. +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1741. @@ -990,11 +990,26 @@ is_vif_type_change_allowed(struct mwifiex_adapter *adapter,
  1742. }
  1743. case NL80211_IFTYPE_P2P_CLIENT:
  1744. + switch (new_iftype) {
  1745. + case NL80211_IFTYPE_ADHOC:
  1746. + case NL80211_IFTYPE_STATION:
  1747. + return true;
  1748. + case NL80211_IFTYPE_P2P_GO:
  1749. + return true;
  1750. + case NL80211_IFTYPE_AP:
  1751. + return adapter->curr_iface_comb.uap_intf !=
  1752. + adapter->iface_limit.uap_intf;
  1753. + default:
  1754. + return false;
  1755. + }
  1756. +
  1757. case NL80211_IFTYPE_P2P_GO:
  1758. switch (new_iftype) {
  1759. case NL80211_IFTYPE_ADHOC:
  1760. case NL80211_IFTYPE_STATION:
  1761. return true;
  1762. + case NL80211_IFTYPE_P2P_CLIENT:
  1763. + return true;
  1764. case NL80211_IFTYPE_AP:
  1765. return adapter->curr_iface_comb.uap_intf !=
  1766. adapter->iface_limit.uap_intf;
  1767. @@ -1265,6 +1280,24 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
  1768. }
  1769. case NL80211_IFTYPE_P2P_CLIENT:
  1770. + if (mwifiex_cfg80211_deinit_p2p(priv))
  1771. + return -EFAULT;
  1772. +
  1773. + switch (type) {
  1774. + case NL80211_IFTYPE_ADHOC:
  1775. + case NL80211_IFTYPE_STATION:
  1776. + return mwifiex_change_vif_to_sta_adhoc(dev, curr_iftype,
  1777. + type, params);
  1778. + case NL80211_IFTYPE_P2P_GO:
  1779. + return mwifiex_change_vif_to_p2p(dev, curr_iftype,
  1780. + type, params);
  1781. + case NL80211_IFTYPE_AP:
  1782. + return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
  1783. + params);
  1784. + default:
  1785. + goto errnotsupp;
  1786. + }
  1787. +
  1788. case NL80211_IFTYPE_P2P_GO:
  1789. if (mwifiex_cfg80211_deinit_p2p(priv))
  1790. return -EFAULT;
  1791. @@ -1274,6 +1307,9 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
  1792. case NL80211_IFTYPE_STATION:
  1793. return mwifiex_change_vif_to_sta_adhoc(dev, curr_iftype,
  1794. type, params);
  1795. + case NL80211_IFTYPE_P2P_CLIENT:
  1796. + return mwifiex_change_vif_to_p2p(dev, curr_iftype,
  1797. + type, params);
  1798. case NL80211_IFTYPE_AP:
  1799. return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
  1800. params);
  1801. --
  1802. 2.33.0
  1803. From 76192487da2c919208f751c7f527f3f30c0dffc0 Mon Sep 17 00:00:00 2001
  1804. From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
  1805. Date: Fri, 26 Mar 2021 15:31:08 +0100
  1806. Subject: [PATCH] mwifiex: Handle interface type changes from AP to STATION
  1807. Looks like this case was simply overseen, so handle it, too.
  1808. Patchset: wifi
  1809. ---
  1810. drivers/net/wireless/marvell/mwifiex/cfg80211.c | 1 +
  1811. 1 file changed, 1 insertion(+)
  1812. diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1813. index a37b504bd084..e65f285e3efe 100644
  1814. --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1815. +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1816. @@ -1268,6 +1268,7 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
  1817. case NL80211_IFTYPE_AP:
  1818. switch (type) {
  1819. case NL80211_IFTYPE_ADHOC:
  1820. + case NL80211_IFTYPE_STATION:
  1821. return mwifiex_change_vif_to_sta_adhoc(dev, curr_iftype,
  1822. type, params);
  1823. break;
  1824. --
  1825. 2.33.0
  1826. From 11436598ffa34d032944ba65666ff8dfb8759228 Mon Sep 17 00:00:00 2001
  1827. From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
  1828. Date: Fri, 26 Mar 2021 15:32:16 +0100
  1829. Subject: [PATCH] mwifiex: Properly initialize private structure on interface
  1830. type changes
  1831. When creating a new virtual interface in mwifiex_add_virtual_intf(), we
  1832. update our internal driver states like bss_type, bss_priority, bss_role
  1833. and bss_mode to reflect the mode the firmware will be set to.
  1834. When switching virtual interface mode using
  1835. mwifiex_init_new_priv_params() though, we currently only update bss_mode
  1836. and bss_role. In order for the interface mode switch to actually work,
  1837. we also need to update bss_type to its proper value, so do that.
  1838. This fixes a crash of the firmware (because the driver tries to execute
  1839. commands that are invalid in AP mode) when switching from station mode
  1840. to AP mode.
  1841. Patchset: wifi
  1842. ---
  1843. drivers/net/wireless/marvell/mwifiex/cfg80211.c | 10 +++++++---
  1844. 1 file changed, 7 insertions(+), 3 deletions(-)
  1845. diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1846. index e65f285e3efe..a290312313f3 100644
  1847. --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1848. +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1849. @@ -908,16 +908,20 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv,
  1850. switch (type) {
  1851. case NL80211_IFTYPE_STATION:
  1852. case NL80211_IFTYPE_ADHOC:
  1853. - priv->bss_role = MWIFIEX_BSS_ROLE_STA;
  1854. + priv->bss_role = MWIFIEX_BSS_ROLE_STA;
  1855. + priv->bss_type = MWIFIEX_BSS_TYPE_STA;
  1856. break;
  1857. case NL80211_IFTYPE_P2P_CLIENT:
  1858. - priv->bss_role = MWIFIEX_BSS_ROLE_STA;
  1859. + priv->bss_role = MWIFIEX_BSS_ROLE_STA;
  1860. + priv->bss_type = MWIFIEX_BSS_TYPE_P2P;
  1861. break;
  1862. case NL80211_IFTYPE_P2P_GO:
  1863. - priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
  1864. + priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
  1865. + priv->bss_type = MWIFIEX_BSS_TYPE_P2P;
  1866. break;
  1867. case NL80211_IFTYPE_AP:
  1868. priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
  1869. + priv->bss_type = MWIFIEX_BSS_TYPE_UAP;
  1870. break;
  1871. default:
  1872. mwifiex_dbg(adapter, ERROR,
  1873. --
  1874. 2.33.0
  1875. From 9146bb7cf0770adeaa38ab1e456ca69466814e5e Mon Sep 17 00:00:00 2001
  1876. From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
  1877. Date: Sat, 27 Mar 2021 12:19:14 +0100
  1878. Subject: [PATCH] mwifiex: Fix copy-paste mistake when creating virtual
  1879. interface
  1880. The BSS priority here for a new P2P_CLIENT device was accidentally set
  1881. to an enum that's certainly not meant for this. Since
  1882. MWIFIEX_BSS_ROLE_STA is 0 anyway, we can just set the bss_priority to 0
  1883. instead here.
  1884. Patchset: wifi
  1885. ---
  1886. drivers/net/wireless/marvell/mwifiex/cfg80211.c | 2 +-
  1887. 1 file changed, 1 insertion(+), 1 deletion(-)
  1888. diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1889. index a290312313f3..1e1cf523e228 100644
  1890. --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1891. +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  1892. @@ -3040,7 +3040,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
  1893. priv->bss_type = MWIFIEX_BSS_TYPE_P2P;
  1894. priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
  1895. - priv->bss_priority = MWIFIEX_BSS_ROLE_STA;
  1896. + priv->bss_priority = 0;
  1897. priv->bss_role = MWIFIEX_BSS_ROLE_STA;
  1898. priv->bss_started = 0;
  1899. --
  1900. 2.33.0
  1901. From 641ae9461195af00e029d5efbec0b22813ff15d2 Mon Sep 17 00:00:00 2001
  1902. From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
  1903. Date: Tue, 13 Apr 2021 14:30:28 +0200
  1904. Subject: [PATCH] mwifiex: Deactive host sleep using HSCFG after it was
  1905. activated manually
  1906. When powersaving (so either wifi powersaving or deep sleep, depending on
  1907. which state the firmware is in) is disabled, the way the firmware goes
  1908. into host sleep is different: Usually the firmware implicitely enters
  1909. host sleep on the next SLEEP event we get when we configured host sleep
  1910. via HSCFG before. When powersaving is disabled though, there are no
  1911. SLEEP events, the way we enter host sleep in that case is different: The
  1912. firmware will send us a HS_ACT_REQ event and after that we "manually"
  1913. make the firmware enter host sleep by sending it another HSCFG command
  1914. with the action HS_ACTIVATE.
  1915. Now waking up from host sleep appears to be different depending on
  1916. whether powersaving is enabled again: When powersaving is enabled, the
  1917. firmware implicitely leaves host sleep as soon as it wakes up and sends
  1918. us an AWAKE event. When powersaving is disabled though, it apparently
  1919. doesn't implicitely leave host sleep, but instead we need to send it a
  1920. HSCFG command with the HS_CONFIGURE action and the HS_CFG_CANCEL
  1921. condition. We didn't do that so far, which is why waking up from host
  1922. sleep was broken when powersaving is disabled.
  1923. So add some additional state to mwifiex_adapter where we keep track of
  1924. whether host sleep was activated manually via HS_ACTIVATE, and if that
  1925. was the case, deactivate it manually again via HS_CFG_CANCEL.
  1926. Patchset: wifi
  1927. ---
  1928. drivers/net/wireless/marvell/mwifiex/cmdevt.c | 21 +++++++++++++++++++
  1929. drivers/net/wireless/marvell/mwifiex/main.c | 18 ++++++++++++++++
  1930. drivers/net/wireless/marvell/mwifiex/main.h | 1 +
  1931. .../net/wireless/marvell/mwifiex/sta_cmd.c | 4 ++++
  1932. 4 files changed, 44 insertions(+)
  1933. diff --git a/drivers/net/wireless/marvell/mwifiex/cmdevt.c b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
  1934. index 3a11342a6bde..5487df8f994d 100644
  1935. --- a/drivers/net/wireless/marvell/mwifiex/cmdevt.c
  1936. +++ b/drivers/net/wireless/marvell/mwifiex/cmdevt.c
  1937. @@ -608,6 +608,11 @@ int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no,
  1938. return -1;
  1939. }
  1940. + if (priv->adapter->hs_activated_manually &&
  1941. + cmd_no != HostCmd_CMD_802_11_HS_CFG_ENH) {
  1942. + mwifiex_cancel_hs(priv, MWIFIEX_ASYNC_CMD);
  1943. + priv->adapter->hs_activated_manually = false;
  1944. + }
  1945. /* Get a new command node */
  1946. cmd_node = mwifiex_get_cmd_node(adapter);
  1947. @@ -714,6 +719,15 @@ mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter,
  1948. }
  1949. }
  1950. + /* Same with exit host sleep cmd, luckily that can't happen at the same time as EXIT_PS */
  1951. + if (command == HostCmd_CMD_802_11_HS_CFG_ENH) {
  1952. + struct host_cmd_ds_802_11_hs_cfg_enh *hs_cfg =
  1953. + &host_cmd->params.opt_hs_cfg;
  1954. +
  1955. + if (le16_to_cpu(hs_cfg->action) == HS_ACTIVATE)
  1956. + add_tail = false;
  1957. + }
  1958. +
  1959. spin_lock_bh(&adapter->cmd_pending_q_lock);
  1960. if (add_tail)
  1961. list_add_tail(&cmd_node->list, &adapter->cmd_pending_q);
  1962. @@ -1216,6 +1230,13 @@ mwifiex_process_hs_config(struct mwifiex_adapter *adapter)
  1963. __func__);
  1964. adapter->if_ops.wakeup(adapter);
  1965. +
  1966. + if (adapter->hs_activated_manually) {
  1967. + mwifiex_cancel_hs(mwifiex_get_priv (adapter, MWIFIEX_BSS_ROLE_ANY),
  1968. + MWIFIEX_ASYNC_CMD);
  1969. + adapter->hs_activated_manually = false;
  1970. + }
  1971. +
  1972. adapter->hs_activated = false;
  1973. clear_bit(MWIFIEX_IS_HS_CONFIGURED, &adapter->work_flags);
  1974. clear_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags);
  1975. diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
  1976. index 6283df5aaaf8..b30547d1f153 100644
  1977. --- a/drivers/net/wireless/marvell/mwifiex/main.c
  1978. +++ b/drivers/net/wireless/marvell/mwifiex/main.c
  1979. @@ -401,6 +401,12 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
  1980. !adapter->scan_processing) &&
  1981. !adapter->data_sent &&
  1982. !skb_queue_empty(&adapter->tx_data_q)) {
  1983. + if (adapter->hs_activated_manually) {
  1984. + mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY),
  1985. + MWIFIEX_ASYNC_CMD);
  1986. + adapter->hs_activated_manually = false;
  1987. + }
  1988. +
  1989. mwifiex_process_tx_queue(adapter);
  1990. if (adapter->hs_activated) {
  1991. clear_bit(MWIFIEX_IS_HS_CONFIGURED,
  1992. @@ -418,6 +424,12 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
  1993. !mwifiex_bypass_txlist_empty(adapter) &&
  1994. !mwifiex_is_tdls_chan_switching
  1995. (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA))) {
  1996. + if (adapter->hs_activated_manually) {
  1997. + mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY),
  1998. + MWIFIEX_ASYNC_CMD);
  1999. + adapter->hs_activated_manually = false;
  2000. + }
  2001. +
  2002. mwifiex_process_bypass_tx(adapter);
  2003. if (adapter->hs_activated) {
  2004. clear_bit(MWIFIEX_IS_HS_CONFIGURED,
  2005. @@ -434,6 +446,12 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
  2006. !adapter->data_sent && !mwifiex_wmm_lists_empty(adapter) &&
  2007. !mwifiex_is_tdls_chan_switching
  2008. (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA))) {
  2009. + if (adapter->hs_activated_manually) {
  2010. + mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY),
  2011. + MWIFIEX_ASYNC_CMD);
  2012. + adapter->hs_activated_manually = false;
  2013. + }
  2014. +
  2015. mwifiex_wmm_process_tx(adapter);
  2016. if (adapter->hs_activated) {
  2017. clear_bit(MWIFIEX_IS_HS_CONFIGURED,
  2018. diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h
  2019. index 5923c5c14c8d..90012cbcfd15 100644
  2020. --- a/drivers/net/wireless/marvell/mwifiex/main.h
  2021. +++ b/drivers/net/wireless/marvell/mwifiex/main.h
  2022. @@ -986,6 +986,7 @@ struct mwifiex_adapter {
  2023. struct timer_list wakeup_timer;
  2024. struct mwifiex_hs_config_param hs_cfg;
  2025. u8 hs_activated;
  2026. + u8 hs_activated_manually;
  2027. u16 hs_activate_wait_q_woken;
  2028. wait_queue_head_t hs_activate_wait_q;
  2029. u8 event_body[MAX_EVENT_SIZE];
  2030. diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
  2031. index d3a968ef21ef..76db9a7b8199 100644
  2032. --- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
  2033. +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
  2034. @@ -396,6 +396,10 @@ mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv,
  2035. if (hs_activate) {
  2036. hs_cfg->action = cpu_to_le16(HS_ACTIVATE);
  2037. hs_cfg->params.hs_activate.resp_ctrl = cpu_to_le16(RESP_NEEDED);
  2038. +
  2039. + adapter->hs_activated_manually = true;
  2040. + mwifiex_dbg(priv->adapter, CMD,
  2041. + "cmd: Activating host sleep manually\n");
  2042. } else {
  2043. hs_cfg->action = cpu_to_le16(HS_CONFIGURE);
  2044. hs_cfg->params.hs_config.conditions = hscfg_param->conditions;
  2045. --
  2046. 2.33.0
  2047. From 0b983e2872f4416a627caa305cc0276443555c9c Mon Sep 17 00:00:00 2001
  2048. From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
  2049. Date: Tue, 13 Apr 2021 14:23:05 +0200
  2050. Subject: [PATCH] mwifiex: Add quirk to disable deep sleep with certain
  2051. hardware revision
  2052. The 88W8897 pcie card with the hardware revision 20 apparently has a
  2053. hardware issue where the card wakes up from deep sleep randomly and very
  2054. often, somewhat depending on the card activity, maybe the hardware has a
  2055. floating wakeup pin or something.
  2056. Those continuous wakeups prevent the card from entering host sleep when
  2057. the computer suspends. And because the host won't answer to events from
  2058. the card anymore while it's suspended, the firmwares internal
  2059. powersaving state machine seems to get confused and the card can't sleep
  2060. anymore at all after that.
  2061. Since we can't work around that hardware bug in the firmware, let's
  2062. get the hardware revision string from the firmware and match it with
  2063. known bad revisions. Then disable auto deep sleep for those revisions,
  2064. which makes sure we no longer get those spurious wakeups.
  2065. Patchset: wifi
  2066. ---
  2067. drivers/net/wireless/marvell/mwifiex/main.c | 14 ++++++++++++++
  2068. drivers/net/wireless/marvell/mwifiex/main.h | 1 +
  2069. .../net/wireless/marvell/mwifiex/sta_cmdresp.c | 16 ++++++++++++++++
  2070. 3 files changed, 31 insertions(+)
  2071. diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c
  2072. index b30547d1f153..347d29fd92c0 100644
  2073. --- a/drivers/net/wireless/marvell/mwifiex/main.c
  2074. +++ b/drivers/net/wireless/marvell/mwifiex/main.c
  2075. @@ -226,6 +226,19 @@ static int mwifiex_process_rx(struct mwifiex_adapter *adapter)
  2076. return 0;
  2077. }
  2078. +static void maybe_quirk_fw_disable_ds(struct mwifiex_adapter *adapter)
  2079. +{
  2080. + struct mwifiex_private *priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
  2081. + struct mwifiex_ver_ext ver_ext;
  2082. +
  2083. + set_bit(MWIFIEX_IS_REQUESTING_FW_VEREXT, &adapter->work_flags);
  2084. +
  2085. + memset(&ver_ext, 0, sizeof(ver_ext));
  2086. + ver_ext.version_str_sel = 1;
  2087. + mwifiex_send_cmd(priv, HostCmd_CMD_VERSION_EXT,
  2088. + HostCmd_ACT_GEN_GET, 0, &ver_ext, false);
  2089. +}
  2090. +
  2091. /*
  2092. * The main process.
  2093. *
  2094. @@ -356,6 +369,7 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
  2095. if (adapter->hw_status == MWIFIEX_HW_STATUS_INIT_DONE) {
  2096. adapter->hw_status = MWIFIEX_HW_STATUS_READY;
  2097. mwifiex_init_fw_complete(adapter);
  2098. + maybe_quirk_fw_disable_ds(adapter);
  2099. }
  2100. }
  2101. diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h
  2102. index 90012cbcfd15..1e829d84b1f6 100644
  2103. --- a/drivers/net/wireless/marvell/mwifiex/main.h
  2104. +++ b/drivers/net/wireless/marvell/mwifiex/main.h
  2105. @@ -524,6 +524,7 @@ enum mwifiex_adapter_work_flags {
  2106. MWIFIEX_IS_SUSPENDED,
  2107. MWIFIEX_IS_HS_CONFIGURED,
  2108. MWIFIEX_IS_HS_ENABLING,
  2109. + MWIFIEX_IS_REQUESTING_FW_VEREXT,
  2110. };
  2111. struct mwifiex_band_config {
  2112. diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c
  2113. index 119ccacd1fcc..fb245adba19f 100644
  2114. --- a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c
  2115. +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c
  2116. @@ -707,6 +707,22 @@ static int mwifiex_ret_ver_ext(struct mwifiex_private *priv,
  2117. {
  2118. struct host_cmd_ds_version_ext *ver_ext = &resp->params.verext;
  2119. + if (test_and_clear_bit(MWIFIEX_IS_REQUESTING_FW_VEREXT, &priv->adapter->work_flags)) {
  2120. + if (strncmp(ver_ext->version_str, "ChipRev:20, BB:9b(10.00), RF:40(21)", 128) == 0) {
  2121. + struct mwifiex_ds_auto_ds auto_ds = {
  2122. + .auto_ds = DEEP_SLEEP_OFF,
  2123. + };
  2124. +
  2125. + mwifiex_dbg(priv->adapter, MSG,
  2126. + "Bad HW revision detected, disabling deep sleep\n");
  2127. +
  2128. + mwifiex_send_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH,
  2129. + DIS_AUTO_PS, BITMAP_AUTO_DS, &auto_ds, false);
  2130. + }
  2131. +
  2132. + return 0;
  2133. + }
  2134. +
  2135. if (version_ext) {
  2136. version_ext->version_str_sel = ver_ext->version_str_sel;
  2137. memcpy(version_ext->version_str, ver_ext->version_str,
  2138. --
  2139. 2.33.0
  2140. From 72db0d979c61e664beb338aff7558a40bd50c585 Mon Sep 17 00:00:00 2001
  2141. From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
  2142. Date: Wed, 11 Nov 2020 15:17:07 +0100
  2143. Subject: [PATCH] mwifiex: Don't log error on suspend if wake-on-wlan is
  2144. disabled
  2145. It's not an error if someone chooses to put their computer to sleep, not
  2146. wanting it to wake up because the person next door has just discovered
  2147. what a magic packet is. So change the loglevel of this annoying message
  2148. from ERROR to INFO.
  2149. Patchset: wifi
  2150. ---
  2151. drivers/net/wireless/marvell/mwifiex/cfg80211.c | 2 +-
  2152. 1 file changed, 1 insertion(+), 1 deletion(-)
  2153. diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  2154. index 1e1cf523e228..1cdd66c37cfc 100644
  2155. --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  2156. +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  2157. @@ -3480,7 +3480,7 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
  2158. }
  2159. if (!wowlan) {
  2160. - mwifiex_dbg(adapter, ERROR,
  2161. + mwifiex_dbg(adapter, INFO,
  2162. "None of the WOWLAN triggers enabled\n");
  2163. ret = 0;
  2164. goto done;
  2165. --
  2166. 2.33.0
  2167. From 8f21280f53919658a62bddd3074dff3149d5ee0f Mon Sep 17 00:00:00 2001
  2168. From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
  2169. Date: Sun, 28 Mar 2021 21:42:54 +0200
  2170. Subject: [PATCH] mwifiex: Log an error on command failure during key-material
  2171. upload
  2172. Sometimes the KEY_MATERIAL command can fail with the 88W8897 firmware
  2173. (when this happens exactly seems pretty random). This appears to prevent
  2174. the access point from starting, so it seems like a good idea to log an
  2175. error in that case.
  2176. Patchset: wifi
  2177. ---
  2178. drivers/net/wireless/marvell/mwifiex/cfg80211.c | 10 ++++++++--
  2179. 1 file changed, 8 insertions(+), 2 deletions(-)
  2180. diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  2181. index 1cdd66c37cfc..6ad935c1bb47 100644
  2182. --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  2183. +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  2184. @@ -519,8 +519,14 @@ mwifiex_cfg80211_set_default_mgmt_key(struct wiphy *wiphy,
  2185. encrypt_key.is_igtk_def_key = true;
  2186. eth_broadcast_addr(encrypt_key.mac_addr);
  2187. - return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
  2188. - HostCmd_ACT_GEN_SET, true, &encrypt_key, true);
  2189. + if (mwifiex_send_cmd(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
  2190. + HostCmd_ACT_GEN_SET, true, &encrypt_key, true)) {
  2191. + mwifiex_dbg(priv->adapter, ERROR,
  2192. + "Sending KEY_MATERIAL command failed\n");
  2193. + return -1;
  2194. + }
  2195. +
  2196. + return 0;
  2197. }
  2198. /*
  2199. --
  2200. 2.33.0
  2201. From f04acb15a376038a69aa59e71a69641b6f26ab41 Mon Sep 17 00:00:00 2001
  2202. From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
  2203. Date: Tue, 13 Apr 2021 12:44:03 +0200
  2204. Subject: [PATCH] mwifiex: Fix an incorrect comment
  2205. We're sending DELBA requests here, not ADDBA requests.
  2206. Patchset: wifi
  2207. ---
  2208. drivers/net/wireless/marvell/mwifiex/11n.c | 2 +-
  2209. 1 file changed, 1 insertion(+), 1 deletion(-)
  2210. diff --git a/drivers/net/wireless/marvell/mwifiex/11n.c b/drivers/net/wireless/marvell/mwifiex/11n.c
  2211. index 6696bce56178..b0695432b26a 100644
  2212. --- a/drivers/net/wireless/marvell/mwifiex/11n.c
  2213. +++ b/drivers/net/wireless/marvell/mwifiex/11n.c
  2214. @@ -125,7 +125,7 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv,
  2215. tx_ba_tbl->ra);
  2216. } else { /*
  2217. * In case of failure, recreate the deleted stream in case
  2218. - * we initiated the ADDBA
  2219. + * we initiated the DELBA
  2220. */
  2221. if (!INITIATOR_BIT(del_ba_param_set))
  2222. return 0;
  2223. --
  2224. 2.33.0
  2225. From 7e38959b0035469e0e21c1013978325c01c3b311 Mon Sep 17 00:00:00 2001
  2226. From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
  2227. Date: Tue, 13 Apr 2021 12:45:59 +0200
  2228. Subject: [PATCH] mwifiex: Send DELBA requests according to spec
  2229. We're currently failing to set the initiator bit for DELBA requests:
  2230. While we set the bit on our del_ba_param_set bitmask, we forget to
  2231. actually copy that bitmask over to the command struct, which means we
  2232. never actually set the initiator bit.
  2233. Fix that and copy the bitmask over to the host_cmd_ds_11n_delba command
  2234. struct.
  2235. Patchset: wifi
  2236. ---
  2237. drivers/net/wireless/marvell/mwifiex/11n.c | 5 +++--
  2238. 1 file changed, 3 insertions(+), 2 deletions(-)
  2239. diff --git a/drivers/net/wireless/marvell/mwifiex/11n.c b/drivers/net/wireless/marvell/mwifiex/11n.c
  2240. index b0695432b26a..9ff2058bcd7e 100644
  2241. --- a/drivers/net/wireless/marvell/mwifiex/11n.c
  2242. +++ b/drivers/net/wireless/marvell/mwifiex/11n.c
  2243. @@ -657,14 +657,15 @@ int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac,
  2244. uint16_t del_ba_param_set;
  2245. memset(&delba, 0, sizeof(delba));
  2246. - delba.del_ba_param_set = cpu_to_le16(tid << DELBA_TID_POS);
  2247. - del_ba_param_set = le16_to_cpu(delba.del_ba_param_set);
  2248. + del_ba_param_set = tid << DELBA_TID_POS;
  2249. +
  2250. if (initiator)
  2251. del_ba_param_set |= IEEE80211_DELBA_PARAM_INITIATOR_MASK;
  2252. else
  2253. del_ba_param_set &= ~IEEE80211_DELBA_PARAM_INITIATOR_MASK;
  2254. + delba.del_ba_param_set = cpu_to_le16(del_ba_param_set);
  2255. memcpy(&delba.peer_mac_addr, peer_mac, ETH_ALEN);
  2256. /* We don't wait for the response of this command */
  2257. --
  2258. 2.33.0
  2259. From b326904b93eebe73866ce9ca95bb20e83571333e Mon Sep 17 00:00:00 2001
  2260. From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl>
  2261. Date: Tue, 13 Apr 2021 12:57:41 +0200
  2262. Subject: [PATCH] mwifiex: Ignore BTCOEX events from the firmware
  2263. The firmware of the pcie 88W8897 chip sends those events very
  2264. unreliably, which means we sometimes end up actually capping the window
  2265. size while bluetooth is disabled, artifically limiting wifi speeds even
  2266. though it's not needed.
  2267. Since we can't fix the firmware, let's just ignore those events, it
  2268. seems that the Windows driver also doesn't change the rx/tx block ack
  2269. buffer sizes when bluetooth gets enabled or disabled, so this is
  2270. consistent with the Windows driver.
  2271. Patchset: wifi
  2272. ---
  2273. drivers/net/wireless/marvell/mwifiex/sta_event.c | 4 +---
  2274. 1 file changed, 1 insertion(+), 3 deletions(-)
  2275. diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c
  2276. index bc79ca4cb803..5e9e67d97857 100644
  2277. --- a/drivers/net/wireless/marvell/mwifiex/sta_event.c
  2278. +++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c
  2279. @@ -1056,9 +1056,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
  2280. adapter->event_skb);
  2281. break;
  2282. case EVENT_BT_COEX_WLAN_PARA_CHANGE:
  2283. - dev_dbg(adapter->dev, "EVENT: BT coex wlan param update\n");
  2284. - mwifiex_bt_coex_wlan_param_update_event(priv,
  2285. - adapter->event_skb);
  2286. + dev_dbg(adapter->dev, "EVENT: ignoring BT coex wlan param update\n");
  2287. break;
  2288. case EVENT_RXBA_SYNC:
  2289. dev_dbg(adapter->dev, "EVENT: RXBA_SYNC\n");
  2290. --
  2291. 2.33.0