2 * This file contains the handling of command.
3 * It prepares command and sends it to firmware when it is ready.
6 #include <linux/kfifo.h>
7 #include <linux/sched.h>
8 #include <linux/slab.h>
9 #include <linux/if_arp.h>
15 #define CAL_NF(nf) ((s32)(-(s32)(nf)))
16 #define CAL_RSSI(snr, nf) ((s32)((s32)(snr) + CAL_NF(nf)))
19 * @brief Simple callback that copies response back into command
21 * @param priv A pointer to struct lbs_private structure
22 * @param extra A pointer to the original command structure for which
23 * 'resp' is a response
24 * @param resp A pointer to the command response
26 * @return 0 on success, error on failure
28 int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
29 struct cmd_header *resp)
31 struct cmd_header *buf = (void *)extra;
34 copy_len = min(le16_to_cpu(buf->size), le16_to_cpu(resp->size));
35 memcpy(buf, resp, copy_len);
38 EXPORT_SYMBOL_GPL(lbs_cmd_copyback);
41 * @brief Simple callback that ignores the result. Use this if
42 * you just want to send a command to the hardware, but don't
43 * care for the result.
46 * @param extra ignored
49 * @return 0 for success
51 static int lbs_cmd_async_callback(struct lbs_private *priv, unsigned long extra,
52 struct cmd_header *resp)
59 * @brief Checks whether a command is allowed in Power Save mode
61 * @param command the command ID
62 * @return 1 if allowed, 0 if not allowed
64 static u8 is_command_allowed_in_ps(u16 cmd)
69 case CMD_802_11_HOST_SLEEP_CFG:
78 * @brief Updates the hardware details like MAC address and regulatory region
80 * @param priv A pointer to struct lbs_private structure
82 * @return 0 on success, error on failure
84 int lbs_update_hw_spec(struct lbs_private *priv)
86 struct cmd_ds_get_hw_spec cmd;
90 lbs_deb_enter(LBS_DEB_CMD);
92 memset(&cmd, 0, sizeof(cmd));
93 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
94 memcpy(cmd.permanentaddr, priv->current_addr, ETH_ALEN);
95 ret = lbs_cmd_with_response(priv, CMD_GET_HW_SPEC, &cmd);
99 priv->fwcapinfo = le32_to_cpu(cmd.fwcapinfo);
101 /* The firmware release is in an interesting format: the patch
102 * level is in the most significant nibble ... so fix that: */
103 priv->fwrelease = le32_to_cpu(cmd.fwrelease);
104 priv->fwrelease = (priv->fwrelease << 8) |
105 (priv->fwrelease >> 24 & 0xff);
107 /* Some firmware capabilities:
108 * CF card firmware 5.0.16p0: cap 0x00000303
109 * USB dongle firmware 5.110.17p2: cap 0x00000303
111 lbs_pr_info("%pM, fw %u.%u.%up%u, cap 0x%08x\n",
113 priv->fwrelease >> 24 & 0xff,
114 priv->fwrelease >> 16 & 0xff,
115 priv->fwrelease >> 8 & 0xff,
116 priv->fwrelease & 0xff,
118 lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n",
119 cmd.hwifversion, cmd.version);
121 /* Clamp region code to 8-bit since FW spec indicates that it should
122 * only ever be 8-bit, even though the field size is 16-bit. Some firmware
123 * returns non-zero high 8 bits here.
125 * Firmware version 4.0.102 used in CF8381 has region code shifted. We
126 * need to check for this problem and handle it properly.
128 if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V4)
129 priv->regioncode = (le16_to_cpu(cmd.regioncode) >> 8) & 0xFF;
131 priv->regioncode = le16_to_cpu(cmd.regioncode) & 0xFF;
133 for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
134 /* use the region code to search for the index */
135 if (priv->regioncode == lbs_region_code_to_index[i])
139 /* if it's unidentified region code, use the default (USA) */
140 if (i >= MRVDRV_MAX_REGION_CODE) {
141 priv->regioncode = 0x10;
142 lbs_pr_info("unidentified region code; using the default (USA)\n");
145 if (priv->current_addr[0] == 0xff)
146 memmove(priv->current_addr, cmd.permanentaddr, ETH_ALEN);
148 memcpy(priv->dev->dev_addr, priv->current_addr, ETH_ALEN);
150 memcpy(priv->mesh_dev->dev_addr, priv->current_addr, ETH_ALEN);
153 lbs_deb_leave(LBS_DEB_CMD);
157 static int lbs_ret_host_sleep_cfg(struct lbs_private *priv, unsigned long dummy,
158 struct cmd_header *resp)
160 lbs_deb_enter(LBS_DEB_CMD);
161 if (priv->is_host_sleep_activated) {
162 priv->is_host_sleep_configured = 0;
163 if (priv->psstate == PS_STATE_FULL_POWER) {
164 priv->is_host_sleep_activated = 0;
165 wake_up_interruptible(&priv->host_sleep_q);
168 priv->is_host_sleep_configured = 1;
170 lbs_deb_leave(LBS_DEB_CMD);
174 int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
175 struct wol_config *p_wol_config)
177 struct cmd_ds_host_sleep cmd_config;
180 cmd_config.hdr.size = cpu_to_le16(sizeof(cmd_config));
181 cmd_config.criteria = cpu_to_le32(criteria);
182 cmd_config.gpio = priv->wol_gpio;
183 cmd_config.gap = priv->wol_gap;
185 if (p_wol_config != NULL)
186 memcpy((uint8_t *)&cmd_config.wol_conf, (uint8_t *)p_wol_config,
187 sizeof(struct wol_config));
189 cmd_config.wol_conf.action = CMD_ACT_ACTION_NONE;
191 ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config.hdr,
192 le16_to_cpu(cmd_config.hdr.size),
193 lbs_ret_host_sleep_cfg, 0);
196 memcpy((uint8_t *) p_wol_config,
197 (uint8_t *)&cmd_config.wol_conf,
198 sizeof(struct wol_config));
200 lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret);
205 EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg);
208 * @brief Sets the Power Save mode
210 * @param priv A pointer to struct lbs_private structure
211 * @param cmd_action The Power Save operation (PS_MODE_ACTION_ENTER_PS or
212 * PS_MODE_ACTION_EXIT_PS)
213 * @param block Whether to block on a response or not
215 * @return 0 on success, error on failure
217 int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block)
219 struct cmd_ds_802_11_ps_mode cmd;
222 lbs_deb_enter(LBS_DEB_CMD);
224 memset(&cmd, 0, sizeof(cmd));
225 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
226 cmd.action = cpu_to_le16(cmd_action);
228 if (cmd_action == PS_MODE_ACTION_ENTER_PS) {
229 lbs_deb_cmd("PS_MODE: action ENTER_PS\n");
230 cmd.multipledtim = cpu_to_le16(1); /* Default DTIM multiple */
231 } else if (cmd_action == PS_MODE_ACTION_EXIT_PS) {
232 lbs_deb_cmd("PS_MODE: action EXIT_PS\n");
234 /* We don't handle CONFIRM_SLEEP here because it needs to
235 * be fastpathed to the firmware.
237 lbs_deb_cmd("PS_MODE: unknown action 0x%X\n", cmd_action);
243 ret = lbs_cmd_with_response(priv, CMD_802_11_PS_MODE, &cmd);
245 lbs_cmd_async(priv, CMD_802_11_PS_MODE, &cmd.hdr, sizeof (cmd));
248 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
252 int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action,
253 struct sleep_params *sp)
255 struct cmd_ds_802_11_sleep_params cmd;
258 lbs_deb_enter(LBS_DEB_CMD);
260 if (cmd_action == CMD_ACT_GET) {
261 memset(&cmd, 0, sizeof(cmd));
263 cmd.error = cpu_to_le16(sp->sp_error);
264 cmd.offset = cpu_to_le16(sp->sp_offset);
265 cmd.stabletime = cpu_to_le16(sp->sp_stabletime);
266 cmd.calcontrol = sp->sp_calcontrol;
267 cmd.externalsleepclk = sp->sp_extsleepclk;
268 cmd.reserved = cpu_to_le16(sp->sp_reserved);
270 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
271 cmd.action = cpu_to_le16(cmd_action);
273 ret = lbs_cmd_with_response(priv, CMD_802_11_SLEEP_PARAMS, &cmd);
276 lbs_deb_cmd("error 0x%x, offset 0x%x, stabletime 0x%x, "
277 "calcontrol 0x%x extsleepclk 0x%x\n",
278 le16_to_cpu(cmd.error), le16_to_cpu(cmd.offset),
279 le16_to_cpu(cmd.stabletime), cmd.calcontrol,
280 cmd.externalsleepclk);
282 sp->sp_error = le16_to_cpu(cmd.error);
283 sp->sp_offset = le16_to_cpu(cmd.offset);
284 sp->sp_stabletime = le16_to_cpu(cmd.stabletime);
285 sp->sp_calcontrol = cmd.calcontrol;
286 sp->sp_extsleepclk = cmd.externalsleepclk;
287 sp->sp_reserved = le16_to_cpu(cmd.reserved);
290 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
294 static int lbs_wait_for_ds_awake(struct lbs_private *priv)
298 lbs_deb_enter(LBS_DEB_CMD);
300 if (priv->is_deep_sleep) {
301 if (!wait_event_interruptible_timeout(priv->ds_awake_q,
302 !priv->is_deep_sleep, (10 * HZ))) {
303 lbs_pr_err("ds_awake_q: timer expired\n");
308 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
312 int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep)
316 lbs_deb_enter(LBS_DEB_CMD);
319 if (priv->is_deep_sleep != 1) {
320 lbs_deb_cmd("deep sleep: sleep\n");
321 BUG_ON(!priv->enter_deep_sleep);
322 ret = priv->enter_deep_sleep(priv);
324 netif_stop_queue(priv->dev);
325 netif_carrier_off(priv->dev);
328 lbs_pr_err("deep sleep: already enabled\n");
331 if (priv->is_deep_sleep) {
332 lbs_deb_cmd("deep sleep: wakeup\n");
333 BUG_ON(!priv->exit_deep_sleep);
334 ret = priv->exit_deep_sleep(priv);
336 ret = lbs_wait_for_ds_awake(priv);
338 lbs_pr_err("deep sleep: wakeup"
344 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
348 static int lbs_ret_host_sleep_activate(struct lbs_private *priv,
350 struct cmd_header *cmd)
352 lbs_deb_enter(LBS_DEB_FW);
353 priv->is_host_sleep_activated = 1;
354 wake_up_interruptible(&priv->host_sleep_q);
355 lbs_deb_leave(LBS_DEB_FW);
359 int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep)
361 struct cmd_header cmd;
363 uint32_t criteria = EHS_REMOVE_WAKEUP;
365 lbs_deb_enter(LBS_DEB_CMD);
368 if (priv->is_host_sleep_activated != 1) {
369 memset(&cmd, 0, sizeof(cmd));
370 ret = lbs_host_sleep_cfg(priv, priv->wol_criteria,
371 (struct wol_config *)NULL);
373 lbs_pr_info("Host sleep configuration failed: "
377 if (priv->psstate == PS_STATE_FULL_POWER) {
378 ret = __lbs_cmd(priv,
379 CMD_802_11_HOST_SLEEP_ACTIVATE,
382 lbs_ret_host_sleep_activate, 0);
384 lbs_pr_info("HOST_SLEEP_ACTIVATE "
385 "failed: %d\n", ret);
388 if (!wait_event_interruptible_timeout(
390 priv->is_host_sleep_activated,
392 lbs_pr_err("host_sleep_q: timer expired\n");
396 lbs_pr_err("host sleep: already enabled\n");
399 if (priv->is_host_sleep_activated)
400 ret = lbs_host_sleep_cfg(priv, criteria,
401 (struct wol_config *)NULL);
408 * @brief Set an SNMP MIB value
410 * @param priv A pointer to struct lbs_private structure
411 * @param oid The OID to set in the firmware
412 * @param val Value to set the OID to
414 * @return 0 on success, error on failure
416 int lbs_set_snmp_mib(struct lbs_private *priv, u32 oid, u16 val)
418 struct cmd_ds_802_11_snmp_mib cmd;
421 lbs_deb_enter(LBS_DEB_CMD);
423 memset(&cmd, 0, sizeof (cmd));
424 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
425 cmd.action = cpu_to_le16(CMD_ACT_SET);
426 cmd.oid = cpu_to_le16((u16) oid);
429 case SNMP_MIB_OID_BSS_TYPE:
430 cmd.bufsize = cpu_to_le16(sizeof(u8));
433 case SNMP_MIB_OID_11D_ENABLE:
434 case SNMP_MIB_OID_FRAG_THRESHOLD:
435 case SNMP_MIB_OID_RTS_THRESHOLD:
436 case SNMP_MIB_OID_SHORT_RETRY_LIMIT:
437 case SNMP_MIB_OID_LONG_RETRY_LIMIT:
438 cmd.bufsize = cpu_to_le16(sizeof(u16));
439 *((__le16 *)(&cmd.value)) = cpu_to_le16(val);
442 lbs_deb_cmd("SNMP_CMD: (set) unhandled OID 0x%x\n", oid);
447 lbs_deb_cmd("SNMP_CMD: (set) oid 0x%x, oid size 0x%x, value 0x%x\n",
448 le16_to_cpu(cmd.oid), le16_to_cpu(cmd.bufsize), val);
450 ret = lbs_cmd_with_response(priv, CMD_802_11_SNMP_MIB, &cmd);
453 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
458 * @brief Get an SNMP MIB value
460 * @param priv A pointer to struct lbs_private structure
461 * @param oid The OID to retrieve from the firmware
462 * @param out_val Location for the returned value
464 * @return 0 on success, error on failure
466 int lbs_get_snmp_mib(struct lbs_private *priv, u32 oid, u16 *out_val)
468 struct cmd_ds_802_11_snmp_mib cmd;
471 lbs_deb_enter(LBS_DEB_CMD);
473 memset(&cmd, 0, sizeof (cmd));
474 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
475 cmd.action = cpu_to_le16(CMD_ACT_GET);
476 cmd.oid = cpu_to_le16(oid);
478 ret = lbs_cmd_with_response(priv, CMD_802_11_SNMP_MIB, &cmd);
482 switch (le16_to_cpu(cmd.bufsize)) {
484 *out_val = cmd.value[0];
487 *out_val = le16_to_cpu(*((__le16 *)(&cmd.value)));
490 lbs_deb_cmd("SNMP_CMD: (get) unhandled OID 0x%x size %d\n",
491 oid, le16_to_cpu(cmd.bufsize));
496 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
501 * @brief Get the min, max, and current TX power
503 * @param priv A pointer to struct lbs_private structure
504 * @param curlevel Current power level in dBm
505 * @param minlevel Minimum supported power level in dBm (optional)
506 * @param maxlevel Maximum supported power level in dBm (optional)
508 * @return 0 on success, error on failure
510 int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel,
513 struct cmd_ds_802_11_rf_tx_power cmd;
516 lbs_deb_enter(LBS_DEB_CMD);
518 memset(&cmd, 0, sizeof(cmd));
519 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
520 cmd.action = cpu_to_le16(CMD_ACT_GET);
522 ret = lbs_cmd_with_response(priv, CMD_802_11_RF_TX_POWER, &cmd);
524 *curlevel = le16_to_cpu(cmd.curlevel);
526 *minlevel = cmd.minlevel;
528 *maxlevel = cmd.maxlevel;
531 lbs_deb_leave(LBS_DEB_CMD);
536 * @brief Set the TX power
538 * @param priv A pointer to struct lbs_private structure
539 * @param dbm The desired power level in dBm
541 * @return 0 on success, error on failure
543 int lbs_set_tx_power(struct lbs_private *priv, s16 dbm)
545 struct cmd_ds_802_11_rf_tx_power cmd;
548 lbs_deb_enter(LBS_DEB_CMD);
550 memset(&cmd, 0, sizeof(cmd));
551 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
552 cmd.action = cpu_to_le16(CMD_ACT_SET);
553 cmd.curlevel = cpu_to_le16(dbm);
555 lbs_deb_cmd("SET_RF_TX_POWER: %d dBm\n", dbm);
557 ret = lbs_cmd_with_response(priv, CMD_802_11_RF_TX_POWER, &cmd);
559 lbs_deb_leave(LBS_DEB_CMD);
564 * @brief Enable or disable monitor mode (only implemented on OLPC usb8388 FW)
566 * @param priv A pointer to struct lbs_private structure
567 * @param enable 1 to enable monitor mode, 0 to disable
569 * @return 0 on success, error on failure
571 int lbs_set_monitor_mode(struct lbs_private *priv, int enable)
573 struct cmd_ds_802_11_monitor_mode cmd;
576 memset(&cmd, 0, sizeof(cmd));
577 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
578 cmd.action = cpu_to_le16(CMD_ACT_SET);
580 cmd.mode = cpu_to_le16(0x1);
582 lbs_deb_cmd("SET_MONITOR_MODE: %d\n", enable);
584 ret = lbs_cmd_with_response(priv, CMD_802_11_MONITOR_MODE, &cmd);
586 priv->dev->type = enable ? ARPHRD_IEEE80211_RADIOTAP :
590 lbs_deb_leave(LBS_DEB_CMD);
595 * @brief Get the radio channel
597 * @param priv A pointer to struct lbs_private structure
599 * @return The channel on success, error on failure
601 static int lbs_get_channel(struct lbs_private *priv)
603 struct cmd_ds_802_11_rf_channel cmd;
606 lbs_deb_enter(LBS_DEB_CMD);
608 memset(&cmd, 0, sizeof(cmd));
609 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
610 cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_GET);
612 ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd);
616 ret = le16_to_cpu(cmd.channel);
617 lbs_deb_cmd("current radio channel is %d\n", ret);
620 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
624 int lbs_update_channel(struct lbs_private *priv)
628 /* the channel in f/w could be out of sync; get the current channel */
629 lbs_deb_enter(LBS_DEB_ASSOC);
631 ret = lbs_get_channel(priv);
636 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
641 * @brief Set the radio channel
643 * @param priv A pointer to struct lbs_private structure
644 * @param channel The desired channel, or 0 to clear a locked channel
646 * @return 0 on success, error on failure
648 int lbs_set_channel(struct lbs_private *priv, u8 channel)
650 struct cmd_ds_802_11_rf_channel cmd;
652 u8 old_channel = priv->channel;
656 lbs_deb_enter(LBS_DEB_CMD);
658 memset(&cmd, 0, sizeof(cmd));
659 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
660 cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_SET);
661 cmd.channel = cpu_to_le16(channel);
663 ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd);
667 priv->channel = (uint8_t) le16_to_cpu(cmd.channel);
668 lbs_deb_cmd("channel switch from %d to %d\n", old_channel,
672 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
677 * @brief Get current RSSI and noise floor
679 * @param priv A pointer to struct lbs_private structure
680 * @param rssi On successful return, signal level in mBm
682 * @return The channel on success, error on failure
684 int lbs_get_rssi(struct lbs_private *priv, s8 *rssi, s8 *nf)
686 struct cmd_ds_802_11_rssi cmd;
689 lbs_deb_enter(LBS_DEB_CMD);
691 BUG_ON(rssi == NULL);
694 memset(&cmd, 0, sizeof(cmd));
695 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
696 /* Average SNR over last 8 beacons */
697 cmd.n_or_snr = cpu_to_le16(8);
699 ret = lbs_cmd_with_response(priv, CMD_802_11_RSSI, &cmd);
701 *nf = CAL_NF(le16_to_cpu(cmd.nf));
702 *rssi = CAL_RSSI(le16_to_cpu(cmd.n_or_snr), le16_to_cpu(cmd.nf));
705 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
710 * @brief Send regulatory and 802.11d domain information to the firmware
712 * @param priv pointer to struct lbs_private
713 * @param request cfg80211 regulatory request structure
714 * @param bands the device's supported bands and channels
716 * @return 0 on success, error code on failure
718 int lbs_set_11d_domain_info(struct lbs_private *priv,
719 struct regulatory_request *request,
720 struct ieee80211_supported_band **bands)
722 struct cmd_ds_802_11d_domain_info cmd;
723 struct mrvl_ie_domain_param_set *domain = &cmd.domain;
724 struct ieee80211_country_ie_triplet *t;
725 enum ieee80211_band band;
726 struct ieee80211_channel *ch;
728 u8 num_parsed_chan = 0;
729 u8 first_channel = 0, next_chan = 0, max_pwr = 0;
734 lbs_deb_enter(LBS_DEB_11D);
736 memset(&cmd, 0, sizeof(cmd));
737 cmd.action = cpu_to_le16(CMD_ACT_SET);
739 lbs_deb_11d("Setting country code '%c%c'\n",
740 request->alpha2[0], request->alpha2[1]);
742 domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN);
744 /* Set country code */
745 domain->country_code[0] = request->alpha2[0];
746 domain->country_code[1] = request->alpha2[1];
747 domain->country_code[2] = ' ';
749 /* Now set up the channel triplets; firmware is somewhat picky here
750 * and doesn't validate channel numbers and spans; hence it would
751 * interpret a triplet of (36, 4, 20) as channels 36, 37, 38, 39. Since
752 * the last 3 aren't valid channels, the driver is responsible for
753 * splitting that up into 4 triplet pairs of (36, 1, 20) + (40, 1, 20)
757 (band < IEEE80211_NUM_BANDS) && (num_triplet < MAX_11D_TRIPLETS);
764 (i < bands[band]->n_channels) && (num_triplet < MAX_11D_TRIPLETS);
766 ch = &bands[band]->channels[i];
767 if (ch->flags & IEEE80211_CHAN_DISABLED)
772 next_chan = first_channel = (u32) ch->hw_value;
773 max_pwr = ch->max_power;
778 if ((ch->hw_value == next_chan + 1) &&
779 (ch->max_power == max_pwr)) {
780 /* Consolidate adjacent channels */
784 /* Add this triplet */
785 lbs_deb_11d("11D triplet (%d, %d, %d)\n",
786 first_channel, num_parsed_chan,
788 t = &domain->triplet[num_triplet];
789 t->chans.first_channel = first_channel;
790 t->chans.num_channels = num_parsed_chan;
791 t->chans.max_power = max_pwr;
798 /* Add last triplet */
799 lbs_deb_11d("11D triplet (%d, %d, %d)\n", first_channel,
800 num_parsed_chan, max_pwr);
801 t = &domain->triplet[num_triplet];
802 t->chans.first_channel = first_channel;
803 t->chans.num_channels = num_parsed_chan;
804 t->chans.max_power = max_pwr;
809 lbs_deb_11d("# triplets %d\n", num_triplet);
811 /* Set command header sizes */
812 triplet_size = num_triplet * sizeof(struct ieee80211_country_ie_triplet);
813 domain->header.len = cpu_to_le16(sizeof(domain->country_code) +
816 lbs_deb_hex(LBS_DEB_11D, "802.11D domain param set",
817 (u8 *) &cmd.domain.country_code,
818 le16_to_cpu(domain->header.len));
820 cmd.hdr.size = cpu_to_le16(sizeof(cmd.hdr) +
822 sizeof(cmd.domain.header) +
823 sizeof(cmd.domain.country_code) +
826 ret = lbs_cmd_with_response(priv, CMD_802_11D_DOMAIN_INFO, &cmd);
828 lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret);
833 * @brief Read a MAC, Baseband, or RF register
835 * @param priv pointer to struct lbs_private
836 * @param cmd register command, one of CMD_MAC_REG_ACCESS,
837 * CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
838 * @param offset byte offset of the register to get
839 * @param value on success, the value of the register at 'offset'
841 * @return 0 on success, error code on failure
843 int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value)
845 struct cmd_ds_reg_access cmd;
848 lbs_deb_enter(LBS_DEB_CMD);
850 BUG_ON(value == NULL);
852 memset(&cmd, 0, sizeof(cmd));
853 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
854 cmd.action = cpu_to_le16(CMD_ACT_GET);
856 if (reg != CMD_MAC_REG_ACCESS &&
857 reg != CMD_BBP_REG_ACCESS &&
858 reg != CMD_RF_REG_ACCESS) {
863 ret = lbs_cmd_with_response(priv, reg, &cmd);
865 if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS)
866 *value = cmd.value.bbp_rf;
867 else if (reg == CMD_MAC_REG_ACCESS)
868 *value = le32_to_cpu(cmd.value.mac);
872 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
877 * @brief Write a MAC, Baseband, or RF register
879 * @param priv pointer to struct lbs_private
880 * @param cmd register command, one of CMD_MAC_REG_ACCESS,
881 * CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
882 * @param offset byte offset of the register to set
883 * @param value the value to write to the register at 'offset'
885 * @return 0 on success, error code on failure
887 int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value)
889 struct cmd_ds_reg_access cmd;
892 lbs_deb_enter(LBS_DEB_CMD);
894 memset(&cmd, 0, sizeof(cmd));
895 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
896 cmd.action = cpu_to_le16(CMD_ACT_SET);
898 if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS)
899 cmd.value.bbp_rf = (u8) (value & 0xFF);
900 else if (reg == CMD_MAC_REG_ACCESS)
901 cmd.value.mac = cpu_to_le32(value);
907 ret = lbs_cmd_with_response(priv, reg, &cmd);
910 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
914 static void lbs_queue_cmd(struct lbs_private *priv,
915 struct cmd_ctrl_node *cmdnode)
920 lbs_deb_enter(LBS_DEB_HOST);
923 lbs_deb_host("QUEUE_CMD: cmdnode is NULL\n");
926 if (!cmdnode->cmdbuf->size) {
927 lbs_deb_host("DNLD_CMD: cmd size is zero\n");
932 /* Exit_PS command needs to be queued in the header always. */
933 if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) {
934 struct cmd_ds_802_11_ps_mode *psm = (void *) &cmdnode->cmdbuf;
936 if (psm->action == cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) {
937 if (priv->psstate != PS_STATE_FULL_POWER)
942 if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_WAKEUP_CONFIRM)
945 spin_lock_irqsave(&priv->driver_lock, flags);
948 list_add_tail(&cmdnode->list, &priv->cmdpendingq);
950 list_add(&cmdnode->list, &priv->cmdpendingq);
952 spin_unlock_irqrestore(&priv->driver_lock, flags);
954 lbs_deb_host("QUEUE_CMD: inserted command 0x%04x into cmdpendingq\n",
955 le16_to_cpu(cmdnode->cmdbuf->command));
958 lbs_deb_leave(LBS_DEB_HOST);
961 static void lbs_submit_command(struct lbs_private *priv,
962 struct cmd_ctrl_node *cmdnode)
965 struct cmd_header *cmd;
971 lbs_deb_enter(LBS_DEB_HOST);
973 cmd = cmdnode->cmdbuf;
975 spin_lock_irqsave(&priv->driver_lock, flags);
976 priv->cur_cmd = cmdnode;
977 spin_unlock_irqrestore(&priv->driver_lock, flags);
979 cmdsize = le16_to_cpu(cmd->size);
980 command = le16_to_cpu(cmd->command);
982 /* These commands take longer */
983 if (command == CMD_802_11_SCAN || command == CMD_802_11_ASSOCIATE)
986 lbs_deb_cmd("DNLD_CMD: command 0x%04x, seq %d, size %d\n",
987 command, le16_to_cpu(cmd->seqnum), cmdsize);
988 lbs_deb_hex(LBS_DEB_CMD, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize);
990 ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize);
993 lbs_pr_info("DNLD_CMD: hw_host_to_card failed: %d\n", ret);
994 /* Let the timer kick in and retry, and potentially reset
995 the whole thing if the condition persists */
999 if (command == CMD_802_11_DEEP_SLEEP) {
1000 if (priv->is_auto_deep_sleep_enabled) {
1001 priv->wakeup_dev_required = 1;
1002 priv->dnld_sent = 0;
1004 priv->is_deep_sleep = 1;
1005 lbs_complete_command(priv, cmdnode, 0);
1007 /* Setup the timer after transmit command */
1008 mod_timer(&priv->command_timer, jiffies + timeo);
1011 lbs_deb_leave(LBS_DEB_HOST);
1015 * This function inserts command node to cmdfreeq
1016 * after cleans it. Requires priv->driver_lock held.
1018 static void __lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
1019 struct cmd_ctrl_node *cmdnode)
1021 lbs_deb_enter(LBS_DEB_HOST);
1026 cmdnode->callback = NULL;
1027 cmdnode->callback_arg = 0;
1029 memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE);
1031 list_add_tail(&cmdnode->list, &priv->cmdfreeq);
1033 lbs_deb_leave(LBS_DEB_HOST);
1036 static void lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
1037 struct cmd_ctrl_node *ptempcmd)
1039 unsigned long flags;
1041 spin_lock_irqsave(&priv->driver_lock, flags);
1042 __lbs_cleanup_and_insert_cmd(priv, ptempcmd);
1043 spin_unlock_irqrestore(&priv->driver_lock, flags);
1046 void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
1049 cmd->result = result;
1050 cmd->cmdwaitqwoken = 1;
1051 wake_up_interruptible(&cmd->cmdwait_q);
1053 if (!cmd->callback || cmd->callback == lbs_cmd_async_callback)
1054 __lbs_cleanup_and_insert_cmd(priv, cmd);
1055 priv->cur_cmd = NULL;
1058 int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on)
1060 struct cmd_ds_802_11_radio_control cmd;
1063 lbs_deb_enter(LBS_DEB_CMD);
1065 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1066 cmd.action = cpu_to_le16(CMD_ACT_SET);
1068 /* Only v8 and below support setting the preamble */
1069 if (priv->fwrelease < 0x09000000) {
1071 case RADIO_PREAMBLE_SHORT:
1072 case RADIO_PREAMBLE_AUTO:
1073 case RADIO_PREAMBLE_LONG:
1074 cmd.control = cpu_to_le16(preamble);
1082 cmd.control |= cpu_to_le16(0x1);
1084 cmd.control &= cpu_to_le16(~0x1);
1085 priv->txpower_cur = 0;
1088 lbs_deb_cmd("RADIO_CONTROL: radio %s, preamble %d\n",
1089 radio_on ? "ON" : "OFF", preamble);
1091 priv->radio_on = radio_on;
1093 ret = lbs_cmd_with_response(priv, CMD_802_11_RADIO_CONTROL, &cmd);
1096 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
1100 void lbs_set_mac_control(struct lbs_private *priv)
1102 struct cmd_ds_mac_control cmd;
1104 lbs_deb_enter(LBS_DEB_CMD);
1106 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1107 cmd.action = cpu_to_le16(priv->mac_control);
1110 lbs_cmd_async(priv, CMD_MAC_CONTROL, &cmd.hdr, sizeof(cmd));
1112 lbs_deb_leave(LBS_DEB_CMD);
1116 * @brief This function allocates the command buffer and link
1117 * it to command free queue.
1119 * @param priv A pointer to struct lbs_private structure
1122 int lbs_allocate_cmd_buffer(struct lbs_private *priv)
1127 struct cmd_ctrl_node *cmdarray;
1129 lbs_deb_enter(LBS_DEB_HOST);
1131 /* Allocate and initialize the command array */
1132 bufsize = sizeof(struct cmd_ctrl_node) * LBS_NUM_CMD_BUFFERS;
1133 if (!(cmdarray = kzalloc(bufsize, GFP_KERNEL))) {
1134 lbs_deb_host("ALLOC_CMD_BUF: tempcmd_array is NULL\n");
1138 priv->cmd_array = cmdarray;
1140 /* Allocate and initialize each command buffer in the command array */
1141 for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
1142 cmdarray[i].cmdbuf = kzalloc(LBS_CMD_BUFFER_SIZE, GFP_KERNEL);
1143 if (!cmdarray[i].cmdbuf) {
1144 lbs_deb_host("ALLOC_CMD_BUF: ptempvirtualaddr is NULL\n");
1150 for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
1151 init_waitqueue_head(&cmdarray[i].cmdwait_q);
1152 lbs_cleanup_and_insert_cmd(priv, &cmdarray[i]);
1157 lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
1162 * @brief This function frees the command buffer.
1164 * @param priv A pointer to struct lbs_private structure
1167 int lbs_free_cmd_buffer(struct lbs_private *priv)
1169 struct cmd_ctrl_node *cmdarray;
1172 lbs_deb_enter(LBS_DEB_HOST);
1174 /* need to check if cmd array is allocated or not */
1175 if (priv->cmd_array == NULL) {
1176 lbs_deb_host("FREE_CMD_BUF: cmd_array is NULL\n");
1180 cmdarray = priv->cmd_array;
1182 /* Release shared memory buffers */
1183 for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
1184 if (cmdarray[i].cmdbuf) {
1185 kfree(cmdarray[i].cmdbuf);
1186 cmdarray[i].cmdbuf = NULL;
1190 /* Release cmd_ctrl_node */
1191 if (priv->cmd_array) {
1192 kfree(priv->cmd_array);
1193 priv->cmd_array = NULL;
1197 lbs_deb_leave(LBS_DEB_HOST);
1202 * @brief This function gets a free command node if available in
1203 * command free queue.
1205 * @param priv A pointer to struct lbs_private structure
1206 * @return cmd_ctrl_node A pointer to cmd_ctrl_node structure or NULL
1208 static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv)
1210 struct cmd_ctrl_node *tempnode;
1211 unsigned long flags;
1213 lbs_deb_enter(LBS_DEB_HOST);
1218 spin_lock_irqsave(&priv->driver_lock, flags);
1220 if (!list_empty(&priv->cmdfreeq)) {
1221 tempnode = list_first_entry(&priv->cmdfreeq,
1222 struct cmd_ctrl_node, list);
1223 list_del(&tempnode->list);
1225 lbs_deb_host("GET_CMD_NODE: cmd_ctrl_node is not available\n");
1229 spin_unlock_irqrestore(&priv->driver_lock, flags);
1231 lbs_deb_leave(LBS_DEB_HOST);
1236 * @brief This function executes next command in command
1237 * pending queue. It will put firmware back to PS mode
1240 * @param priv A pointer to struct lbs_private structure
1243 int lbs_execute_next_command(struct lbs_private *priv)
1245 struct cmd_ctrl_node *cmdnode = NULL;
1246 struct cmd_header *cmd;
1247 unsigned long flags;
1250 /* Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the
1251 * only caller to us is lbs_thread() and we get even when a
1252 * data packet is received */
1253 lbs_deb_enter(LBS_DEB_THREAD);
1255 spin_lock_irqsave(&priv->driver_lock, flags);
1257 if (priv->cur_cmd) {
1258 lbs_pr_alert( "EXEC_NEXT_CMD: already processing command!\n");
1259 spin_unlock_irqrestore(&priv->driver_lock, flags);
1264 if (!list_empty(&priv->cmdpendingq)) {
1265 cmdnode = list_first_entry(&priv->cmdpendingq,
1266 struct cmd_ctrl_node, list);
1269 spin_unlock_irqrestore(&priv->driver_lock, flags);
1272 cmd = cmdnode->cmdbuf;
1274 if (is_command_allowed_in_ps(le16_to_cpu(cmd->command))) {
1275 if ((priv->psstate == PS_STATE_SLEEP) ||
1276 (priv->psstate == PS_STATE_PRE_SLEEP)) {
1278 "EXEC_NEXT_CMD: cannot send cmd 0x%04x in psstate %d\n",
1279 le16_to_cpu(cmd->command),
1284 lbs_deb_host("EXEC_NEXT_CMD: OK to send command "
1285 "0x%04x in psstate %d\n",
1286 le16_to_cpu(cmd->command), priv->psstate);
1287 } else if (priv->psstate != PS_STATE_FULL_POWER) {
1289 * 1. Non-PS command:
1290 * Queue it. set needtowakeup to TRUE if current state
1291 * is SLEEP, otherwise call send EXIT_PS.
1292 * 2. PS command but not EXIT_PS:
1294 * 3. PS command EXIT_PS:
1295 * Set needtowakeup to TRUE if current state is SLEEP,
1296 * otherwise send this command down to firmware
1299 if (cmd->command != cpu_to_le16(CMD_802_11_PS_MODE)) {
1300 /* Prepare to send Exit PS,
1301 * this non PS command will be sent later */
1302 if ((priv->psstate == PS_STATE_SLEEP)
1303 || (priv->psstate == PS_STATE_PRE_SLEEP)
1305 /* w/ new scheme, it will not reach here.
1306 since it is blocked in main_thread. */
1307 priv->needtowakeup = 1;
1309 lbs_set_ps_mode(priv,
1310 PS_MODE_ACTION_EXIT_PS,
1318 * PS command. Ignore it if it is not Exit_PS.
1319 * otherwise send it down immediately.
1321 struct cmd_ds_802_11_ps_mode *psm = (void *)&cmd[1];
1324 "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n",
1327 cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) {
1329 "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n");
1330 list_del(&cmdnode->list);
1331 spin_lock_irqsave(&priv->driver_lock, flags);
1332 lbs_complete_command(priv, cmdnode, 0);
1333 spin_unlock_irqrestore(&priv->driver_lock, flags);
1339 if ((priv->psstate == PS_STATE_SLEEP) ||
1340 (priv->psstate == PS_STATE_PRE_SLEEP)) {
1342 "EXEC_NEXT_CMD: ignore EXIT_PS cmd in sleep\n");
1343 list_del(&cmdnode->list);
1344 spin_lock_irqsave(&priv->driver_lock, flags);
1345 lbs_complete_command(priv, cmdnode, 0);
1346 spin_unlock_irqrestore(&priv->driver_lock, flags);
1347 priv->needtowakeup = 1;
1354 "EXEC_NEXT_CMD: sending EXIT_PS\n");
1357 list_del(&cmdnode->list);
1358 lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n",
1359 le16_to_cpu(cmd->command));
1360 lbs_submit_command(priv, cmdnode);
1363 * check if in power save mode, if yes, put the device back
1368 * This was the old code for libertas+wext. Someone that
1369 * understands this beast should re-code it in a sane way.
1371 * I actually don't understand why this is related to WPA
1372 * and to connection status, shouldn't powering should be
1373 * independ of such things?
1375 if ((priv->psmode != LBS802_11POWERMODECAM) &&
1376 (priv->psstate == PS_STATE_FULL_POWER) &&
1377 ((priv->connect_status == LBS_CONNECTED) ||
1378 lbs_mesh_connected(priv))) {
1379 if (priv->secinfo.WPAenabled ||
1380 priv->secinfo.WPA2enabled) {
1381 /* check for valid WPA group keys */
1382 if (priv->wpa_mcast_key.len ||
1383 priv->wpa_unicast_key.len) {
1385 "EXEC_NEXT_CMD: WPA enabled and GTK_SET"
1386 " go back to PS_SLEEP");
1387 lbs_set_ps_mode(priv,
1388 PS_MODE_ACTION_ENTER_PS,
1393 "EXEC_NEXT_CMD: cmdpendingq empty, "
1394 "go back to PS_SLEEP");
1395 lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS,
1404 lbs_deb_leave(LBS_DEB_THREAD);
1408 static void lbs_send_confirmsleep(struct lbs_private *priv)
1410 unsigned long flags;
1413 lbs_deb_enter(LBS_DEB_HOST);
1414 lbs_deb_hex(LBS_DEB_HOST, "sleep confirm", (u8 *) &confirm_sleep,
1415 sizeof(confirm_sleep));
1417 ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) &confirm_sleep,
1418 sizeof(confirm_sleep));
1420 lbs_pr_alert("confirm_sleep failed\n");
1424 spin_lock_irqsave(&priv->driver_lock, flags);
1426 /* We don't get a response on the sleep-confirmation */
1427 priv->dnld_sent = DNLD_RES_RECEIVED;
1429 if (priv->is_host_sleep_configured) {
1430 priv->is_host_sleep_activated = 1;
1431 wake_up_interruptible(&priv->host_sleep_q);
1434 /* If nothing to do, go back to sleep (?) */
1435 if (!kfifo_len(&priv->event_fifo) && !priv->resp_len[priv->resp_idx])
1436 priv->psstate = PS_STATE_SLEEP;
1438 spin_unlock_irqrestore(&priv->driver_lock, flags);
1441 lbs_deb_leave(LBS_DEB_HOST);
1445 * @brief This function checks condition and prepares to
1446 * send sleep confirm command to firmware if ok.
1448 * @param priv A pointer to struct lbs_private structure
1449 * @param psmode Power Saving mode
1452 void lbs_ps_confirm_sleep(struct lbs_private *priv)
1454 unsigned long flags =0;
1457 lbs_deb_enter(LBS_DEB_HOST);
1459 spin_lock_irqsave(&priv->driver_lock, flags);
1460 if (priv->dnld_sent) {
1462 lbs_deb_host("dnld_sent was set\n");
1465 /* In-progress command? */
1466 if (priv->cur_cmd) {
1468 lbs_deb_host("cur_cmd was set\n");
1471 /* Pending events or command responses? */
1472 if (kfifo_len(&priv->event_fifo) || priv->resp_len[priv->resp_idx]) {
1474 lbs_deb_host("pending events or command responses\n");
1476 spin_unlock_irqrestore(&priv->driver_lock, flags);
1479 lbs_deb_host("sending lbs_ps_confirm_sleep\n");
1480 lbs_send_confirmsleep(priv);
1482 lbs_deb_host("sleep confirm has been delayed\n");
1485 lbs_deb_leave(LBS_DEB_HOST);
1490 * @brief Configures the transmission power control functionality.
1492 * @param priv A pointer to struct lbs_private structure
1493 * @param enable Transmission power control enable
1494 * @param p0 Power level when link quality is good (dBm).
1495 * @param p1 Power level when link quality is fair (dBm).
1496 * @param p2 Power level when link quality is poor (dBm).
1497 * @param usesnr Use Signal to Noise Ratio in TPC
1499 * @return 0 on success
1501 int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1,
1502 int8_t p2, int usesnr)
1504 struct cmd_ds_802_11_tpc_cfg cmd;
1507 memset(&cmd, 0, sizeof(cmd));
1508 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1509 cmd.action = cpu_to_le16(CMD_ACT_SET);
1510 cmd.enable = !!enable;
1511 cmd.usesnr = !!usesnr;
1516 ret = lbs_cmd_with_response(priv, CMD_802_11_TPC_CFG, &cmd);
1522 * @brief Configures the power adaptation settings.
1524 * @param priv A pointer to struct lbs_private structure
1525 * @param enable Power adaptation enable
1526 * @param p0 Power level for 1, 2, 5.5 and 11 Mbps (dBm).
1527 * @param p1 Power level for 6, 9, 12, 18, 22, 24 and 36 Mbps (dBm).
1528 * @param p2 Power level for 48 and 54 Mbps (dBm).
1530 * @return 0 on Success
1533 int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0,
1534 int8_t p1, int8_t p2)
1536 struct cmd_ds_802_11_pa_cfg cmd;
1539 memset(&cmd, 0, sizeof(cmd));
1540 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1541 cmd.action = cpu_to_le16(CMD_ACT_SET);
1542 cmd.enable = !!enable;
1547 ret = lbs_cmd_with_response(priv, CMD_802_11_PA_CFG , &cmd);
1553 struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv,
1554 uint16_t command, struct cmd_header *in_cmd, int in_cmd_size,
1555 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
1556 unsigned long callback_arg)
1558 struct cmd_ctrl_node *cmdnode;
1560 lbs_deb_enter(LBS_DEB_HOST);
1562 if (priv->surpriseremoved) {
1563 lbs_deb_host("PREP_CMD: card removed\n");
1564 cmdnode = ERR_PTR(-ENOENT);
1568 /* No commands are allowed in Deep Sleep until we toggle the GPIO
1569 * to wake up the card and it has signaled that it's ready.
1571 if (!priv->is_auto_deep_sleep_enabled) {
1572 if (priv->is_deep_sleep) {
1573 lbs_deb_cmd("command not allowed in deep sleep\n");
1574 cmdnode = ERR_PTR(-EBUSY);
1579 cmdnode = lbs_get_free_cmd_node(priv);
1580 if (cmdnode == NULL) {
1581 lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
1583 /* Wake up main thread to execute next command */
1584 wake_up_interruptible(&priv->waitq);
1585 cmdnode = ERR_PTR(-ENOBUFS);
1589 cmdnode->callback = callback;
1590 cmdnode->callback_arg = callback_arg;
1592 /* Copy the incoming command to the buffer */
1593 memcpy(cmdnode->cmdbuf, in_cmd, in_cmd_size);
1595 /* Set sequence number, clean result, move to buffer */
1597 cmdnode->cmdbuf->command = cpu_to_le16(command);
1598 cmdnode->cmdbuf->size = cpu_to_le16(in_cmd_size);
1599 cmdnode->cmdbuf->seqnum = cpu_to_le16(priv->seqnum);
1600 cmdnode->cmdbuf->result = 0;
1602 lbs_deb_host("PREP_CMD: command 0x%04x\n", command);
1604 cmdnode->cmdwaitqwoken = 0;
1605 lbs_queue_cmd(priv, cmdnode);
1606 wake_up_interruptible(&priv->waitq);
1609 lbs_deb_leave_args(LBS_DEB_HOST, "ret %p", cmdnode);
1613 void lbs_cmd_async(struct lbs_private *priv, uint16_t command,
1614 struct cmd_header *in_cmd, int in_cmd_size)
1616 lbs_deb_enter(LBS_DEB_CMD);
1617 __lbs_cmd_async(priv, command, in_cmd, in_cmd_size,
1618 lbs_cmd_async_callback, 0);
1619 lbs_deb_leave(LBS_DEB_CMD);
1622 int __lbs_cmd(struct lbs_private *priv, uint16_t command,
1623 struct cmd_header *in_cmd, int in_cmd_size,
1624 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
1625 unsigned long callback_arg)
1627 struct cmd_ctrl_node *cmdnode;
1628 unsigned long flags;
1631 lbs_deb_enter(LBS_DEB_HOST);
1633 cmdnode = __lbs_cmd_async(priv, command, in_cmd, in_cmd_size,
1634 callback, callback_arg);
1635 if (IS_ERR(cmdnode)) {
1636 ret = PTR_ERR(cmdnode);
1641 wait_event_interruptible(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken);
1643 spin_lock_irqsave(&priv->driver_lock, flags);
1644 ret = cmdnode->result;
1646 lbs_pr_info("PREP_CMD: command 0x%04x failed: %d\n",
1649 __lbs_cleanup_and_insert_cmd(priv, cmdnode);
1650 spin_unlock_irqrestore(&priv->driver_lock, flags);
1653 lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
1656 EXPORT_SYMBOL_GPL(__lbs_cmd);