0005-wifi.patch 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. From 25533d6a5d98372ae1a7e04c7fb0fd35bd4d19f6 Mon Sep 17 00:00:00 2001
  2. From: kitakar5525 <34676735+kitakar5525@users.noreply.github.com>
  3. Date: Thu, 20 Feb 2020 16:51:11 +0900
  4. Subject: [PATCH 5/6] wifi
  5. ---
  6. .../net/wireless/marvell/mwifiex/cfg80211.c | 26 ++++++
  7. drivers/net/wireless/marvell/mwifiex/pcie.c | 84 +++++++++++--------
  8. .../net/wireless/marvell/mwifiex/sta_cmd.c | 31 ++-----
  9. 3 files changed, 84 insertions(+), 57 deletions(-)
  10. diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
  11. index 9e6dc289ec3e8..00b4bc4469892 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 fc1706d0647d7..b51c5e3571426 100644
  52. --- a/drivers/net/wireless/marvell/mwifiex/pcie.c
  53. +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
  54. @@ -146,38 +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 pci_dev *pdev = to_pci_dev(dev);
  66. + struct pcie_service_card *card = pci_get_drvdata(pdev);
  67. struct mwifiex_adapter *adapter;
  68. - struct pcie_service_card *card = dev_get_drvdata(dev);
  69. -
  70. + struct mwifiex_private *priv;
  71. + const struct mwifiex_pcie_card_reg *reg;
  72. + u32 fw_status;
  73. + int ret;
  74. /* Might still be loading firmware */
  75. wait_for_completion(&card->fw_done);
  76. adapter = card->adapter;
  77. - if (!adapter) {
  78. - dev_err(dev, "adapter is not valid\n");
  79. + if (!adapter || !adapter->priv_num)
  80. return 0;
  81. - }
  82. - mwifiex_enable_wake(adapter);
  83. + reg = card->pcie.reg;
  84. + if (reg)
  85. + ret = mwifiex_read_reg(adapter, reg->fw_status, &fw_status);
  86. + else
  87. + fw_status = -1;
  88. - /* Enable the Host Sleep */
  89. - if (!mwifiex_enable_hs(adapter)) {
  90. - mwifiex_dbg(adapter, ERROR,
  91. - "cmd: failed to suspend\n");
  92. - clear_bit(MWIFIEX_IS_HS_ENABLING, &adapter->work_flags);
  93. - mwifiex_disable_wake(adapter);
  94. - return -EFAULT;
  95. - }
  96. + if (fw_status == FIRMWARE_READY_PCIE && !adapter->mfg_mode) {
  97. + mwifiex_deauthenticate_all(adapter);
  98. - flush_workqueue(adapter->workqueue);
  99. + priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
  100. +
  101. + mwifiex_disable_auto_ds(priv);
  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_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);
  106. + }
  107. +
  108. + mwifiex_remove_card(adapter);
  109. return 0;
  110. }
  111. @@ -189,31 +196,35 @@ static int mwifiex_pcie_suspend(struct device *dev)
  112. *
  113. * If already not resumed, this function turns on the traffic and
  114. * sends a host sleep cancel request to the firmware.
  115. + *
  116. + * XXX: ignoring all the above comment and probes the card that was
  117. + * removed on suspend. Required code is extracted from mwifiex_pcie_probe().
  118. */
  119. static int mwifiex_pcie_resume(struct device *dev)
  120. {
  121. - struct mwifiex_adapter *adapter;
  122. - struct pcie_service_card *card = dev_get_drvdata(dev);
  123. + struct pci_dev *pdev = to_pci_dev(dev);
  124. + struct pcie_service_card *card = pci_get_drvdata(pdev);
  125. + int ret;
  126. + pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
  127. + pdev->vendor, pdev->device, pdev->revision);
  128. - if (!card->adapter) {
  129. - dev_err(dev, "adapter structure is not valid\n");
  130. - return 0;
  131. - }
  132. + init_completion(&card->fw_done);
  133. - adapter = card->adapter;
  134. + card->dev = pdev;
  135. - if (!test_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags)) {
  136. - mwifiex_dbg(adapter, WARN,
  137. - "Device already resumed\n");
  138. - return 0;
  139. + /* device tree node parsing and platform specific configuration */
  140. + if (pdev->dev.of_node) {
  141. + ret = mwifiex_pcie_probe_of(&pdev->dev);
  142. + if (ret)
  143. + return ret;
  144. }
  145. - clear_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags);
  146. -
  147. - mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
  148. - MWIFIEX_ASYNC_CMD);
  149. - mwifiex_disable_wake(adapter);
  150. + if (mwifiex_add_card(card, &card->fw_done, &pcie_ops,
  151. + MWIFIEX_PCIE, &pdev->dev)) {
  152. + pr_err("%s failed\n", __func__);
  153. + return -1;
  154. + }
  155. return 0;
  156. }
  157. @@ -229,8 +240,13 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
  158. const struct pci_device_id *ent)
  159. {
  160. struct pcie_service_card *card;
  161. + struct pci_dev *parent_pdev = pci_upstream_bridge(pdev);
  162. int ret;
  163. + /* disable bridge_d3 to fix driver crashing after suspend on gen4+
  164. + * Surface devices */
  165. + parent_pdev->bridge_d3 = false;
  166. +
  167. pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n",
  168. pdev->vendor, pdev->device, pdev->revision);
  169. diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
  170. index 4ed10cf82f9a4..410bef3d6a6eb 100644
  171. --- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
  172. +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c
  173. @@ -2254,7 +2254,6 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
  174. * - Function init (for first interface only)
  175. * - Read MAC address (for first interface only)
  176. * - Reconfigure Tx buffer size (for first interface only)
  177. - * - Enable auto deep sleep (for first interface only)
  178. * - Get Tx rate
  179. * - Get Tx power
  180. * - Set IBSS coalescing status
  181. @@ -2267,7 +2266,6 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
  182. struct mwifiex_adapter *adapter = priv->adapter;
  183. int ret;
  184. struct mwifiex_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl;
  185. - struct mwifiex_ds_auto_ds auto_ds;
  186. enum state_11d_t state_11d;
  187. struct mwifiex_ds_11n_tx_cfg tx_cfg;
  188. u8 sdio_sp_rx_aggr_enable;
  189. @@ -2339,16 +2337,10 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
  190. if (ret)
  191. return -1;
  192. - if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
  193. - /* Enable IEEE PS by default */
  194. - priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
  195. - ret = mwifiex_send_cmd(priv,
  196. - HostCmd_CMD_802_11_PS_MODE_ENH,
  197. - EN_AUTO_PS, BITMAP_STA_PS, NULL,
  198. - true);
  199. - if (ret)
  200. - return -1;
  201. - }
  202. + /* Not enabling ps_mode (IEEE power_save) by default. Enabling
  203. + * this causes connection instability, especially on 5GHz APs
  204. + * and eventually causes "firmware wakeup failed". Therefore,
  205. + * the relevant code was removed from here. */
  206. if (drcs) {
  207. adapter->drcs_enabled = true;
  208. @@ -2395,17 +2387,10 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
  209. if (ret)
  210. return -1;
  211. - if (!disable_auto_ds && first_sta &&
  212. - priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
  213. - /* Enable auto deep sleep */
  214. - auto_ds.auto_ds = DEEP_SLEEP_ON;
  215. - auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME;
  216. - ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_PS_MODE_ENH,
  217. - EN_AUTO_PS, BITMAP_AUTO_DS,
  218. - &auto_ds, true);
  219. - if (ret)
  220. - return -1;
  221. - }
  222. + /* Not enabling auto deep sleep (auto_ds) by default. Enabling
  223. + * this reportedly causes "suspend/resume fails when not connected
  224. + * to an Access Point." Therefore, the relevant code was removed
  225. + * from here. */
  226. if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
  227. /* Send cmd to FW to enable/disable 11D function */
  228. --
  229. 2.28.0