2 * This file contains the handling of command.
3 * It prepares command and sends it to firmware when it is ready.
6 #include <net/iw_handler.h>
16 static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv);
17 static void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
18 struct cmd_ctrl_node *ptempnode,
23 * @brief Checks whether a command is allowed in Power Save mode
25 * @param command the command ID
26 * @return 1 if allowed, 0 if not allowed
28 static u8 is_command_allowed_in_ps(u16 cmd)
40 * @brief Updates the hardware details like MAC address and regulatory region
42 * @param priv A pointer to struct lbs_private structure
44 * @return 0 on success, error on failure
46 int lbs_update_hw_spec(struct lbs_private *priv)
48 struct cmd_ds_get_hw_spec cmd;
53 lbs_deb_enter(LBS_DEB_CMD);
55 memset(&cmd, 0, sizeof(cmd));
56 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
57 memcpy(cmd.permanentaddr, priv->current_addr, ETH_ALEN);
58 ret = lbs_cmd_with_response(priv, CMD_GET_HW_SPEC, &cmd);
62 priv->fwcapinfo = le32_to_cpu(cmd.fwcapinfo);
63 memcpy(priv->fwreleasenumber, cmd.fwreleasenumber, 4);
65 lbs_deb_cmd("GET_HW_SPEC: firmware release %u.%u.%up%u\n",
66 priv->fwreleasenumber[2], priv->fwreleasenumber[1],
67 priv->fwreleasenumber[0], priv->fwreleasenumber[3]);
68 lbs_deb_cmd("GET_HW_SPEC: MAC addr %s\n",
69 print_mac(mac, cmd.permanentaddr));
70 lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n",
71 cmd.hwifversion, cmd.version);
73 /* Clamp region code to 8-bit since FW spec indicates that it should
74 * only ever be 8-bit, even though the field size is 16-bit. Some firmware
75 * returns non-zero high 8 bits here.
77 priv->regioncode = le16_to_cpu(cmd.regioncode) & 0xFF;
79 for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
80 /* use the region code to search for the index */
81 if (priv->regioncode == lbs_region_code_to_index[i])
85 /* if it's unidentified region code, use the default (USA) */
86 if (i >= MRVDRV_MAX_REGION_CODE) {
87 priv->regioncode = 0x10;
88 lbs_pr_info("unidentified region code; using the default (USA)\n");
91 if (priv->current_addr[0] == 0xff)
92 memmove(priv->current_addr, cmd.permanentaddr, ETH_ALEN);
94 memcpy(priv->dev->dev_addr, priv->current_addr, ETH_ALEN);
96 memcpy(priv->mesh_dev->dev_addr, priv->current_addr, ETH_ALEN);
98 if (lbs_set_regiontable(priv, priv->regioncode, 0)) {
103 if (lbs_set_universaltable(priv, 0)) {
109 lbs_deb_leave(LBS_DEB_CMD);
113 int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria)
115 struct cmd_ds_host_sleep cmd_config;
118 cmd_config.hdr.size = cpu_to_le16(sizeof(cmd_config));
119 cmd_config.criteria = cpu_to_le32(criteria);
120 cmd_config.gpio = priv->wol_gpio;
121 cmd_config.gap = priv->wol_gap;
123 ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config);
125 lbs_deb_cmd("Set WOL criteria to %x\n", criteria);
126 priv->wol_criteria = criteria;
128 lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret);
133 EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg);
135 static int lbs_cmd_802_11_ps_mode(struct lbs_private *priv,
136 struct cmd_ds_command *cmd,
139 struct cmd_ds_802_11_ps_mode *psm = &cmd->params.psmode;
141 lbs_deb_enter(LBS_DEB_CMD);
143 cmd->command = cpu_to_le16(CMD_802_11_PS_MODE);
144 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ps_mode) +
146 psm->action = cpu_to_le16(cmd_action);
147 psm->multipledtim = 0;
148 switch (cmd_action) {
149 case CMD_SUBCMD_ENTER_PS:
150 lbs_deb_cmd("PS command:" "SubCode- Enter PS\n");
152 psm->locallisteninterval = 0;
153 psm->nullpktinterval = 0;
155 cpu_to_le16(MRVDRV_DEFAULT_MULTIPLE_DTIM);
158 case CMD_SUBCMD_EXIT_PS:
159 lbs_deb_cmd("PS command:" "SubCode- Exit PS\n");
162 case CMD_SUBCMD_SLEEP_CONFIRMED:
163 lbs_deb_cmd("PS command: SubCode- sleep confirm\n");
170 lbs_deb_leave(LBS_DEB_CMD);
174 static int lbs_cmd_802_11_inactivity_timeout(struct lbs_private *priv,
175 struct cmd_ds_command *cmd,
176 u16 cmd_action, void *pdata_buf)
178 u16 *timeout = pdata_buf;
180 lbs_deb_enter(LBS_DEB_CMD);
182 cmd->command = cpu_to_le16(CMD_802_11_INACTIVITY_TIMEOUT);
184 cpu_to_le16(sizeof(struct cmd_ds_802_11_inactivity_timeout)
187 cmd->params.inactivity_timeout.action = cpu_to_le16(cmd_action);
190 cmd->params.inactivity_timeout.timeout = cpu_to_le16(*timeout);
192 cmd->params.inactivity_timeout.timeout = 0;
194 lbs_deb_leave(LBS_DEB_CMD);
198 static int lbs_cmd_802_11_sleep_params(struct lbs_private *priv,
199 struct cmd_ds_command *cmd,
202 struct cmd_ds_802_11_sleep_params *sp = &cmd->params.sleep_params;
204 lbs_deb_enter(LBS_DEB_CMD);
206 cmd->size = cpu_to_le16((sizeof(struct cmd_ds_802_11_sleep_params)) +
208 cmd->command = cpu_to_le16(CMD_802_11_SLEEP_PARAMS);
210 if (cmd_action == CMD_ACT_GET) {
211 memset(&priv->sp, 0, sizeof(struct sleep_params));
212 memset(sp, 0, sizeof(struct cmd_ds_802_11_sleep_params));
213 sp->action = cpu_to_le16(cmd_action);
214 } else if (cmd_action == CMD_ACT_SET) {
215 sp->action = cpu_to_le16(cmd_action);
216 sp->error = cpu_to_le16(priv->sp.sp_error);
217 sp->offset = cpu_to_le16(priv->sp.sp_offset);
218 sp->stabletime = cpu_to_le16(priv->sp.sp_stabletime);
219 sp->calcontrol = (u8) priv->sp.sp_calcontrol;
220 sp->externalsleepclk = (u8) priv->sp.sp_extsleepclk;
221 sp->reserved = cpu_to_le16(priv->sp.sp_reserved);
224 lbs_deb_leave(LBS_DEB_CMD);
228 static int lbs_cmd_802_11_set_wep(struct lbs_private *priv,
229 struct cmd_ds_command *cmd,
233 struct cmd_ds_802_11_set_wep *wep = &cmd->params.wep;
235 struct assoc_request * assoc_req = pdata_buf;
237 lbs_deb_enter(LBS_DEB_CMD);
239 cmd->command = cpu_to_le16(CMD_802_11_SET_WEP);
240 cmd->size = cpu_to_le16(sizeof(*wep) + S_DS_GEN);
242 if (cmd_act == CMD_ACT_ADD) {
246 lbs_deb_cmd("Invalid association request!\n");
251 wep->action = cpu_to_le16(CMD_ACT_ADD);
253 /* default tx key index */
254 wep->keyindex = cpu_to_le16((u16)(assoc_req->wep_tx_keyidx &
255 (u32)CMD_WEP_KEY_INDEX_MASK));
257 /* Copy key types and material to host command structure */
258 for (i = 0; i < 4; i++) {
259 struct enc_key * pkey = &assoc_req->wep_keys[i];
263 wep->keytype[i] = CMD_TYPE_WEP_40_BIT;
264 memmove(&wep->keymaterial[i], pkey->key,
266 lbs_deb_cmd("SET_WEP: add key %d (40 bit)\n", i);
268 case KEY_LEN_WEP_104:
269 wep->keytype[i] = CMD_TYPE_WEP_104_BIT;
270 memmove(&wep->keymaterial[i], pkey->key,
272 lbs_deb_cmd("SET_WEP: add key %d (104 bit)\n", i);
277 lbs_deb_cmd("SET_WEP: invalid key %d, length %d\n",
284 } else if (cmd_act == CMD_ACT_REMOVE) {
285 /* ACT_REMOVE clears _all_ WEP keys */
286 wep->action = cpu_to_le16(CMD_ACT_REMOVE);
288 /* default tx key index */
289 wep->keyindex = cpu_to_le16((u16)(priv->wep_tx_keyidx &
290 (u32)CMD_WEP_KEY_INDEX_MASK));
291 lbs_deb_cmd("SET_WEP: remove key %d\n", priv->wep_tx_keyidx);
297 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
301 static int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv,
302 struct cmd_ds_command *cmd,
306 struct cmd_ds_802_11_enable_rsn *penableRSN = &cmd->params.enbrsn;
307 u32 * enable = pdata_buf;
309 lbs_deb_enter(LBS_DEB_CMD);
311 cmd->command = cpu_to_le16(CMD_802_11_ENABLE_RSN);
312 cmd->size = cpu_to_le16(sizeof(*penableRSN) + S_DS_GEN);
313 penableRSN->action = cpu_to_le16(cmd_action);
315 if (cmd_action == CMD_ACT_SET) {
317 penableRSN->enable = cpu_to_le16(CMD_ENABLE_RSN);
319 penableRSN->enable = cpu_to_le16(CMD_DISABLE_RSN);
320 lbs_deb_cmd("ENABLE_RSN: %d\n", *enable);
323 lbs_deb_leave(LBS_DEB_CMD);
328 static ssize_t lbs_tlv_size(const u8 *tlv, u16 size)
331 struct mrvlietypesheader *tlv_h;
334 tlv_h = (struct mrvlietypesheader *) tlv;
337 length = le16_to_cpu(tlv_h->len) +
338 sizeof(struct mrvlietypesheader);
346 static void lbs_cmd_802_11_subscribe_event(struct lbs_private *priv,
347 struct cmd_ds_command *cmd, u16 cmd_action,
350 struct cmd_ds_802_11_subscribe_event *events =
351 (struct cmd_ds_802_11_subscribe_event *) pdata_buf;
353 /* pdata_buf points to a struct cmd_ds_802_11_subscribe_event and room
354 * for various Marvell TLVs */
356 lbs_deb_enter(LBS_DEB_CMD);
358 cmd->size = cpu_to_le16(sizeof(*events)
359 - sizeof(events->tlv)
361 cmd->params.subscribe_event.action = cpu_to_le16(cmd_action);
362 if (cmd_action == CMD_ACT_GET) {
363 cmd->params.subscribe_event.events = 0;
365 ssize_t sz = lbs_tlv_size(events->tlv, sizeof(events->tlv));
366 cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) + sz);
367 cmd->params.subscribe_event.events = events->events;
368 memcpy(cmd->params.subscribe_event.tlv, events->tlv, sz);
371 lbs_deb_leave(LBS_DEB_CMD);
374 static void set_one_wpa_key(struct MrvlIEtype_keyParamSet * pkeyparamset,
375 struct enc_key * pkey)
377 lbs_deb_enter(LBS_DEB_CMD);
379 if (pkey->flags & KEY_INFO_WPA_ENABLED) {
380 pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_ENABLED);
382 if (pkey->flags & KEY_INFO_WPA_UNICAST) {
383 pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_UNICAST);
385 if (pkey->flags & KEY_INFO_WPA_MCAST) {
386 pkeyparamset->keyinfo |= cpu_to_le16(KEY_INFO_WPA_MCAST);
389 pkeyparamset->type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
390 pkeyparamset->keytypeid = cpu_to_le16(pkey->type);
391 pkeyparamset->keylen = cpu_to_le16(pkey->len);
392 memcpy(pkeyparamset->key, pkey->key, pkey->len);
393 pkeyparamset->length = cpu_to_le16( sizeof(pkeyparamset->keytypeid)
394 + sizeof(pkeyparamset->keyinfo)
395 + sizeof(pkeyparamset->keylen)
396 + sizeof(pkeyparamset->key));
397 lbs_deb_leave(LBS_DEB_CMD);
400 static int lbs_cmd_802_11_key_material(struct lbs_private *priv,
401 struct cmd_ds_command *cmd,
403 u32 cmd_oid, void *pdata_buf)
405 struct cmd_ds_802_11_key_material *pkeymaterial =
406 &cmd->params.keymaterial;
407 struct assoc_request * assoc_req = pdata_buf;
411 lbs_deb_enter(LBS_DEB_CMD);
413 cmd->command = cpu_to_le16(CMD_802_11_KEY_MATERIAL);
414 pkeymaterial->action = cpu_to_le16(cmd_action);
416 if (cmd_action == CMD_ACT_GET) {
417 cmd->size = cpu_to_le16(S_DS_GEN + sizeof (pkeymaterial->action));
422 memset(&pkeymaterial->keyParamSet, 0, sizeof(pkeymaterial->keyParamSet));
424 if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
425 set_one_wpa_key(&pkeymaterial->keyParamSet[index],
426 &assoc_req->wpa_unicast_key);
430 if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) {
431 set_one_wpa_key(&pkeymaterial->keyParamSet[index],
432 &assoc_req->wpa_mcast_key);
436 cmd->size = cpu_to_le16( S_DS_GEN
437 + sizeof (pkeymaterial->action)
438 + (index * sizeof(struct MrvlIEtype_keyParamSet)));
443 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
447 static int lbs_cmd_802_11_reset(struct lbs_private *priv,
448 struct cmd_ds_command *cmd, int cmd_action)
450 struct cmd_ds_802_11_reset *reset = &cmd->params.reset;
452 lbs_deb_enter(LBS_DEB_CMD);
454 cmd->command = cpu_to_le16(CMD_802_11_RESET);
455 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_reset) + S_DS_GEN);
456 reset->action = cpu_to_le16(cmd_action);
458 lbs_deb_leave(LBS_DEB_CMD);
462 static int lbs_cmd_802_11_get_log(struct lbs_private *priv,
463 struct cmd_ds_command *cmd)
465 lbs_deb_enter(LBS_DEB_CMD);
466 cmd->command = cpu_to_le16(CMD_802_11_GET_LOG);
468 cpu_to_le16(sizeof(struct cmd_ds_802_11_get_log) + S_DS_GEN);
470 lbs_deb_leave(LBS_DEB_CMD);
474 static int lbs_cmd_802_11_get_stat(struct lbs_private *priv,
475 struct cmd_ds_command *cmd)
477 lbs_deb_enter(LBS_DEB_CMD);
478 cmd->command = cpu_to_le16(CMD_802_11_GET_STAT);
480 cpu_to_le16(sizeof(struct cmd_ds_802_11_get_stat) + S_DS_GEN);
482 lbs_deb_leave(LBS_DEB_CMD);
486 static int lbs_cmd_802_11_snmp_mib(struct lbs_private *priv,
487 struct cmd_ds_command *cmd,
489 int cmd_oid, void *pdata_buf)
491 struct cmd_ds_802_11_snmp_mib *pSNMPMIB = &cmd->params.smib;
494 lbs_deb_enter(LBS_DEB_CMD);
496 lbs_deb_cmd("SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid);
498 cmd->command = cpu_to_le16(CMD_802_11_SNMP_MIB);
499 cmd->size = cpu_to_le16(sizeof(*pSNMPMIB) + S_DS_GEN);
502 case OID_802_11_INFRASTRUCTURE_MODE:
504 u8 mode = (u8) (size_t) pdata_buf;
505 pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET);
506 pSNMPMIB->oid = cpu_to_le16((u16) DESIRED_BSSTYPE_I);
507 pSNMPMIB->bufsize = cpu_to_le16(sizeof(u8));
508 if (mode == IW_MODE_ADHOC) {
509 ucTemp = SNMP_MIB_VALUE_ADHOC;
511 /* Infra and Auto modes */
512 ucTemp = SNMP_MIB_VALUE_INFRA;
515 memmove(pSNMPMIB->value, &ucTemp, sizeof(u8));
520 case OID_802_11D_ENABLE:
524 pSNMPMIB->oid = cpu_to_le16((u16) DOT11D_I);
526 if (cmd_action == CMD_ACT_SET) {
527 pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET);
528 pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
529 ulTemp = *(u32 *)pdata_buf;
530 *((__le16 *)(pSNMPMIB->value)) =
531 cpu_to_le16((u16) ulTemp);
536 case OID_802_11_FRAGMENTATION_THRESHOLD:
540 pSNMPMIB->oid = cpu_to_le16((u16) FRAGTHRESH_I);
542 if (cmd_action == CMD_ACT_GET) {
543 pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_GET);
544 } else if (cmd_action == CMD_ACT_SET) {
545 pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET);
546 pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
547 ulTemp = *((u32 *) pdata_buf);
548 *((__le16 *)(pSNMPMIB->value)) =
549 cpu_to_le16((u16) ulTemp);
556 case OID_802_11_RTS_THRESHOLD:
560 pSNMPMIB->oid = cpu_to_le16(RTSTHRESH_I);
562 if (cmd_action == CMD_ACT_GET) {
563 pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_GET);
564 } else if (cmd_action == CMD_ACT_SET) {
565 pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET);
566 pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
567 ulTemp = *((u32 *)pdata_buf);
568 *(__le16 *)(pSNMPMIB->value) =
569 cpu_to_le16((u16) ulTemp);
574 case OID_802_11_TX_RETRYCOUNT:
575 pSNMPMIB->oid = cpu_to_le16((u16) SHORT_RETRYLIM_I);
577 if (cmd_action == CMD_ACT_GET) {
578 pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_GET);
579 } else if (cmd_action == CMD_ACT_SET) {
580 pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET);
581 pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
582 *((__le16 *)(pSNMPMIB->value)) =
583 cpu_to_le16((u16) priv->txretrycount);
592 "SNMP_CMD: command=0x%x, size=0x%x, seqnum=0x%x, result=0x%x\n",
593 le16_to_cpu(cmd->command), le16_to_cpu(cmd->size),
594 le16_to_cpu(cmd->seqnum), le16_to_cpu(cmd->result));
597 "SNMP_CMD: action 0x%x, oid 0x%x, oidsize 0x%x, value 0x%x\n",
598 le16_to_cpu(pSNMPMIB->querytype), le16_to_cpu(pSNMPMIB->oid),
599 le16_to_cpu(pSNMPMIB->bufsize),
600 le16_to_cpu(*(__le16 *) pSNMPMIB->value));
602 lbs_deb_leave(LBS_DEB_CMD);
606 static int lbs_cmd_802_11_rf_tx_power(struct lbs_private *priv,
607 struct cmd_ds_command *cmd,
608 u16 cmd_action, void *pdata_buf)
611 struct cmd_ds_802_11_rf_tx_power *prtp = &cmd->params.txp;
613 lbs_deb_enter(LBS_DEB_CMD);
616 cpu_to_le16((sizeof(struct cmd_ds_802_11_rf_tx_power)) + S_DS_GEN);
617 cmd->command = cpu_to_le16(CMD_802_11_RF_TX_POWER);
618 prtp->action = cpu_to_le16(cmd_action);
620 lbs_deb_cmd("RF_TX_POWER_CMD: size:%d cmd:0x%x Act:%d\n",
621 le16_to_cpu(cmd->size), le16_to_cpu(cmd->command),
622 le16_to_cpu(prtp->action));
624 switch (cmd_action) {
625 case CMD_ACT_TX_POWER_OPT_GET:
626 prtp->action = cpu_to_le16(CMD_ACT_GET);
627 prtp->currentlevel = 0;
630 case CMD_ACT_TX_POWER_OPT_SET_HIGH:
631 prtp->action = cpu_to_le16(CMD_ACT_SET);
632 prtp->currentlevel = cpu_to_le16(CMD_ACT_TX_POWER_INDEX_HIGH);
635 case CMD_ACT_TX_POWER_OPT_SET_MID:
636 prtp->action = cpu_to_le16(CMD_ACT_SET);
637 prtp->currentlevel = cpu_to_le16(CMD_ACT_TX_POWER_INDEX_MID);
640 case CMD_ACT_TX_POWER_OPT_SET_LOW:
641 prtp->action = cpu_to_le16(CMD_ACT_SET);
642 prtp->currentlevel = cpu_to_le16(*((u16 *) pdata_buf));
646 lbs_deb_leave(LBS_DEB_CMD);
650 static int lbs_cmd_802_11_monitor_mode(struct lbs_private *priv,
651 struct cmd_ds_command *cmd,
652 u16 cmd_action, void *pdata_buf)
654 struct cmd_ds_802_11_monitor_mode *monitor = &cmd->params.monitor;
656 cmd->command = cpu_to_le16(CMD_802_11_MONITOR_MODE);
658 cpu_to_le16(sizeof(struct cmd_ds_802_11_monitor_mode) +
661 monitor->action = cpu_to_le16(cmd_action);
662 if (cmd_action == CMD_ACT_SET) {
664 cpu_to_le16((u16) (*(u32 *) pdata_buf));
670 static int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv,
671 struct cmd_ds_command *cmd,
674 struct cmd_ds_802_11_rate_adapt_rateset
675 *rateadapt = &cmd->params.rateset;
677 lbs_deb_enter(LBS_DEB_CMD);
679 cpu_to_le16(sizeof(struct cmd_ds_802_11_rate_adapt_rateset)
681 cmd->command = cpu_to_le16(CMD_802_11_RATE_ADAPT_RATESET);
683 rateadapt->action = cpu_to_le16(cmd_action);
684 rateadapt->enablehwauto = cpu_to_le16(priv->enablehwauto);
685 rateadapt->bitmap = cpu_to_le16(priv->ratebitmap);
687 lbs_deb_leave(LBS_DEB_CMD);
692 * @brief Get the current data rate
694 * @param priv A pointer to struct lbs_private structure
696 * @return The data rate on success, error on failure
698 int lbs_get_data_rate(struct lbs_private *priv)
700 struct cmd_ds_802_11_data_rate cmd;
703 lbs_deb_enter(LBS_DEB_CMD);
705 memset(&cmd, 0, sizeof(cmd));
706 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
707 cmd.action = cpu_to_le16(CMD_ACT_GET_TX_RATE);
709 ret = lbs_cmd_with_response(priv, CMD_802_11_DATA_RATE, &cmd);
713 lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) &cmd, sizeof (cmd));
715 ret = (int) lbs_fw_index_to_data_rate(cmd.rates[0]);
716 lbs_deb_cmd("DATA_RATE: current rate 0x%02x\n", ret);
719 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
724 * @brief Set the data rate
726 * @param priv A pointer to struct lbs_private structure
727 * @param rate The desired data rate, or 0 to clear a locked rate
729 * @return 0 on success, error on failure
731 int lbs_set_data_rate(struct lbs_private *priv, u8 rate)
733 struct cmd_ds_802_11_data_rate cmd;
736 lbs_deb_enter(LBS_DEB_CMD);
738 memset(&cmd, 0, sizeof(cmd));
739 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
742 cmd.action = cpu_to_le16(CMD_ACT_SET_TX_FIX_RATE);
743 cmd.rates[0] = lbs_data_rate_to_fw_index(rate);
744 if (cmd.rates[0] == 0) {
745 lbs_deb_cmd("DATA_RATE: invalid requested rate of"
750 lbs_deb_cmd("DATA_RATE: set fixed 0x%02X\n", cmd.rates[0]);
752 cmd.action = cpu_to_le16(CMD_ACT_SET_TX_AUTO);
753 lbs_deb_cmd("DATA_RATE: setting auto\n");
756 ret = lbs_cmd_with_response(priv, CMD_802_11_DATA_RATE, &cmd);
760 lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) &cmd, sizeof (cmd));
762 /* FIXME: get actual rates FW can do if this command actually returns
763 * all data rates supported.
765 priv->cur_rate = lbs_fw_index_to_data_rate(cmd.rates[0]);
766 lbs_deb_cmd("DATA_RATE: current rate is 0x%02x\n", priv->cur_rate);
769 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
773 static int lbs_cmd_mac_multicast_adr(struct lbs_private *priv,
774 struct cmd_ds_command *cmd,
777 struct cmd_ds_mac_multicast_adr *pMCastAdr = &cmd->params.madr;
779 lbs_deb_enter(LBS_DEB_CMD);
780 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mac_multicast_adr) +
782 cmd->command = cpu_to_le16(CMD_MAC_MULTICAST_ADR);
784 lbs_deb_cmd("MULTICAST_ADR: setting %d addresses\n", pMCastAdr->nr_of_adrs);
785 pMCastAdr->action = cpu_to_le16(cmd_action);
786 pMCastAdr->nr_of_adrs =
787 cpu_to_le16((u16) priv->nr_of_multicastmacaddr);
788 memcpy(pMCastAdr->maclist, priv->multicastlist,
789 priv->nr_of_multicastmacaddr * ETH_ALEN);
791 lbs_deb_leave(LBS_DEB_CMD);
796 * @brief Get the radio channel
798 * @param priv A pointer to struct lbs_private structure
800 * @return The channel on success, error on failure
802 int lbs_get_channel(struct lbs_private *priv)
804 struct cmd_ds_802_11_rf_channel cmd;
807 lbs_deb_enter(LBS_DEB_CMD);
809 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
810 cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_GET);
812 ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd);
816 ret = le16_to_cpu(cmd.channel);
817 lbs_deb_cmd("current radio channel is %d\n", ret);
820 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
825 * @brief Set the radio channel
827 * @param priv A pointer to struct lbs_private structure
828 * @param channel The desired channel, or 0 to clear a locked channel
830 * @return 0 on success, error on failure
832 int lbs_set_channel(struct lbs_private *priv, u8 channel)
834 struct cmd_ds_802_11_rf_channel cmd;
835 u8 old_channel = priv->curbssparams.channel;
838 lbs_deb_enter(LBS_DEB_CMD);
840 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
841 cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_SET);
842 cmd.channel = cpu_to_le16(channel);
844 ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd);
848 priv->curbssparams.channel = (uint8_t) le16_to_cpu(cmd.channel);
849 lbs_deb_cmd("channel switch from %d to %d\n", old_channel,
850 priv->curbssparams.channel);
853 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
857 static int lbs_cmd_802_11_rssi(struct lbs_private *priv,
858 struct cmd_ds_command *cmd)
861 lbs_deb_enter(LBS_DEB_CMD);
862 cmd->command = cpu_to_le16(CMD_802_11_RSSI);
863 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rssi) + S_DS_GEN);
864 cmd->params.rssi.N = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR);
866 /* reset Beacon SNR/NF/RSSI values */
867 priv->SNR[TYPE_BEACON][TYPE_NOAVG] = 0;
868 priv->SNR[TYPE_BEACON][TYPE_AVG] = 0;
869 priv->NF[TYPE_BEACON][TYPE_NOAVG] = 0;
870 priv->NF[TYPE_BEACON][TYPE_AVG] = 0;
871 priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = 0;
872 priv->RSSI[TYPE_BEACON][TYPE_AVG] = 0;
874 lbs_deb_leave(LBS_DEB_CMD);
878 static int lbs_cmd_reg_access(struct lbs_private *priv,
879 struct cmd_ds_command *cmdptr,
880 u8 cmd_action, void *pdata_buf)
882 struct lbs_offset_value *offval;
884 lbs_deb_enter(LBS_DEB_CMD);
886 offval = (struct lbs_offset_value *)pdata_buf;
888 switch (le16_to_cpu(cmdptr->command)) {
889 case CMD_MAC_REG_ACCESS:
891 struct cmd_ds_mac_reg_access *macreg;
894 cpu_to_le16(sizeof (struct cmd_ds_mac_reg_access)
897 (struct cmd_ds_mac_reg_access *)&cmdptr->params.
900 macreg->action = cpu_to_le16(cmd_action);
901 macreg->offset = cpu_to_le16((u16) offval->offset);
902 macreg->value = cpu_to_le32(offval->value);
907 case CMD_BBP_REG_ACCESS:
909 struct cmd_ds_bbp_reg_access *bbpreg;
913 (struct cmd_ds_bbp_reg_access)
916 (struct cmd_ds_bbp_reg_access *)&cmdptr->params.
919 bbpreg->action = cpu_to_le16(cmd_action);
920 bbpreg->offset = cpu_to_le16((u16) offval->offset);
921 bbpreg->value = (u8) offval->value;
926 case CMD_RF_REG_ACCESS:
928 struct cmd_ds_rf_reg_access *rfreg;
932 (struct cmd_ds_rf_reg_access) +
935 (struct cmd_ds_rf_reg_access *)&cmdptr->params.
938 rfreg->action = cpu_to_le16(cmd_action);
939 rfreg->offset = cpu_to_le16((u16) offval->offset);
940 rfreg->value = (u8) offval->value;
949 lbs_deb_leave(LBS_DEB_CMD);
953 static int lbs_cmd_802_11_mac_address(struct lbs_private *priv,
954 struct cmd_ds_command *cmd,
958 lbs_deb_enter(LBS_DEB_CMD);
959 cmd->command = cpu_to_le16(CMD_802_11_MAC_ADDRESS);
960 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_mac_address) +
964 cmd->params.macadd.action = cpu_to_le16(cmd_action);
966 if (cmd_action == CMD_ACT_SET) {
967 memcpy(cmd->params.macadd.macadd,
968 priv->current_addr, ETH_ALEN);
969 lbs_deb_hex(LBS_DEB_CMD, "SET_CMD: MAC addr", priv->current_addr, 6);
972 lbs_deb_leave(LBS_DEB_CMD);
976 static int lbs_cmd_802_11_eeprom_access(struct lbs_private *priv,
977 struct cmd_ds_command *cmd,
978 int cmd_action, void *pdata_buf)
980 struct lbs_ioctl_regrdwr *ea = pdata_buf;
982 lbs_deb_enter(LBS_DEB_CMD);
984 cmd->command = cpu_to_le16(CMD_802_11_EEPROM_ACCESS);
985 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_eeprom_access) +
989 cmd->params.rdeeprom.action = cpu_to_le16(ea->action);
990 cmd->params.rdeeprom.offset = cpu_to_le16(ea->offset);
991 cmd->params.rdeeprom.bytecount = cpu_to_le16(ea->NOB);
992 cmd->params.rdeeprom.value = 0;
994 lbs_deb_leave(LBS_DEB_CMD);
998 static int lbs_cmd_bt_access(struct lbs_private *priv,
999 struct cmd_ds_command *cmd,
1000 u16 cmd_action, void *pdata_buf)
1002 struct cmd_ds_bt_access *bt_access = &cmd->params.bt;
1003 lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
1005 cmd->command = cpu_to_le16(CMD_BT_ACCESS);
1006 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_bt_access) + S_DS_GEN);
1008 bt_access->action = cpu_to_le16(cmd_action);
1010 switch (cmd_action) {
1011 case CMD_ACT_BT_ACCESS_ADD:
1012 memcpy(bt_access->addr1, pdata_buf, 2 * ETH_ALEN);
1013 lbs_deb_hex(LBS_DEB_MESH, "BT_ADD: blinded MAC addr", bt_access->addr1, 6);
1015 case CMD_ACT_BT_ACCESS_DEL:
1016 memcpy(bt_access->addr1, pdata_buf, 1 * ETH_ALEN);
1017 lbs_deb_hex(LBS_DEB_MESH, "BT_DEL: blinded MAC addr", bt_access->addr1, 6);
1019 case CMD_ACT_BT_ACCESS_LIST:
1020 bt_access->id = cpu_to_le32(*(u32 *) pdata_buf);
1022 case CMD_ACT_BT_ACCESS_RESET:
1024 case CMD_ACT_BT_ACCESS_SET_INVERT:
1025 bt_access->id = cpu_to_le32(*(u32 *) pdata_buf);
1027 case CMD_ACT_BT_ACCESS_GET_INVERT:
1032 lbs_deb_leave(LBS_DEB_CMD);
1036 static int lbs_cmd_fwt_access(struct lbs_private *priv,
1037 struct cmd_ds_command *cmd,
1038 u16 cmd_action, void *pdata_buf)
1040 struct cmd_ds_fwt_access *fwt_access = &cmd->params.fwt;
1041 lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
1043 cmd->command = cpu_to_le16(CMD_FWT_ACCESS);
1044 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access) + S_DS_GEN);
1048 memcpy(fwt_access, pdata_buf, sizeof(*fwt_access));
1050 memset(fwt_access, 0, sizeof(*fwt_access));
1052 fwt_access->action = cpu_to_le16(cmd_action);
1054 lbs_deb_leave(LBS_DEB_CMD);
1058 int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
1059 struct cmd_ds_mesh_access *cmd)
1063 lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
1065 cmd->hdr.command = cpu_to_le16(CMD_MESH_ACCESS);
1066 cmd->hdr.size = cpu_to_le16(sizeof(*cmd));
1067 cmd->hdr.result = 0;
1069 cmd->action = cpu_to_le16(cmd_action);
1071 ret = lbs_cmd_with_response(priv, CMD_MESH_ACCESS, cmd);
1073 lbs_deb_leave(LBS_DEB_CMD);
1076 EXPORT_SYMBOL_GPL(lbs_mesh_access);
1078 int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan)
1080 struct cmd_ds_mesh_config cmd;
1082 memset(&cmd, 0, sizeof(cmd));
1083 cmd.action = cpu_to_le16(enable);
1084 cmd.channel = cpu_to_le16(chan);
1085 cmd.type = cpu_to_le16(priv->mesh_tlv);
1086 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1089 cmd.length = cpu_to_le16(priv->mesh_ssid_len);
1090 memcpy(cmd.data, priv->mesh_ssid, priv->mesh_ssid_len);
1092 lbs_deb_cmd("mesh config enable %d TLV %x channel %d SSID %s\n",
1093 enable, priv->mesh_tlv, chan,
1094 escape_essid(priv->mesh_ssid, priv->mesh_ssid_len));
1095 return lbs_cmd_with_response(priv, CMD_MESH_CONFIG, &cmd);
1098 static int lbs_cmd_bcn_ctrl(struct lbs_private * priv,
1099 struct cmd_ds_command *cmd,
1102 struct cmd_ds_802_11_beacon_control
1103 *bcn_ctrl = &cmd->params.bcn_ctrl;
1105 lbs_deb_enter(LBS_DEB_CMD);
1107 cpu_to_le16(sizeof(struct cmd_ds_802_11_beacon_control)
1109 cmd->command = cpu_to_le16(CMD_802_11_BEACON_CTRL);
1111 bcn_ctrl->action = cpu_to_le16(cmd_action);
1112 bcn_ctrl->beacon_enable = cpu_to_le16(priv->beacon_enable);
1113 bcn_ctrl->beacon_period = cpu_to_le16(priv->beacon_period);
1115 lbs_deb_leave(LBS_DEB_CMD);
1119 static void lbs_queue_cmd(struct lbs_private *priv,
1120 struct cmd_ctrl_node *cmdnode)
1122 unsigned long flags;
1125 lbs_deb_enter(LBS_DEB_HOST);
1128 lbs_deb_host("QUEUE_CMD: cmdnode is NULL\n");
1131 if (!cmdnode->cmdbuf->size) {
1132 lbs_deb_host("DNLD_CMD: cmd size is zero\n");
1135 cmdnode->result = 0;
1137 /* Exit_PS command needs to be queued in the header always. */
1138 if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) {
1139 struct cmd_ds_802_11_ps_mode *psm = (void *) &cmdnode->cmdbuf[1];
1141 if (psm->action == cpu_to_le16(CMD_SUBCMD_EXIT_PS)) {
1142 if (priv->psstate != PS_STATE_FULL_POWER)
1147 spin_lock_irqsave(&priv->driver_lock, flags);
1150 list_add_tail(&cmdnode->list, &priv->cmdpendingq);
1152 list_add(&cmdnode->list, &priv->cmdpendingq);
1154 spin_unlock_irqrestore(&priv->driver_lock, flags);
1156 lbs_deb_host("QUEUE_CMD: inserted command 0x%04x into cmdpendingq\n",
1157 le16_to_cpu(cmdnode->cmdbuf->command));
1160 lbs_deb_leave(LBS_DEB_HOST);
1163 static void lbs_submit_command(struct lbs_private *priv,
1164 struct cmd_ctrl_node *cmdnode)
1166 unsigned long flags;
1167 struct cmd_header *cmd;
1173 lbs_deb_enter(LBS_DEB_HOST);
1175 cmd = cmdnode->cmdbuf;
1177 spin_lock_irqsave(&priv->driver_lock, flags);
1178 priv->cur_cmd = cmdnode;
1179 priv->cur_cmd_retcode = 0;
1180 spin_unlock_irqrestore(&priv->driver_lock, flags);
1182 cmdsize = le16_to_cpu(cmd->size);
1183 command = le16_to_cpu(cmd->command);
1185 /* These commands take longer */
1186 if (command == CMD_802_11_SCAN || command == CMD_802_11_ASSOCIATE ||
1187 command == CMD_802_11_AUTHENTICATE)
1190 lbs_deb_host("DNLD_CMD: command 0x%04x, seq %d, size %d, jiffies %lu\n",
1191 command, le16_to_cpu(cmd->seqnum), cmdsize, jiffies);
1192 lbs_deb_hex(LBS_DEB_HOST, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize);
1194 ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize);
1197 lbs_pr_info("DNLD_CMD: hw_host_to_card failed: %d\n", ret);
1198 /* Let the timer kick in and retry, and potentially reset
1199 the whole thing if the condition persists */
1202 lbs_deb_cmd("DNLD_CMD: sent command 0x%04x, jiffies %lu\n",
1205 /* Setup the timer after transmit command */
1206 mod_timer(&priv->command_timer, jiffies + timeo);
1208 lbs_deb_leave(LBS_DEB_HOST);
1211 static int lbs_cmd_mac_control(struct lbs_private *priv,
1212 struct cmd_ds_command *cmd)
1214 struct cmd_ds_mac_control *mac = &cmd->params.macctrl;
1216 lbs_deb_enter(LBS_DEB_CMD);
1218 cmd->command = cpu_to_le16(CMD_MAC_CONTROL);
1219 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mac_control) + S_DS_GEN);
1220 mac->action = cpu_to_le16(priv->currentpacketfilter);
1222 lbs_deb_cmd("MAC_CONTROL: action 0x%x, size %d\n",
1223 le16_to_cpu(mac->action), le16_to_cpu(cmd->size));
1225 lbs_deb_leave(LBS_DEB_CMD);
1230 * This function inserts command node to cmdfreeq
1231 * after cleans it. Requires priv->driver_lock held.
1233 static void __lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
1234 struct cmd_ctrl_node *cmdnode)
1236 lbs_deb_enter(LBS_DEB_HOST);
1241 cmdnode->callback = NULL;
1242 cmdnode->callback_arg = 0;
1244 memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE);
1246 list_add_tail(&cmdnode->list, &priv->cmdfreeq);
1248 lbs_deb_leave(LBS_DEB_HOST);
1251 static void lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
1252 struct cmd_ctrl_node *ptempcmd)
1254 unsigned long flags;
1256 spin_lock_irqsave(&priv->driver_lock, flags);
1257 __lbs_cleanup_and_insert_cmd(priv, ptempcmd);
1258 spin_unlock_irqrestore(&priv->driver_lock, flags);
1261 void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
1264 if (cmd == priv->cur_cmd)
1265 priv->cur_cmd_retcode = result;
1267 cmd->result = result;
1268 cmd->cmdwaitqwoken = 1;
1269 wake_up_interruptible(&cmd->cmdwait_q);
1272 __lbs_cleanup_and_insert_cmd(priv, cmd);
1273 priv->cur_cmd = NULL;
1276 int lbs_set_radio_control(struct lbs_private *priv)
1279 struct cmd_ds_802_11_radio_control cmd;
1281 lbs_deb_enter(LBS_DEB_CMD);
1283 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1284 cmd.action = cpu_to_le16(CMD_ACT_SET);
1286 switch (priv->preamble) {
1287 case CMD_TYPE_SHORT_PREAMBLE:
1288 cmd.control = cpu_to_le16(SET_SHORT_PREAMBLE);
1291 case CMD_TYPE_LONG_PREAMBLE:
1292 cmd.control = cpu_to_le16(SET_LONG_PREAMBLE);
1295 case CMD_TYPE_AUTO_PREAMBLE:
1297 cmd.control = cpu_to_le16(SET_AUTO_PREAMBLE);
1302 cmd.control |= cpu_to_le16(TURN_ON_RF);
1304 cmd.control &= cpu_to_le16(~TURN_ON_RF);
1306 lbs_deb_cmd("RADIO_SET: radio %d, preamble %d\n", priv->radioon,
1309 ret = lbs_cmd_with_response(priv, CMD_802_11_RADIO_CONTROL, &cmd);
1311 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
1315 int lbs_set_mac_packet_filter(struct lbs_private *priv)
1319 lbs_deb_enter(LBS_DEB_CMD);
1321 /* Send MAC control command to station */
1322 ret = lbs_prepare_and_send_command(priv,
1323 CMD_MAC_CONTROL, 0, 0, 0, NULL);
1325 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
1330 * @brief This function prepare the command before send to firmware.
1332 * @param priv A pointer to struct lbs_private structure
1333 * @param cmd_no command number
1334 * @param cmd_action command action: GET or SET
1335 * @param wait_option wait option: wait response or not
1336 * @param cmd_oid cmd oid: treated as sub command
1337 * @param pdata_buf A pointer to informaion buffer
1340 int lbs_prepare_and_send_command(struct lbs_private *priv,
1343 u16 wait_option, u32 cmd_oid, void *pdata_buf)
1346 struct cmd_ctrl_node *cmdnode;
1347 struct cmd_ds_command *cmdptr;
1348 unsigned long flags;
1350 lbs_deb_enter(LBS_DEB_HOST);
1353 lbs_deb_host("PREP_CMD: priv is NULL\n");
1358 if (priv->surpriseremoved) {
1359 lbs_deb_host("PREP_CMD: card removed\n");
1364 cmdnode = lbs_get_cmd_ctrl_node(priv);
1366 if (cmdnode == NULL) {
1367 lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
1369 /* Wake up main thread to execute next command */
1370 wake_up_interruptible(&priv->waitq);
1375 lbs_set_cmd_ctrl_node(priv, cmdnode, pdata_buf);
1377 cmdptr = (struct cmd_ds_command *)cmdnode->cmdbuf;
1379 lbs_deb_host("PREP_CMD: command 0x%04x\n", cmd_no);
1381 /* Set sequence number, command and INT option */
1383 cmdptr->seqnum = cpu_to_le16(priv->seqnum);
1385 cmdptr->command = cpu_to_le16(cmd_no);
1389 case CMD_802_11_PS_MODE:
1390 ret = lbs_cmd_802_11_ps_mode(priv, cmdptr, cmd_action);
1393 case CMD_802_11_SCAN:
1394 ret = lbs_cmd_80211_scan(priv, cmdptr, pdata_buf);
1397 case CMD_MAC_CONTROL:
1398 ret = lbs_cmd_mac_control(priv, cmdptr);
1401 case CMD_802_11_ASSOCIATE:
1402 case CMD_802_11_REASSOCIATE:
1403 ret = lbs_cmd_80211_associate(priv, cmdptr, pdata_buf);
1406 case CMD_802_11_DEAUTHENTICATE:
1407 ret = lbs_cmd_80211_deauthenticate(priv, cmdptr);
1410 case CMD_802_11_SET_WEP:
1411 ret = lbs_cmd_802_11_set_wep(priv, cmdptr, cmd_action, pdata_buf);
1414 case CMD_802_11_AD_HOC_START:
1415 ret = lbs_cmd_80211_ad_hoc_start(priv, cmdptr, pdata_buf);
1420 case CMD_802_11_RESET:
1421 ret = lbs_cmd_802_11_reset(priv, cmdptr, cmd_action);
1424 case CMD_802_11_GET_LOG:
1425 ret = lbs_cmd_802_11_get_log(priv, cmdptr);
1428 case CMD_802_11_AUTHENTICATE:
1429 ret = lbs_cmd_80211_authenticate(priv, cmdptr, pdata_buf);
1432 case CMD_802_11_GET_STAT:
1433 ret = lbs_cmd_802_11_get_stat(priv, cmdptr);
1436 case CMD_802_11_SNMP_MIB:
1437 ret = lbs_cmd_802_11_snmp_mib(priv, cmdptr,
1438 cmd_action, cmd_oid, pdata_buf);
1441 case CMD_MAC_REG_ACCESS:
1442 case CMD_BBP_REG_ACCESS:
1443 case CMD_RF_REG_ACCESS:
1444 ret = lbs_cmd_reg_access(priv, cmdptr, cmd_action, pdata_buf);
1447 case CMD_802_11_RF_TX_POWER:
1448 ret = lbs_cmd_802_11_rf_tx_power(priv, cmdptr,
1449 cmd_action, pdata_buf);
1452 case CMD_802_11_RATE_ADAPT_RATESET:
1453 ret = lbs_cmd_802_11_rate_adapt_rateset(priv,
1454 cmdptr, cmd_action);
1457 case CMD_MAC_MULTICAST_ADR:
1458 ret = lbs_cmd_mac_multicast_adr(priv, cmdptr, cmd_action);
1461 case CMD_802_11_MONITOR_MODE:
1462 ret = lbs_cmd_802_11_monitor_mode(priv, cmdptr,
1463 cmd_action, pdata_buf);
1466 case CMD_802_11_AD_HOC_JOIN:
1467 ret = lbs_cmd_80211_ad_hoc_join(priv, cmdptr, pdata_buf);
1470 case CMD_802_11_RSSI:
1471 ret = lbs_cmd_802_11_rssi(priv, cmdptr);
1474 case CMD_802_11_AD_HOC_STOP:
1475 ret = lbs_cmd_80211_ad_hoc_stop(priv, cmdptr);
1478 case CMD_802_11_ENABLE_RSN:
1479 ret = lbs_cmd_802_11_enable_rsn(priv, cmdptr, cmd_action,
1483 case CMD_802_11_KEY_MATERIAL:
1484 ret = lbs_cmd_802_11_key_material(priv, cmdptr, cmd_action,
1485 cmd_oid, pdata_buf);
1488 case CMD_802_11_PAIRWISE_TSC:
1490 case CMD_802_11_GROUP_TSC:
1493 case CMD_802_11_MAC_ADDRESS:
1494 ret = lbs_cmd_802_11_mac_address(priv, cmdptr, cmd_action);
1497 case CMD_802_11_EEPROM_ACCESS:
1498 ret = lbs_cmd_802_11_eeprom_access(priv, cmdptr,
1499 cmd_action, pdata_buf);
1502 case CMD_802_11_SET_AFC:
1503 case CMD_802_11_GET_AFC:
1505 cmdptr->command = cpu_to_le16(cmd_no);
1506 cmdptr->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_afc) +
1509 memmove(&cmdptr->params.afc,
1510 pdata_buf, sizeof(struct cmd_ds_802_11_afc));
1515 case CMD_802_11D_DOMAIN_INFO:
1516 ret = lbs_cmd_802_11d_domain_info(priv, cmdptr,
1517 cmd_no, cmd_action);
1520 case CMD_802_11_SLEEP_PARAMS:
1521 ret = lbs_cmd_802_11_sleep_params(priv, cmdptr, cmd_action);
1523 case CMD_802_11_INACTIVITY_TIMEOUT:
1524 ret = lbs_cmd_802_11_inactivity_timeout(priv, cmdptr,
1525 cmd_action, pdata_buf);
1526 lbs_set_cmd_ctrl_node(priv, cmdnode, pdata_buf);
1529 case CMD_802_11_TPC_CFG:
1530 cmdptr->command = cpu_to_le16(CMD_802_11_TPC_CFG);
1532 cpu_to_le16(sizeof(struct cmd_ds_802_11_tpc_cfg) +
1535 memmove(&cmdptr->params.tpccfg,
1536 pdata_buf, sizeof(struct cmd_ds_802_11_tpc_cfg));
1540 case CMD_802_11_LED_GPIO_CTRL:
1542 struct mrvlietypes_ledgpio *gpio =
1543 (struct mrvlietypes_ledgpio*)
1544 cmdptr->params.ledgpio.data;
1546 memmove(&cmdptr->params.ledgpio,
1548 sizeof(struct cmd_ds_802_11_led_ctrl));
1551 cpu_to_le16(CMD_802_11_LED_GPIO_CTRL);
1553 #define ACTION_NUMLED_TLVTYPE_LEN_FIELDS_LEN 8
1555 cpu_to_le16(le16_to_cpu(gpio->header.len)
1557 + ACTION_NUMLED_TLVTYPE_LEN_FIELDS_LEN);
1558 gpio->header.len = gpio->header.len;
1563 case CMD_802_11_SUBSCRIBE_EVENT:
1564 lbs_cmd_802_11_subscribe_event(priv, cmdptr,
1565 cmd_action, pdata_buf);
1567 case CMD_802_11_PWR_CFG:
1568 cmdptr->command = cpu_to_le16(CMD_802_11_PWR_CFG);
1570 cpu_to_le16(sizeof(struct cmd_ds_802_11_pwr_cfg) +
1572 memmove(&cmdptr->params.pwrcfg, pdata_buf,
1573 sizeof(struct cmd_ds_802_11_pwr_cfg));
1578 ret = lbs_cmd_bt_access(priv, cmdptr, cmd_action, pdata_buf);
1581 case CMD_FWT_ACCESS:
1582 ret = lbs_cmd_fwt_access(priv, cmdptr, cmd_action, pdata_buf);
1586 cmdptr->command = cpu_to_le16(CMD_GET_TSF);
1587 cmdptr->size = cpu_to_le16(sizeof(struct cmd_ds_get_tsf) +
1591 case CMD_802_11_BEACON_CTRL:
1592 ret = lbs_cmd_bcn_ctrl(priv, cmdptr, cmd_action);
1595 lbs_deb_host("PREP_CMD: unknown command 0x%04x\n", cmd_no);
1600 /* return error, since the command preparation failed */
1602 lbs_deb_host("PREP_CMD: command preparation failed\n");
1603 lbs_cleanup_and_insert_cmd(priv, cmdnode);
1608 cmdnode->cmdwaitqwoken = 0;
1610 lbs_queue_cmd(priv, cmdnode);
1611 wake_up_interruptible(&priv->waitq);
1613 if (wait_option & CMD_OPTION_WAITFORRSP) {
1614 lbs_deb_host("PREP_CMD: wait for response\n");
1616 wait_event_interruptible(cmdnode->cmdwait_q,
1617 cmdnode->cmdwaitqwoken);
1620 spin_lock_irqsave(&priv->driver_lock, flags);
1621 if (priv->cur_cmd_retcode) {
1622 lbs_deb_host("PREP_CMD: command failed with return code %d\n",
1623 priv->cur_cmd_retcode);
1624 priv->cur_cmd_retcode = 0;
1627 spin_unlock_irqrestore(&priv->driver_lock, flags);
1630 lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
1633 EXPORT_SYMBOL_GPL(lbs_prepare_and_send_command);
1636 * @brief This function allocates the command buffer and link
1637 * it to command free queue.
1639 * @param priv A pointer to struct lbs_private structure
1642 int lbs_allocate_cmd_buffer(struct lbs_private *priv)
1647 struct cmd_ctrl_node *cmdarray;
1649 lbs_deb_enter(LBS_DEB_HOST);
1651 /* Allocate and initialize the command array */
1652 bufsize = sizeof(struct cmd_ctrl_node) * LBS_NUM_CMD_BUFFERS;
1653 if (!(cmdarray = kzalloc(bufsize, GFP_KERNEL))) {
1654 lbs_deb_host("ALLOC_CMD_BUF: tempcmd_array is NULL\n");
1658 priv->cmd_array = cmdarray;
1660 /* Allocate and initialize each command buffer in the command array */
1661 for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
1662 cmdarray[i].cmdbuf = kzalloc(LBS_CMD_BUFFER_SIZE, GFP_KERNEL);
1663 if (!cmdarray[i].cmdbuf) {
1664 lbs_deb_host("ALLOC_CMD_BUF: ptempvirtualaddr is NULL\n");
1670 for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
1671 init_waitqueue_head(&cmdarray[i].cmdwait_q);
1672 lbs_cleanup_and_insert_cmd(priv, &cmdarray[i]);
1677 lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
1682 * @brief This function frees the command buffer.
1684 * @param priv A pointer to struct lbs_private structure
1687 int lbs_free_cmd_buffer(struct lbs_private *priv)
1689 struct cmd_ctrl_node *cmdarray;
1692 lbs_deb_enter(LBS_DEB_HOST);
1694 /* need to check if cmd array is allocated or not */
1695 if (priv->cmd_array == NULL) {
1696 lbs_deb_host("FREE_CMD_BUF: cmd_array is NULL\n");
1700 cmdarray = priv->cmd_array;
1702 /* Release shared memory buffers */
1703 for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
1704 if (cmdarray[i].cmdbuf) {
1705 kfree(cmdarray[i].cmdbuf);
1706 cmdarray[i].cmdbuf = NULL;
1710 /* Release cmd_ctrl_node */
1711 if (priv->cmd_array) {
1712 kfree(priv->cmd_array);
1713 priv->cmd_array = NULL;
1717 lbs_deb_leave(LBS_DEB_HOST);
1722 * @brief This function gets a free command node if available in
1723 * command free queue.
1725 * @param priv A pointer to struct lbs_private structure
1726 * @return cmd_ctrl_node A pointer to cmd_ctrl_node structure or NULL
1728 static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv)
1730 struct cmd_ctrl_node *tempnode;
1731 unsigned long flags;
1733 lbs_deb_enter(LBS_DEB_HOST);
1738 spin_lock_irqsave(&priv->driver_lock, flags);
1740 if (!list_empty(&priv->cmdfreeq)) {
1741 tempnode = list_first_entry(&priv->cmdfreeq,
1742 struct cmd_ctrl_node, list);
1743 list_del(&tempnode->list);
1745 lbs_deb_host("GET_CMD_NODE: cmd_ctrl_node is not available\n");
1749 spin_unlock_irqrestore(&priv->driver_lock, flags);
1751 lbs_deb_leave(LBS_DEB_HOST);
1756 * @brief This function cleans command node.
1758 * @param ptempnode A pointer to cmdCtrlNode structure
1763 * @brief This function initializes the command node.
1765 * @param priv A pointer to struct lbs_private structure
1766 * @param ptempnode A pointer to cmd_ctrl_node structure
1767 * @param pdata_buf A pointer to informaion buffer
1770 static void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
1771 struct cmd_ctrl_node *ptempnode,
1774 lbs_deb_enter(LBS_DEB_HOST);
1779 ptempnode->callback = NULL;
1780 ptempnode->callback_arg = (unsigned long)pdata_buf;
1782 lbs_deb_leave(LBS_DEB_HOST);
1786 * @brief This function executes next command in command
1787 * pending queue. It will put fimware back to PS mode
1790 * @param priv A pointer to struct lbs_private structure
1793 int lbs_execute_next_command(struct lbs_private *priv)
1795 struct cmd_ctrl_node *cmdnode = NULL;
1796 struct cmd_header *cmd;
1797 unsigned long flags;
1800 // Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the
1801 // only caller to us is lbs_thread() and we get even when a
1802 // data packet is received
1803 lbs_deb_enter(LBS_DEB_THREAD);
1805 spin_lock_irqsave(&priv->driver_lock, flags);
1807 if (priv->cur_cmd) {
1808 lbs_pr_alert( "EXEC_NEXT_CMD: already processing command!\n");
1809 spin_unlock_irqrestore(&priv->driver_lock, flags);
1814 if (!list_empty(&priv->cmdpendingq)) {
1815 cmdnode = list_first_entry(&priv->cmdpendingq,
1816 struct cmd_ctrl_node, list);
1819 spin_unlock_irqrestore(&priv->driver_lock, flags);
1822 cmd = cmdnode->cmdbuf;
1824 if (is_command_allowed_in_ps(le16_to_cpu(cmd->command))) {
1825 if ((priv->psstate == PS_STATE_SLEEP) ||
1826 (priv->psstate == PS_STATE_PRE_SLEEP)) {
1828 "EXEC_NEXT_CMD: cannot send cmd 0x%04x in psstate %d\n",
1829 le16_to_cpu(cmd->command),
1834 lbs_deb_host("EXEC_NEXT_CMD: OK to send command "
1835 "0x%04x in psstate %d\n",
1836 le16_to_cpu(cmd->command), priv->psstate);
1837 } else if (priv->psstate != PS_STATE_FULL_POWER) {
1839 * 1. Non-PS command:
1840 * Queue it. set needtowakeup to TRUE if current state
1841 * is SLEEP, otherwise call lbs_ps_wakeup to send Exit_PS.
1842 * 2. PS command but not Exit_PS:
1844 * 3. PS command Exit_PS:
1845 * Set needtowakeup to TRUE if current state is SLEEP,
1846 * otherwise send this command down to firmware
1849 if (cmd->command != cpu_to_le16(CMD_802_11_PS_MODE)) {
1850 /* Prepare to send Exit PS,
1851 * this non PS command will be sent later */
1852 if ((priv->psstate == PS_STATE_SLEEP)
1853 || (priv->psstate == PS_STATE_PRE_SLEEP)
1855 /* w/ new scheme, it will not reach here.
1856 since it is blocked in main_thread. */
1857 priv->needtowakeup = 1;
1859 lbs_ps_wakeup(priv, 0);
1865 * PS command. Ignore it if it is not Exit_PS.
1866 * otherwise send it down immediately.
1868 struct cmd_ds_802_11_ps_mode *psm = (void *)&cmd[1];
1871 "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n",
1874 cpu_to_le16(CMD_SUBCMD_EXIT_PS)) {
1876 "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n");
1877 list_del(&cmdnode->list);
1878 spin_lock_irqsave(&priv->driver_lock, flags);
1879 lbs_complete_command(priv, cmdnode, 0);
1880 spin_unlock_irqrestore(&priv->driver_lock, flags);
1886 if ((priv->psstate == PS_STATE_SLEEP) ||
1887 (priv->psstate == PS_STATE_PRE_SLEEP)) {
1889 "EXEC_NEXT_CMD: ignore EXIT_PS cmd in sleep\n");
1890 list_del(&cmdnode->list);
1891 spin_lock_irqsave(&priv->driver_lock, flags);
1892 lbs_complete_command(priv, cmdnode, 0);
1893 spin_unlock_irqrestore(&priv->driver_lock, flags);
1894 priv->needtowakeup = 1;
1901 "EXEC_NEXT_CMD: sending EXIT_PS\n");
1904 list_del(&cmdnode->list);
1905 lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n",
1906 le16_to_cpu(cmd->command));
1907 lbs_submit_command(priv, cmdnode);
1910 * check if in power save mode, if yes, put the device back
1913 if ((priv->psmode != LBS802_11POWERMODECAM) &&
1914 (priv->psstate == PS_STATE_FULL_POWER) &&
1915 ((priv->connect_status == LBS_CONNECTED) ||
1916 (priv->mesh_connect_status == LBS_CONNECTED))) {
1917 if (priv->secinfo.WPAenabled ||
1918 priv->secinfo.WPA2enabled) {
1919 /* check for valid WPA group keys */
1920 if (priv->wpa_mcast_key.len ||
1921 priv->wpa_unicast_key.len) {
1923 "EXEC_NEXT_CMD: WPA enabled and GTK_SET"
1924 " go back to PS_SLEEP");
1925 lbs_ps_sleep(priv, 0);
1929 "EXEC_NEXT_CMD: cmdpendingq empty, "
1930 "go back to PS_SLEEP");
1931 lbs_ps_sleep(priv, 0);
1938 lbs_deb_leave(LBS_DEB_THREAD);
1942 void lbs_send_iwevcustom_event(struct lbs_private *priv, s8 *str)
1944 union iwreq_data iwrq;
1947 lbs_deb_enter(LBS_DEB_WEXT);
1949 memset(&iwrq, 0, sizeof(union iwreq_data));
1950 memset(buf, 0, sizeof(buf));
1952 snprintf(buf, sizeof(buf) - 1, "%s", str);
1954 iwrq.data.length = strlen(buf) + 1 + IW_EV_LCP_LEN;
1956 /* Send Event to upper layer */
1957 lbs_deb_wext("event indication string %s\n", (char *)buf);
1958 lbs_deb_wext("event indication length %d\n", iwrq.data.length);
1959 lbs_deb_wext("sending wireless event IWEVCUSTOM for %s\n", str);
1961 wireless_send_event(priv->dev, IWEVCUSTOM, &iwrq, buf);
1963 lbs_deb_leave(LBS_DEB_WEXT);
1966 static int sendconfirmsleep(struct lbs_private *priv, u8 *cmdptr, u16 size)
1968 unsigned long flags;
1971 lbs_deb_enter(LBS_DEB_HOST);
1973 lbs_deb_host("SEND_SLEEPC_CMD: before download, cmd size %d\n",
1976 lbs_deb_hex(LBS_DEB_HOST, "sleep confirm command", cmdptr, size);
1978 ret = priv->hw_host_to_card(priv, MVMS_CMD, cmdptr, size);
1980 spin_lock_irqsave(&priv->driver_lock, flags);
1981 if (priv->intcounter || priv->currenttxskb)
1982 lbs_deb_host("SEND_SLEEPC_CMD: intcounter %d, currenttxskb %p\n",
1983 priv->intcounter, priv->currenttxskb);
1984 spin_unlock_irqrestore(&priv->driver_lock, flags);
1988 "SEND_SLEEPC_CMD: Host to Card failed for Confirm Sleep\n");
1990 spin_lock_irqsave(&priv->driver_lock, flags);
1991 if (!priv->intcounter) {
1992 priv->psstate = PS_STATE_SLEEP;
1994 lbs_deb_host("SEND_SLEEPC_CMD: after sent, intcounter %d\n",
1997 spin_unlock_irqrestore(&priv->driver_lock, flags);
1999 lbs_deb_host("SEND_SLEEPC_CMD: sent confirm sleep\n");
2002 lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
2006 void lbs_ps_sleep(struct lbs_private *priv, int wait_option)
2008 lbs_deb_enter(LBS_DEB_HOST);
2011 * PS is currently supported only in Infrastructure mode
2012 * Remove this check if it is to be supported in IBSS mode also
2015 lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE,
2016 CMD_SUBCMD_ENTER_PS, wait_option, 0, NULL);
2018 lbs_deb_leave(LBS_DEB_HOST);
2022 * @brief This function sends Exit_PS command to firmware.
2024 * @param priv A pointer to struct lbs_private structure
2025 * @param wait_option wait response or not
2028 void lbs_ps_wakeup(struct lbs_private *priv, int wait_option)
2032 lbs_deb_enter(LBS_DEB_HOST);
2034 Localpsmode = cpu_to_le32(LBS802_11POWERMODECAM);
2036 lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE,
2038 wait_option, 0, &Localpsmode);
2040 lbs_deb_leave(LBS_DEB_HOST);
2044 * @brief This function checks condition and prepares to
2045 * send sleep confirm command to firmware if ok.
2047 * @param priv A pointer to struct lbs_private structure
2048 * @param psmode Power Saving mode
2051 void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode)
2053 unsigned long flags =0;
2056 lbs_deb_enter(LBS_DEB_HOST);
2058 if (priv->dnld_sent) {
2060 lbs_deb_host("dnld_sent was set\n");
2063 spin_lock_irqsave(&priv->driver_lock, flags);
2064 if (priv->cur_cmd) {
2066 lbs_deb_host("cur_cmd was set\n");
2068 if (priv->intcounter > 0) {
2070 lbs_deb_host("intcounter %d\n", priv->intcounter);
2072 spin_unlock_irqrestore(&priv->driver_lock, flags);
2075 lbs_deb_host("sending lbs_ps_confirm_sleep\n");
2076 sendconfirmsleep(priv, (u8 *) & priv->lbs_ps_confirm_sleep,
2077 sizeof(struct PS_CMD_ConfirmSleep));
2079 lbs_deb_host("sleep confirm has been delayed\n");
2082 lbs_deb_leave(LBS_DEB_HOST);
2087 * @brief Simple callback that copies response back into command
2089 * @param priv A pointer to struct lbs_private structure
2090 * @param extra A pointer to the original command structure for which
2091 * 'resp' is a response
2092 * @param resp A pointer to the command response
2094 * @return 0 on success, error on failure
2096 int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
2097 struct cmd_header *resp)
2099 struct cmd_header *buf = (void *)extra;
2102 lbs_deb_enter(LBS_DEB_CMD);
2104 copy_len = min(le16_to_cpu(buf->size), le16_to_cpu(resp->size));
2105 lbs_deb_cmd("Copying back %u bytes; command response was %u bytes, "
2106 "copy back buffer was %u bytes\n", copy_len,
2107 le16_to_cpu(resp->size), le16_to_cpu(buf->size));
2108 memcpy(buf, resp, copy_len);
2110 lbs_deb_leave(LBS_DEB_CMD);
2113 EXPORT_SYMBOL_GPL(lbs_cmd_copyback);
2115 struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, uint16_t command,
2116 struct cmd_header *in_cmd, int in_cmd_size,
2117 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
2118 unsigned long callback_arg)
2120 struct cmd_ctrl_node *cmdnode;
2122 lbs_deb_enter(LBS_DEB_HOST);
2124 if (priv->surpriseremoved) {
2125 lbs_deb_host("PREP_CMD: card removed\n");
2126 cmdnode = ERR_PTR(-ENOENT);
2130 cmdnode = lbs_get_cmd_ctrl_node(priv);
2131 if (cmdnode == NULL) {
2132 lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
2134 /* Wake up main thread to execute next command */
2135 wake_up_interruptible(&priv->waitq);
2136 cmdnode = ERR_PTR(-ENOBUFS);
2140 cmdnode->callback = callback;
2141 cmdnode->callback_arg = callback_arg;
2143 /* Copy the incoming command to the buffer */
2144 memcpy(cmdnode->cmdbuf, in_cmd, in_cmd_size);
2146 /* Set sequence number, clean result, move to buffer */
2148 cmdnode->cmdbuf->command = cpu_to_le16(command);
2149 cmdnode->cmdbuf->size = cpu_to_le16(in_cmd_size);
2150 cmdnode->cmdbuf->seqnum = cpu_to_le16(priv->seqnum);
2151 cmdnode->cmdbuf->result = 0;
2153 lbs_deb_host("PREP_CMD: command 0x%04x\n", command);
2155 /* here was the big old switch() statement, which is now obsolete,
2156 * because the caller of lbs_cmd() sets up all of *cmd for us. */
2158 cmdnode->cmdwaitqwoken = 0;
2159 lbs_queue_cmd(priv, cmdnode);
2160 wake_up_interruptible(&priv->waitq);
2163 lbs_deb_leave_args(LBS_DEB_HOST, "ret %p", cmdnode);
2167 int __lbs_cmd(struct lbs_private *priv, uint16_t command,
2168 struct cmd_header *in_cmd, int in_cmd_size,
2169 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
2170 unsigned long callback_arg)
2172 struct cmd_ctrl_node *cmdnode;
2173 unsigned long flags;
2176 lbs_deb_enter(LBS_DEB_HOST);
2178 cmdnode = __lbs_cmd_async(priv, command, in_cmd, in_cmd_size,
2179 callback, callback_arg);
2180 if (IS_ERR(cmdnode)) {
2181 ret = PTR_ERR(cmdnode);
2186 wait_event_interruptible(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken);
2188 spin_lock_irqsave(&priv->driver_lock, flags);
2189 ret = cmdnode->result;
2191 lbs_pr_info("PREP_CMD: command 0x%04x failed: %d\n",
2194 __lbs_cleanup_and_insert_cmd(priv, cmdnode);
2195 spin_unlock_irqrestore(&priv->driver_lock, flags);
2198 lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
2201 EXPORT_SYMBOL_GPL(__lbs_cmd);