0010-wifi.patch 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. From 9bb4c5b00ce73302b1321f7b51bfbe7bcf7386fb Mon Sep 17 00:00:00 2001
  2. From: sebanc <22224731+sebanc@users.noreply.github.com>
  3. Date: Mon, 4 Nov 2019 09:30:57 +0100
  4. Subject: [PATCH 10/10] wifi
  5. ---
  6. .../net/wireless/marvell/mwifiex/cfg80211.c | 26 ++++++
  7. drivers/net/wireless/marvell/mwifiex/pcie.c | 86 +++++++++++--------
  8. .../net/wireless/marvell/mwifiex/sta_cmd.c | 31 ++-----
  9. 3 files changed, 83 insertions(+), 60 deletions(-)
  10. diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  11. index 7b74ef71bef1..d8e65b733cb3 100644
  12. --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  13. +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  14. @@ -25,6 +25,11 @@
  15. static char *reg_alpha2;
  16. module_param(reg_alpha2, charp, 0);
  17. +static bool allow_ps_mode;
  18. +module_param(allow_ps_mode, bool, 0444);
  19. +MODULE_PARM_DESC(allow_ps_mode,
  20. + "allow WiFi power management to be enabled. (default: disallowed)");
  21. +
  22. static const struct ieee80211_iface_limit mwifiex_ap_sta_limits[] = {
  23. {
  24. .max = 3, .types = BIT(NL80211_IFTYPE_STATION) |
  25. @@ -439,6 +444,27 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy,
  26. ps_mode = enabled;
  27. + /* Allow ps_mode to be enabled only when allow_ps_mode is set
  28. + * (but always allow ps_mode to be disabled in case it gets enabled
  29. + * for unknown reason and you want to disable it) */
  30. + if (ps_mode && !allow_ps_mode) {
  31. + dev_info(priv->adapter->dev,
  32. + "Request to enable ps_mode received but it's disallowed "
  33. + "by module parameter. Rejecting the request.\n");
  34. +
  35. + /* Return negative value to inform userspace tools that setting
  36. + * power_save to be enabled is not permitted. */
  37. + return -1;
  38. + }
  39. +
  40. + if (ps_mode)
  41. + dev_warn(priv->adapter->dev,
  42. + "WARN: Request to enable ps_mode received. Enabling it. "
  43. + "Disable it if you encounter connection instability.\n");
  44. + else
  45. + dev_info(priv->adapter->dev,
  46. + "Request to disable ps_mode received. Disabling it.\n");
  47. +
  48. return mwifiex_drv_set_power(priv, &ps_mode);
  49. }
  50. diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
  51. index 991b9cc18000..2464f536192c 100644
  52. --- a/drivers/net/wireless/marvell/mwifiex/pcie.c
  53. +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
  54. @@ -146,40 +146,45 @@ static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter)
  55. *
  56. * If already not suspended, this function allocates and sends a host
  57. * sleep activate request to the firmware and turns off the traffic.
  58. + *
  59. + * XXX: ignoring all the above comment and just removes the card to
  60. + * fix S0ix and "AP scanning (sometimes) not working after suspend".
  61. + * Required code is extracted from mwifiex_pcie_remove().
  62. */
  63. static int mwifiex_pcie_suspend(struct device *dev)
  64. {
  65. - struct mwifiex_adapter *adapter;
  66. - struct pcie_service_card *card;
  67. struct pci_dev *pdev = to_pci_dev(dev);
  68. -
  69. - card = pci_get_drvdata(pdev);
  70. + struct pcie_service_card *card = pci_get_drvdata(pdev);
  71. + struct mwifiex_adapter *adapter;
  72. + struct mwifiex_private *priv;
  73. + const struct mwifiex_pcie_card_reg *reg;
  74. + u32 fw_status;
  75. + int ret;
  76. /* Might still be loading firmware */
  77. wait_for_completion(&card->fw_done);
  78. adapter = card->adapter;
  79. - if (!adapter) {
  80. - dev_err(dev, "adapter is not valid\n");
  81. + if (!adapter || !adapter->priv_num)
  82. return 0;
  83. - }
  84. - mwifiex_enable_wake(adapter);
  85. + reg = card->pcie.reg;
  86. + if (reg)
  87. + ret = mwifiex_read_reg(adapter, reg->fw_status, &fw_status);
  88. + else
  89. + fw_status = -1;
  90. - /* Enable the Host Sleep */
  91. - if (!mwifiex_enable_hs(adapter)) {
  92. - mwifiex_dbg(adapter, ERROR,
  93. - "cmd: failed to suspend\n");
  94. - clear_bit(MWIFIEX_IS_HS_ENABLING, &adapter->work_flags);
  95. - mwifiex_disable_wake(adapter);
  96. - return -EFAULT;
  97. - }
  98. + if (fw_status == FIRMWARE_READY_PCIE && !adapter->mfg_mode) {
  99. + mwifiex_deauthenticate_all(adapter);
  100. - flush_workqueue(adapter->workqueue);
  101. + priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
  102. - /* Indicate device suspended */
  103. - set_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags);
  104. - clear_bit(MWIFIEX_IS_HS_ENABLING, &adapter->work_flags);
  105. + mwifiex_disable_auto_ds(priv);
  106. +
  107. + mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
  108. + }
  109. +
  110. + mwifiex_remove_card(adapter);
  111. return 0;
  112. }
  113. @@ -191,33 +196,35 @@ static int mwifiex_pcie_suspend(struct device *dev)
  114. *
  115. * If already not resumed, this function turns on the traffic and
  116. * sends a host sleep cancel request to the firmware.
  117. + *
  118. + * XXX: ignoring all the above comment and probes the card that was
  119. + * removed on suspend. Required code is extracted from mwifiex_pcie_probe().
  120. */
  121. static int mwifiex_pcie_resume(struct device *dev)
  122. {
  123. - struct mwifiex_adapter *adapter;
  124. - struct pcie_service_card *card;
  125. struct pci_dev *pdev = to_pci_dev(dev);
  126. + struct pcie_service_card *card = pci_get_drvdata(pdev);
  127. + int ret;
  128. - card = pci_get_drvdata(pdev);
  129. + pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
  130. + pdev->vendor, pdev->device, pdev->revision);
  131. - if (!card->adapter) {
  132. - dev_err(dev, "adapter structure is not valid\n");
  133. - return 0;
  134. - }
  135. + init_completion(&card->fw_done);
  136. - adapter = card->adapter;
  137. + card->dev = pdev;
  138. - if (!test_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags)) {
  139. - mwifiex_dbg(adapter, WARN,
  140. - "Device already resumed\n");
  141. - return 0;
  142. + /* device tree node parsing and platform specific configuration */
  143. + if (pdev->dev.of_node) {
  144. + ret = mwifiex_pcie_probe_of(&pdev->dev);
  145. + if (ret)
  146. + return ret;
  147. }
  148. - clear_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags);
  149. -
  150. - mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
  151. - MWIFIEX_ASYNC_CMD);
  152. - mwifiex_disable_wake(adapter);
  153. + if (mwifiex_add_card(card, &card->fw_done, &pcie_ops,
  154. + MWIFIEX_PCIE, &pdev->dev)) {
  155. + pr_err("%s failed\n", __func__);
  156. + return -1;
  157. + }
  158. return 0;
  159. }
  160. @@ -233,8 +240,13 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
  161. const struct pci_device_id *ent)
  162. {
  163. struct pcie_service_card *card;
  164. + struct pci_dev *parent_pdev = pci_upstream_bridge(pdev);
  165. int ret;
  166. + /* disable bridge_d3 to fix driver crashing after suspend on gen4+
  167. + * Surface devices */
  168. + parent_pdev->bridge_d3 = false;
  169. +
  170. pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
  171. pdev->vendor, pdev->device, pdev->revision);
  172. diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
  173. index 4ed10cf82f9a..410bef3d6a6e 100644
  174. --- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
  175. +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
  176. @@ -2254,7 +2254,6 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
  177. * - Function init (for first interface only)
  178. * - Read MAC address (for first interface only)
  179. * - Reconfigure Tx buffer size (for first interface only)
  180. - * - Enable auto deep sleep (for first interface only)
  181. * - Get Tx rate
  182. * - Get Tx power
  183. * - Set IBSS coalescing status
  184. @@ -2267,7 +2266,6 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
  185. struct mwifiex_adapter *adapter = priv->adapter;
  186. int ret;
  187. struct mwifiex_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl;
  188. - struct mwifiex_ds_auto_ds auto_ds;
  189. enum state_11d_t state_11d;
  190. struct mwifiex_ds_11n_tx_cfg tx_cfg;
  191. u8 sdio_sp_rx_aggr_enable;
  192. @@ -2339,16 +2337,10 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
  193. if (ret)
  194. return -1;
  195. - if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
  196. - /* Enable IEEE PS by default */
  197. - priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
  198. - ret = mwifiex_send_cmd(priv,
  199. - HostCmd_CMD_802_11_PS_MODE_ENH,
  200. - EN_AUTO_PS, BITMAP_STA_PS, NULL,
  201. - true);
  202. - if (ret)
  203. - return -1;
  204. - }
  205. + /* Not enabling ps_mode (IEEE power_save) by default. Enabling
  206. + * this causes connection instability, especially on 5GHz APs
  207. + * and eventually causes "firmware wakeup failed". Therefore,
  208. + * the relevant code was removed from here. */
  209. if (drcs) {
  210. adapter->drcs_enabled = true;
  211. @@ -2395,17 +2387,10 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
  212. if (ret)
  213. return -1;
  214. - if (!disable_auto_ds && first_sta &&
  215. - priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
  216. - /* Enable auto deep sleep */
  217. - auto_ds.auto_ds = DEEP_SLEEP_ON;
  218. - auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME;
  219. - ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH,
  220. - EN_AUTO_PS, BITMAP_AUTO_DS,
  221. - &auto_ds, true);
  222. - if (ret)
  223. - return -1;
  224. - }
  225. + /* Not enabling auto deep sleep (auto_ds) by default. Enabling
  226. + * this reportedly causes "suspend/resume fails when not connected
  227. + * to an Access Point." Therefore, the relevant code was removed
  228. + * from here. */
  229. if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
  230. /* Send cmd to FW to enable/disable 11D function */
  231. --
  232. 2.26.2