sta_cmdresp.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213
  1. /*
  2. * Marvell Wireless LAN device driver: station command response handling
  3. *
  4. * Copyright (C) 2011-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 "util.h"
  22. #include "fw.h"
  23. #include "main.h"
  24. #include "wmm.h"
  25. #include "11n.h"
  26. #include "11ac.h"
  27. /*
  28. * This function handles the command response error case.
  29. *
  30. * For scan response error, the function cancels all the pending
  31. * scan commands and generates an event to inform the applications
  32. * of the scan completion.
  33. *
  34. * For Power Save command failure, we do not retry enter PS
  35. * command in case of Ad-hoc mode.
  36. *
  37. * For all other response errors, the current command buffer is freed
  38. * and returned to the free command queue.
  39. */
  40. static void
  41. mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
  42. struct host_cmd_ds_command *resp)
  43. {
  44. struct cmd_ctrl_node *cmd_node = NULL, *tmp_node;
  45. struct mwifiex_adapter *adapter = priv->adapter;
  46. struct host_cmd_ds_802_11_ps_mode_enh *pm;
  47. unsigned long flags;
  48. mwifiex_dbg(adapter, ERROR,
  49. "CMD_RESP: cmd %#x error, result=%#x\n",
  50. resp->command, resp->result);
  51. if (adapter->curr_cmd->wait_q_enabled)
  52. adapter->cmd_wait_q.status = -1;
  53. switch (le16_to_cpu(resp->command)) {
  54. case HostCmd_CMD_802_11_PS_MODE_ENH:
  55. pm = &resp->params.psmode_enh;
  56. mwifiex_dbg(adapter, ERROR,
  57. "PS_MODE_ENH cmd failed: result=0x%x action=0x%X\n",
  58. resp->result, le16_to_cpu(pm->action));
  59. /* We do not re-try enter-ps command in ad-hoc mode. */
  60. if (le16_to_cpu(pm->action) == EN_AUTO_PS &&
  61. (le16_to_cpu(pm->params.ps_bitmap) & BITMAP_STA_PS) &&
  62. priv->bss_mode == NL80211_IFTYPE_ADHOC)
  63. adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
  64. break;
  65. case HostCmd_CMD_802_11_SCAN:
  66. case HostCmd_CMD_802_11_SCAN_EXT:
  67. /* Cancel all pending scan command */
  68. spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
  69. list_for_each_entry_safe(cmd_node, tmp_node,
  70. &adapter->scan_pending_q, list) {
  71. list_del(&cmd_node->list);
  72. spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
  73. flags);
  74. mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
  75. spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
  76. }
  77. spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
  78. spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
  79. adapter->scan_processing = false;
  80. spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
  81. break;
  82. case HostCmd_CMD_MAC_CONTROL:
  83. break;
  84. case HostCmd_CMD_SDIO_SP_RX_AGGR_CFG:
  85. mwifiex_dbg(adapter, MSG,
  86. "SDIO RX single-port aggregation Not support\n");
  87. break;
  88. default:
  89. break;
  90. }
  91. /* Handling errors here */
  92. mwifiex_recycle_cmd_node(adapter, adapter->curr_cmd);
  93. spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
  94. adapter->curr_cmd = NULL;
  95. spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
  96. }
  97. /*
  98. * This function handles the command response of get RSSI info.
  99. *
  100. * Handling includes changing the header fields into CPU format
  101. * and saving the following parameters in driver -
  102. * - Last data and beacon RSSI value
  103. * - Average data and beacon RSSI value
  104. * - Last data and beacon NF value
  105. * - Average data and beacon NF value
  106. *
  107. * The parameters are send to the application as well, along with
  108. * calculated SNR values.
  109. */
  110. static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv,
  111. struct host_cmd_ds_command *resp)
  112. {
  113. struct host_cmd_ds_802_11_rssi_info_rsp *rssi_info_rsp =
  114. &resp->params.rssi_info_rsp;
  115. struct mwifiex_ds_misc_subsc_evt *subsc_evt =
  116. &priv->async_subsc_evt_storage;
  117. priv->data_rssi_last = le16_to_cpu(rssi_info_rsp->data_rssi_last);
  118. priv->data_nf_last = le16_to_cpu(rssi_info_rsp->data_nf_last);
  119. priv->data_rssi_avg = le16_to_cpu(rssi_info_rsp->data_rssi_avg);
  120. priv->data_nf_avg = le16_to_cpu(rssi_info_rsp->data_nf_avg);
  121. priv->bcn_rssi_last = le16_to_cpu(rssi_info_rsp->bcn_rssi_last);
  122. priv->bcn_nf_last = le16_to_cpu(rssi_info_rsp->bcn_nf_last);
  123. priv->bcn_rssi_avg = le16_to_cpu(rssi_info_rsp->bcn_rssi_avg);
  124. priv->bcn_nf_avg = le16_to_cpu(rssi_info_rsp->bcn_nf_avg);
  125. if (priv->subsc_evt_rssi_state == EVENT_HANDLED)
  126. return 0;
  127. memset(subsc_evt, 0x00, sizeof(struct mwifiex_ds_misc_subsc_evt));
  128. /* Resubscribe low and high rssi events with new thresholds */
  129. subsc_evt->events = BITMASK_BCN_RSSI_LOW | BITMASK_BCN_RSSI_HIGH;
  130. subsc_evt->action = HostCmd_ACT_BITWISE_SET;
  131. if (priv->subsc_evt_rssi_state == RSSI_LOW_RECVD) {
  132. subsc_evt->bcn_l_rssi_cfg.abs_value = abs(priv->bcn_rssi_avg -
  133. priv->cqm_rssi_hyst);
  134. subsc_evt->bcn_h_rssi_cfg.abs_value = abs(priv->cqm_rssi_thold);
  135. } else if (priv->subsc_evt_rssi_state == RSSI_HIGH_RECVD) {
  136. subsc_evt->bcn_l_rssi_cfg.abs_value = abs(priv->cqm_rssi_thold);
  137. subsc_evt->bcn_h_rssi_cfg.abs_value = abs(priv->bcn_rssi_avg +
  138. priv->cqm_rssi_hyst);
  139. }
  140. subsc_evt->bcn_l_rssi_cfg.evt_freq = 1;
  141. subsc_evt->bcn_h_rssi_cfg.evt_freq = 1;
  142. priv->subsc_evt_rssi_state = EVENT_HANDLED;
  143. mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SUBSCRIBE_EVENT,
  144. 0, 0, subsc_evt, false);
  145. return 0;
  146. }
  147. /*
  148. * This function handles the command response of set/get SNMP
  149. * MIB parameters.
  150. *
  151. * Handling includes changing the header fields into CPU format
  152. * and saving the parameter in driver.
  153. *
  154. * The following parameters are supported -
  155. * - Fragmentation threshold
  156. * - RTS threshold
  157. * - Short retry limit
  158. */
  159. static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv,
  160. struct host_cmd_ds_command *resp,
  161. u32 *data_buf)
  162. {
  163. struct host_cmd_ds_802_11_snmp_mib *smib = &resp->params.smib;
  164. u16 oid = le16_to_cpu(smib->oid);
  165. u16 query_type = le16_to_cpu(smib->query_type);
  166. u32 ul_temp;
  167. mwifiex_dbg(priv->adapter, INFO,
  168. "info: SNMP_RESP: oid value = %#x,\t"
  169. "query_type = %#x, buf size = %#x\n",
  170. oid, query_type, le16_to_cpu(smib->buf_size));
  171. if (query_type == HostCmd_ACT_GEN_GET) {
  172. ul_temp = le16_to_cpu(*((__le16 *) (smib->value)));
  173. if (data_buf)
  174. *data_buf = ul_temp;
  175. switch (oid) {
  176. case FRAG_THRESH_I:
  177. mwifiex_dbg(priv->adapter, INFO,
  178. "info: SNMP_RESP: FragThsd =%u\n",
  179. ul_temp);
  180. break;
  181. case RTS_THRESH_I:
  182. mwifiex_dbg(priv->adapter, INFO,
  183. "info: SNMP_RESP: RTSThsd =%u\n",
  184. ul_temp);
  185. break;
  186. case SHORT_RETRY_LIM_I:
  187. mwifiex_dbg(priv->adapter, INFO,
  188. "info: SNMP_RESP: TxRetryCount=%u\n",
  189. ul_temp);
  190. break;
  191. case DTIM_PERIOD_I:
  192. mwifiex_dbg(priv->adapter, INFO,
  193. "info: SNMP_RESP: DTIM period=%u\n",
  194. ul_temp);
  195. default:
  196. break;
  197. }
  198. }
  199. return 0;
  200. }
  201. /*
  202. * This function handles the command response of get log request
  203. *
  204. * Handling includes changing the header fields into CPU format
  205. * and sending the received parameters to application.
  206. */
  207. static int mwifiex_ret_get_log(struct mwifiex_private *priv,
  208. struct host_cmd_ds_command *resp,
  209. struct mwifiex_ds_get_stats *stats)
  210. {
  211. struct host_cmd_ds_802_11_get_log *get_log =
  212. &resp->params.get_log;
  213. if (stats) {
  214. stats->mcast_tx_frame = le32_to_cpu(get_log->mcast_tx_frame);
  215. stats->failed = le32_to_cpu(get_log->failed);
  216. stats->retry = le32_to_cpu(get_log->retry);
  217. stats->multi_retry = le32_to_cpu(get_log->multi_retry);
  218. stats->frame_dup = le32_to_cpu(get_log->frame_dup);
  219. stats->rts_success = le32_to_cpu(get_log->rts_success);
  220. stats->rts_failure = le32_to_cpu(get_log->rts_failure);
  221. stats->ack_failure = le32_to_cpu(get_log->ack_failure);
  222. stats->rx_frag = le32_to_cpu(get_log->rx_frag);
  223. stats->mcast_rx_frame = le32_to_cpu(get_log->mcast_rx_frame);
  224. stats->fcs_error = le32_to_cpu(get_log->fcs_error);
  225. stats->tx_frame = le32_to_cpu(get_log->tx_frame);
  226. stats->wep_icv_error[0] =
  227. le32_to_cpu(get_log->wep_icv_err_cnt[0]);
  228. stats->wep_icv_error[1] =
  229. le32_to_cpu(get_log->wep_icv_err_cnt[1]);
  230. stats->wep_icv_error[2] =
  231. le32_to_cpu(get_log->wep_icv_err_cnt[2]);
  232. stats->wep_icv_error[3] =
  233. le32_to_cpu(get_log->wep_icv_err_cnt[3]);
  234. stats->bcn_rcv_cnt = le32_to_cpu(get_log->bcn_rcv_cnt);
  235. stats->bcn_miss_cnt = le32_to_cpu(get_log->bcn_miss_cnt);
  236. }
  237. return 0;
  238. }
  239. /*
  240. * This function handles the command response of set/get Tx rate
  241. * configurations.
  242. *
  243. * Handling includes changing the header fields into CPU format
  244. * and saving the following parameters in driver -
  245. * - DSSS rate bitmap
  246. * - OFDM rate bitmap
  247. * - HT MCS rate bitmaps
  248. *
  249. * Based on the new rate bitmaps, the function re-evaluates if
  250. * auto data rate has been activated. If not, it sends another
  251. * query to the firmware to get the current Tx data rate.
  252. */
  253. static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv,
  254. struct host_cmd_ds_command *resp)
  255. {
  256. struct host_cmd_ds_tx_rate_cfg *rate_cfg = &resp->params.tx_rate_cfg;
  257. struct mwifiex_rate_scope *rate_scope;
  258. struct mwifiex_ie_types_header *head;
  259. u16 tlv, tlv_buf_len, tlv_buf_left;
  260. u8 *tlv_buf;
  261. u32 i;
  262. tlv_buf = ((u8 *)rate_cfg) + sizeof(struct host_cmd_ds_tx_rate_cfg);
  263. tlv_buf_left = le16_to_cpu(resp->size) - S_DS_GEN - sizeof(*rate_cfg);
  264. while (tlv_buf_left >= sizeof(*head)) {
  265. head = (struct mwifiex_ie_types_header *)tlv_buf;
  266. tlv = le16_to_cpu(head->type);
  267. tlv_buf_len = le16_to_cpu(head->len);
  268. if (tlv_buf_left < (sizeof(*head) + tlv_buf_len))
  269. break;
  270. switch (tlv) {
  271. case TLV_TYPE_RATE_SCOPE:
  272. rate_scope = (struct mwifiex_rate_scope *) tlv_buf;
  273. priv->bitmap_rates[0] =
  274. le16_to_cpu(rate_scope->hr_dsss_rate_bitmap);
  275. priv->bitmap_rates[1] =
  276. le16_to_cpu(rate_scope->ofdm_rate_bitmap);
  277. for (i = 0;
  278. i <
  279. sizeof(rate_scope->ht_mcs_rate_bitmap) /
  280. sizeof(u16); i++)
  281. priv->bitmap_rates[2 + i] =
  282. le16_to_cpu(rate_scope->
  283. ht_mcs_rate_bitmap[i]);
  284. if (priv->adapter->fw_api_ver == MWIFIEX_FW_V15) {
  285. for (i = 0; i < ARRAY_SIZE(rate_scope->
  286. vht_mcs_rate_bitmap);
  287. i++)
  288. priv->bitmap_rates[10 + i] =
  289. le16_to_cpu(rate_scope->
  290. vht_mcs_rate_bitmap[i]);
  291. }
  292. break;
  293. /* Add RATE_DROP tlv here */
  294. }
  295. tlv_buf += (sizeof(*head) + tlv_buf_len);
  296. tlv_buf_left -= (sizeof(*head) + tlv_buf_len);
  297. }
  298. priv->is_data_rate_auto = mwifiex_is_rate_auto(priv);
  299. if (priv->is_data_rate_auto)
  300. priv->data_rate = 0;
  301. else
  302. return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_TX_RATE_QUERY,
  303. HostCmd_ACT_GEN_GET, 0, NULL, false);
  304. return 0;
  305. }
  306. /*
  307. * This function handles the command response of get Tx power level.
  308. *
  309. * Handling includes saving the maximum and minimum Tx power levels
  310. * in driver, as well as sending the values to user.
  311. */
  312. static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf)
  313. {
  314. int length, max_power = -1, min_power = -1;
  315. struct mwifiex_types_power_group *pg_tlv_hdr;
  316. struct mwifiex_power_group *pg;
  317. if (!data_buf)
  318. return -1;
  319. pg_tlv_hdr = (struct mwifiex_types_power_group *)((u8 *)data_buf);
  320. pg = (struct mwifiex_power_group *)
  321. ((u8 *) pg_tlv_hdr + sizeof(struct mwifiex_types_power_group));
  322. length = le16_to_cpu(pg_tlv_hdr->length);
  323. /* At least one structure required to update power */
  324. if (length < sizeof(struct mwifiex_power_group))
  325. return 0;
  326. max_power = pg->power_max;
  327. min_power = pg->power_min;
  328. length -= sizeof(struct mwifiex_power_group);
  329. while (length >= sizeof(struct mwifiex_power_group)) {
  330. pg++;
  331. if (max_power < pg->power_max)
  332. max_power = pg->power_max;
  333. if (min_power > pg->power_min)
  334. min_power = pg->power_min;
  335. length -= sizeof(struct mwifiex_power_group);
  336. }
  337. priv->min_tx_power_level = (u8) min_power;
  338. priv->max_tx_power_level = (u8) max_power;
  339. return 0;
  340. }
  341. /*
  342. * This function handles the command response of set/get Tx power
  343. * configurations.
  344. *
  345. * Handling includes changing the header fields into CPU format
  346. * and saving the current Tx power level in driver.
  347. */
  348. static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv,
  349. struct host_cmd_ds_command *resp)
  350. {
  351. struct mwifiex_adapter *adapter = priv->adapter;
  352. struct host_cmd_ds_txpwr_cfg *txp_cfg = &resp->params.txp_cfg;
  353. struct mwifiex_types_power_group *pg_tlv_hdr;
  354. struct mwifiex_power_group *pg;
  355. u16 action = le16_to_cpu(txp_cfg->action);
  356. u16 tlv_buf_left;
  357. pg_tlv_hdr = (struct mwifiex_types_power_group *)
  358. ((u8 *)txp_cfg +
  359. sizeof(struct host_cmd_ds_txpwr_cfg));
  360. pg = (struct mwifiex_power_group *)
  361. ((u8 *)pg_tlv_hdr +
  362. sizeof(struct mwifiex_types_power_group));
  363. tlv_buf_left = le16_to_cpu(resp->size) - S_DS_GEN - sizeof(*txp_cfg);
  364. if (tlv_buf_left <
  365. le16_to_cpu(pg_tlv_hdr->length) + sizeof(*pg_tlv_hdr))
  366. return 0;
  367. switch (action) {
  368. case HostCmd_ACT_GEN_GET:
  369. if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
  370. mwifiex_get_power_level(priv, pg_tlv_hdr);
  371. priv->tx_power_level = (u16) pg->power_min;
  372. break;
  373. case HostCmd_ACT_GEN_SET:
  374. if (!le32_to_cpu(txp_cfg->mode))
  375. break;
  376. if (pg->power_max == pg->power_min)
  377. priv->tx_power_level = (u16) pg->power_min;
  378. break;
  379. default:
  380. mwifiex_dbg(adapter, ERROR,
  381. "CMD_RESP: unknown cmd action %d\n",
  382. action);
  383. return 0;
  384. }
  385. mwifiex_dbg(adapter, INFO,
  386. "info: Current TxPower Level = %d, Max Power=%d, Min Power=%d\n",
  387. priv->tx_power_level, priv->max_tx_power_level,
  388. priv->min_tx_power_level);
  389. return 0;
  390. }
  391. /*
  392. * This function handles the command response of get RF Tx power.
  393. */
  394. static int mwifiex_ret_rf_tx_power(struct mwifiex_private *priv,
  395. struct host_cmd_ds_command *resp)
  396. {
  397. struct host_cmd_ds_rf_tx_pwr *txp = &resp->params.txp;
  398. u16 action = le16_to_cpu(txp->action);
  399. priv->tx_power_level = le16_to_cpu(txp->cur_level);
  400. if (action == HostCmd_ACT_GEN_GET) {
  401. priv->max_tx_power_level = txp->max_power;
  402. priv->min_tx_power_level = txp->min_power;
  403. }
  404. mwifiex_dbg(priv->adapter, INFO,
  405. "Current TxPower Level=%d, Max Power=%d, Min Power=%d\n",
  406. priv->tx_power_level, priv->max_tx_power_level,
  407. priv->min_tx_power_level);
  408. return 0;
  409. }
  410. /*
  411. * This function handles the command response of set rf antenna
  412. */
  413. static int mwifiex_ret_rf_antenna(struct mwifiex_private *priv,
  414. struct host_cmd_ds_command *resp)
  415. {
  416. struct host_cmd_ds_rf_ant_mimo *ant_mimo = &resp->params.ant_mimo;
  417. struct host_cmd_ds_rf_ant_siso *ant_siso = &resp->params.ant_siso;
  418. struct mwifiex_adapter *adapter = priv->adapter;
  419. if (adapter->hw_dev_mcs_support == HT_STREAM_2X2)
  420. mwifiex_dbg(adapter, INFO,
  421. "RF_ANT_RESP: Tx action = 0x%x, Tx Mode = 0x%04x\t"
  422. "Rx action = 0x%x, Rx Mode = 0x%04x\n",
  423. le16_to_cpu(ant_mimo->action_tx),
  424. le16_to_cpu(ant_mimo->tx_ant_mode),
  425. le16_to_cpu(ant_mimo->action_rx),
  426. le16_to_cpu(ant_mimo->rx_ant_mode));
  427. else
  428. mwifiex_dbg(adapter, INFO,
  429. "RF_ANT_RESP: action = 0x%x, Mode = 0x%04x\n",
  430. le16_to_cpu(ant_siso->action),
  431. le16_to_cpu(ant_siso->ant_mode));
  432. return 0;
  433. }
  434. /*
  435. * This function handles the command response of set/get MAC address.
  436. *
  437. * Handling includes saving the MAC address in driver.
  438. */
  439. static int mwifiex_ret_802_11_mac_address(struct mwifiex_private *priv,
  440. struct host_cmd_ds_command *resp)
  441. {
  442. struct host_cmd_ds_802_11_mac_address *cmd_mac_addr =
  443. &resp->params.mac_addr;
  444. memcpy(priv->curr_addr, cmd_mac_addr->mac_addr, ETH_ALEN);
  445. mwifiex_dbg(priv->adapter, INFO,
  446. "info: set mac address: %pM\n", priv->curr_addr);
  447. return 0;
  448. }
  449. /*
  450. * This function handles the command response of set/get MAC multicast
  451. * address.
  452. */
  453. static int mwifiex_ret_mac_multicast_adr(struct mwifiex_private *priv,
  454. struct host_cmd_ds_command *resp)
  455. {
  456. return 0;
  457. }
  458. /*
  459. * This function handles the command response of get Tx rate query.
  460. *
  461. * Handling includes changing the header fields into CPU format
  462. * and saving the Tx rate and HT information parameters in driver.
  463. *
  464. * Both rate configuration and current data rate can be retrieved
  465. * with this request.
  466. */
  467. static int mwifiex_ret_802_11_tx_rate_query(struct mwifiex_private *priv,
  468. struct host_cmd_ds_command *resp)
  469. {
  470. priv->tx_rate = resp->params.tx_rate.tx_rate;
  471. priv->tx_htinfo = resp->params.tx_rate.ht_info;
  472. if (!priv->is_data_rate_auto)
  473. priv->data_rate =
  474. mwifiex_index_to_data_rate(priv, priv->tx_rate,
  475. priv->tx_htinfo);
  476. return 0;
  477. }
  478. /*
  479. * This function handles the command response of a deauthenticate
  480. * command.
  481. *
  482. * If the deauthenticated MAC matches the current BSS MAC, the connection
  483. * state is reset.
  484. */
  485. static int mwifiex_ret_802_11_deauthenticate(struct mwifiex_private *priv,
  486. struct host_cmd_ds_command *resp)
  487. {
  488. struct mwifiex_adapter *adapter = priv->adapter;
  489. adapter->dbg.num_cmd_deauth++;
  490. if (!memcmp(resp->params.deauth.mac_addr,
  491. &priv->curr_bss_params.bss_descriptor.mac_address,
  492. sizeof(resp->params.deauth.mac_addr)))
  493. mwifiex_reset_connect_state(priv, WLAN_REASON_DEAUTH_LEAVING);
  494. return 0;
  495. }
  496. /*
  497. * This function handles the command response of ad-hoc stop.
  498. *
  499. * The function resets the connection state in driver.
  500. */
  501. static int mwifiex_ret_802_11_ad_hoc_stop(struct mwifiex_private *priv,
  502. struct host_cmd_ds_command *resp)
  503. {
  504. mwifiex_reset_connect_state(priv, WLAN_REASON_DEAUTH_LEAVING);
  505. return 0;
  506. }
  507. /*
  508. * This function handles the command response of set/get v1 key material.
  509. *
  510. * Handling includes updating the driver parameters to reflect the
  511. * changes.
  512. */
  513. static int mwifiex_ret_802_11_key_material_v1(struct mwifiex_private *priv,
  514. struct host_cmd_ds_command *resp)
  515. {
  516. struct host_cmd_ds_802_11_key_material *key =
  517. &resp->params.key_material;
  518. if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) {
  519. if ((le16_to_cpu(key->key_param_set.key_info) & KEY_MCAST)) {
  520. mwifiex_dbg(priv->adapter, INFO,
  521. "info: key: GTK is set\n");
  522. priv->wpa_is_gtk_set = true;
  523. priv->scan_block = false;
  524. priv->port_open = true;
  525. }
  526. }
  527. memset(priv->aes_key.key_param_set.key, 0,
  528. sizeof(key->key_param_set.key));
  529. priv->aes_key.key_param_set.key_len = key->key_param_set.key_len;
  530. memcpy(priv->aes_key.key_param_set.key, key->key_param_set.key,
  531. le16_to_cpu(priv->aes_key.key_param_set.key_len));
  532. return 0;
  533. }
  534. /*
  535. * This function handles the command response of set/get v2 key material.
  536. *
  537. * Handling includes updating the driver parameters to reflect the
  538. * changes.
  539. */
  540. static int mwifiex_ret_802_11_key_material_v2(struct mwifiex_private *priv,
  541. struct host_cmd_ds_command *resp)
  542. {
  543. struct host_cmd_ds_802_11_key_material_v2 *key_v2;
  544. __le16 len;
  545. key_v2 = &resp->params.key_material_v2;
  546. if (le16_to_cpu(key_v2->action) == HostCmd_ACT_GEN_SET) {
  547. if ((le16_to_cpu(key_v2->key_param_set.key_info) & KEY_MCAST)) {
  548. mwifiex_dbg(priv->adapter, INFO, "info: key: GTK is set\n");
  549. priv->wpa_is_gtk_set = true;
  550. priv->scan_block = false;
  551. priv->port_open = true;
  552. }
  553. }
  554. if (key_v2->key_param_set.key_type != KEY_TYPE_ID_AES)
  555. return 0;
  556. memset(priv->aes_key_v2.key_param_set.key_params.aes.key, 0,
  557. WLAN_KEY_LEN_CCMP);
  558. priv->aes_key_v2.key_param_set.key_params.aes.key_len =
  559. key_v2->key_param_set.key_params.aes.key_len;
  560. len = priv->aes_key_v2.key_param_set.key_params.aes.key_len;
  561. memcpy(priv->aes_key_v2.key_param_set.key_params.aes.key,
  562. key_v2->key_param_set.key_params.aes.key, le16_to_cpu(len));
  563. return 0;
  564. }
  565. /* Wrapper function for processing response of key material command */
  566. static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv,
  567. struct host_cmd_ds_command *resp)
  568. {
  569. if (priv->adapter->key_api_major_ver == KEY_API_VER_MAJOR_V2)
  570. return mwifiex_ret_802_11_key_material_v2(priv, resp);
  571. else
  572. return mwifiex_ret_802_11_key_material_v1(priv, resp);
  573. }
  574. /*
  575. * This function handles the command response of get 11d domain information.
  576. */
  577. static int mwifiex_ret_802_11d_domain_info(struct mwifiex_private *priv,
  578. struct host_cmd_ds_command *resp)
  579. {
  580. struct host_cmd_ds_802_11d_domain_info_rsp *domain_info =
  581. &resp->params.domain_info_resp;
  582. struct mwifiex_ietypes_domain_param_set *domain = &domain_info->domain;
  583. u16 action = le16_to_cpu(domain_info->action);
  584. u8 no_of_triplet;
  585. no_of_triplet = (u8) ((le16_to_cpu(domain->header.len)
  586. - IEEE80211_COUNTRY_STRING_LEN)
  587. / sizeof(struct ieee80211_country_ie_triplet));
  588. mwifiex_dbg(priv->adapter, INFO,
  589. "info: 11D Domain Info Resp: no_of_triplet=%d\n",
  590. no_of_triplet);
  591. if (no_of_triplet > MWIFIEX_MAX_TRIPLET_802_11D) {
  592. mwifiex_dbg(priv->adapter, FATAL,
  593. "11D: invalid number of triplets %d returned\n",
  594. no_of_triplet);
  595. return -1;
  596. }
  597. switch (action) {
  598. case HostCmd_ACT_GEN_SET: /* Proc Set Action */
  599. break;
  600. case HostCmd_ACT_GEN_GET:
  601. break;
  602. default:
  603. mwifiex_dbg(priv->adapter, ERROR,
  604. "11D: invalid action:%d\n", domain_info->action);
  605. return -1;
  606. }
  607. return 0;
  608. }
  609. /*
  610. * This function handles the command response of get extended version.
  611. *
  612. * Handling includes forming the extended version string and sending it
  613. * to application.
  614. */
  615. static int mwifiex_ret_ver_ext(struct mwifiex_private *priv,
  616. struct host_cmd_ds_command *resp,
  617. struct host_cmd_ds_version_ext *version_ext)
  618. {
  619. struct host_cmd_ds_version_ext *ver_ext = &resp->params.verext;
  620. if (version_ext) {
  621. version_ext->version_str_sel = ver_ext->version_str_sel;
  622. memcpy(version_ext->version_str, ver_ext->version_str,
  623. sizeof(char) * 128);
  624. memcpy(priv->version_str, ver_ext->version_str, 128);
  625. }
  626. return 0;
  627. }
  628. /*
  629. * This function handles the command response of remain on channel.
  630. */
  631. static int
  632. mwifiex_ret_remain_on_chan(struct mwifiex_private *priv,
  633. struct host_cmd_ds_command *resp,
  634. struct host_cmd_ds_remain_on_chan *roc_cfg)
  635. {
  636. struct host_cmd_ds_remain_on_chan *resp_cfg = &resp->params.roc_cfg;
  637. if (roc_cfg)
  638. memcpy(roc_cfg, resp_cfg, sizeof(*roc_cfg));
  639. return 0;
  640. }
  641. /*
  642. * This function handles the command response of P2P mode cfg.
  643. */
  644. static int
  645. mwifiex_ret_p2p_mode_cfg(struct mwifiex_private *priv,
  646. struct host_cmd_ds_command *resp,
  647. void *data_buf)
  648. {
  649. struct host_cmd_ds_p2p_mode_cfg *mode_cfg = &resp->params.mode_cfg;
  650. if (data_buf)
  651. *((u16 *)data_buf) = le16_to_cpu(mode_cfg->mode);
  652. return 0;
  653. }
  654. /* This function handles the command response of mem_access command
  655. */
  656. static int
  657. mwifiex_ret_mem_access(struct mwifiex_private *priv,
  658. struct host_cmd_ds_command *resp, void *pioctl_buf)
  659. {
  660. struct host_cmd_ds_mem_access *mem = (void *)&resp->params.mem;
  661. priv->mem_rw.addr = le32_to_cpu(mem->addr);
  662. priv->mem_rw.value = le32_to_cpu(mem->value);
  663. return 0;
  664. }
  665. /*
  666. * This function handles the command response of register access.
  667. *
  668. * The register value and offset are returned to the user. For EEPROM
  669. * access, the byte count is also returned.
  670. */
  671. static int mwifiex_ret_reg_access(u16 type, struct host_cmd_ds_command *resp,
  672. void *data_buf)
  673. {
  674. struct mwifiex_ds_reg_rw *reg_rw;
  675. struct mwifiex_ds_read_eeprom *eeprom;
  676. union reg {
  677. struct host_cmd_ds_mac_reg_access *mac;
  678. struct host_cmd_ds_bbp_reg_access *bbp;
  679. struct host_cmd_ds_rf_reg_access *rf;
  680. struct host_cmd_ds_pmic_reg_access *pmic;
  681. struct host_cmd_ds_802_11_eeprom_access *eeprom;
  682. } r;
  683. if (!data_buf)
  684. return 0;
  685. reg_rw = data_buf;
  686. eeprom = data_buf;
  687. switch (type) {
  688. case HostCmd_CMD_MAC_REG_ACCESS:
  689. r.mac = &resp->params.mac_reg;
  690. reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.mac->offset));
  691. reg_rw->value = r.mac->value;
  692. break;
  693. case HostCmd_CMD_BBP_REG_ACCESS:
  694. r.bbp = &resp->params.bbp_reg;
  695. reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.bbp->offset));
  696. reg_rw->value = cpu_to_le32((u32) r.bbp->value);
  697. break;
  698. case HostCmd_CMD_RF_REG_ACCESS:
  699. r.rf = &resp->params.rf_reg;
  700. reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset));
  701. reg_rw->value = cpu_to_le32((u32) r.bbp->value);
  702. break;
  703. case HostCmd_CMD_PMIC_REG_ACCESS:
  704. r.pmic = &resp->params.pmic_reg;
  705. reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.pmic->offset));
  706. reg_rw->value = cpu_to_le32((u32) r.pmic->value);
  707. break;
  708. case HostCmd_CMD_CAU_REG_ACCESS:
  709. r.rf = &resp->params.rf_reg;
  710. reg_rw->offset = cpu_to_le32((u32) le16_to_cpu(r.rf->offset));
  711. reg_rw->value = cpu_to_le32((u32) r.rf->value);
  712. break;
  713. case HostCmd_CMD_802_11_EEPROM_ACCESS:
  714. r.eeprom = &resp->params.eeprom;
  715. pr_debug("info: EEPROM read len=%x\n", r.eeprom->byte_count);
  716. if (le16_to_cpu(eeprom->byte_count) <
  717. le16_to_cpu(r.eeprom->byte_count)) {
  718. eeprom->byte_count = cpu_to_le16(0);
  719. pr_debug("info: EEPROM read length is too big\n");
  720. return -1;
  721. }
  722. eeprom->offset = r.eeprom->offset;
  723. eeprom->byte_count = r.eeprom->byte_count;
  724. if (le16_to_cpu(eeprom->byte_count) > 0)
  725. memcpy(&eeprom->value, &r.eeprom->value,
  726. le16_to_cpu(r.eeprom->byte_count));
  727. break;
  728. default:
  729. return -1;
  730. }
  731. return 0;
  732. }
  733. /*
  734. * This function handles the command response of get IBSS coalescing status.
  735. *
  736. * If the received BSSID is different than the current one, the current BSSID,
  737. * beacon interval, ATIM window and ERP information are updated, along with
  738. * changing the ad-hoc state accordingly.
  739. */
  740. static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv,
  741. struct host_cmd_ds_command *resp)
  742. {
  743. struct host_cmd_ds_802_11_ibss_status *ibss_coal_resp =
  744. &(resp->params.ibss_coalescing);
  745. if (le16_to_cpu(ibss_coal_resp->action) == HostCmd_ACT_GEN_SET)
  746. return 0;
  747. mwifiex_dbg(priv->adapter, INFO,
  748. "info: new BSSID %pM\n", ibss_coal_resp->bssid);
  749. /* If rsp has NULL BSSID, Just return..... No Action */
  750. if (is_zero_ether_addr(ibss_coal_resp->bssid)) {
  751. mwifiex_dbg(priv->adapter, FATAL, "new BSSID is NULL\n");
  752. return 0;
  753. }
  754. /* If BSSID is diff, modify current BSS parameters */
  755. if (!ether_addr_equal(priv->curr_bss_params.bss_descriptor.mac_address, ibss_coal_resp->bssid)) {
  756. /* BSSID */
  757. memcpy(priv->curr_bss_params.bss_descriptor.mac_address,
  758. ibss_coal_resp->bssid, ETH_ALEN);
  759. /* Beacon Interval */
  760. priv->curr_bss_params.bss_descriptor.beacon_period
  761. = le16_to_cpu(ibss_coal_resp->beacon_interval);
  762. /* ERP Information */
  763. priv->curr_bss_params.bss_descriptor.erp_flags =
  764. (u8) le16_to_cpu(ibss_coal_resp->use_g_rate_protect);
  765. priv->adhoc_state = ADHOC_COALESCED;
  766. }
  767. return 0;
  768. }
  769. static int mwifiex_ret_tdls_oper(struct mwifiex_private *priv,
  770. struct host_cmd_ds_command *resp)
  771. {
  772. struct host_cmd_ds_tdls_oper *cmd_tdls_oper = &resp->params.tdls_oper;
  773. u16 reason = le16_to_cpu(cmd_tdls_oper->reason);
  774. u16 action = le16_to_cpu(cmd_tdls_oper->tdls_action);
  775. struct mwifiex_sta_node *node =
  776. mwifiex_get_sta_entry(priv, cmd_tdls_oper->peer_mac);
  777. switch (action) {
  778. case ACT_TDLS_DELETE:
  779. if (reason) {
  780. if (!node || reason == TDLS_ERR_LINK_NONEXISTENT)
  781. mwifiex_dbg(priv->adapter, MSG,
  782. "TDLS link delete for %pM failed: reason %d\n",
  783. cmd_tdls_oper->peer_mac, reason);
  784. else
  785. mwifiex_dbg(priv->adapter, ERROR,
  786. "TDLS link delete for %pM failed: reason %d\n",
  787. cmd_tdls_oper->peer_mac, reason);
  788. } else {
  789. mwifiex_dbg(priv->adapter, MSG,
  790. "TDLS link delete for %pM successful\n",
  791. cmd_tdls_oper->peer_mac);
  792. }
  793. break;
  794. case ACT_TDLS_CREATE:
  795. if (reason) {
  796. mwifiex_dbg(priv->adapter, ERROR,
  797. "TDLS link creation for %pM failed: reason %d",
  798. cmd_tdls_oper->peer_mac, reason);
  799. if (node && reason != TDLS_ERR_LINK_EXISTS)
  800. node->tdls_status = TDLS_SETUP_FAILURE;
  801. } else {
  802. mwifiex_dbg(priv->adapter, MSG,
  803. "TDLS link creation for %pM successful",
  804. cmd_tdls_oper->peer_mac);
  805. }
  806. break;
  807. case ACT_TDLS_CONFIG:
  808. if (reason) {
  809. mwifiex_dbg(priv->adapter, ERROR,
  810. "TDLS link config for %pM failed, reason %d\n",
  811. cmd_tdls_oper->peer_mac, reason);
  812. if (node)
  813. node->tdls_status = TDLS_SETUP_FAILURE;
  814. } else {
  815. mwifiex_dbg(priv->adapter, MSG,
  816. "TDLS link config for %pM successful\n",
  817. cmd_tdls_oper->peer_mac);
  818. }
  819. break;
  820. default:
  821. mwifiex_dbg(priv->adapter, ERROR,
  822. "Unknown TDLS command action response %d", action);
  823. return -1;
  824. }
  825. return 0;
  826. }
  827. /*
  828. * This function handles the command response for subscribe event command.
  829. */
  830. static int mwifiex_ret_subsc_evt(struct mwifiex_private *priv,
  831. struct host_cmd_ds_command *resp)
  832. {
  833. struct host_cmd_ds_802_11_subsc_evt *cmd_sub_event =
  834. &resp->params.subsc_evt;
  835. /* For every subscribe event command (Get/Set/Clear), FW reports the
  836. * current set of subscribed events*/
  837. mwifiex_dbg(priv->adapter, EVENT,
  838. "Bitmap of currently subscribed events: %16x\n",
  839. le16_to_cpu(cmd_sub_event->events));
  840. return 0;
  841. }
  842. static int mwifiex_ret_uap_sta_list(struct mwifiex_private *priv,
  843. struct host_cmd_ds_command *resp)
  844. {
  845. struct host_cmd_ds_sta_list *sta_list =
  846. &resp->params.sta_list;
  847. struct mwifiex_ie_types_sta_info *sta_info = (void *)&sta_list->tlv;
  848. int i;
  849. struct mwifiex_sta_node *sta_node;
  850. for (i = 0; i < sta_list->sta_count; i++) {
  851. sta_node = mwifiex_get_sta_entry(priv, sta_info->mac);
  852. if (unlikely(!sta_node))
  853. continue;
  854. sta_node->stats.rssi = sta_info->rssi;
  855. sta_info++;
  856. }
  857. return 0;
  858. }
  859. /* This function handles the command response of set_cfg_data */
  860. static int mwifiex_ret_cfg_data(struct mwifiex_private *priv,
  861. struct host_cmd_ds_command *resp)
  862. {
  863. if (resp->result != HostCmd_RESULT_OK) {
  864. mwifiex_dbg(priv->adapter, ERROR, "Cal data cmd resp failed\n");
  865. return -1;
  866. }
  867. return 0;
  868. }
  869. /** This Function handles the command response of sdio rx aggr */
  870. static int mwifiex_ret_sdio_rx_aggr_cfg(struct mwifiex_private *priv,
  871. struct host_cmd_ds_command *resp)
  872. {
  873. struct mwifiex_adapter *adapter = priv->adapter;
  874. struct host_cmd_sdio_sp_rx_aggr_cfg *cfg =
  875. &resp->params.sdio_rx_aggr_cfg;
  876. adapter->sdio_rx_aggr_enable = cfg->enable;
  877. adapter->sdio_rx_block_size = le16_to_cpu(cfg->block_size);
  878. return 0;
  879. }
  880. /*
  881. * This function handles the command responses.
  882. *
  883. * This is a generic function, which calls command specific
  884. * response handlers based on the command ID.
  885. */
  886. int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
  887. struct host_cmd_ds_command *resp)
  888. {
  889. int ret = 0;
  890. struct mwifiex_adapter *adapter = priv->adapter;
  891. void *data_buf = adapter->curr_cmd->data_buf;
  892. /* If the command is not successful, cleanup and return failure */
  893. if (resp->result != HostCmd_RESULT_OK) {
  894. mwifiex_process_cmdresp_error(priv, resp);
  895. return -1;
  896. }
  897. /* Command successful, handle response */
  898. switch (cmdresp_no) {
  899. case HostCmd_CMD_GET_HW_SPEC:
  900. ret = mwifiex_ret_get_hw_spec(priv, resp);
  901. break;
  902. case HostCmd_CMD_CFG_DATA:
  903. ret = mwifiex_ret_cfg_data(priv, resp);
  904. break;
  905. case HostCmd_CMD_MAC_CONTROL:
  906. break;
  907. case HostCmd_CMD_802_11_MAC_ADDRESS:
  908. ret = mwifiex_ret_802_11_mac_address(priv, resp);
  909. break;
  910. case HostCmd_CMD_MAC_MULTICAST_ADR:
  911. ret = mwifiex_ret_mac_multicast_adr(priv, resp);
  912. break;
  913. case HostCmd_CMD_TX_RATE_CFG:
  914. ret = mwifiex_ret_tx_rate_cfg(priv, resp);
  915. break;
  916. case HostCmd_CMD_802_11_SCAN:
  917. ret = mwifiex_ret_802_11_scan(priv, resp);
  918. adapter->curr_cmd->wait_q_enabled = false;
  919. break;
  920. case HostCmd_CMD_802_11_SCAN_EXT:
  921. ret = mwifiex_ret_802_11_scan_ext(priv, resp);
  922. adapter->curr_cmd->wait_q_enabled = false;
  923. break;
  924. case HostCmd_CMD_802_11_BG_SCAN_QUERY:
  925. ret = mwifiex_ret_802_11_scan(priv, resp);
  926. mwifiex_dbg(adapter, CMD,
  927. "info: CMD_RESP: BG_SCAN result is ready!\n");
  928. break;
  929. case HostCmd_CMD_TXPWR_CFG:
  930. ret = mwifiex_ret_tx_power_cfg(priv, resp);
  931. break;
  932. case HostCmd_CMD_RF_TX_PWR:
  933. ret = mwifiex_ret_rf_tx_power(priv, resp);
  934. break;
  935. case HostCmd_CMD_RF_ANTENNA:
  936. ret = mwifiex_ret_rf_antenna(priv, resp);
  937. break;
  938. case HostCmd_CMD_802_11_PS_MODE_ENH:
  939. ret = mwifiex_ret_enh_power_mode(priv, resp, data_buf);
  940. break;
  941. case HostCmd_CMD_802_11_HS_CFG_ENH:
  942. ret = mwifiex_ret_802_11_hs_cfg(priv, resp);
  943. break;
  944. case HostCmd_CMD_802_11_ASSOCIATE:
  945. ret = mwifiex_ret_802_11_associate(priv, resp);
  946. break;
  947. case HostCmd_CMD_802_11_DEAUTHENTICATE:
  948. ret = mwifiex_ret_802_11_deauthenticate(priv, resp);
  949. break;
  950. case HostCmd_CMD_802_11_AD_HOC_START:
  951. case HostCmd_CMD_802_11_AD_HOC_JOIN:
  952. ret = mwifiex_ret_802_11_ad_hoc(priv, resp);
  953. break;
  954. case HostCmd_CMD_802_11_AD_HOC_STOP:
  955. ret = mwifiex_ret_802_11_ad_hoc_stop(priv, resp);
  956. break;
  957. case HostCmd_CMD_802_11_GET_LOG:
  958. ret = mwifiex_ret_get_log(priv, resp, data_buf);
  959. break;
  960. case HostCmd_CMD_RSSI_INFO:
  961. ret = mwifiex_ret_802_11_rssi_info(priv, resp);
  962. break;
  963. case HostCmd_CMD_802_11_SNMP_MIB:
  964. ret = mwifiex_ret_802_11_snmp_mib(priv, resp, data_buf);
  965. break;
  966. case HostCmd_CMD_802_11_TX_RATE_QUERY:
  967. ret = mwifiex_ret_802_11_tx_rate_query(priv, resp);
  968. break;
  969. case HostCmd_CMD_VERSION_EXT:
  970. ret = mwifiex_ret_ver_ext(priv, resp, data_buf);
  971. break;
  972. case HostCmd_CMD_REMAIN_ON_CHAN:
  973. ret = mwifiex_ret_remain_on_chan(priv, resp, data_buf);
  974. break;
  975. case HostCmd_CMD_11AC_CFG:
  976. break;
  977. case HostCmd_CMD_P2P_MODE_CFG:
  978. ret = mwifiex_ret_p2p_mode_cfg(priv, resp, data_buf);
  979. break;
  980. case HostCmd_CMD_MGMT_FRAME_REG:
  981. case HostCmd_CMD_FUNC_INIT:
  982. case HostCmd_CMD_FUNC_SHUTDOWN:
  983. break;
  984. case HostCmd_CMD_802_11_KEY_MATERIAL:
  985. ret = mwifiex_ret_802_11_key_material(priv, resp);
  986. break;
  987. case HostCmd_CMD_802_11D_DOMAIN_INFO:
  988. ret = mwifiex_ret_802_11d_domain_info(priv, resp);
  989. break;
  990. case HostCmd_CMD_11N_ADDBA_REQ:
  991. ret = mwifiex_ret_11n_addba_req(priv, resp);
  992. break;
  993. case HostCmd_CMD_11N_DELBA:
  994. ret = mwifiex_ret_11n_delba(priv, resp);
  995. break;
  996. case HostCmd_CMD_11N_ADDBA_RSP:
  997. ret = mwifiex_ret_11n_addba_resp(priv, resp);
  998. break;
  999. case HostCmd_CMD_RECONFIGURE_TX_BUFF:
  1000. adapter->tx_buf_size = (u16) le16_to_cpu(resp->params.
  1001. tx_buf.buff_size);
  1002. adapter->tx_buf_size = (adapter->tx_buf_size
  1003. / MWIFIEX_SDIO_BLOCK_SIZE)
  1004. * MWIFIEX_SDIO_BLOCK_SIZE;
  1005. adapter->curr_tx_buf_size = adapter->tx_buf_size;
  1006. mwifiex_dbg(adapter, CMD, "cmd: curr_tx_buf_size=%d\n",
  1007. adapter->curr_tx_buf_size);
  1008. if (adapter->if_ops.update_mp_end_port)
  1009. adapter->if_ops.update_mp_end_port(adapter,
  1010. le16_to_cpu(resp->params.tx_buf.mp_end_port));
  1011. break;
  1012. case HostCmd_CMD_AMSDU_AGGR_CTRL:
  1013. break;
  1014. case HostCmd_CMD_WMM_GET_STATUS:
  1015. ret = mwifiex_ret_wmm_get_status(priv, resp);
  1016. break;
  1017. case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS:
  1018. ret = mwifiex_ret_ibss_coalescing_status(priv, resp);
  1019. break;
  1020. case HostCmd_CMD_MEM_ACCESS:
  1021. ret = mwifiex_ret_mem_access(priv, resp, data_buf);
  1022. break;
  1023. case HostCmd_CMD_MAC_REG_ACCESS:
  1024. case HostCmd_CMD_BBP_REG_ACCESS:
  1025. case HostCmd_CMD_RF_REG_ACCESS:
  1026. case HostCmd_CMD_PMIC_REG_ACCESS:
  1027. case HostCmd_CMD_CAU_REG_ACCESS:
  1028. case HostCmd_CMD_802_11_EEPROM_ACCESS:
  1029. ret = mwifiex_ret_reg_access(cmdresp_no, resp, data_buf);
  1030. break;
  1031. case HostCmd_CMD_SET_BSS_MODE:
  1032. break;
  1033. case HostCmd_CMD_11N_CFG:
  1034. break;
  1035. case HostCmd_CMD_PCIE_DESC_DETAILS:
  1036. break;
  1037. case HostCmd_CMD_802_11_SUBSCRIBE_EVENT:
  1038. ret = mwifiex_ret_subsc_evt(priv, resp);
  1039. break;
  1040. case HostCmd_CMD_UAP_SYS_CONFIG:
  1041. break;
  1042. case HOST_CMD_APCMD_STA_LIST:
  1043. ret = mwifiex_ret_uap_sta_list(priv, resp);
  1044. break;
  1045. case HostCmd_CMD_UAP_BSS_START:
  1046. adapter->tx_lock_flag = false;
  1047. adapter->pps_uapsd_mode = false;
  1048. adapter->delay_null_pkt = false;
  1049. priv->bss_started = 1;
  1050. break;
  1051. case HostCmd_CMD_UAP_BSS_STOP:
  1052. priv->bss_started = 0;
  1053. break;
  1054. case HostCmd_CMD_UAP_STA_DEAUTH:
  1055. break;
  1056. case HOST_CMD_APCMD_SYS_RESET:
  1057. break;
  1058. case HostCmd_CMD_MEF_CFG:
  1059. break;
  1060. case HostCmd_CMD_COALESCE_CFG:
  1061. break;
  1062. case HostCmd_CMD_TDLS_OPER:
  1063. ret = mwifiex_ret_tdls_oper(priv, resp);
  1064. case HostCmd_CMD_MC_POLICY:
  1065. break;
  1066. case HostCmd_CMD_CHAN_REPORT_REQUEST:
  1067. break;
  1068. case HostCmd_CMD_SDIO_SP_RX_AGGR_CFG:
  1069. ret = mwifiex_ret_sdio_rx_aggr_cfg(priv, resp);
  1070. break;
  1071. case HostCmd_CMD_TDLS_CONFIG:
  1072. break;
  1073. default:
  1074. mwifiex_dbg(adapter, ERROR,
  1075. "CMD_RESP: unknown cmd response %#x\n",
  1076. resp->command);
  1077. break;
  1078. }
  1079. return ret;
  1080. }