0007-wifi.patch 89 KB

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