Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cmd.c
Go to the documentation of this file.
1 /*
2  * This file contains the handling of command.
3  * It prepares command and sends it to firmware when it is ready.
4  */
5 
6 #include <linux/hardirq.h>
7 #include <linux/kfifo.h>
8 #include <linux/sched.h>
9 #include <linux/slab.h>
10 #include <linux/if_arp.h>
11 #include <linux/export.h>
12 
13 #include "decl.h"
14 #include "cfg.h"
15 #include "cmd.h"
16 
17 #define CAL_NF(nf) ((s32)(-(s32)(nf)))
18 #define CAL_RSSI(snr, nf) ((s32)((s32)(snr) + CAL_NF(nf)))
19 
30 int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
31  struct cmd_header *resp)
32 {
33  struct cmd_header *buf = (void *)extra;
34  uint16_t copy_len;
35 
36  copy_len = min(le16_to_cpu(buf->size), le16_to_cpu(resp->size));
37  memcpy(buf, resp, copy_len);
38  return 0;
39 }
41 
53 static int lbs_cmd_async_callback(struct lbs_private *priv, unsigned long extra,
54  struct cmd_header *resp)
55 {
56  return 0;
57 }
58 
59 
67 static u8 is_command_allowed_in_ps(u16 cmd)
68 {
69  switch (cmd) {
70  case CMD_802_11_RSSI:
71  return 1;
73  return 1;
74  default:
75  break;
76  }
77  return 0;
78 }
79 
89 {
90  struct cmd_ds_get_hw_spec cmd;
91  int ret = -1;
92  u32 i;
93 
95 
96  memset(&cmd, 0, sizeof(cmd));
97  cmd.hdr.size = cpu_to_le16(sizeof(cmd));
99  ret = lbs_cmd_with_response(priv, CMD_GET_HW_SPEC, &cmd);
100  if (ret)
101  goto out;
102 
103  priv->fwcapinfo = le32_to_cpu(cmd.fwcapinfo);
104 
105  /* The firmware release is in an interesting format: the patch
106  * level is in the most significant nibble ... so fix that: */
107  priv->fwrelease = le32_to_cpu(cmd.fwrelease);
108  priv->fwrelease = (priv->fwrelease << 8) |
109  (priv->fwrelease >> 24 & 0xff);
110 
111  /* Some firmware capabilities:
112  * CF card firmware 5.0.16p0: cap 0x00000303
113  * USB dongle firmware 5.110.17p2: cap 0x00000303
114  */
115  netdev_info(priv->dev, "%pM, fw %u.%u.%up%u, cap 0x%08x\n",
116  cmd.permanentaddr,
117  priv->fwrelease >> 24 & 0xff,
118  priv->fwrelease >> 16 & 0xff,
119  priv->fwrelease >> 8 & 0xff,
120  priv->fwrelease & 0xff,
121  priv->fwcapinfo);
122  lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n",
123  cmd.hwifversion, cmd.version);
124 
125  /* Clamp region code to 8-bit since FW spec indicates that it should
126  * only ever be 8-bit, even though the field size is 16-bit. Some firmware
127  * returns non-zero high 8 bits here.
128  *
129  * Firmware version 4.0.102 used in CF8381 has region code shifted. We
130  * need to check for this problem and handle it properly.
131  */
132  if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V4)
133  priv->regioncode = (le16_to_cpu(cmd.regioncode) >> 8) & 0xFF;
134  else
135  priv->regioncode = le16_to_cpu(cmd.regioncode) & 0xFF;
136 
137  for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
138  /* use the region code to search for the index */
139  if (priv->regioncode == lbs_region_code_to_index[i])
140  break;
141  }
142 
143  /* if it's unidentified region code, use the default (USA) */
144  if (i >= MRVDRV_MAX_REGION_CODE) {
145  priv->regioncode = 0x10;
146  netdev_info(priv->dev,
147  "unidentified region code; using the default (USA)\n");
148  }
149 
150  if (priv->current_addr[0] == 0xff)
152 
153  if (!priv->copied_hwaddr) {
154  memcpy(priv->dev->dev_addr, priv->current_addr, ETH_ALEN);
155  if (priv->mesh_dev)
156  memcpy(priv->mesh_dev->dev_addr,
157  priv->current_addr, ETH_ALEN);
158  priv->copied_hwaddr = 1;
159  }
160 
161 out:
163  return ret;
164 }
165 
166 static int lbs_ret_host_sleep_cfg(struct lbs_private *priv, unsigned long dummy,
167  struct cmd_header *resp)
168 {
170  if (priv->is_host_sleep_activated) {
171  priv->is_host_sleep_configured = 0;
172  if (priv->psstate == PS_STATE_FULL_POWER) {
173  priv->is_host_sleep_activated = 0;
175  }
176  } else {
177  priv->is_host_sleep_configured = 1;
178  }
180  return 0;
181 }
182 
184  struct wol_config *p_wol_config)
185 {
186  struct cmd_ds_host_sleep cmd_config;
187  int ret;
188 
189  /*
190  * Certain firmware versions do not support EHS_REMOVE_WAKEUP command
191  * and the card will return a failure. Since we need to be
192  * able to reset the mask, in those cases we set a 0 mask instead.
193  */
194  if (criteria == EHS_REMOVE_WAKEUP && !priv->ehs_remove_supported)
195  criteria = 0;
196 
197  cmd_config.hdr.size = cpu_to_le16(sizeof(cmd_config));
198  cmd_config.criteria = cpu_to_le32(criteria);
199  cmd_config.gpio = priv->wol_gpio;
200  cmd_config.gap = priv->wol_gap;
201 
202  if (p_wol_config != NULL)
203  memcpy((uint8_t *)&cmd_config.wol_conf, (uint8_t *)p_wol_config,
204  sizeof(struct wol_config));
205  else
206  cmd_config.wol_conf.action = CMD_ACT_ACTION_NONE;
207 
208  ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config.hdr,
209  le16_to_cpu(cmd_config.hdr.size),
210  lbs_ret_host_sleep_cfg, 0);
211  if (!ret) {
212  if (p_wol_config)
213  memcpy((uint8_t *) p_wol_config,
214  (uint8_t *)&cmd_config.wol_conf,
215  sizeof(struct wol_config));
216  } else {
217  netdev_info(priv->dev, "HOST_SLEEP_CFG failed %d\n", ret);
218  }
219 
220  return ret;
221 }
223 
234 int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block)
235 {
236  struct cmd_ds_802_11_ps_mode cmd;
237  int ret = 0;
238 
240 
241  memset(&cmd, 0, sizeof(cmd));
242  cmd.hdr.size = cpu_to_le16(sizeof(cmd));
243  cmd.action = cpu_to_le16(cmd_action);
244 
245  if (cmd_action == PS_MODE_ACTION_ENTER_PS) {
246  lbs_deb_cmd("PS_MODE: action ENTER_PS\n");
247  cmd.multipledtim = cpu_to_le16(1); /* Default DTIM multiple */
248  } else if (cmd_action == PS_MODE_ACTION_EXIT_PS) {
249  lbs_deb_cmd("PS_MODE: action EXIT_PS\n");
250  } else {
251  /* We don't handle CONFIRM_SLEEP here because it needs to
252  * be fastpathed to the firmware.
253  */
254  lbs_deb_cmd("PS_MODE: unknown action 0x%X\n", cmd_action);
255  ret = -EOPNOTSUPP;
256  goto out;
257  }
258 
259  if (block)
260  ret = lbs_cmd_with_response(priv, CMD_802_11_PS_MODE, &cmd);
261  else
262  lbs_cmd_async(priv, CMD_802_11_PS_MODE, &cmd.hdr, sizeof (cmd));
263 
264 out:
265  lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
266  return ret;
267 }
268 
269 int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action,
270  struct sleep_params *sp)
271 {
272  struct cmd_ds_802_11_sleep_params cmd;
273  int ret;
274 
276 
277  if (cmd_action == CMD_ACT_GET) {
278  memset(&cmd, 0, sizeof(cmd));
279  } else {
280  cmd.error = cpu_to_le16(sp->sp_error);
281  cmd.offset = cpu_to_le16(sp->sp_offset);
283  cmd.calcontrol = sp->sp_calcontrol;
285  cmd.reserved = cpu_to_le16(sp->sp_reserved);
286  }
287  cmd.hdr.size = cpu_to_le16(sizeof(cmd));
288  cmd.action = cpu_to_le16(cmd_action);
289 
291 
292  if (!ret) {
293  lbs_deb_cmd("error 0x%x, offset 0x%x, stabletime 0x%x, "
294  "calcontrol 0x%x extsleepclk 0x%x\n",
295  le16_to_cpu(cmd.error), le16_to_cpu(cmd.offset),
297  cmd.externalsleepclk);
298 
299  sp->sp_error = le16_to_cpu(cmd.error);
300  sp->sp_offset = le16_to_cpu(cmd.offset);
302  sp->sp_calcontrol = cmd.calcontrol;
304  sp->sp_reserved = le16_to_cpu(cmd.reserved);
305  }
306 
307  lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
308  return 0;
309 }
310 
311 static int lbs_wait_for_ds_awake(struct lbs_private *priv)
312 {
313  int ret = 0;
314 
316 
317  if (priv->is_deep_sleep) {
319  !priv->is_deep_sleep, (10 * HZ))) {
320  netdev_err(priv->dev, "ds_awake_q: timer expired\n");
321  ret = -1;
322  }
323  }
324 
325  lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
326  return ret;
327 }
328 
329 int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep)
330 {
331  int ret = 0;
332 
334 
335  if (deep_sleep) {
336  if (priv->is_deep_sleep != 1) {
337  lbs_deb_cmd("deep sleep: sleep\n");
338  BUG_ON(!priv->enter_deep_sleep);
339  ret = priv->enter_deep_sleep(priv);
340  if (!ret) {
341  netif_stop_queue(priv->dev);
342  netif_carrier_off(priv->dev);
343  }
344  } else {
345  netdev_err(priv->dev, "deep sleep: already enabled\n");
346  }
347  } else {
348  if (priv->is_deep_sleep) {
349  lbs_deb_cmd("deep sleep: wakeup\n");
350  BUG_ON(!priv->exit_deep_sleep);
351  ret = priv->exit_deep_sleep(priv);
352  if (!ret) {
353  ret = lbs_wait_for_ds_awake(priv);
354  if (ret)
355  netdev_err(priv->dev,
356  "deep sleep: wakeup failed\n");
357  }
358  }
359  }
360 
361  lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
362  return ret;
363 }
364 
365 static int lbs_ret_host_sleep_activate(struct lbs_private *priv,
366  unsigned long dummy,
367  struct cmd_header *cmd)
368 {
370  priv->is_host_sleep_activated = 1;
373  return 0;
374 }
375 
376 int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep)
377 {
378  struct cmd_header cmd;
379  int ret = 0;
381 
383 
384  if (host_sleep) {
385  if (priv->is_host_sleep_activated != 1) {
386  memset(&cmd, 0, sizeof(cmd));
387  ret = lbs_host_sleep_cfg(priv, priv->wol_criteria,
388  (struct wol_config *)NULL);
389  if (ret) {
390  netdev_info(priv->dev,
391  "Host sleep configuration failed: %d\n",
392  ret);
393  return ret;
394  }
395  if (priv->psstate == PS_STATE_FULL_POWER) {
396  ret = __lbs_cmd(priv,
398  &cmd,
399  sizeof(cmd),
400  lbs_ret_host_sleep_activate, 0);
401  if (ret)
402  netdev_info(priv->dev,
403  "HOST_SLEEP_ACTIVATE failed: %d\n",
404  ret);
405  }
406 
408  priv->host_sleep_q,
410  (10 * HZ))) {
411  netdev_err(priv->dev,
412  "host_sleep_q: timer expired\n");
413  ret = -1;
414  }
415  } else {
416  netdev_err(priv->dev, "host sleep: already enabled\n");
417  }
418  } else {
419  if (priv->is_host_sleep_activated)
420  ret = lbs_host_sleep_cfg(priv, criteria,
421  (struct wol_config *)NULL);
422  }
423 
424  return ret;
425 }
426 
437 {
438  struct cmd_ds_802_11_snmp_mib cmd;
439  int ret;
440 
442 
443  memset(&cmd, 0, sizeof (cmd));
444  cmd.hdr.size = cpu_to_le16(sizeof(cmd));
446  cmd.oid = cpu_to_le16((u16) oid);
447 
448  switch (oid) {
450  cmd.bufsize = cpu_to_le16(sizeof(u8));
451  cmd.value[0] = val;
452  break;
458  cmd.bufsize = cpu_to_le16(sizeof(u16));
459  *((__le16 *)(&cmd.value)) = cpu_to_le16(val);
460  break;
461  default:
462  lbs_deb_cmd("SNMP_CMD: (set) unhandled OID 0x%x\n", oid);
463  ret = -EINVAL;
464  goto out;
465  }
466 
467  lbs_deb_cmd("SNMP_CMD: (set) oid 0x%x, oid size 0x%x, value 0x%x\n",
468  le16_to_cpu(cmd.oid), le16_to_cpu(cmd.bufsize), val);
469 
470  ret = lbs_cmd_with_response(priv, CMD_802_11_SNMP_MIB, &cmd);
471 
472 out:
473  lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
474  return ret;
475 }
476 
486 int lbs_get_snmp_mib(struct lbs_private *priv, u32 oid, u16 *out_val)
487 {
488  struct cmd_ds_802_11_snmp_mib cmd;
489  int ret;
490 
492 
493  memset(&cmd, 0, sizeof (cmd));
494  cmd.hdr.size = cpu_to_le16(sizeof(cmd));
496  cmd.oid = cpu_to_le16(oid);
497 
498  ret = lbs_cmd_with_response(priv, CMD_802_11_SNMP_MIB, &cmd);
499  if (ret)
500  goto out;
501 
502  switch (le16_to_cpu(cmd.bufsize)) {
503  case sizeof(u8):
504  *out_val = cmd.value[0];
505  break;
506  case sizeof(u16):
507  *out_val = le16_to_cpu(*((__le16 *)(&cmd.value)));
508  break;
509  default:
510  lbs_deb_cmd("SNMP_CMD: (get) unhandled OID 0x%x size %d\n",
511  oid, le16_to_cpu(cmd.bufsize));
512  break;
513  }
514 
515 out:
516  lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
517  return ret;
518 }
519 
530 int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel,
531  s16 *maxlevel)
532 {
533  struct cmd_ds_802_11_rf_tx_power cmd;
534  int ret;
535 
537 
538  memset(&cmd, 0, sizeof(cmd));
539  cmd.hdr.size = cpu_to_le16(sizeof(cmd));
541 
543  if (ret == 0) {
544  *curlevel = le16_to_cpu(cmd.curlevel);
545  if (minlevel)
546  *minlevel = cmd.minlevel;
547  if (maxlevel)
548  *maxlevel = cmd.maxlevel;
549  }
550 
552  return ret;
553 }
554 
564 {
565  struct cmd_ds_802_11_rf_tx_power cmd;
566  int ret;
567 
569 
570  memset(&cmd, 0, sizeof(cmd));
571  cmd.hdr.size = cpu_to_le16(sizeof(cmd));
573  cmd.curlevel = cpu_to_le16(dbm);
574 
575  lbs_deb_cmd("SET_RF_TX_POWER: %d dBm\n", dbm);
576 
578 
580  return ret;
581 }
582 
593 {
594  struct cmd_ds_802_11_monitor_mode cmd;
595  int ret;
596 
597  memset(&cmd, 0, sizeof(cmd));
598  cmd.hdr.size = cpu_to_le16(sizeof(cmd));
600  if (enable)
601  cmd.mode = cpu_to_le16(0x1);
602 
603  lbs_deb_cmd("SET_MONITOR_MODE: %d\n", enable);
604 
606  if (ret == 0) {
607  priv->dev->type = enable ? ARPHRD_IEEE80211_RADIOTAP :
608  ARPHRD_ETHER;
609  }
610 
612  return ret;
613 }
614 
622 static int lbs_get_channel(struct lbs_private *priv)
623 {
624  struct cmd_ds_802_11_rf_channel cmd;
625  int ret = 0;
626 
628 
629  memset(&cmd, 0, sizeof(cmd));
630  cmd.hdr.size = cpu_to_le16(sizeof(cmd));
632 
633  ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd);
634  if (ret)
635  goto out;
636 
637  ret = le16_to_cpu(cmd.channel);
638  lbs_deb_cmd("current radio channel is %d\n", ret);
639 
640 out:
641  lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
642  return ret;
643 }
644 
646 {
647  int ret;
648 
649  /* the channel in f/w could be out of sync; get the current channel */
651 
652  ret = lbs_get_channel(priv);
653  if (ret > 0) {
654  priv->channel = ret;
655  ret = 0;
656  }
657  lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
658  return ret;
659 }
660 
670 {
671  struct cmd_ds_802_11_rf_channel cmd;
672 #ifdef DEBUG
673  u8 old_channel = priv->channel;
674 #endif
675  int ret = 0;
676 
678 
679  memset(&cmd, 0, sizeof(cmd));
680  cmd.hdr.size = cpu_to_le16(sizeof(cmd));
682  cmd.channel = cpu_to_le16(channel);
683 
684  ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd);
685  if (ret)
686  goto out;
687 
688  priv->channel = (uint8_t) le16_to_cpu(cmd.channel);
689  lbs_deb_cmd("channel switch from %d to %d\n", old_channel,
690  priv->channel);
691 
692 out:
693  lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
694  return ret;
695 }
696 
706 int lbs_get_rssi(struct lbs_private *priv, s8 *rssi, s8 *nf)
707 {
708  struct cmd_ds_802_11_rssi cmd;
709  int ret = 0;
710 
712 
713  BUG_ON(rssi == NULL);
714  BUG_ON(nf == NULL);
715 
716  memset(&cmd, 0, sizeof(cmd));
717  cmd.hdr.size = cpu_to_le16(sizeof(cmd));
718  /* Average SNR over last 8 beacons */
719  cmd.n_or_snr = cpu_to_le16(8);
720 
721  ret = lbs_cmd_with_response(priv, CMD_802_11_RSSI, &cmd);
722  if (ret == 0) {
723  *nf = CAL_NF(le16_to_cpu(cmd.nf));
724  *rssi = CAL_RSSI(le16_to_cpu(cmd.n_or_snr), le16_to_cpu(cmd.nf));
725  }
726 
727  lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
728  return ret;
729 }
730 
740 {
741  struct wiphy *wiphy = priv->wdev->wiphy;
742  struct ieee80211_supported_band **bands = wiphy->bands;
743  struct cmd_ds_802_11d_domain_info cmd;
744  struct mrvl_ie_domain_param_set *domain = &cmd.domain;
746  enum ieee80211_band band;
747  struct ieee80211_channel *ch;
748  u8 num_triplet = 0;
749  u8 num_parsed_chan = 0;
750  u8 first_channel = 0, next_chan = 0, max_pwr = 0;
751  u8 i, flag = 0;
752  size_t triplet_size;
753  int ret = 0;
754 
756  if (!priv->country_code[0])
757  goto out;
758 
759  memset(&cmd, 0, sizeof(cmd));
761 
762  lbs_deb_11d("Setting country code '%c%c'\n",
763  priv->country_code[0], priv->country_code[1]);
764 
765  domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN);
766 
767  /* Set country code */
768  domain->country_code[0] = priv->country_code[0];
769  domain->country_code[1] = priv->country_code[1];
770  domain->country_code[2] = ' ';
771 
772  /* Now set up the channel triplets; firmware is somewhat picky here
773  * and doesn't validate channel numbers and spans; hence it would
774  * interpret a triplet of (36, 4, 20) as channels 36, 37, 38, 39. Since
775  * the last 3 aren't valid channels, the driver is responsible for
776  * splitting that up into 4 triplet pairs of (36, 1, 20) + (40, 1, 20)
777  * etc.
778  */
779  for (band = 0;
780  (band < IEEE80211_NUM_BANDS) && (num_triplet < MAX_11D_TRIPLETS);
781  band++) {
782 
783  if (!bands[band])
784  continue;
785 
786  for (i = 0;
787  (i < bands[band]->n_channels) && (num_triplet < MAX_11D_TRIPLETS);
788  i++) {
789  ch = &bands[band]->channels[i];
790  if (ch->flags & IEEE80211_CHAN_DISABLED)
791  continue;
792 
793  if (!flag) {
794  flag = 1;
795  next_chan = first_channel = (u32) ch->hw_value;
796  max_pwr = ch->max_power;
797  num_parsed_chan = 1;
798  continue;
799  }
800 
801  if ((ch->hw_value == next_chan + 1) &&
802  (ch->max_power == max_pwr)) {
803  /* Consolidate adjacent channels */
804  next_chan++;
805  num_parsed_chan++;
806  } else {
807  /* Add this triplet */
808  lbs_deb_11d("11D triplet (%d, %d, %d)\n",
809  first_channel, num_parsed_chan,
810  max_pwr);
811  t = &domain->triplet[num_triplet];
812  t->chans.first_channel = first_channel;
813  t->chans.num_channels = num_parsed_chan;
814  t->chans.max_power = max_pwr;
815  num_triplet++;
816  flag = 0;
817  }
818  }
819 
820  if (flag) {
821  /* Add last triplet */
822  lbs_deb_11d("11D triplet (%d, %d, %d)\n", first_channel,
823  num_parsed_chan, max_pwr);
824  t = &domain->triplet[num_triplet];
825  t->chans.first_channel = first_channel;
826  t->chans.num_channels = num_parsed_chan;
827  t->chans.max_power = max_pwr;
828  num_triplet++;
829  }
830  }
831 
832  lbs_deb_11d("# triplets %d\n", num_triplet);
833 
834  /* Set command header sizes */
835  triplet_size = num_triplet * sizeof(struct ieee80211_country_ie_triplet);
836  domain->header.len = cpu_to_le16(sizeof(domain->country_code) +
837  triplet_size);
838 
839  lbs_deb_hex(LBS_DEB_11D, "802.11D domain param set",
840  (u8 *) &cmd.domain.country_code,
841  le16_to_cpu(domain->header.len));
842 
843  cmd.hdr.size = cpu_to_le16(sizeof(cmd.hdr) +
844  sizeof(cmd.action) +
845  sizeof(cmd.domain.header) +
846  sizeof(cmd.domain.country_code) +
847  triplet_size);
848 
850 
851 out:
852  lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret);
853  return ret;
854 }
855 
868 {
869  struct cmd_ds_reg_access cmd;
870  int ret = 0;
871 
873 
874  BUG_ON(value == NULL);
875 
876  memset(&cmd, 0, sizeof(cmd));
877  cmd.hdr.size = cpu_to_le16(sizeof(cmd));
879  cmd.offset = cpu_to_le16(offset);
880 
881  if (reg != CMD_MAC_REG_ACCESS &&
882  reg != CMD_BBP_REG_ACCESS &&
883  reg != CMD_RF_REG_ACCESS) {
884  ret = -EINVAL;
885  goto out;
886  }
887 
888  ret = lbs_cmd_with_response(priv, reg, &cmd);
889  if (!ret) {
890  if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS)
891  *value = cmd.value.bbp_rf;
892  else if (reg == CMD_MAC_REG_ACCESS)
893  *value = le32_to_cpu(cmd.value.mac);
894  }
895 
896 out:
897  lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
898  return ret;
899 }
900 
913 {
914  struct cmd_ds_reg_access cmd;
915  int ret = 0;
916 
918 
919  memset(&cmd, 0, sizeof(cmd));
920  cmd.hdr.size = cpu_to_le16(sizeof(cmd));
922  cmd.offset = cpu_to_le16(offset);
923 
924  if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS)
925  cmd.value.bbp_rf = (u8) (value & 0xFF);
926  else if (reg == CMD_MAC_REG_ACCESS)
927  cmd.value.mac = cpu_to_le32(value);
928  else {
929  ret = -EINVAL;
930  goto out;
931  }
932 
933  ret = lbs_cmd_with_response(priv, reg, &cmd);
934 
935 out:
936  lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
937  return ret;
938 }
939 
940 static void lbs_queue_cmd(struct lbs_private *priv,
941  struct cmd_ctrl_node *cmdnode)
942 {
943  unsigned long flags;
944  int addtail = 1;
945 
947 
948  if (!cmdnode) {
949  lbs_deb_host("QUEUE_CMD: cmdnode is NULL\n");
950  goto done;
951  }
952  if (!cmdnode->cmdbuf->size) {
953  lbs_deb_host("DNLD_CMD: cmd size is zero\n");
954  goto done;
955  }
956  cmdnode->result = 0;
957 
958  /* Exit_PS command needs to be queued in the header always. */
959  if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) {
960  struct cmd_ds_802_11_ps_mode *psm = (void *) &cmdnode->cmdbuf;
961 
963  if (priv->psstate != PS_STATE_FULL_POWER)
964  addtail = 0;
965  }
966  }
967 
968  if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_WAKEUP_CONFIRM)
969  addtail = 0;
970 
971  spin_lock_irqsave(&priv->driver_lock, flags);
972 
973  if (addtail)
974  list_add_tail(&cmdnode->list, &priv->cmdpendingq);
975  else
976  list_add(&cmdnode->list, &priv->cmdpendingq);
977 
978  spin_unlock_irqrestore(&priv->driver_lock, flags);
979 
980  lbs_deb_host("QUEUE_CMD: inserted command 0x%04x into cmdpendingq\n",
981  le16_to_cpu(cmdnode->cmdbuf->command));
982 
983 done:
985 }
986 
987 static void lbs_submit_command(struct lbs_private *priv,
988  struct cmd_ctrl_node *cmdnode)
989 {
990  unsigned long flags;
991  struct cmd_header *cmd;
992  uint16_t cmdsize;
994  int timeo = 3 * HZ;
995  int ret;
996 
998 
999  cmd = cmdnode->cmdbuf;
1000 
1001  spin_lock_irqsave(&priv->driver_lock, flags);
1002  priv->seqnum++;
1003  cmd->seqnum = cpu_to_le16(priv->seqnum);
1004  priv->cur_cmd = cmdnode;
1005  spin_unlock_irqrestore(&priv->driver_lock, flags);
1006 
1007  cmdsize = le16_to_cpu(cmd->size);
1008  command = le16_to_cpu(cmd->command);
1009 
1010  /* These commands take longer */
1011  if (command == CMD_802_11_SCAN || command == CMD_802_11_ASSOCIATE)
1012  timeo = 5 * HZ;
1013 
1014  lbs_deb_cmd("DNLD_CMD: command 0x%04x, seq %d, size %d\n",
1015  command, le16_to_cpu(cmd->seqnum), cmdsize);
1016  lbs_deb_hex(LBS_DEB_CMD, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize);
1017 
1018  ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize);
1019 
1020  if (ret) {
1021  netdev_info(priv->dev, "DNLD_CMD: hw_host_to_card failed: %d\n",
1022  ret);
1023  /* Reset dnld state machine, report failure */
1024  priv->dnld_sent = DNLD_RES_RECEIVED;
1025  lbs_complete_command(priv, cmdnode, ret);
1026  }
1027 
1028  if (command == CMD_802_11_DEEP_SLEEP) {
1029  if (priv->is_auto_deep_sleep_enabled) {
1030  priv->wakeup_dev_required = 1;
1031  priv->dnld_sent = 0;
1032  }
1033  priv->is_deep_sleep = 1;
1034  lbs_complete_command(priv, cmdnode, 0);
1035  } else {
1036  /* Setup the timer after transmit command */
1037  mod_timer(&priv->command_timer, jiffies + timeo);
1038  }
1039 
1041 }
1042 
1043 /*
1044  * This function inserts command node to cmdfreeq
1045  * after cleans it. Requires priv->driver_lock held.
1046  */
1047 static void __lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
1048  struct cmd_ctrl_node *cmdnode)
1049 {
1051 
1052  if (!cmdnode)
1053  goto out;
1054 
1055  cmdnode->callback = NULL;
1056  cmdnode->callback_arg = 0;
1057 
1058  memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE);
1059 
1060  list_add_tail(&cmdnode->list, &priv->cmdfreeq);
1061  out:
1063 }
1064 
1065 static void lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
1066  struct cmd_ctrl_node *ptempcmd)
1067 {
1068  unsigned long flags;
1069 
1070  spin_lock_irqsave(&priv->driver_lock, flags);
1071  __lbs_cleanup_and_insert_cmd(priv, ptempcmd);
1072  spin_unlock_irqrestore(&priv->driver_lock, flags);
1073 }
1074 
1075 void __lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
1076  int result)
1077 {
1078  /*
1079  * Normally, commands are removed from cmdpendingq before being
1080  * submitted. However, we can arrive here on alternative codepaths
1081  * where the command is still pending. Make sure the command really
1082  * isn't part of a list at this point.
1083  */
1084  list_del_init(&cmd->list);
1085 
1086  cmd->result = result;
1087  cmd->cmdwaitqwoken = 1;
1088  wake_up(&cmd->cmdwait_q);
1089 
1090  if (!cmd->callback || cmd->callback == lbs_cmd_async_callback)
1091  __lbs_cleanup_and_insert_cmd(priv, cmd);
1092  priv->cur_cmd = NULL;
1093  wake_up(&priv->waitq);
1094 }
1095 
1096 void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
1097  int result)
1098 {
1099  unsigned long flags;
1100  spin_lock_irqsave(&priv->driver_lock, flags);
1101  __lbs_complete_command(priv, cmd, result);
1102  spin_unlock_irqrestore(&priv->driver_lock, flags);
1103 }
1104 
1105 int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on)
1106 {
1107  struct cmd_ds_802_11_radio_control cmd;
1108  int ret = -EINVAL;
1109 
1111 
1112  cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1114 
1115  /* Only v8 and below support setting the preamble */
1116  if (priv->fwrelease < 0x09000000) {
1117  switch (preamble) {
1118  case RADIO_PREAMBLE_SHORT:
1119  case RADIO_PREAMBLE_AUTO:
1120  case RADIO_PREAMBLE_LONG:
1121  cmd.control = cpu_to_le16(preamble);
1122  break;
1123  default:
1124  goto out;
1125  }
1126  }
1127 
1128  if (radio_on)
1129  cmd.control |= cpu_to_le16(0x1);
1130  else {
1131  cmd.control &= cpu_to_le16(~0x1);
1132  priv->txpower_cur = 0;
1133  }
1134 
1135  lbs_deb_cmd("RADIO_CONTROL: radio %s, preamble %d\n",
1136  radio_on ? "ON" : "OFF", preamble);
1137 
1138  priv->radio_on = radio_on;
1139 
1141 
1142 out:
1143  lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
1144  return ret;
1145 }
1146 
1148 {
1149  struct cmd_ds_mac_control cmd;
1150 
1152 
1153  cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1154  cmd.action = cpu_to_le16(priv->mac_control);
1155  cmd.reserved = 0;
1156 
1157  lbs_cmd_async(priv, CMD_MAC_CONTROL, &cmd.hdr, sizeof(cmd));
1158 
1160 }
1161 
1163 {
1164  struct cmd_ds_mac_control cmd;
1165  int ret = 0;
1166 
1168 
1169  cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1170  cmd.action = cpu_to_le16(priv->mac_control);
1171  cmd.reserved = 0;
1172  ret = lbs_cmd_with_response(priv, CMD_MAC_CONTROL, &cmd);
1173 
1175  return ret;
1176 }
1177 
1187 {
1188  int ret = 0;
1189  u32 bufsize;
1190  u32 i;
1191  struct cmd_ctrl_node *cmdarray;
1192 
1194 
1195  /* Allocate and initialize the command array */
1196  bufsize = sizeof(struct cmd_ctrl_node) * LBS_NUM_CMD_BUFFERS;
1197  if (!(cmdarray = kzalloc(bufsize, GFP_KERNEL))) {
1198  lbs_deb_host("ALLOC_CMD_BUF: tempcmd_array is NULL\n");
1199  ret = -1;
1200  goto done;
1201  }
1202  priv->cmd_array = cmdarray;
1203 
1204  /* Allocate and initialize each command buffer in the command array */
1205  for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
1206  cmdarray[i].cmdbuf = kzalloc(LBS_CMD_BUFFER_SIZE, GFP_KERNEL);
1207  if (!cmdarray[i].cmdbuf) {
1208  lbs_deb_host("ALLOC_CMD_BUF: ptempvirtualaddr is NULL\n");
1209  ret = -1;
1210  goto done;
1211  }
1212  }
1213 
1214  for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
1215  init_waitqueue_head(&cmdarray[i].cmdwait_q);
1216  lbs_cleanup_and_insert_cmd(priv, &cmdarray[i]);
1217  }
1218  ret = 0;
1219 
1220 done:
1221  lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
1222  return ret;
1223 }
1224 
1233 {
1234  struct cmd_ctrl_node *cmdarray;
1235  unsigned int i;
1236 
1238 
1239  /* need to check if cmd array is allocated or not */
1240  if (priv->cmd_array == NULL) {
1241  lbs_deb_host("FREE_CMD_BUF: cmd_array is NULL\n");
1242  goto done;
1243  }
1244 
1245  cmdarray = priv->cmd_array;
1246 
1247  /* Release shared memory buffers */
1248  for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
1249  if (cmdarray[i].cmdbuf) {
1250  kfree(cmdarray[i].cmdbuf);
1251  cmdarray[i].cmdbuf = NULL;
1252  }
1253  }
1254 
1255  /* Release cmd_ctrl_node */
1256  if (priv->cmd_array) {
1257  kfree(priv->cmd_array);
1258  priv->cmd_array = NULL;
1259  }
1260 
1261 done:
1263  return 0;
1264 }
1265 
1275 static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv)
1276 {
1277  struct cmd_ctrl_node *tempnode;
1278  unsigned long flags;
1279 
1281 
1282  if (!priv)
1283  return NULL;
1284 
1285  spin_lock_irqsave(&priv->driver_lock, flags);
1286 
1287  if (!list_empty(&priv->cmdfreeq)) {
1288  tempnode = list_first_entry(&priv->cmdfreeq,
1289  struct cmd_ctrl_node, list);
1290  list_del_init(&tempnode->list);
1291  } else {
1292  lbs_deb_host("GET_CMD_NODE: cmd_ctrl_node is not available\n");
1293  tempnode = NULL;
1294  }
1295 
1296  spin_unlock_irqrestore(&priv->driver_lock, flags);
1297 
1299  return tempnode;
1300 }
1301 
1311 {
1312  struct cmd_ctrl_node *cmdnode = NULL;
1313  struct cmd_header *cmd;
1314  unsigned long flags;
1315  int ret = 0;
1316 
1317  /* Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the
1318  * only caller to us is lbs_thread() and we get even when a
1319  * data packet is received */
1321 
1322  spin_lock_irqsave(&priv->driver_lock, flags);
1323 
1324  if (priv->cur_cmd) {
1325  netdev_alert(priv->dev,
1326  "EXEC_NEXT_CMD: already processing command!\n");
1327  spin_unlock_irqrestore(&priv->driver_lock, flags);
1328  ret = -1;
1329  goto done;
1330  }
1331 
1332  if (!list_empty(&priv->cmdpendingq)) {
1333  cmdnode = list_first_entry(&priv->cmdpendingq,
1334  struct cmd_ctrl_node, list);
1335  }
1336 
1337  spin_unlock_irqrestore(&priv->driver_lock, flags);
1338 
1339  if (cmdnode) {
1340  cmd = cmdnode->cmdbuf;
1341 
1342  if (is_command_allowed_in_ps(le16_to_cpu(cmd->command))) {
1343  if ((priv->psstate == PS_STATE_SLEEP) ||
1344  (priv->psstate == PS_STATE_PRE_SLEEP)) {
1345  lbs_deb_host(
1346  "EXEC_NEXT_CMD: cannot send cmd 0x%04x in psstate %d\n",
1347  le16_to_cpu(cmd->command),
1348  priv->psstate);
1349  ret = -1;
1350  goto done;
1351  }
1352  lbs_deb_host("EXEC_NEXT_CMD: OK to send command "
1353  "0x%04x in psstate %d\n",
1354  le16_to_cpu(cmd->command), priv->psstate);
1355  } else if (priv->psstate != PS_STATE_FULL_POWER) {
1356  /*
1357  * 1. Non-PS command:
1358  * Queue it. set needtowakeup to TRUE if current state
1359  * is SLEEP, otherwise call send EXIT_PS.
1360  * 2. PS command but not EXIT_PS:
1361  * Ignore it.
1362  * 3. PS command EXIT_PS:
1363  * Set needtowakeup to TRUE if current state is SLEEP,
1364  * otherwise send this command down to firmware
1365  * immediately.
1366  */
1367  if (cmd->command != cpu_to_le16(CMD_802_11_PS_MODE)) {
1368  /* Prepare to send Exit PS,
1369  * this non PS command will be sent later */
1370  if ((priv->psstate == PS_STATE_SLEEP)
1371  || (priv->psstate == PS_STATE_PRE_SLEEP)
1372  ) {
1373  /* w/ new scheme, it will not reach here.
1374  since it is blocked in main_thread. */
1375  priv->needtowakeup = 1;
1376  } else {
1377  lbs_set_ps_mode(priv,
1379  false);
1380  }
1381 
1382  ret = 0;
1383  goto done;
1384  } else {
1385  /*
1386  * PS command. Ignore it if it is not Exit_PS.
1387  * otherwise send it down immediately.
1388  */
1389  struct cmd_ds_802_11_ps_mode *psm = (void *)&cmd[1];
1390 
1391  lbs_deb_host(
1392  "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n",
1393  psm->action);
1394  if (psm->action !=
1396  lbs_deb_host(
1397  "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n");
1398  lbs_complete_command(priv, cmdnode, 0);
1399 
1400  ret = 0;
1401  goto done;
1402  }
1403 
1404  if ((priv->psstate == PS_STATE_SLEEP) ||
1405  (priv->psstate == PS_STATE_PRE_SLEEP)) {
1406  lbs_deb_host(
1407  "EXEC_NEXT_CMD: ignore EXIT_PS cmd in sleep\n");
1408  lbs_complete_command(priv, cmdnode, 0);
1409  priv->needtowakeup = 1;
1410 
1411  ret = 0;
1412  goto done;
1413  }
1414 
1415  lbs_deb_host(
1416  "EXEC_NEXT_CMD: sending EXIT_PS\n");
1417  }
1418  }
1419  spin_lock_irqsave(&priv->driver_lock, flags);
1420  list_del_init(&cmdnode->list);
1421  spin_unlock_irqrestore(&priv->driver_lock, flags);
1422  lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n",
1423  le16_to_cpu(cmd->command));
1424  lbs_submit_command(priv, cmdnode);
1425  } else {
1426  /*
1427  * check if in power save mode, if yes, put the device back
1428  * to PS mode
1429  */
1430 #ifdef TODO
1431  /*
1432  * This was the old code for libertas+wext. Someone that
1433  * understands this beast should re-code it in a sane way.
1434  *
1435  * I actually don't understand why this is related to WPA
1436  * and to connection status, shouldn't powering should be
1437  * independ of such things?
1438  */
1439  if ((priv->psmode != LBS802_11POWERMODECAM) &&
1440  (priv->psstate == PS_STATE_FULL_POWER) &&
1441  ((priv->connect_status == LBS_CONNECTED) ||
1442  lbs_mesh_connected(priv))) {
1443  if (priv->secinfo.WPAenabled ||
1444  priv->secinfo.WPA2enabled) {
1445  /* check for valid WPA group keys */
1446  if (priv->wpa_mcast_key.len ||
1447  priv->wpa_unicast_key.len) {
1448  lbs_deb_host(
1449  "EXEC_NEXT_CMD: WPA enabled and GTK_SET"
1450  " go back to PS_SLEEP");
1451  lbs_set_ps_mode(priv,
1453  false);
1454  }
1455  } else {
1456  lbs_deb_host(
1457  "EXEC_NEXT_CMD: cmdpendingq empty, "
1458  "go back to PS_SLEEP");
1460  false);
1461  }
1462  }
1463 #endif
1464  }
1465 
1466  ret = 0;
1467 done:
1469  return ret;
1470 }
1471 
1472 static void lbs_send_confirmsleep(struct lbs_private *priv)
1473 {
1474  unsigned long flags;
1475  int ret;
1476 
1478  lbs_deb_hex(LBS_DEB_HOST, "sleep confirm", (u8 *) &confirm_sleep,
1479  sizeof(confirm_sleep));
1480 
1481  ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) &confirm_sleep,
1482  sizeof(confirm_sleep));
1483  if (ret) {
1484  netdev_alert(priv->dev, "confirm_sleep failed\n");
1485  goto out;
1486  }
1487 
1488  spin_lock_irqsave(&priv->driver_lock, flags);
1489 
1490  /* We don't get a response on the sleep-confirmation */
1491  priv->dnld_sent = DNLD_RES_RECEIVED;
1492 
1493  if (priv->is_host_sleep_configured) {
1494  priv->is_host_sleep_activated = 1;
1496  }
1497 
1498  /* If nothing to do, go back to sleep (?) */
1499  if (!kfifo_len(&priv->event_fifo) && !priv->resp_len[priv->resp_idx])
1500  priv->psstate = PS_STATE_SLEEP;
1501 
1502  spin_unlock_irqrestore(&priv->driver_lock, flags);
1503 
1504 out:
1506 }
1507 
1517 {
1518  unsigned long flags =0;
1519  int allowed = 1;
1520 
1522 
1523  spin_lock_irqsave(&priv->driver_lock, flags);
1524  if (priv->dnld_sent) {
1525  allowed = 0;
1526  lbs_deb_host("dnld_sent was set\n");
1527  }
1528 
1529  /* In-progress command? */
1530  if (priv->cur_cmd) {
1531  allowed = 0;
1532  lbs_deb_host("cur_cmd was set\n");
1533  }
1534 
1535  /* Pending events or command responses? */
1536  if (kfifo_len(&priv->event_fifo) || priv->resp_len[priv->resp_idx]) {
1537  allowed = 0;
1538  lbs_deb_host("pending events or command responses\n");
1539  }
1540  spin_unlock_irqrestore(&priv->driver_lock, flags);
1541 
1542  if (allowed) {
1543  lbs_deb_host("sending lbs_ps_confirm_sleep\n");
1544  lbs_send_confirmsleep(priv);
1545  } else {
1546  lbs_deb_host("sleep confirm has been delayed\n");
1547  }
1548 
1550 }
1551 
1552 
1566  int8_t p2, int usesnr)
1567 {
1568  struct cmd_ds_802_11_tpc_cfg cmd;
1569  int ret;
1570 
1571  memset(&cmd, 0, sizeof(cmd));
1572  cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1574  cmd.enable = !!enable;
1575  cmd.usesnr = !!usesnr;
1576  cmd.P0 = p0;
1577  cmd.P1 = p1;
1578  cmd.P2 = p2;
1579 
1580  ret = lbs_cmd_with_response(priv, CMD_802_11_TPC_CFG, &cmd);
1581 
1582  return ret;
1583 }
1584 
1598  int8_t p1, int8_t p2)
1599 {
1600  struct cmd_ds_802_11_pa_cfg cmd;
1601  int ret;
1602 
1603  memset(&cmd, 0, sizeof(cmd));
1604  cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1606  cmd.enable = !!enable;
1607  cmd.P0 = p0;
1608  cmd.P1 = p1;
1609  cmd.P2 = p2;
1610 
1611  ret = lbs_cmd_with_response(priv, CMD_802_11_PA_CFG , &cmd);
1612 
1613  return ret;
1614 }
1615 
1616 
1618  uint16_t command, struct cmd_header *in_cmd, int in_cmd_size,
1619  int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
1620  unsigned long callback_arg)
1621 {
1622  struct cmd_ctrl_node *cmdnode;
1623 
1625 
1626  if (priv->surpriseremoved) {
1627  lbs_deb_host("PREP_CMD: card removed\n");
1628  cmdnode = ERR_PTR(-ENOENT);
1629  goto done;
1630  }
1631 
1632  /* No commands are allowed in Deep Sleep until we toggle the GPIO
1633  * to wake up the card and it has signaled that it's ready.
1634  */
1635  if (!priv->is_auto_deep_sleep_enabled) {
1636  if (priv->is_deep_sleep) {
1637  lbs_deb_cmd("command not allowed in deep sleep\n");
1638  cmdnode = ERR_PTR(-EBUSY);
1639  goto done;
1640  }
1641  }
1642 
1643  cmdnode = lbs_get_free_cmd_node(priv);
1644  if (cmdnode == NULL) {
1645  lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
1646 
1647  /* Wake up main thread to execute next command */
1648  wake_up(&priv->waitq);
1649  cmdnode = ERR_PTR(-ENOBUFS);
1650  goto done;
1651  }
1652 
1653  cmdnode->callback = callback;
1654  cmdnode->callback_arg = callback_arg;
1655 
1656  /* Copy the incoming command to the buffer */
1657  memcpy(cmdnode->cmdbuf, in_cmd, in_cmd_size);
1658 
1659  /* Set command, clean result, move to buffer */
1660  cmdnode->cmdbuf->command = cpu_to_le16(command);
1661  cmdnode->cmdbuf->size = cpu_to_le16(in_cmd_size);
1662  cmdnode->cmdbuf->result = 0;
1663 
1664  lbs_deb_host("PREP_CMD: command 0x%04x\n", command);
1665 
1666  cmdnode->cmdwaitqwoken = 0;
1667  lbs_queue_cmd(priv, cmdnode);
1668  wake_up(&priv->waitq);
1669 
1670  done:
1671  lbs_deb_leave_args(LBS_DEB_HOST, "ret %p", cmdnode);
1672  return cmdnode;
1673 }
1674 
1675 void lbs_cmd_async(struct lbs_private *priv, uint16_t command,
1676  struct cmd_header *in_cmd, int in_cmd_size)
1677 {
1679  __lbs_cmd_async(priv, command, in_cmd, in_cmd_size,
1680  lbs_cmd_async_callback, 0);
1682 }
1683 
1684 int __lbs_cmd(struct lbs_private *priv, uint16_t command,
1685  struct cmd_header *in_cmd, int in_cmd_size,
1686  int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
1687  unsigned long callback_arg)
1688 {
1689  struct cmd_ctrl_node *cmdnode;
1690  unsigned long flags;
1691  int ret = 0;
1692 
1694 
1695  cmdnode = __lbs_cmd_async(priv, command, in_cmd, in_cmd_size,
1696  callback, callback_arg);
1697  if (IS_ERR(cmdnode)) {
1698  ret = PTR_ERR(cmdnode);
1699  goto done;
1700  }
1701 
1702  might_sleep();
1703 
1704  /*
1705  * Be careful with signals here. A signal may be received as the system
1706  * goes into suspend or resume. We do not want this to interrupt the
1707  * command, so we perform an uninterruptible sleep.
1708  */
1709  wait_event(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken);
1710 
1711  spin_lock_irqsave(&priv->driver_lock, flags);
1712  ret = cmdnode->result;
1713  if (ret)
1714  netdev_info(priv->dev, "PREP_CMD: command 0x%04x failed: %d\n",
1715  command, ret);
1716 
1717  __lbs_cleanup_and_insert_cmd(priv, cmdnode);
1718  spin_unlock_irqrestore(&priv->driver_lock, flags);
1719 
1720 done:
1721  lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
1722  return ret;
1723 }