11ac.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. /*
  2. * Marvell Wireless LAN device driver: 802.11ac
  3. *
  4. * Copyright (C) 2013-2014, Marvell International Ltd.
  5. *
  6. * This software file (the "File") is distributed by Marvell International
  7. * Ltd. under the terms of the GNU General Public License Version 2, June 1991
  8. * (the "License"). You may use, redistribute and/or modify this File in
  9. * accordance with the terms and conditions of the License, a copy of which
  10. * is available by writing to the Free Software Foundation, Inc.,
  11. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
  12. * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
  13. *
  14. * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
  15. * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
  16. * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
  17. * this warranty disclaimer.
  18. */
  19. #include "decl.h"
  20. #include "ioctl.h"
  21. #include "fw.h"
  22. #include "main.h"
  23. #include "11ac.h"
  24. /* Tables of the MCS map to the highest data rate (in Mbps) supported
  25. * for long GI.
  26. */
  27. static const u16 max_rate_lgi_80MHZ[8][3] = {
  28. {0x124, 0x15F, 0x186}, /* NSS = 1 */
  29. {0x249, 0x2BE, 0x30C}, /* NSS = 2 */
  30. {0x36D, 0x41D, 0x492}, /* NSS = 3 */
  31. {0x492, 0x57C, 0x618}, /* NSS = 4 */
  32. {0x5B6, 0x6DB, 0x79E}, /* NSS = 5 */
  33. {0x6DB, 0x83A, 0x0}, /* NSS = 6 */
  34. {0x7FF, 0x999, 0xAAA}, /* NSS = 7 */
  35. {0x924, 0xAF8, 0xC30} /* NSS = 8 */
  36. };
  37. static const u16 max_rate_lgi_160MHZ[8][3] = {
  38. {0x249, 0x2BE, 0x30C}, /* NSS = 1 */
  39. {0x492, 0x57C, 0x618}, /* NSS = 2 */
  40. {0x6DB, 0x83A, 0x0}, /* NSS = 3 */
  41. {0x924, 0xAF8, 0xC30}, /* NSS = 4 */
  42. {0xB6D, 0xDB6, 0xF3C}, /* NSS = 5 */
  43. {0xDB6, 0x1074, 0x1248}, /* NSS = 6 */
  44. {0xFFF, 0x1332, 0x1554}, /* NSS = 7 */
  45. {0x1248, 0x15F0, 0x1860} /* NSS = 8 */
  46. };
  47. /* This function converts the 2-bit MCS map to the highest long GI
  48. * VHT data rate.
  49. */
  50. static u16
  51. mwifiex_convert_mcsmap_to_maxrate(struct mwifiex_private *priv,
  52. u8 bands, u16 mcs_map)
  53. {
  54. u8 i, nss, mcs;
  55. u16 max_rate = 0;
  56. u32 usr_vht_cap_info = 0;
  57. struct mwifiex_adapter *adapter = priv->adapter;
  58. if (bands & BAND_AAC)
  59. usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_a;
  60. else
  61. usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_bg;
  62. /* find the max NSS supported */
  63. nss = 1;
  64. for (i = 1; i <= 8; i++) {
  65. mcs = GET_VHTNSSMCS(mcs_map, i);
  66. if (mcs < IEEE80211_VHT_MCS_NOT_SUPPORTED)
  67. nss = i;
  68. }
  69. mcs = GET_VHTNSSMCS(mcs_map, nss);
  70. /* if mcs is 3, nss must be 1 (NSS = 1). Default mcs to MCS 0~9 */
  71. if (mcs == IEEE80211_VHT_MCS_NOT_SUPPORTED)
  72. mcs = IEEE80211_VHT_MCS_SUPPORT_0_9;
  73. if (GET_VHTCAP_CHWDSET(usr_vht_cap_info)) {
  74. /* support 160 MHz */
  75. max_rate = max_rate_lgi_160MHZ[nss - 1][mcs];
  76. if (!max_rate)
  77. /* MCS9 is not supported in NSS6 */
  78. max_rate = max_rate_lgi_160MHZ[nss - 1][mcs - 1];
  79. } else {
  80. max_rate = max_rate_lgi_80MHZ[nss - 1][mcs];
  81. if (!max_rate)
  82. /* MCS9 is not supported in NSS3 */
  83. max_rate = max_rate_lgi_80MHZ[nss - 1][mcs - 1];
  84. }
  85. return max_rate;
  86. }
  87. static void
  88. mwifiex_fill_vht_cap_info(struct mwifiex_private *priv,
  89. struct ieee80211_vht_cap *vht_cap, u8 bands)
  90. {
  91. struct mwifiex_adapter *adapter = priv->adapter;
  92. if (bands & BAND_A)
  93. vht_cap->vht_cap_info =
  94. cpu_to_le32(adapter->usr_dot_11ac_dev_cap_a);
  95. else
  96. vht_cap->vht_cap_info =
  97. cpu_to_le32(adapter->usr_dot_11ac_dev_cap_bg);
  98. }
  99. void mwifiex_fill_vht_cap_tlv(struct mwifiex_private *priv,
  100. struct ieee80211_vht_cap *vht_cap, u8 bands)
  101. {
  102. struct mwifiex_adapter *adapter = priv->adapter;
  103. u16 mcs_map_user, mcs_map_resp, mcs_map_result;
  104. u16 mcs_user, mcs_resp, nss, tmp;
  105. /* Fill VHT cap info */
  106. mwifiex_fill_vht_cap_info(priv, vht_cap, bands);
  107. /* rx MCS Set: find the minimum of the user rx mcs and ap rx mcs */
  108. mcs_map_user = GET_DEVRXMCSMAP(adapter->usr_dot_11ac_mcs_support);
  109. mcs_map_resp = le16_to_cpu(vht_cap->supp_mcs.rx_mcs_map);
  110. mcs_map_result = 0;
  111. for (nss = 1; nss <= 8; nss++) {
  112. mcs_user = GET_VHTNSSMCS(mcs_map_user, nss);
  113. mcs_resp = GET_VHTNSSMCS(mcs_map_resp, nss);
  114. if ((mcs_user == IEEE80211_VHT_MCS_NOT_SUPPORTED) ||
  115. (mcs_resp == IEEE80211_VHT_MCS_NOT_SUPPORTED))
  116. SET_VHTNSSMCS(mcs_map_result, nss,
  117. IEEE80211_VHT_MCS_NOT_SUPPORTED);
  118. else
  119. SET_VHTNSSMCS(mcs_map_result, nss,
  120. min(mcs_user, mcs_resp));
  121. }
  122. vht_cap->supp_mcs.rx_mcs_map = cpu_to_le16(mcs_map_result);
  123. tmp = mwifiex_convert_mcsmap_to_maxrate(priv, bands, mcs_map_result);
  124. vht_cap->supp_mcs.rx_highest = cpu_to_le16(tmp);
  125. /* tx MCS Set: find the minimum of the user tx mcs and ap tx mcs */
  126. mcs_map_user = GET_DEVTXMCSMAP(adapter->usr_dot_11ac_mcs_support);
  127. mcs_map_resp = le16_to_cpu(vht_cap->supp_mcs.tx_mcs_map);
  128. mcs_map_result = 0;
  129. for (nss = 1; nss <= 8; nss++) {
  130. mcs_user = GET_VHTNSSMCS(mcs_map_user, nss);
  131. mcs_resp = GET_VHTNSSMCS(mcs_map_resp, nss);
  132. if ((mcs_user == IEEE80211_VHT_MCS_NOT_SUPPORTED) ||
  133. (mcs_resp == IEEE80211_VHT_MCS_NOT_SUPPORTED))
  134. SET_VHTNSSMCS(mcs_map_result, nss,
  135. IEEE80211_VHT_MCS_NOT_SUPPORTED);
  136. else
  137. SET_VHTNSSMCS(mcs_map_result, nss,
  138. min(mcs_user, mcs_resp));
  139. }
  140. vht_cap->supp_mcs.tx_mcs_map = cpu_to_le16(mcs_map_result);
  141. tmp = mwifiex_convert_mcsmap_to_maxrate(priv, bands, mcs_map_result);
  142. vht_cap->supp_mcs.tx_highest = cpu_to_le16(tmp);
  143. return;
  144. }
  145. int mwifiex_cmd_append_11ac_tlv(struct mwifiex_private *priv,
  146. struct mwifiex_bssdescriptor *bss_desc,
  147. u8 **buffer)
  148. {
  149. struct mwifiex_ie_types_vhtcap *vht_cap;
  150. struct mwifiex_ie_types_oper_mode_ntf *oper_ntf;
  151. struct ieee_types_oper_mode_ntf *ieee_oper_ntf;
  152. struct mwifiex_ie_types_vht_oper *vht_op;
  153. struct mwifiex_adapter *adapter = priv->adapter;
  154. u8 supp_chwd_set;
  155. u32 usr_vht_cap_info;
  156. int ret_len = 0;
  157. if (bss_desc->bss_band & BAND_A)
  158. usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_a;
  159. else
  160. usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_bg;
  161. /* VHT Capabilities IE */
  162. if (bss_desc->bcn_vht_cap) {
  163. vht_cap = (struct mwifiex_ie_types_vhtcap *)*buffer;
  164. memset(vht_cap, 0, sizeof(*vht_cap));
  165. vht_cap->header.type = cpu_to_le16(WLAN_EID_VHT_CAPABILITY);
  166. vht_cap->header.len =
  167. cpu_to_le16(sizeof(struct ieee80211_vht_cap));
  168. memcpy((u8 *)vht_cap + sizeof(struct mwifiex_ie_types_header),
  169. (u8 *)bss_desc->bcn_vht_cap,
  170. le16_to_cpu(vht_cap->header.len));
  171. mwifiex_fill_vht_cap_tlv(priv, &vht_cap->vht_cap,
  172. bss_desc->bss_band);
  173. *buffer += sizeof(*vht_cap);
  174. ret_len += sizeof(*vht_cap);
  175. }
  176. /* VHT Operation IE */
  177. if (bss_desc->bcn_vht_oper) {
  178. if (priv->bss_mode == NL80211_IFTYPE_STATION) {
  179. vht_op = (struct mwifiex_ie_types_vht_oper *)*buffer;
  180. memset(vht_op, 0, sizeof(*vht_op));
  181. vht_op->header.type =
  182. cpu_to_le16(WLAN_EID_VHT_OPERATION);
  183. vht_op->header.len = cpu_to_le16(sizeof(*vht_op) -
  184. sizeof(struct mwifiex_ie_types_header));
  185. memcpy((u8 *)vht_op +
  186. sizeof(struct mwifiex_ie_types_header),
  187. (u8 *)bss_desc->bcn_vht_oper,
  188. le16_to_cpu(vht_op->header.len));
  189. /* negotiate the channel width and central freq
  190. * and keep the central freq as the peer suggests
  191. */
  192. supp_chwd_set = GET_VHTCAP_CHWDSET(usr_vht_cap_info);
  193. switch (supp_chwd_set) {
  194. case 0:
  195. vht_op->chan_width =
  196. min_t(u8, IEEE80211_VHT_CHANWIDTH_80MHZ,
  197. bss_desc->bcn_vht_oper->chan_width);
  198. break;
  199. case 1:
  200. vht_op->chan_width =
  201. min_t(u8, IEEE80211_VHT_CHANWIDTH_160MHZ,
  202. bss_desc->bcn_vht_oper->chan_width);
  203. break;
  204. case 2:
  205. vht_op->chan_width =
  206. min_t(u8, IEEE80211_VHT_CHANWIDTH_80P80MHZ,
  207. bss_desc->bcn_vht_oper->chan_width);
  208. break;
  209. default:
  210. vht_op->chan_width =
  211. IEEE80211_VHT_CHANWIDTH_USE_HT;
  212. break;
  213. }
  214. *buffer += sizeof(*vht_op);
  215. ret_len += sizeof(*vht_op);
  216. }
  217. }
  218. /* Operating Mode Notification IE */
  219. if (bss_desc->oper_mode) {
  220. ieee_oper_ntf = bss_desc->oper_mode;
  221. oper_ntf = (void *)*buffer;
  222. memset(oper_ntf, 0, sizeof(*oper_ntf));
  223. oper_ntf->header.type = cpu_to_le16(WLAN_EID_OPMODE_NOTIF);
  224. oper_ntf->header.len = cpu_to_le16(sizeof(u8));
  225. oper_ntf->oper_mode = ieee_oper_ntf->oper_mode;
  226. *buffer += sizeof(*oper_ntf);
  227. ret_len += sizeof(*oper_ntf);
  228. }
  229. return ret_len;
  230. }
  231. int mwifiex_cmd_11ac_cfg(struct mwifiex_private *priv,
  232. struct host_cmd_ds_command *cmd, u16 cmd_action,
  233. struct mwifiex_11ac_vht_cfg *cfg)
  234. {
  235. struct host_cmd_11ac_vht_cfg *vhtcfg = &cmd->params.vht_cfg;
  236. cmd->command = cpu_to_le16(HostCmd_CMD_11AC_CFG);
  237. cmd->size = cpu_to_le16(sizeof(struct host_cmd_11ac_vht_cfg) +
  238. S_DS_GEN);
  239. vhtcfg->action = cpu_to_le16(cmd_action);
  240. vhtcfg->band_config = cfg->band_config;
  241. vhtcfg->misc_config = cfg->misc_config;
  242. vhtcfg->cap_info = cpu_to_le32(cfg->cap_info);
  243. vhtcfg->mcs_tx_set = cpu_to_le32(cfg->mcs_tx_set);
  244. vhtcfg->mcs_rx_set = cpu_to_le32(cfg->mcs_rx_set);
  245. return 0;
  246. }
  247. /* This function initializes the BlockACK setup information for given
  248. * mwifiex_private structure for 11ac enabled networks.
  249. */
  250. void mwifiex_set_11ac_ba_params(struct mwifiex_private *priv)
  251. {
  252. priv->add_ba_param.timeout = MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT;
  253. if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
  254. priv->add_ba_param.tx_win_size =
  255. MWIFIEX_11AC_UAP_AMPDU_DEF_TXWINSIZE;
  256. priv->add_ba_param.rx_win_size =
  257. MWIFIEX_11AC_UAP_AMPDU_DEF_RXWINSIZE;
  258. } else {
  259. priv->add_ba_param.tx_win_size =
  260. MWIFIEX_11AC_STA_AMPDU_DEF_TXWINSIZE;
  261. priv->add_ba_param.rx_win_size =
  262. MWIFIEX_11AC_STA_AMPDU_DEF_RXWINSIZE;
  263. }
  264. return;
  265. }
  266. bool mwifiex_is_bss_in_11ac_mode(struct mwifiex_private *priv)
  267. {
  268. struct mwifiex_bssdescriptor *bss_desc;
  269. struct ieee80211_vht_operation *vht_oper;
  270. bss_desc = &priv->curr_bss_params.bss_descriptor;
  271. vht_oper = bss_desc->bcn_vht_oper;
  272. if (!bss_desc->bcn_vht_cap || !vht_oper)
  273. return false;
  274. if (vht_oper->chan_width == IEEE80211_VHT_CHANWIDTH_USE_HT)
  275. return false;
  276. return true;
  277. }
  278. u8 mwifiex_get_center_freq_index(struct mwifiex_private *priv, u8 band,
  279. u32 pri_chan, u8 chan_bw)
  280. {
  281. u8 center_freq_idx = 0;
  282. if (band & BAND_AAC) {
  283. switch (pri_chan) {
  284. case 36:
  285. case 40:
  286. case 44:
  287. case 48:
  288. if (chan_bw == IEEE80211_VHT_CHANWIDTH_80MHZ)
  289. center_freq_idx = 42;
  290. break;
  291. case 52:
  292. case 56:
  293. case 60:
  294. case 64:
  295. if (chan_bw == IEEE80211_VHT_CHANWIDTH_80MHZ)
  296. center_freq_idx = 58;
  297. else if (chan_bw == IEEE80211_VHT_CHANWIDTH_160MHZ)
  298. center_freq_idx = 50;
  299. break;
  300. case 100:
  301. case 104:
  302. case 108:
  303. case 112:
  304. if (chan_bw == IEEE80211_VHT_CHANWIDTH_80MHZ)
  305. center_freq_idx = 106;
  306. break;
  307. case 116:
  308. case 120:
  309. case 124:
  310. case 128:
  311. if (chan_bw == IEEE80211_VHT_CHANWIDTH_80MHZ)
  312. center_freq_idx = 122;
  313. else if (chan_bw == IEEE80211_VHT_CHANWIDTH_160MHZ)
  314. center_freq_idx = 114;
  315. break;
  316. case 132:
  317. case 136:
  318. case 140:
  319. case 144:
  320. if (chan_bw == IEEE80211_VHT_CHANWIDTH_80MHZ)
  321. center_freq_idx = 138;
  322. break;
  323. case 149:
  324. case 153:
  325. case 157:
  326. case 161:
  327. if (chan_bw == IEEE80211_VHT_CHANWIDTH_80MHZ)
  328. center_freq_idx = 155;
  329. break;
  330. default:
  331. center_freq_idx = 42;
  332. }
  333. }
  334. return center_freq_idx;
  335. }