Merge branch 'io_remap_pfn_range' of git://www.jni.nu/cris
[pandora-kernel.git] / drivers / net / wireless / libertas / cmd.c
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/kfifo.h>
7 #include <linux/sched.h>
8 #include <linux/slab.h>
9 #include <linux/if_arp.h>
10
11 #include "decl.h"
12 #include "cfg.h"
13 #include "cmd.h"
14
15 #define CAL_NF(nf)              ((s32)(-(s32)(nf)))
16 #define CAL_RSSI(snr, nf)       ((s32)((s32)(snr) + CAL_NF(nf)))
17
18 /**
19  *  @brief Simple callback that copies response back into command
20  *
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
25  *
26  *  @return             0 on success, error on failure
27  */
28 int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
29                      struct cmd_header *resp)
30 {
31         struct cmd_header *buf = (void *)extra;
32         uint16_t copy_len;
33
34         copy_len = min(le16_to_cpu(buf->size), le16_to_cpu(resp->size));
35         memcpy(buf, resp, copy_len);
36         return 0;
37 }
38 EXPORT_SYMBOL_GPL(lbs_cmd_copyback);
39
40 /**
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.
44  *
45  *  @param priv         ignored
46  *  @param extra        ignored
47  *  @param resp         ignored
48  *
49  *  @return             0 for success
50  */
51 static int lbs_cmd_async_callback(struct lbs_private *priv, unsigned long extra,
52                      struct cmd_header *resp)
53 {
54         return 0;
55 }
56
57
58 /**
59  *  @brief Checks whether a command is allowed in Power Save mode
60  *
61  *  @param command the command ID
62  *  @return        1 if allowed, 0 if not allowed
63  */
64 static u8 is_command_allowed_in_ps(u16 cmd)
65 {
66         switch (cmd) {
67         case CMD_802_11_RSSI:
68                 return 1;
69         case CMD_802_11_HOST_SLEEP_CFG:
70                 return 1;
71         default:
72                 break;
73         }
74         return 0;
75 }
76
77 /**
78  *  @brief Updates the hardware details like MAC address and regulatory region
79  *
80  *  @param priv         A pointer to struct lbs_private structure
81  *
82  *  @return             0 on success, error on failure
83  */
84 int lbs_update_hw_spec(struct lbs_private *priv)
85 {
86         struct cmd_ds_get_hw_spec cmd;
87         int ret = -1;
88         u32 i;
89
90         lbs_deb_enter(LBS_DEB_CMD);
91
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);
96         if (ret)
97                 goto out;
98
99         priv->fwcapinfo = le32_to_cpu(cmd.fwcapinfo);
100
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);
106
107         /* Some firmware capabilities:
108          * CF card    firmware 5.0.16p0:   cap 0x00000303
109          * USB dongle firmware 5.110.17p2: cap 0x00000303
110          */
111         lbs_pr_info("%pM, fw %u.%u.%up%u, cap 0x%08x\n",
112                 cmd.permanentaddr,
113                 priv->fwrelease >> 24 & 0xff,
114                 priv->fwrelease >> 16 & 0xff,
115                 priv->fwrelease >>  8 & 0xff,
116                 priv->fwrelease       & 0xff,
117                 priv->fwcapinfo);
118         lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n",
119                     cmd.hwifversion, cmd.version);
120
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.
124          *
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.
127          */
128         if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V4)
129                 priv->regioncode = (le16_to_cpu(cmd.regioncode) >> 8) & 0xFF;
130         else
131                 priv->regioncode = le16_to_cpu(cmd.regioncode) & 0xFF;
132
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])
136                         break;
137         }
138
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");
143         }
144
145         if (priv->current_addr[0] == 0xff)
146                 memmove(priv->current_addr, cmd.permanentaddr, ETH_ALEN);
147
148         memcpy(priv->dev->dev_addr, priv->current_addr, ETH_ALEN);
149         if (priv->mesh_dev)
150                 memcpy(priv->mesh_dev->dev_addr, priv->current_addr, ETH_ALEN);
151
152 out:
153         lbs_deb_leave(LBS_DEB_CMD);
154         return ret;
155 }
156
157 static int lbs_ret_host_sleep_cfg(struct lbs_private *priv, unsigned long dummy,
158                         struct cmd_header *resp)
159 {
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);
166                 }
167         } else {
168                 priv->is_host_sleep_configured = 1;
169         }
170         lbs_deb_leave(LBS_DEB_CMD);
171         return 0;
172 }
173
174 int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
175                 struct wol_config *p_wol_config)
176 {
177         struct cmd_ds_host_sleep cmd_config;
178         int ret;
179
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;
184
185         if (p_wol_config != NULL)
186                 memcpy((uint8_t *)&cmd_config.wol_conf, (uint8_t *)p_wol_config,
187                                 sizeof(struct wol_config));
188         else
189                 cmd_config.wol_conf.action = CMD_ACT_ACTION_NONE;
190
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);
194         if (!ret) {
195                 if (p_wol_config)
196                         memcpy((uint8_t *) p_wol_config,
197                                         (uint8_t *)&cmd_config.wol_conf,
198                                         sizeof(struct wol_config));
199         } else {
200                 lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret);
201         }
202
203         return ret;
204 }
205 EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg);
206
207 /**
208  *  @brief Sets the Power Save mode
209  *
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
214  *
215  *  @return             0 on success, error on failure
216  */
217 int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block)
218 {
219         struct cmd_ds_802_11_ps_mode cmd;
220         int ret = 0;
221
222         lbs_deb_enter(LBS_DEB_CMD);
223
224         memset(&cmd, 0, sizeof(cmd));
225         cmd.hdr.size = cpu_to_le16(sizeof(cmd));
226         cmd.action = cpu_to_le16(cmd_action);
227
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");
233         } else {
234                 /* We don't handle CONFIRM_SLEEP here because it needs to
235                  * be fastpathed to the firmware.
236                  */
237                 lbs_deb_cmd("PS_MODE: unknown action 0x%X\n", cmd_action);
238                 ret = -EOPNOTSUPP;
239                 goto out;
240         }
241
242         if (block)
243                 ret = lbs_cmd_with_response(priv, CMD_802_11_PS_MODE, &cmd);
244         else
245                 lbs_cmd_async(priv, CMD_802_11_PS_MODE, &cmd.hdr, sizeof (cmd));
246
247 out:
248         lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
249         return ret;
250 }
251
252 int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action,
253                                 struct sleep_params *sp)
254 {
255         struct cmd_ds_802_11_sleep_params cmd;
256         int ret;
257
258         lbs_deb_enter(LBS_DEB_CMD);
259
260         if (cmd_action == CMD_ACT_GET) {
261                 memset(&cmd, 0, sizeof(cmd));
262         } else {
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);
269         }
270         cmd.hdr.size = cpu_to_le16(sizeof(cmd));
271         cmd.action = cpu_to_le16(cmd_action);
272
273         ret = lbs_cmd_with_response(priv, CMD_802_11_SLEEP_PARAMS, &cmd);
274
275         if (!ret) {
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);
281
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);
288         }
289
290         lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
291         return 0;
292 }
293
294 static int lbs_wait_for_ds_awake(struct lbs_private *priv)
295 {
296         int ret = 0;
297
298         lbs_deb_enter(LBS_DEB_CMD);
299
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");
304                         ret = -1;
305                 }
306         }
307
308         lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
309         return ret;
310 }
311
312 int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep)
313 {
314         int ret =  0;
315
316         lbs_deb_enter(LBS_DEB_CMD);
317
318         if (deep_sleep) {
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);
323                         if (!ret) {
324                                 netif_stop_queue(priv->dev);
325                                 netif_carrier_off(priv->dev);
326                         }
327                 } else {
328                         lbs_pr_err("deep sleep: already enabled\n");
329                 }
330         } else {
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);
335                         if (!ret) {
336                                 ret = lbs_wait_for_ds_awake(priv);
337                                 if (ret)
338                                         lbs_pr_err("deep sleep: wakeup"
339                                                         "failed\n");
340                         }
341                 }
342         }
343
344         lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
345         return ret;
346 }
347
348 static int lbs_ret_host_sleep_activate(struct lbs_private *priv,
349                 unsigned long dummy,
350                 struct cmd_header *cmd)
351 {
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);
356         return 0;
357 }
358
359 int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep)
360 {
361         struct cmd_header cmd;
362         int ret = 0;
363         uint32_t criteria = EHS_REMOVE_WAKEUP;
364
365         lbs_deb_enter(LBS_DEB_CMD);
366
367         if (host_sleep) {
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);
372                         if (ret) {
373                                 lbs_pr_info("Host sleep configuration failed: "
374                                                 "%d\n", ret);
375                                 return ret;
376                         }
377                         if (priv->psstate == PS_STATE_FULL_POWER) {
378                                 ret = __lbs_cmd(priv,
379                                                 CMD_802_11_HOST_SLEEP_ACTIVATE,
380                                                 &cmd,
381                                                 sizeof(cmd),
382                                                 lbs_ret_host_sleep_activate, 0);
383                                 if (ret)
384                                         lbs_pr_info("HOST_SLEEP_ACTIVATE "
385                                                         "failed: %d\n", ret);
386                         }
387
388                         if (!wait_event_interruptible_timeout(
389                                                 priv->host_sleep_q,
390                                                 priv->is_host_sleep_activated,
391                                                 (10 * HZ))) {
392                                 lbs_pr_err("host_sleep_q: timer expired\n");
393                                 ret = -1;
394                         }
395                 } else {
396                         lbs_pr_err("host sleep: already enabled\n");
397                 }
398         } else {
399                 if (priv->is_host_sleep_activated)
400                         ret = lbs_host_sleep_cfg(priv, criteria,
401                                         (struct wol_config *)NULL);
402         }
403
404         return ret;
405 }
406
407 /**
408  *  @brief Set an SNMP MIB value
409  *
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
413  *
414  *  @return             0 on success, error on failure
415  */
416 int lbs_set_snmp_mib(struct lbs_private *priv, u32 oid, u16 val)
417 {
418         struct cmd_ds_802_11_snmp_mib cmd;
419         int ret;
420
421         lbs_deb_enter(LBS_DEB_CMD);
422
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);
427
428         switch (oid) {
429         case SNMP_MIB_OID_BSS_TYPE:
430                 cmd.bufsize = cpu_to_le16(sizeof(u8));
431                 cmd.value[0] = val;
432                 break;
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);
440                 break;
441         default:
442                 lbs_deb_cmd("SNMP_CMD: (set) unhandled OID 0x%x\n", oid);
443                 ret = -EINVAL;
444                 goto out;
445         }
446
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);
449
450         ret = lbs_cmd_with_response(priv, CMD_802_11_SNMP_MIB, &cmd);
451
452 out:
453         lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
454         return ret;
455 }
456
457 /**
458  *  @brief Get an SNMP MIB value
459  *
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
463  *
464  *  @return             0 on success, error on failure
465  */
466 int lbs_get_snmp_mib(struct lbs_private *priv, u32 oid, u16 *out_val)
467 {
468         struct cmd_ds_802_11_snmp_mib cmd;
469         int ret;
470
471         lbs_deb_enter(LBS_DEB_CMD);
472
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);
477
478         ret = lbs_cmd_with_response(priv, CMD_802_11_SNMP_MIB, &cmd);
479         if (ret)
480                 goto out;
481
482         switch (le16_to_cpu(cmd.bufsize)) {
483         case sizeof(u8):
484                 *out_val = cmd.value[0];
485                 break;
486         case sizeof(u16):
487                 *out_val = le16_to_cpu(*((__le16 *)(&cmd.value)));
488                 break;
489         default:
490                 lbs_deb_cmd("SNMP_CMD: (get) unhandled OID 0x%x size %d\n",
491                             oid, le16_to_cpu(cmd.bufsize));
492                 break;
493         }
494
495 out:
496         lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
497         return ret;
498 }
499
500 /**
501  *  @brief Get the min, max, and current TX power
502  *
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)
507  *
508  *  @return             0 on success, error on failure
509  */
510 int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel,
511                      s16 *maxlevel)
512 {
513         struct cmd_ds_802_11_rf_tx_power cmd;
514         int ret;
515
516         lbs_deb_enter(LBS_DEB_CMD);
517
518         memset(&cmd, 0, sizeof(cmd));
519         cmd.hdr.size = cpu_to_le16(sizeof(cmd));
520         cmd.action = cpu_to_le16(CMD_ACT_GET);
521
522         ret = lbs_cmd_with_response(priv, CMD_802_11_RF_TX_POWER, &cmd);
523         if (ret == 0) {
524                 *curlevel = le16_to_cpu(cmd.curlevel);
525                 if (minlevel)
526                         *minlevel = cmd.minlevel;
527                 if (maxlevel)
528                         *maxlevel = cmd.maxlevel;
529         }
530
531         lbs_deb_leave(LBS_DEB_CMD);
532         return ret;
533 }
534
535 /**
536  *  @brief Set the TX power
537  *
538  *  @param priv         A pointer to struct lbs_private structure
539  *  @param dbm          The desired power level in dBm
540  *
541  *  @return             0 on success, error on failure
542  */
543 int lbs_set_tx_power(struct lbs_private *priv, s16 dbm)
544 {
545         struct cmd_ds_802_11_rf_tx_power cmd;
546         int ret;
547
548         lbs_deb_enter(LBS_DEB_CMD);
549
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);
554
555         lbs_deb_cmd("SET_RF_TX_POWER: %d dBm\n", dbm);
556
557         ret = lbs_cmd_with_response(priv, CMD_802_11_RF_TX_POWER, &cmd);
558
559         lbs_deb_leave(LBS_DEB_CMD);
560         return ret;
561 }
562
563 /**
564  *  @brief Enable or disable monitor mode (only implemented on OLPC usb8388 FW)
565  *
566  *  @param priv        A pointer to struct lbs_private structure
567  *  @param enable      1 to enable monitor mode, 0 to disable
568  *
569  *  @return            0 on success, error on failure
570  */
571 int lbs_set_monitor_mode(struct lbs_private *priv, int enable)
572 {
573         struct cmd_ds_802_11_monitor_mode cmd;
574         int ret;
575
576         memset(&cmd, 0, sizeof(cmd));
577         cmd.hdr.size = cpu_to_le16(sizeof(cmd));
578         cmd.action = cpu_to_le16(CMD_ACT_SET);
579         if (enable)
580                 cmd.mode = cpu_to_le16(0x1);
581
582         lbs_deb_cmd("SET_MONITOR_MODE: %d\n", enable);
583
584         ret = lbs_cmd_with_response(priv, CMD_802_11_MONITOR_MODE, &cmd);
585         if (ret == 0) {
586                 priv->dev->type = enable ? ARPHRD_IEEE80211_RADIOTAP :
587                                                 ARPHRD_ETHER;
588         }
589
590         lbs_deb_leave(LBS_DEB_CMD);
591         return ret;
592 }
593
594 /**
595  *  @brief Get the radio channel
596  *
597  *  @param priv         A pointer to struct lbs_private structure
598  *
599  *  @return             The channel on success, error on failure
600  */
601 static int lbs_get_channel(struct lbs_private *priv)
602 {
603         struct cmd_ds_802_11_rf_channel cmd;
604         int ret = 0;
605
606         lbs_deb_enter(LBS_DEB_CMD);
607
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);
611
612         ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd);
613         if (ret)
614                 goto out;
615
616         ret = le16_to_cpu(cmd.channel);
617         lbs_deb_cmd("current radio channel is %d\n", ret);
618
619 out:
620         lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
621         return ret;
622 }
623
624 int lbs_update_channel(struct lbs_private *priv)
625 {
626         int ret;
627
628         /* the channel in f/w could be out of sync; get the current channel */
629         lbs_deb_enter(LBS_DEB_ASSOC);
630
631         ret = lbs_get_channel(priv);
632         if (ret > 0) {
633                 priv->channel = ret;
634                 ret = 0;
635         }
636         lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
637         return ret;
638 }
639
640 /**
641  *  @brief Set the radio channel
642  *
643  *  @param priv         A pointer to struct lbs_private structure
644  *  @param channel      The desired channel, or 0 to clear a locked channel
645  *
646  *  @return             0 on success, error on failure
647  */
648 int lbs_set_channel(struct lbs_private *priv, u8 channel)
649 {
650         struct cmd_ds_802_11_rf_channel cmd;
651 #ifdef DEBUG
652         u8 old_channel = priv->channel;
653 #endif
654         int ret = 0;
655
656         lbs_deb_enter(LBS_DEB_CMD);
657
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);
662
663         ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd);
664         if (ret)
665                 goto out;
666
667         priv->channel = (uint8_t) le16_to_cpu(cmd.channel);
668         lbs_deb_cmd("channel switch from %d to %d\n", old_channel,
669                 priv->channel);
670
671 out:
672         lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
673         return ret;
674 }
675
676 /**
677  *  @brief Get current RSSI and noise floor
678  *
679  *  @param priv         A pointer to struct lbs_private structure
680  *  @param rssi         On successful return, signal level in mBm
681  *
682  *  @return             The channel on success, error on failure
683  */
684 int lbs_get_rssi(struct lbs_private *priv, s8 *rssi, s8 *nf)
685 {
686         struct cmd_ds_802_11_rssi cmd;
687         int ret = 0;
688
689         lbs_deb_enter(LBS_DEB_CMD);
690
691         BUG_ON(rssi == NULL);
692         BUG_ON(nf == NULL);
693
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);
698
699         ret = lbs_cmd_with_response(priv, CMD_802_11_RSSI, &cmd);
700         if (ret == 0) {
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));
703         }
704
705         lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
706         return ret;
707 }
708
709 /**
710  *  @brief Send regulatory and 802.11d domain information to the firmware
711  *
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
715  *
716  *  @return             0 on success, error code on failure
717 */
718 int lbs_set_11d_domain_info(struct lbs_private *priv,
719                             struct regulatory_request *request,
720                             struct ieee80211_supported_band **bands)
721 {
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;
727         u8 num_triplet = 0;
728         u8 num_parsed_chan = 0;
729         u8 first_channel = 0, next_chan = 0, max_pwr = 0;
730         u8 i, flag = 0;
731         size_t triplet_size;
732         int ret;
733
734         lbs_deb_enter(LBS_DEB_11D);
735
736         memset(&cmd, 0, sizeof(cmd));
737         cmd.action = cpu_to_le16(CMD_ACT_SET);
738
739         lbs_deb_11d("Setting country code '%c%c'\n",
740                     request->alpha2[0], request->alpha2[1]);
741
742         domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN);
743
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] = ' ';
748
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)
754          * etc.
755          */
756         for (band = 0;
757              (band < IEEE80211_NUM_BANDS) && (num_triplet < MAX_11D_TRIPLETS);
758              band++) {
759
760                 if (!bands[band])
761                         continue;
762
763                 for (i = 0;
764                      (i < bands[band]->n_channels) && (num_triplet < MAX_11D_TRIPLETS);
765                      i++) {
766                         ch = &bands[band]->channels[i];
767                         if (ch->flags & IEEE80211_CHAN_DISABLED)
768                                 continue;
769
770                         if (!flag) {
771                                 flag = 1;
772                                 next_chan = first_channel = (u32) ch->hw_value;
773                                 max_pwr = ch->max_power;
774                                 num_parsed_chan = 1;
775                                 continue;
776                         }
777
778                         if ((ch->hw_value == next_chan + 1) &&
779                                         (ch->max_power == max_pwr)) {
780                                 /* Consolidate adjacent channels */
781                                 next_chan++;
782                                 num_parsed_chan++;
783                         } else {
784                                 /* Add this triplet */
785                                 lbs_deb_11d("11D triplet (%d, %d, %d)\n",
786                                         first_channel, num_parsed_chan,
787                                         max_pwr);
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;
792                                 num_triplet++;
793                                 flag = 0;
794                         }
795                 }
796
797                 if (flag) {
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;
805                         num_triplet++;
806                 }
807         }
808
809         lbs_deb_11d("# triplets %d\n", num_triplet);
810
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) +
814                                         triplet_size);
815
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));
819
820         cmd.hdr.size = cpu_to_le16(sizeof(cmd.hdr) +
821                                    sizeof(cmd.action) +
822                                    sizeof(cmd.domain.header) +
823                                    sizeof(cmd.domain.country_code) +
824                                    triplet_size);
825
826         ret = lbs_cmd_with_response(priv, CMD_802_11D_DOMAIN_INFO, &cmd);
827
828         lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret);
829         return ret;
830 }
831
832 /**
833  *  @brief Read a MAC, Baseband, or RF register
834  *
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'
840  *
841  *  @return             0 on success, error code on failure
842 */
843 int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value)
844 {
845         struct cmd_ds_reg_access cmd;
846         int ret = 0;
847
848         lbs_deb_enter(LBS_DEB_CMD);
849
850         BUG_ON(value == NULL);
851
852         memset(&cmd, 0, sizeof(cmd));
853         cmd.hdr.size = cpu_to_le16(sizeof(cmd));
854         cmd.action = cpu_to_le16(CMD_ACT_GET);
855
856         if (reg != CMD_MAC_REG_ACCESS &&
857             reg != CMD_BBP_REG_ACCESS &&
858             reg != CMD_RF_REG_ACCESS) {
859                 ret = -EINVAL;
860                 goto out;
861         }
862
863         ret = lbs_cmd_with_response(priv, reg, &cmd);
864         if (ret) {
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);
869         }
870
871 out:
872         lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
873         return ret;
874 }
875
876 /**
877  *  @brief Write a MAC, Baseband, or RF register
878  *
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'
884  *
885  *  @return             0 on success, error code on failure
886 */
887 int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value)
888 {
889         struct cmd_ds_reg_access cmd;
890         int ret = 0;
891
892         lbs_deb_enter(LBS_DEB_CMD);
893
894         memset(&cmd, 0, sizeof(cmd));
895         cmd.hdr.size = cpu_to_le16(sizeof(cmd));
896         cmd.action = cpu_to_le16(CMD_ACT_SET);
897
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);
902         else {
903                 ret = -EINVAL;
904                 goto out;
905         }
906
907         ret = lbs_cmd_with_response(priv, reg, &cmd);
908
909 out:
910         lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
911         return ret;
912 }
913
914 static void lbs_queue_cmd(struct lbs_private *priv,
915                           struct cmd_ctrl_node *cmdnode)
916 {
917         unsigned long flags;
918         int addtail = 1;
919
920         lbs_deb_enter(LBS_DEB_HOST);
921
922         if (!cmdnode) {
923                 lbs_deb_host("QUEUE_CMD: cmdnode is NULL\n");
924                 goto done;
925         }
926         if (!cmdnode->cmdbuf->size) {
927                 lbs_deb_host("DNLD_CMD: cmd size is zero\n");
928                 goto done;
929         }
930         cmdnode->result = 0;
931
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;
935
936                 if (psm->action == cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) {
937                         if (priv->psstate != PS_STATE_FULL_POWER)
938                                 addtail = 0;
939                 }
940         }
941
942         if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_WAKEUP_CONFIRM)
943                 addtail = 0;
944
945         spin_lock_irqsave(&priv->driver_lock, flags);
946
947         if (addtail)
948                 list_add_tail(&cmdnode->list, &priv->cmdpendingq);
949         else
950                 list_add(&cmdnode->list, &priv->cmdpendingq);
951
952         spin_unlock_irqrestore(&priv->driver_lock, flags);
953
954         lbs_deb_host("QUEUE_CMD: inserted command 0x%04x into cmdpendingq\n",
955                      le16_to_cpu(cmdnode->cmdbuf->command));
956
957 done:
958         lbs_deb_leave(LBS_DEB_HOST);
959 }
960
961 static void lbs_submit_command(struct lbs_private *priv,
962                                struct cmd_ctrl_node *cmdnode)
963 {
964         unsigned long flags;
965         struct cmd_header *cmd;
966         uint16_t cmdsize;
967         uint16_t command;
968         int timeo = 3 * HZ;
969         int ret;
970
971         lbs_deb_enter(LBS_DEB_HOST);
972
973         cmd = cmdnode->cmdbuf;
974
975         spin_lock_irqsave(&priv->driver_lock, flags);
976         priv->cur_cmd = cmdnode;
977         spin_unlock_irqrestore(&priv->driver_lock, flags);
978
979         cmdsize = le16_to_cpu(cmd->size);
980         command = le16_to_cpu(cmd->command);
981
982         /* These commands take longer */
983         if (command == CMD_802_11_SCAN || command == CMD_802_11_ASSOCIATE)
984                 timeo = 5 * HZ;
985
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);
989
990         ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize);
991
992         if (ret) {
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 */
996                 timeo = HZ/4;
997         }
998
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;
1003                 }
1004                 priv->is_deep_sleep = 1;
1005                 lbs_complete_command(priv, cmdnode, 0);
1006         } else {
1007                 /* Setup the timer after transmit command */
1008                 mod_timer(&priv->command_timer, jiffies + timeo);
1009         }
1010
1011         lbs_deb_leave(LBS_DEB_HOST);
1012 }
1013
1014 /**
1015  *  This function inserts command node to cmdfreeq
1016  *  after cleans it. Requires priv->driver_lock held.
1017  */
1018 static void __lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
1019                                          struct cmd_ctrl_node *cmdnode)
1020 {
1021         lbs_deb_enter(LBS_DEB_HOST);
1022
1023         if (!cmdnode)
1024                 goto out;
1025
1026         cmdnode->callback = NULL;
1027         cmdnode->callback_arg = 0;
1028
1029         memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE);
1030
1031         list_add_tail(&cmdnode->list, &priv->cmdfreeq);
1032  out:
1033         lbs_deb_leave(LBS_DEB_HOST);
1034 }
1035
1036 static void lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
1037         struct cmd_ctrl_node *ptempcmd)
1038 {
1039         unsigned long flags;
1040
1041         spin_lock_irqsave(&priv->driver_lock, flags);
1042         __lbs_cleanup_and_insert_cmd(priv, ptempcmd);
1043         spin_unlock_irqrestore(&priv->driver_lock, flags);
1044 }
1045
1046 void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
1047                           int result)
1048 {
1049         cmd->result = result;
1050         cmd->cmdwaitqwoken = 1;
1051         wake_up_interruptible(&cmd->cmdwait_q);
1052
1053         if (!cmd->callback || cmd->callback == lbs_cmd_async_callback)
1054                 __lbs_cleanup_and_insert_cmd(priv, cmd);
1055         priv->cur_cmd = NULL;
1056 }
1057
1058 int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on)
1059 {
1060         struct cmd_ds_802_11_radio_control cmd;
1061         int ret = -EINVAL;
1062
1063         lbs_deb_enter(LBS_DEB_CMD);
1064
1065         cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1066         cmd.action = cpu_to_le16(CMD_ACT_SET);
1067
1068         /* Only v8 and below support setting the preamble */
1069         if (priv->fwrelease < 0x09000000) {
1070                 switch (preamble) {
1071                 case RADIO_PREAMBLE_SHORT:
1072                 case RADIO_PREAMBLE_AUTO:
1073                 case RADIO_PREAMBLE_LONG:
1074                         cmd.control = cpu_to_le16(preamble);
1075                         break;
1076                 default:
1077                         goto out;
1078                 }
1079         }
1080
1081         if (radio_on)
1082                 cmd.control |= cpu_to_le16(0x1);
1083         else {
1084                 cmd.control &= cpu_to_le16(~0x1);
1085                 priv->txpower_cur = 0;
1086         }
1087
1088         lbs_deb_cmd("RADIO_CONTROL: radio %s, preamble %d\n",
1089                     radio_on ? "ON" : "OFF", preamble);
1090
1091         priv->radio_on = radio_on;
1092
1093         ret = lbs_cmd_with_response(priv, CMD_802_11_RADIO_CONTROL, &cmd);
1094
1095 out:
1096         lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
1097         return ret;
1098 }
1099
1100 void lbs_set_mac_control(struct lbs_private *priv)
1101 {
1102         struct cmd_ds_mac_control cmd;
1103
1104         lbs_deb_enter(LBS_DEB_CMD);
1105
1106         cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1107         cmd.action = cpu_to_le16(priv->mac_control);
1108         cmd.reserved = 0;
1109
1110         lbs_cmd_async(priv, CMD_MAC_CONTROL, &cmd.hdr, sizeof(cmd));
1111
1112         lbs_deb_leave(LBS_DEB_CMD);
1113 }
1114
1115 /**
1116  *  @brief This function allocates the command buffer and link
1117  *  it to command free queue.
1118  *
1119  *  @param priv         A pointer to struct lbs_private structure
1120  *  @return             0 or -1
1121  */
1122 int lbs_allocate_cmd_buffer(struct lbs_private *priv)
1123 {
1124         int ret = 0;
1125         u32 bufsize;
1126         u32 i;
1127         struct cmd_ctrl_node *cmdarray;
1128
1129         lbs_deb_enter(LBS_DEB_HOST);
1130
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");
1135                 ret = -1;
1136                 goto done;
1137         }
1138         priv->cmd_array = cmdarray;
1139
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");
1145                         ret = -1;
1146                         goto done;
1147                 }
1148         }
1149
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]);
1153         }
1154         ret = 0;
1155
1156 done:
1157         lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
1158         return ret;
1159 }
1160
1161 /**
1162  *  @brief This function frees the command buffer.
1163  *
1164  *  @param priv         A pointer to struct lbs_private structure
1165  *  @return             0 or -1
1166  */
1167 int lbs_free_cmd_buffer(struct lbs_private *priv)
1168 {
1169         struct cmd_ctrl_node *cmdarray;
1170         unsigned int i;
1171
1172         lbs_deb_enter(LBS_DEB_HOST);
1173
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");
1177                 goto done;
1178         }
1179
1180         cmdarray = priv->cmd_array;
1181
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;
1187                 }
1188         }
1189
1190         /* Release cmd_ctrl_node */
1191         if (priv->cmd_array) {
1192                 kfree(priv->cmd_array);
1193                 priv->cmd_array = NULL;
1194         }
1195
1196 done:
1197         lbs_deb_leave(LBS_DEB_HOST);
1198         return 0;
1199 }
1200
1201 /**
1202  *  @brief This function gets a free command node if available in
1203  *  command free queue.
1204  *
1205  *  @param priv         A pointer to struct lbs_private structure
1206  *  @return cmd_ctrl_node A pointer to cmd_ctrl_node structure or NULL
1207  */
1208 static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv)
1209 {
1210         struct cmd_ctrl_node *tempnode;
1211         unsigned long flags;
1212
1213         lbs_deb_enter(LBS_DEB_HOST);
1214
1215         if (!priv)
1216                 return NULL;
1217
1218         spin_lock_irqsave(&priv->driver_lock, flags);
1219
1220         if (!list_empty(&priv->cmdfreeq)) {
1221                 tempnode = list_first_entry(&priv->cmdfreeq,
1222                                             struct cmd_ctrl_node, list);
1223                 list_del(&tempnode->list);
1224         } else {
1225                 lbs_deb_host("GET_CMD_NODE: cmd_ctrl_node is not available\n");
1226                 tempnode = NULL;
1227         }
1228
1229         spin_unlock_irqrestore(&priv->driver_lock, flags);
1230
1231         lbs_deb_leave(LBS_DEB_HOST);
1232         return tempnode;
1233 }
1234
1235 /**
1236  *  @brief This function executes next command in command
1237  *  pending queue. It will put firmware back to PS mode
1238  *  if applicable.
1239  *
1240  *  @param priv     A pointer to struct lbs_private structure
1241  *  @return        0 or -1
1242  */
1243 int lbs_execute_next_command(struct lbs_private *priv)
1244 {
1245         struct cmd_ctrl_node *cmdnode = NULL;
1246         struct cmd_header *cmd;
1247         unsigned long flags;
1248         int ret = 0;
1249
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);
1254
1255         spin_lock_irqsave(&priv->driver_lock, flags);
1256
1257         if (priv->cur_cmd) {
1258                 lbs_pr_alert( "EXEC_NEXT_CMD: already processing command!\n");
1259                 spin_unlock_irqrestore(&priv->driver_lock, flags);
1260                 ret = -1;
1261                 goto done;
1262         }
1263
1264         if (!list_empty(&priv->cmdpendingq)) {
1265                 cmdnode = list_first_entry(&priv->cmdpendingq,
1266                                            struct cmd_ctrl_node, list);
1267         }
1268
1269         spin_unlock_irqrestore(&priv->driver_lock, flags);
1270
1271         if (cmdnode) {
1272                 cmd = cmdnode->cmdbuf;
1273
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)) {
1277                                 lbs_deb_host(
1278                                        "EXEC_NEXT_CMD: cannot send cmd 0x%04x in psstate %d\n",
1279                                        le16_to_cpu(cmd->command),
1280                                        priv->psstate);
1281                                 ret = -1;
1282                                 goto done;
1283                         }
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) {
1288                         /*
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:
1293                          * Ignore it.
1294                          * 3. PS command EXIT_PS:
1295                          * Set needtowakeup to TRUE if current state is SLEEP,
1296                          * otherwise send this command down to firmware
1297                          * immediately.
1298                          */
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)
1304                                     ) {
1305                                         /* w/ new scheme, it will not reach here.
1306                                            since it is blocked in main_thread. */
1307                                         priv->needtowakeup = 1;
1308                                 } else {
1309                                         lbs_set_ps_mode(priv,
1310                                                         PS_MODE_ACTION_EXIT_PS,
1311                                                         false);
1312                                 }
1313
1314                                 ret = 0;
1315                                 goto done;
1316                         } else {
1317                                 /*
1318                                  * PS command. Ignore it if it is not Exit_PS.
1319                                  * otherwise send it down immediately.
1320                                  */
1321                                 struct cmd_ds_802_11_ps_mode *psm = (void *)&cmd[1];
1322
1323                                 lbs_deb_host(
1324                                        "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n",
1325                                        psm->action);
1326                                 if (psm->action !=
1327                                     cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) {
1328                                         lbs_deb_host(
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);
1334
1335                                         ret = 0;
1336                                         goto done;
1337                                 }
1338
1339                                 if ((priv->psstate == PS_STATE_SLEEP) ||
1340                                     (priv->psstate == PS_STATE_PRE_SLEEP)) {
1341                                         lbs_deb_host(
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;
1348
1349                                         ret = 0;
1350                                         goto done;
1351                                 }
1352
1353                                 lbs_deb_host(
1354                                        "EXEC_NEXT_CMD: sending EXIT_PS\n");
1355                         }
1356                 }
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);
1361         } else {
1362                 /*
1363                  * check if in power save mode, if yes, put the device back
1364                  * to PS mode
1365                  */
1366 #ifdef TODO
1367                 /*
1368                  * This was the old code for libertas+wext. Someone that
1369                  * understands this beast should re-code it in a sane way.
1370                  *
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?
1374                  */
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) {
1384                                         lbs_deb_host(
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,
1389                                                         false);
1390                                 }
1391                         } else {
1392                                 lbs_deb_host(
1393                                        "EXEC_NEXT_CMD: cmdpendingq empty, "
1394                                        "go back to PS_SLEEP");
1395                                 lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS,
1396                                                 false);
1397                         }
1398                 }
1399 #endif
1400         }
1401
1402         ret = 0;
1403 done:
1404         lbs_deb_leave(LBS_DEB_THREAD);
1405         return ret;
1406 }
1407
1408 static void lbs_send_confirmsleep(struct lbs_private *priv)
1409 {
1410         unsigned long flags;
1411         int ret;
1412
1413         lbs_deb_enter(LBS_DEB_HOST);
1414         lbs_deb_hex(LBS_DEB_HOST, "sleep confirm", (u8 *) &confirm_sleep,
1415                 sizeof(confirm_sleep));
1416
1417         ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) &confirm_sleep,
1418                 sizeof(confirm_sleep));
1419         if (ret) {
1420                 lbs_pr_alert("confirm_sleep failed\n");
1421                 goto out;
1422         }
1423
1424         spin_lock_irqsave(&priv->driver_lock, flags);
1425
1426         /* We don't get a response on the sleep-confirmation */
1427         priv->dnld_sent = DNLD_RES_RECEIVED;
1428
1429         if (priv->is_host_sleep_configured) {
1430                 priv->is_host_sleep_activated = 1;
1431                 wake_up_interruptible(&priv->host_sleep_q);
1432         }
1433
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;
1437
1438         spin_unlock_irqrestore(&priv->driver_lock, flags);
1439
1440 out:
1441         lbs_deb_leave(LBS_DEB_HOST);
1442 }
1443
1444 /**
1445  *  @brief This function checks condition and prepares to
1446  *  send sleep confirm command to firmware if ok.
1447  *
1448  *  @param priv         A pointer to struct lbs_private structure
1449  *  @param psmode       Power Saving mode
1450  *  @return             n/a
1451  */
1452 void lbs_ps_confirm_sleep(struct lbs_private *priv)
1453 {
1454         unsigned long flags =0;
1455         int allowed = 1;
1456
1457         lbs_deb_enter(LBS_DEB_HOST);
1458
1459         spin_lock_irqsave(&priv->driver_lock, flags);
1460         if (priv->dnld_sent) {
1461                 allowed = 0;
1462                 lbs_deb_host("dnld_sent was set\n");
1463         }
1464
1465         /* In-progress command? */
1466         if (priv->cur_cmd) {
1467                 allowed = 0;
1468                 lbs_deb_host("cur_cmd was set\n");
1469         }
1470
1471         /* Pending events or command responses? */
1472         if (kfifo_len(&priv->event_fifo) || priv->resp_len[priv->resp_idx]) {
1473                 allowed = 0;
1474                 lbs_deb_host("pending events or command responses\n");
1475         }
1476         spin_unlock_irqrestore(&priv->driver_lock, flags);
1477
1478         if (allowed) {
1479                 lbs_deb_host("sending lbs_ps_confirm_sleep\n");
1480                 lbs_send_confirmsleep(priv);
1481         } else {
1482                 lbs_deb_host("sleep confirm has been delayed\n");
1483         }
1484
1485         lbs_deb_leave(LBS_DEB_HOST);
1486 }
1487
1488
1489 /**
1490  * @brief Configures the transmission power control functionality.
1491  *
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
1498  *
1499  * @return 0 on success
1500  */
1501 int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1,
1502                 int8_t p2, int usesnr)
1503 {
1504         struct cmd_ds_802_11_tpc_cfg cmd;
1505         int ret;
1506
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;
1512         cmd.P0 = p0;
1513         cmd.P1 = p1;
1514         cmd.P2 = p2;
1515
1516         ret = lbs_cmd_with_response(priv, CMD_802_11_TPC_CFG, &cmd);
1517
1518         return ret;
1519 }
1520
1521 /**
1522  * @brief Configures the power adaptation settings.
1523  *
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).
1529  *
1530  * @return 0 on Success
1531  */
1532
1533 int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0,
1534                 int8_t p1, int8_t p2)
1535 {
1536         struct cmd_ds_802_11_pa_cfg cmd;
1537         int ret;
1538
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;
1543         cmd.P0 = p0;
1544         cmd.P1 = p1;
1545         cmd.P2 = p2;
1546
1547         ret = lbs_cmd_with_response(priv, CMD_802_11_PA_CFG , &cmd);
1548
1549         return ret;
1550 }
1551
1552
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)
1557 {
1558         struct cmd_ctrl_node *cmdnode;
1559
1560         lbs_deb_enter(LBS_DEB_HOST);
1561
1562         if (priv->surpriseremoved) {
1563                 lbs_deb_host("PREP_CMD: card removed\n");
1564                 cmdnode = ERR_PTR(-ENOENT);
1565                 goto done;
1566         }
1567
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.
1570          */
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);
1575                         goto done;
1576                 }
1577         }
1578
1579         cmdnode = lbs_get_free_cmd_node(priv);
1580         if (cmdnode == NULL) {
1581                 lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
1582
1583                 /* Wake up main thread to execute next command */
1584                 wake_up_interruptible(&priv->waitq);
1585                 cmdnode = ERR_PTR(-ENOBUFS);
1586                 goto done;
1587         }
1588
1589         cmdnode->callback = callback;
1590         cmdnode->callback_arg = callback_arg;
1591
1592         /* Copy the incoming command to the buffer */
1593         memcpy(cmdnode->cmdbuf, in_cmd, in_cmd_size);
1594
1595         /* Set sequence number, clean result, move to buffer */
1596         priv->seqnum++;
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;
1601
1602         lbs_deb_host("PREP_CMD: command 0x%04x\n", command);
1603
1604         cmdnode->cmdwaitqwoken = 0;
1605         lbs_queue_cmd(priv, cmdnode);
1606         wake_up_interruptible(&priv->waitq);
1607
1608  done:
1609         lbs_deb_leave_args(LBS_DEB_HOST, "ret %p", cmdnode);
1610         return cmdnode;
1611 }
1612
1613 void lbs_cmd_async(struct lbs_private *priv, uint16_t command,
1614         struct cmd_header *in_cmd, int in_cmd_size)
1615 {
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);
1620 }
1621
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)
1626 {
1627         struct cmd_ctrl_node *cmdnode;
1628         unsigned long flags;
1629         int ret = 0;
1630
1631         lbs_deb_enter(LBS_DEB_HOST);
1632
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);
1637                 goto done;
1638         }
1639
1640         might_sleep();
1641         wait_event_interruptible(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken);
1642
1643         spin_lock_irqsave(&priv->driver_lock, flags);
1644         ret = cmdnode->result;
1645         if (ret)
1646                 lbs_pr_info("PREP_CMD: command 0x%04x failed: %d\n",
1647                             command, ret);
1648
1649         __lbs_cleanup_and_insert_cmd(priv, cmdnode);
1650         spin_unlock_irqrestore(&priv->driver_lock, flags);
1651
1652 done:
1653         lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
1654         return ret;
1655 }
1656 EXPORT_SYMBOL_GPL(__lbs_cmd);