Merge branch 'devicetree/arm-next' of git://git.secretlab.ca/git/linux-2.6 into devel...
[pandora-kernel.git] / drivers / net / wireless / mwifiex / cmdevt.c
1 /*
2  * Marvell Wireless LAN device driver: commands and events
3  *
4  * Copyright (C) 2011, Marvell International Ltd.
5  *
6  * This software file (the "File") is distributed by Marvell International
7  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
8  * (the "License").  You may use, redistribute and/or modify this File in
9  * accordance with the terms and conditions of the License, a copy of which
10  * is available by writing to the Free Software Foundation, Inc.,
11  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
12  * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
13  *
14  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
16  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
17  * this warranty disclaimer.
18  */
19
20 #include "decl.h"
21 #include "ioctl.h"
22 #include "util.h"
23 #include "fw.h"
24 #include "main.h"
25 #include "wmm.h"
26 #include "11n.h"
27
28 /*
29  * This function initializes a command node.
30  *
31  * The actual allocation of the node is not done by this function. It only
32  * initiates a node by filling it with default parameters. Similarly,
33  * allocation of the different buffers used (IOCTL buffer, data buffer) are
34  * not done by this function either.
35  */
36 static void
37 mwifiex_init_cmd_node(struct mwifiex_private *priv,
38                       struct cmd_ctrl_node *cmd_node,
39                       u32 cmd_oid, void *data_buf)
40 {
41         cmd_node->priv = priv;
42         cmd_node->cmd_oid = cmd_oid;
43         cmd_node->wait_q_enabled = priv->adapter->cmd_wait_q_required;
44         priv->adapter->cmd_wait_q_required = false;
45         cmd_node->data_buf = data_buf;
46         cmd_node->cmd_skb = cmd_node->skb;
47 }
48
49 /*
50  * This function returns a command node from the free queue depending upon
51  * availability.
52  */
53 static struct cmd_ctrl_node *
54 mwifiex_get_cmd_node(struct mwifiex_adapter *adapter)
55 {
56         struct cmd_ctrl_node *cmd_node;
57         unsigned long flags;
58
59         spin_lock_irqsave(&adapter->cmd_free_q_lock, flags);
60         if (list_empty(&adapter->cmd_free_q)) {
61                 dev_err(adapter->dev, "GET_CMD_NODE: cmd node not available\n");
62                 spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags);
63                 return NULL;
64         }
65         cmd_node = list_first_entry(&adapter->cmd_free_q,
66                         struct cmd_ctrl_node, list);
67         list_del(&cmd_node->list);
68         spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags);
69
70         return cmd_node;
71 }
72
73 /*
74  * This function cleans up a command node.
75  *
76  * The function resets the fields including the buffer pointers.
77  * This function does not try to free the buffers. They must be
78  * freed before calling this function.
79  *
80  * This function will however call the receive completion callback
81  * in case a response buffer is still available before resetting
82  * the pointer.
83  */
84 static void
85 mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter,
86                        struct cmd_ctrl_node *cmd_node)
87 {
88         cmd_node->cmd_oid = 0;
89         cmd_node->cmd_flag = 0;
90         cmd_node->data_buf = NULL;
91         cmd_node->wait_q_enabled = false;
92
93         if (cmd_node->resp_skb) {
94                 dev_kfree_skb_any(cmd_node->resp_skb);
95                 cmd_node->resp_skb = NULL;
96         }
97 }
98
99 /*
100  * This function sends a host command to the firmware.
101  *
102  * The function copies the host command into the driver command
103  * buffer, which will be transferred to the firmware later by the
104  * main thread.
105  */
106 static int mwifiex_cmd_host_cmd(struct mwifiex_private *priv,
107                                 struct host_cmd_ds_command *cmd, void *data_buf)
108 {
109         struct mwifiex_ds_misc_cmd *pcmd_ptr =
110                 (struct mwifiex_ds_misc_cmd *) data_buf;
111
112         /* Copy the HOST command to command buffer */
113         memcpy((void *) cmd, pcmd_ptr->cmd, pcmd_ptr->len);
114         dev_dbg(priv->adapter->dev, "cmd: host cmd size = %d\n", pcmd_ptr->len);
115         return 0;
116 }
117
118 /*
119  * This function downloads a command to the firmware.
120  *
121  * The function performs sanity tests, sets the command sequence
122  * number and size, converts the header fields to CPU format before
123  * sending. Afterwards, it logs the command ID and action for debugging
124  * and sets up the command timeout timer.
125  */
126 static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
127                                   struct cmd_ctrl_node *cmd_node)
128 {
129
130         struct mwifiex_adapter *adapter = priv->adapter;
131         int ret;
132         struct host_cmd_ds_command *host_cmd;
133         uint16_t cmd_code;
134         uint16_t cmd_size;
135         struct timeval tstamp;
136         unsigned long flags;
137
138         if (!adapter || !cmd_node)
139                 return -1;
140
141         host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data);
142
143         /* Sanity test */
144         if (host_cmd == NULL || host_cmd->size == 0) {
145                 dev_err(adapter->dev, "DNLD_CMD: host_cmd is null"
146                         " or cmd size is 0, not sending\n");
147                 if (cmd_node->wait_q_enabled)
148                         adapter->cmd_wait_q.status = -1;
149                 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
150                 return -1;
151         }
152
153         /* Set command sequence number */
154         adapter->seq_num++;
155         host_cmd->seq_num = cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO
156                             (adapter->seq_num, cmd_node->priv->bss_num,
157                              cmd_node->priv->bss_type));
158
159         spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
160         adapter->curr_cmd = cmd_node;
161         spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
162
163         cmd_code = le16_to_cpu(host_cmd->command);
164         cmd_size = le16_to_cpu(host_cmd->size);
165
166         skb_trim(cmd_node->cmd_skb, cmd_size);
167
168         do_gettimeofday(&tstamp);
169         dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d,"
170                 " seqno %#x\n",
171                 tstamp.tv_sec, tstamp.tv_usec, cmd_code,
172                le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)), cmd_size,
173                le16_to_cpu(host_cmd->seq_num));
174
175         skb_push(cmd_node->cmd_skb, INTF_HEADER_LEN);
176
177         ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_CMD,
178                                              cmd_node->cmd_skb->data,
179                                              cmd_node->cmd_skb->len, NULL);
180
181         skb_pull(cmd_node->cmd_skb, INTF_HEADER_LEN);
182
183         if (ret == -1) {
184                 dev_err(adapter->dev, "DNLD_CMD: host to card failed\n");
185                 if (cmd_node->wait_q_enabled)
186                         adapter->cmd_wait_q.status = -1;
187                 mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
188
189                 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
190                 adapter->curr_cmd = NULL;
191                 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
192
193                 adapter->dbg.num_cmd_host_to_card_failure++;
194                 return -1;
195         }
196
197         /* Save the last command id and action to debug log */
198         adapter->dbg.last_cmd_index =
199                 (adapter->dbg.last_cmd_index + 1) % DBG_CMD_NUM;
200         adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index] = cmd_code;
201         adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index] =
202                 le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN));
203
204         /* Clear BSS_NO_BITS from HostCmd */
205         cmd_code &= HostCmd_CMD_ID_MASK;
206
207         /* Setup the timer after transmit command */
208         mod_timer(&adapter->cmd_timer,
209                 jiffies + (MWIFIEX_TIMER_10S * HZ) / 1000);
210
211         return 0;
212 }
213
214 /*
215  * This function downloads a sleep confirm command to the firmware.
216  *
217  * The function performs sanity tests, sets the command sequence
218  * number and size, converts the header fields to CPU format before
219  * sending.
220  *
221  * No responses are needed for sleep confirm command.
222  */
223 static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
224 {
225         int ret;
226         struct mwifiex_private *priv;
227         struct mwifiex_opt_sleep_confirm *sleep_cfm_buf =
228                                 (struct mwifiex_opt_sleep_confirm *)
229                                 adapter->sleep_cfm->data;
230         priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
231
232         sleep_cfm_buf->seq_num =
233                 cpu_to_le16((HostCmd_SET_SEQ_NO_BSS_INFO
234                                         (adapter->seq_num, priv->bss_num,
235                                          priv->bss_type)));
236         adapter->seq_num++;
237
238         skb_push(adapter->sleep_cfm, INTF_HEADER_LEN);
239         ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_CMD,
240                                              adapter->sleep_cfm->data,
241                                              adapter->sleep_cfm->len, NULL);
242         skb_pull(adapter->sleep_cfm, INTF_HEADER_LEN);
243
244         if (ret == -1) {
245                 dev_err(adapter->dev, "SLEEP_CFM: failed\n");
246                 adapter->dbg.num_cmd_sleep_cfm_host_to_card_failure++;
247                 return -1;
248         }
249         if (GET_BSS_ROLE(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY))
250                         == MWIFIEX_BSS_ROLE_STA) {
251                 if (!sleep_cfm_buf->resp_ctrl)
252                         /* Response is not needed for sleep
253                            confirm command */
254                         adapter->ps_state = PS_STATE_SLEEP;
255                 else
256                         adapter->ps_state = PS_STATE_SLEEP_CFM;
257
258                 if (!sleep_cfm_buf->resp_ctrl
259                                 && (adapter->is_hs_configured
260                                         && !adapter->sleep_period.period)) {
261                         adapter->pm_wakeup_card_req = true;
262                         mwifiex_hs_activated_event(mwifiex_get_priv(adapter,
263                                                 MWIFIEX_BSS_ROLE_STA), true);
264                 }
265         }
266
267         return ret;
268 }
269
270 /*
271  * This function allocates the command buffers and links them to
272  * the command free queue.
273  *
274  * The driver uses a pre allocated number of command buffers, which
275  * are created at driver initializations and freed at driver cleanup.
276  * Every command needs to obtain a command buffer from this pool before
277  * it can be issued. The command free queue lists the command buffers
278  * currently free to use, while the command pending queue lists the
279  * command buffers already in use and awaiting handling. Command buffers
280  * are returned to the free queue after use.
281  */
282 int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter)
283 {
284         struct cmd_ctrl_node *cmd_array;
285         u32 buf_size;
286         u32 i;
287
288         /* Allocate and initialize struct cmd_ctrl_node */
289         buf_size = sizeof(struct cmd_ctrl_node) * MWIFIEX_NUM_OF_CMD_BUFFER;
290         cmd_array = kzalloc(buf_size, GFP_KERNEL);
291         if (!cmd_array) {
292                 dev_err(adapter->dev, "%s: failed to alloc cmd_array\n",
293                                 __func__);
294                 return -ENOMEM;
295         }
296
297         adapter->cmd_pool = cmd_array;
298         memset(adapter->cmd_pool, 0, buf_size);
299
300         /* Allocate and initialize command buffers */
301         for (i = 0; i < MWIFIEX_NUM_OF_CMD_BUFFER; i++) {
302                 cmd_array[i].skb = dev_alloc_skb(MWIFIEX_SIZE_OF_CMD_BUFFER);
303                 if (!cmd_array[i].skb) {
304                         dev_err(adapter->dev, "ALLOC_CMD_BUF: out of memory\n");
305                         return -1;
306                 }
307         }
308
309         for (i = 0; i < MWIFIEX_NUM_OF_CMD_BUFFER; i++)
310                 mwifiex_insert_cmd_to_free_q(adapter, &cmd_array[i]);
311
312         return 0;
313 }
314
315 /*
316  * This function frees the command buffers.
317  *
318  * The function calls the completion callback for all the command
319  * buffers that still have response buffers associated with them.
320  */
321 int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter)
322 {
323         struct cmd_ctrl_node *cmd_array;
324         u32 i;
325
326         /* Need to check if cmd pool is allocated or not */
327         if (!adapter->cmd_pool) {
328                 dev_dbg(adapter->dev, "info: FREE_CMD_BUF: cmd_pool is null\n");
329                 return 0;
330         }
331
332         cmd_array = adapter->cmd_pool;
333
334         /* Release shared memory buffers */
335         for (i = 0; i < MWIFIEX_NUM_OF_CMD_BUFFER; i++) {
336                 if (cmd_array[i].skb) {
337                         dev_dbg(adapter->dev, "cmd: free cmd buffer %d\n", i);
338                         dev_kfree_skb_any(cmd_array[i].skb);
339                 }
340                 if (!cmd_array[i].resp_skb)
341                         continue;
342                 dev_kfree_skb_any(cmd_array[i].resp_skb);
343         }
344         /* Release struct cmd_ctrl_node */
345         if (adapter->cmd_pool) {
346                 dev_dbg(adapter->dev, "cmd: free cmd pool\n");
347                 kfree(adapter->cmd_pool);
348                 adapter->cmd_pool = NULL;
349         }
350
351         return 0;
352 }
353
354 /*
355  * This function handles events generated by firmware.
356  *
357  * Event body of events received from firmware are not used (though they are
358  * saved), only the event ID is used. Some events are re-invoked by
359  * the driver, with a new event body.
360  *
361  * After processing, the function calls the completion callback
362  * for cleanup.
363  */
364 int mwifiex_process_event(struct mwifiex_adapter *adapter)
365 {
366         int ret;
367         struct mwifiex_private *priv =
368                 mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
369         struct sk_buff *skb = adapter->event_skb;
370         u32 eventcause = adapter->event_cause;
371         struct timeval tstamp;
372         struct mwifiex_rxinfo *rx_info;
373
374         /* Save the last event to debug log */
375         adapter->dbg.last_event_index =
376                 (adapter->dbg.last_event_index + 1) % DBG_CMD_NUM;
377         adapter->dbg.last_event[adapter->dbg.last_event_index] =
378                 (u16) eventcause;
379
380         /* Get BSS number and corresponding priv */
381         priv = mwifiex_get_priv_by_id(adapter, EVENT_GET_BSS_NUM(eventcause),
382                                       EVENT_GET_BSS_TYPE(eventcause));
383         if (!priv)
384                 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
385         /* Clear BSS_NO_BITS from event */
386         eventcause &= EVENT_ID_MASK;
387         adapter->event_cause = eventcause;
388
389         if (skb) {
390                 rx_info = MWIFIEX_SKB_RXCB(skb);
391                 rx_info->bss_index = priv->bss_index;
392         }
393
394         if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE) {
395                 do_gettimeofday(&tstamp);
396                 dev_dbg(adapter->dev, "event: %lu.%lu: cause: %#x\n",
397                        tstamp.tv_sec, tstamp.tv_usec, eventcause);
398         }
399
400         ret = mwifiex_process_sta_event(priv);
401
402         adapter->event_cause = 0;
403         adapter->event_skb = NULL;
404
405         dev_kfree_skb_any(skb);
406
407         return ret;
408 }
409
410 /*
411  * This function is used to send synchronous command to the firmware.
412  *
413  * it allocates a wait queue for the command and wait for the command
414  * response.
415  */
416 int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no,
417                           u16 cmd_action, u32 cmd_oid, void *data_buf)
418 {
419         int ret = 0;
420         struct mwifiex_adapter *adapter = priv->adapter;
421
422         adapter->cmd_wait_q_required = true;
423         adapter->cmd_wait_q.condition = false;
424
425         ret = mwifiex_send_cmd_async(priv, cmd_no, cmd_action, cmd_oid,
426                                      data_buf);
427         if (!ret)
428                 ret = mwifiex_wait_queue_complete(adapter);
429
430         return ret;
431 }
432
433
434 /*
435  * This function prepares a command and asynchronously send it to the firmware.
436  *
437  * Preparation includes -
438  *      - Sanity tests to make sure the card is still present or the FW
439  *        is not reset
440  *      - Getting a new command node from the command free queue
441  *      - Initializing the command node for default parameters
442  *      - Fill up the non-default parameters and buffer pointers
443  *      - Add the command to pending queue
444  */
445 int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
446                            u16 cmd_action, u32 cmd_oid, void *data_buf)
447 {
448         int ret;
449         struct mwifiex_adapter *adapter = priv->adapter;
450         struct cmd_ctrl_node *cmd_node;
451         struct host_cmd_ds_command *cmd_ptr;
452
453         if (!adapter) {
454                 pr_err("PREP_CMD: adapter is NULL\n");
455                 return -1;
456         }
457
458         if (adapter->is_suspended) {
459                 dev_err(adapter->dev, "PREP_CMD: device in suspended state\n");
460                 return -1;
461         }
462
463         if (adapter->surprise_removed) {
464                 dev_err(adapter->dev, "PREP_CMD: card is removed\n");
465                 return -1;
466         }
467
468         if (adapter->hw_status == MWIFIEX_HW_STATUS_RESET) {
469                 if (cmd_no != HostCmd_CMD_FUNC_INIT) {
470                         dev_err(adapter->dev, "PREP_CMD: FW in reset state\n");
471                         return -1;
472                 }
473         }
474
475         /* Get a new command node */
476         cmd_node = mwifiex_get_cmd_node(adapter);
477
478         if (!cmd_node) {
479                 dev_err(adapter->dev, "PREP_CMD: no free cmd node\n");
480                 return -1;
481         }
482
483         /* Initialize the command node */
484         mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, data_buf);
485
486         if (!cmd_node->cmd_skb) {
487                 dev_err(adapter->dev, "PREP_CMD: no free cmd buf\n");
488                 return -1;
489         }
490
491         memset(skb_put(cmd_node->cmd_skb, sizeof(struct host_cmd_ds_command)),
492                0, sizeof(struct host_cmd_ds_command));
493
494         cmd_ptr = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data);
495         cmd_ptr->command = cpu_to_le16(cmd_no);
496         cmd_ptr->result = 0;
497
498         /* Prepare command */
499         if (cmd_no) {
500                 ret = mwifiex_sta_prepare_cmd(priv, cmd_no, cmd_action,
501                                               cmd_oid, data_buf, cmd_ptr);
502         } else {
503                 ret = mwifiex_cmd_host_cmd(priv, cmd_ptr, data_buf);
504                 cmd_node->cmd_flag |= CMD_F_HOSTCMD;
505         }
506
507         /* Return error, since the command preparation failed */
508         if (ret) {
509                 dev_err(adapter->dev, "PREP_CMD: cmd %#x preparation failed\n",
510                                                         cmd_no);
511                 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
512                 return -1;
513         }
514
515         /* Send command */
516         if (cmd_no == HostCmd_CMD_802_11_SCAN)
517                 mwifiex_queue_scan_cmd(priv, cmd_node);
518         else
519                 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
520
521         return ret;
522 }
523
524 /*
525  * This function returns a command to the command free queue.
526  *
527  * The function also calls the completion callback if required, before
528  * cleaning the command node and re-inserting it into the free queue.
529  */
530 void
531 mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter,
532                              struct cmd_ctrl_node *cmd_node)
533 {
534         unsigned long flags;
535
536         if (!cmd_node)
537                 return;
538
539         if (cmd_node->wait_q_enabled)
540                 mwifiex_complete_cmd(adapter);
541         /* Clean the node */
542         mwifiex_clean_cmd_node(adapter, cmd_node);
543
544         /* Insert node into cmd_free_q */
545         spin_lock_irqsave(&adapter->cmd_free_q_lock, flags);
546         list_add_tail(&cmd_node->list, &adapter->cmd_free_q);
547         spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags);
548 }
549
550 /*
551  * This function queues a command to the command pending queue.
552  *
553  * This in effect adds the command to the command list to be executed.
554  * Exit PS command is handled specially, by placing it always to the
555  * front of the command queue.
556  */
557 void
558 mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter,
559                                 struct cmd_ctrl_node *cmd_node, u32 add_tail)
560 {
561         struct host_cmd_ds_command *host_cmd = NULL;
562         u16 command;
563         unsigned long flags;
564
565         host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data);
566         if (!host_cmd) {
567                 dev_err(adapter->dev, "QUEUE_CMD: host_cmd is NULL\n");
568                 return;
569         }
570
571         command = le16_to_cpu(host_cmd->command);
572
573         /* Exit_PS command needs to be queued in the header always. */
574         if (command == HostCmd_CMD_802_11_PS_MODE_ENH) {
575                 struct host_cmd_ds_802_11_ps_mode_enh *pm =
576                         &host_cmd->params.psmode_enh;
577                 if ((le16_to_cpu(pm->action) == DIS_PS)
578                     || (le16_to_cpu(pm->action) == DIS_AUTO_PS)) {
579                         if (adapter->ps_state != PS_STATE_AWAKE)
580                                 add_tail = false;
581                 }
582         }
583
584         spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
585         if (add_tail)
586                 list_add_tail(&cmd_node->list, &adapter->cmd_pending_q);
587         else
588                 list_add(&cmd_node->list, &adapter->cmd_pending_q);
589         spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
590
591         dev_dbg(adapter->dev, "cmd: QUEUE_CMD: cmd=%#x is queued\n", command);
592 }
593
594 /*
595  * This function executes the next command in command pending queue.
596  *
597  * This function will fail if a command is already in processing stage,
598  * otherwise it will dequeue the first command from the command pending
599  * queue and send to the firmware.
600  *
601  * If the device is currently in host sleep mode, any commands, except the
602  * host sleep configuration command will de-activate the host sleep. For PS
603  * mode, the function will put the firmware back to sleep if applicable.
604  */
605 int mwifiex_exec_next_cmd(struct mwifiex_adapter *adapter)
606 {
607         struct mwifiex_private *priv;
608         struct cmd_ctrl_node *cmd_node;
609         int ret = 0;
610         struct host_cmd_ds_command *host_cmd;
611         unsigned long cmd_flags;
612         unsigned long cmd_pending_q_flags;
613
614         /* Check if already in processing */
615         if (adapter->curr_cmd) {
616                 dev_err(adapter->dev, "EXEC_NEXT_CMD: cmd in processing\n");
617                 return -1;
618         }
619
620         spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
621         /* Check if any command is pending */
622         spin_lock_irqsave(&adapter->cmd_pending_q_lock, cmd_pending_q_flags);
623         if (list_empty(&adapter->cmd_pending_q)) {
624                 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
625                                        cmd_pending_q_flags);
626                 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
627                 return 0;
628         }
629         cmd_node = list_first_entry(&adapter->cmd_pending_q,
630                                     struct cmd_ctrl_node, list);
631         spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
632                                cmd_pending_q_flags);
633
634         host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data);
635         priv = cmd_node->priv;
636
637         if (adapter->ps_state != PS_STATE_AWAKE) {
638                 dev_err(adapter->dev, "%s: cannot send cmd in sleep state,"
639                                 " this should not happen\n", __func__);
640                 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
641                 return ret;
642         }
643
644         spin_lock_irqsave(&adapter->cmd_pending_q_lock, cmd_pending_q_flags);
645         list_del(&cmd_node->list);
646         spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
647                                cmd_pending_q_flags);
648
649         spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
650         ret = mwifiex_dnld_cmd_to_fw(priv, cmd_node);
651         priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
652         /* Any command sent to the firmware when host is in sleep
653          * mode should de-configure host sleep. We should skip the
654          * host sleep configuration command itself though
655          */
656         if (priv && (host_cmd->command !=
657              cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH))) {
658                 if (adapter->hs_activated) {
659                         adapter->is_hs_configured = false;
660                         mwifiex_hs_activated_event(priv, false);
661                 }
662         }
663
664         return ret;
665 }
666
667 /*
668  * This function handles the command response.
669  *
670  * After processing, the function cleans the command node and puts
671  * it back to the command free queue.
672  */
673 int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
674 {
675         struct host_cmd_ds_command *resp;
676         struct mwifiex_private *priv =
677                 mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
678         int ret = 0;
679         uint16_t orig_cmdresp_no;
680         uint16_t cmdresp_no;
681         uint16_t cmdresp_result;
682         struct timeval tstamp;
683         unsigned long flags;
684
685         /* Now we got response from FW, cancel the command timer */
686         del_timer(&adapter->cmd_timer);
687
688         if (!adapter->curr_cmd || !adapter->curr_cmd->resp_skb) {
689                 resp = (struct host_cmd_ds_command *) adapter->upld_buf;
690                 dev_err(adapter->dev, "CMD_RESP: NULL curr_cmd, %#x\n",
691                        le16_to_cpu(resp->command));
692                 return -1;
693         }
694
695         adapter->num_cmd_timeout = 0;
696
697         resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data;
698         if (adapter->curr_cmd->cmd_flag & CMD_F_CANCELED) {
699                 dev_err(adapter->dev, "CMD_RESP: %#x been canceled\n",
700                                 le16_to_cpu(resp->command));
701                 mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
702                 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
703                 adapter->curr_cmd = NULL;
704                 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
705                 return -1;
706         }
707
708         if (adapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) {
709                 /* Copy original response back to response buffer */
710                 struct mwifiex_ds_misc_cmd *hostcmd = NULL;
711                 uint16_t size = le16_to_cpu(resp->size);
712                 dev_dbg(adapter->dev, "info: host cmd resp size = %d\n", size);
713                 size = min_t(u16, size, MWIFIEX_SIZE_OF_CMD_BUFFER);
714                 if (adapter->curr_cmd->data_buf) {
715                         hostcmd = (struct mwifiex_ds_misc_cmd *)
716                                                 adapter->curr_cmd->data_buf;
717                         hostcmd->len = size;
718                         memcpy(hostcmd->cmd, (void *) resp, size);
719                 }
720         }
721         orig_cmdresp_no = le16_to_cpu(resp->command);
722
723         /* Get BSS number and corresponding priv */
724         priv = mwifiex_get_priv_by_id(adapter,
725                         HostCmd_GET_BSS_NO(le16_to_cpu(resp->seq_num)),
726                         HostCmd_GET_BSS_TYPE(le16_to_cpu(resp->seq_num)));
727         if (!priv)
728                 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
729         /* Clear RET_BIT from HostCmd */
730         resp->command = cpu_to_le16(orig_cmdresp_no & HostCmd_CMD_ID_MASK);
731
732         cmdresp_no = le16_to_cpu(resp->command);
733         cmdresp_result = le16_to_cpu(resp->result);
734
735         /* Save the last command response to debug log */
736         adapter->dbg.last_cmd_resp_index =
737                 (adapter->dbg.last_cmd_resp_index + 1) % DBG_CMD_NUM;
738         adapter->dbg.last_cmd_resp_id[adapter->dbg.last_cmd_resp_index] =
739                 orig_cmdresp_no;
740
741         do_gettimeofday(&tstamp);
742         dev_dbg(adapter->dev, "cmd: CMD_RESP: (%lu.%lu): 0x%x, result %d,"
743                 " len %d, seqno 0x%x\n",
744                tstamp.tv_sec, tstamp.tv_usec, orig_cmdresp_no, cmdresp_result,
745                le16_to_cpu(resp->size), le16_to_cpu(resp->seq_num));
746
747         if (!(orig_cmdresp_no & HostCmd_RET_BIT)) {
748                 dev_err(adapter->dev, "CMD_RESP: invalid cmd resp\n");
749                 if (adapter->curr_cmd->wait_q_enabled)
750                         adapter->cmd_wait_q.status = -1;
751
752                 mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
753                 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
754                 adapter->curr_cmd = NULL;
755                 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
756                 return -1;
757         }
758
759         if (adapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) {
760                 adapter->curr_cmd->cmd_flag &= ~CMD_F_HOSTCMD;
761                 if ((cmdresp_result == HostCmd_RESULT_OK)
762                     && (cmdresp_no == HostCmd_CMD_802_11_HS_CFG_ENH))
763                         ret = mwifiex_ret_802_11_hs_cfg(priv, resp);
764         } else {
765                 /* handle response */
766                 ret = mwifiex_process_sta_cmdresp(priv, cmdresp_no, resp);
767         }
768
769         /* Check init command response */
770         if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) {
771                 if (ret == -1) {
772                         dev_err(adapter->dev, "%s: cmd %#x failed during "
773                                 "initialization\n", __func__, cmdresp_no);
774                         mwifiex_init_fw_complete(adapter);
775                         return -1;
776                 } else if (adapter->last_init_cmd == cmdresp_no)
777                         adapter->hw_status = MWIFIEX_HW_STATUS_INIT_DONE;
778         }
779
780         if (adapter->curr_cmd) {
781                 if (adapter->curr_cmd->wait_q_enabled && (!ret))
782                         adapter->cmd_wait_q.status = 0;
783                 else if (adapter->curr_cmd->wait_q_enabled && (ret == -1))
784                         adapter->cmd_wait_q.status = -1;
785
786                 /* Clean up and put current command back to cmd_free_q */
787                 mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
788
789                 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
790                 adapter->curr_cmd = NULL;
791                 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
792         }
793
794         return ret;
795 }
796
797 /*
798  * This function handles the timeout of command sending.
799  *
800  * It will re-send the same command again.
801  */
802 void
803 mwifiex_cmd_timeout_func(unsigned long function_context)
804 {
805         struct mwifiex_adapter *adapter =
806                 (struct mwifiex_adapter *) function_context;
807         struct cmd_ctrl_node *cmd_node;
808         struct timeval tstamp;
809
810         adapter->num_cmd_timeout++;
811         adapter->dbg.num_cmd_timeout++;
812         if (!adapter->curr_cmd) {
813                 dev_dbg(adapter->dev, "cmd: empty curr_cmd\n");
814                 return;
815         }
816         cmd_node = adapter->curr_cmd;
817         if (cmd_node->wait_q_enabled)
818                 adapter->cmd_wait_q.status = -ETIMEDOUT;
819
820         if (cmd_node) {
821                 adapter->dbg.timeout_cmd_id =
822                         adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index];
823                 adapter->dbg.timeout_cmd_act =
824                         adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index];
825                 do_gettimeofday(&tstamp);
826                 dev_err(adapter->dev, "%s: Timeout cmd id (%lu.%lu) = %#x,"
827                         " act = %#x\n", __func__,
828                        tstamp.tv_sec, tstamp.tv_usec,
829                        adapter->dbg.timeout_cmd_id,
830                        adapter->dbg.timeout_cmd_act);
831
832                 dev_err(adapter->dev, "num_data_h2c_failure = %d\n",
833                        adapter->dbg.num_tx_host_to_card_failure);
834                 dev_err(adapter->dev, "num_cmd_h2c_failure = %d\n",
835                        adapter->dbg.num_cmd_host_to_card_failure);
836
837                 dev_err(adapter->dev, "num_cmd_timeout = %d\n",
838                        adapter->dbg.num_cmd_timeout);
839                 dev_err(adapter->dev, "num_tx_timeout = %d\n",
840                        adapter->dbg.num_tx_timeout);
841
842                 dev_err(adapter->dev, "last_cmd_index = %d\n",
843                        adapter->dbg.last_cmd_index);
844                 print_hex_dump_bytes("last_cmd_id: ", DUMP_PREFIX_OFFSET,
845                                 adapter->dbg.last_cmd_id, DBG_CMD_NUM);
846                 print_hex_dump_bytes("last_cmd_act: ", DUMP_PREFIX_OFFSET,
847                                 adapter->dbg.last_cmd_act, DBG_CMD_NUM);
848
849                 dev_err(adapter->dev, "last_cmd_resp_index = %d\n",
850                        adapter->dbg.last_cmd_resp_index);
851                 print_hex_dump_bytes("last_cmd_resp_id: ", DUMP_PREFIX_OFFSET,
852                                 adapter->dbg.last_cmd_resp_id, DBG_CMD_NUM);
853
854                 dev_err(adapter->dev, "last_event_index = %d\n",
855                        adapter->dbg.last_event_index);
856                 print_hex_dump_bytes("last_event: ", DUMP_PREFIX_OFFSET,
857                                 adapter->dbg.last_event, DBG_CMD_NUM);
858
859                 dev_err(adapter->dev, "data_sent=%d cmd_sent=%d\n",
860                        adapter->data_sent, adapter->cmd_sent);
861
862                 dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n",
863                                 adapter->ps_mode, adapter->ps_state);
864         }
865         if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
866                 mwifiex_init_fw_complete(adapter);
867 }
868
869 /*
870  * This function cancels all the pending commands.
871  *
872  * The current command, all commands in command pending queue and all scan
873  * commands in scan pending queue are cancelled. All the completion callbacks
874  * are called with failure status to ensure cleanup.
875  */
876 void
877 mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
878 {
879         struct cmd_ctrl_node *cmd_node = NULL, *tmp_node;
880         unsigned long flags;
881
882         /* Cancel current cmd */
883         if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) {
884                 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
885                 adapter->curr_cmd->wait_q_enabled = false;
886                 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
887                 adapter->cmd_wait_q.status = -1;
888                 mwifiex_complete_cmd(adapter);
889         }
890         /* Cancel all pending command */
891         spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
892         list_for_each_entry_safe(cmd_node, tmp_node,
893                                  &adapter->cmd_pending_q, list) {
894                 list_del(&cmd_node->list);
895                 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
896
897                 if (cmd_node->wait_q_enabled) {
898                         adapter->cmd_wait_q.status = -1;
899                         mwifiex_complete_cmd(adapter);
900                         cmd_node->wait_q_enabled = false;
901                 }
902                 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
903                 spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
904         }
905         spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
906
907         /* Cancel all pending scan command */
908         spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
909         list_for_each_entry_safe(cmd_node, tmp_node,
910                                  &adapter->scan_pending_q, list) {
911                 list_del(&cmd_node->list);
912                 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
913
914                 cmd_node->wait_q_enabled = false;
915                 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
916                 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
917         }
918         spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
919
920         spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
921         adapter->scan_processing = false;
922         spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
923 }
924
925 /*
926  * This function cancels all pending commands that matches with
927  * the given IOCTL request.
928  *
929  * Both the current command buffer and the pending command queue are
930  * searched for matching IOCTL request. The completion callback of
931  * the matched command is called with failure status to ensure cleanup.
932  * In case of scan commands, all pending commands in scan pending queue
933  * are cancelled.
934  */
935 void
936 mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
937 {
938         struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL;
939         unsigned long cmd_flags;
940         unsigned long cmd_pending_q_flags;
941         unsigned long scan_pending_q_flags;
942         uint16_t cancel_scan_cmd = false;
943
944         if ((adapter->curr_cmd) &&
945              (adapter->curr_cmd->wait_q_enabled)) {
946                 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
947                 cmd_node = adapter->curr_cmd;
948                 cmd_node->wait_q_enabled = false;
949                 cmd_node->cmd_flag |= CMD_F_CANCELED;
950                 spin_lock_irqsave(&adapter->cmd_pending_q_lock,
951                                   cmd_pending_q_flags);
952                 list_del(&cmd_node->list);
953                 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
954                                        cmd_pending_q_flags);
955                 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
956                 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
957         }
958
959         /* Cancel all pending scan command */
960         spin_lock_irqsave(&adapter->scan_pending_q_lock,
961                           scan_pending_q_flags);
962         list_for_each_entry_safe(cmd_node, tmp_node,
963                                  &adapter->scan_pending_q, list) {
964                 list_del(&cmd_node->list);
965                 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
966                                        scan_pending_q_flags);
967                 cmd_node->wait_q_enabled = false;
968                 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
969                 spin_lock_irqsave(&adapter->scan_pending_q_lock,
970                                   scan_pending_q_flags);
971                 cancel_scan_cmd = true;
972         }
973         spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
974                                scan_pending_q_flags);
975
976         if (cancel_scan_cmd) {
977                 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
978                 adapter->scan_processing = false;
979                 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
980         }
981         adapter->cmd_wait_q.status = -1;
982         mwifiex_complete_cmd(adapter);
983 }
984
985 /*
986  * This function sends the sleep confirm command to firmware, if
987  * possible.
988  *
989  * The sleep confirm command cannot be issued if command response,
990  * data response or event response is awaiting handling, or if we
991  * are in the middle of sending a command, or expecting a command
992  * response.
993  */
994 void
995 mwifiex_check_ps_cond(struct mwifiex_adapter *adapter)
996 {
997         if (!adapter->cmd_sent &&
998             !adapter->curr_cmd && !IS_CARD_RX_RCVD(adapter))
999                 mwifiex_dnld_sleep_confirm_cmd(adapter);
1000         else
1001                 dev_dbg(adapter->dev,
1002                         "cmd: Delay Sleep Confirm (%s%s%s)\n",
1003                        (adapter->cmd_sent) ? "D" : "",
1004                        (adapter->curr_cmd) ? "C" : "",
1005                        (IS_CARD_RX_RCVD(adapter)) ? "R" : "");
1006 }
1007
1008 /*
1009  * This function sends a Host Sleep activated event to applications.
1010  *
1011  * This event is generated by the driver, with a blank event body.
1012  */
1013 void
1014 mwifiex_hs_activated_event(struct mwifiex_private *priv, u8 activated)
1015 {
1016         if (activated) {
1017                 if (priv->adapter->is_hs_configured) {
1018                         priv->adapter->hs_activated = true;
1019                         dev_dbg(priv->adapter->dev, "event: hs_activated\n");
1020                         priv->adapter->hs_activate_wait_q_woken = true;
1021                         wake_up_interruptible(
1022                                 &priv->adapter->hs_activate_wait_q);
1023                 } else {
1024                         dev_dbg(priv->adapter->dev, "event: HS not configured\n");
1025                 }
1026         } else {
1027                 dev_dbg(priv->adapter->dev, "event: hs_deactivated\n");
1028                 priv->adapter->hs_activated = false;
1029         }
1030 }
1031
1032 /*
1033  * This function handles the command response of a Host Sleep configuration
1034  * command.
1035  *
1036  * Handling includes changing the header fields into CPU format
1037  * and setting the current host sleep activation status in driver.
1038  *
1039  * In case host sleep status change, the function generates an event to
1040  * notify the applications.
1041  */
1042 int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv,
1043                               struct host_cmd_ds_command *resp)
1044 {
1045         struct mwifiex_adapter *adapter = priv->adapter;
1046         struct host_cmd_ds_802_11_hs_cfg_enh *phs_cfg =
1047                 &resp->params.opt_hs_cfg;
1048         uint32_t conditions = le32_to_cpu(phs_cfg->params.hs_config.conditions);
1049
1050         if (phs_cfg->action == cpu_to_le16(HS_ACTIVATE)) {
1051                 mwifiex_hs_activated_event(priv, true);
1052                 return 0;
1053         } else {
1054                 dev_dbg(adapter->dev, "cmd: CMD_RESP: HS_CFG cmd reply"
1055                         " result=%#x, conditions=0x%x gpio=0x%x gap=0x%x\n",
1056                         resp->result, conditions,
1057                        phs_cfg->params.hs_config.gpio,
1058                        phs_cfg->params.hs_config.gap);
1059         }
1060         if (conditions != HOST_SLEEP_CFG_CANCEL) {
1061                 adapter->is_hs_configured = true;
1062         } else {
1063                 adapter->is_hs_configured = false;
1064                 if (adapter->hs_activated)
1065                         mwifiex_hs_activated_event(priv, false);
1066         }
1067
1068         return 0;
1069 }
1070
1071 /*
1072  * This function wakes up the adapter and generates a Host Sleep
1073  * cancel event on receiving the power up interrupt.
1074  */
1075 void
1076 mwifiex_process_hs_config(struct mwifiex_adapter *adapter)
1077 {
1078         dev_dbg(adapter->dev, "info: %s: auto cancelling host sleep"
1079                 " since there is interrupt from the firmware\n", __func__);
1080
1081         adapter->if_ops.wakeup(adapter);
1082         adapter->hs_activated = false;
1083         adapter->is_hs_configured = false;
1084         mwifiex_hs_activated_event(mwifiex_get_priv(adapter,
1085                                    MWIFIEX_BSS_ROLE_ANY), false);
1086 }
1087
1088 /*
1089  * This function handles the command response of a sleep confirm command.
1090  *
1091  * The function sets the card state to SLEEP if the response indicates success.
1092  */
1093 void
1094 mwifiex_process_sleep_confirm_resp(struct mwifiex_adapter *adapter,
1095                                    u8 *pbuf, u32 upld_len)
1096 {
1097         struct host_cmd_ds_command *cmd = (struct host_cmd_ds_command *) pbuf;
1098         struct mwifiex_private *priv =
1099                 mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
1100         uint16_t result = le16_to_cpu(cmd->result);
1101         uint16_t command = le16_to_cpu(cmd->command);
1102         uint16_t seq_num = le16_to_cpu(cmd->seq_num);
1103
1104         if (!upld_len) {
1105                 dev_err(adapter->dev, "%s: cmd size is 0\n", __func__);
1106                 return;
1107         }
1108
1109         /* Get BSS number and corresponding priv */
1110         priv = mwifiex_get_priv_by_id(adapter, HostCmd_GET_BSS_NO(seq_num),
1111                                       HostCmd_GET_BSS_TYPE(seq_num));
1112         if (!priv)
1113                 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
1114
1115         /* Update sequence number */
1116         seq_num = HostCmd_GET_SEQ_NO(seq_num);
1117         /* Clear RET_BIT from HostCmd */
1118         command &= HostCmd_CMD_ID_MASK;
1119
1120         if (command != HostCmd_CMD_802_11_PS_MODE_ENH) {
1121                 dev_err(adapter->dev, "%s: received unexpected response for"
1122                         " cmd %x, result = %x\n", __func__, command, result);
1123                 return;
1124         }
1125
1126         if (result) {
1127                 dev_err(adapter->dev, "%s: sleep confirm cmd failed\n",
1128                                                 __func__);
1129                 adapter->pm_wakeup_card_req = false;
1130                 adapter->ps_state = PS_STATE_AWAKE;
1131                 return;
1132         }
1133         adapter->pm_wakeup_card_req = true;
1134         if (adapter->is_hs_configured)
1135                 mwifiex_hs_activated_event(mwifiex_get_priv(adapter,
1136                                            MWIFIEX_BSS_ROLE_ANY), true);
1137         adapter->ps_state = PS_STATE_SLEEP;
1138         cmd->command = cpu_to_le16(command);
1139         cmd->seq_num = cpu_to_le16(seq_num);
1140 }
1141 EXPORT_SYMBOL_GPL(mwifiex_process_sleep_confirm_resp);
1142
1143 /*
1144  * This function prepares an enhanced power mode command.
1145  *
1146  * This function can be used to disable power save or to configure
1147  * power save with auto PS or STA PS or auto deep sleep.
1148  *
1149  * Preparation includes -
1150  *      - Setting command ID, action and proper size
1151  *      - Setting Power Save bitmap, PS parameters TLV, PS mode TLV,
1152  *        auto deep sleep TLV (as required)
1153  *      - Ensuring correct endian-ness
1154  */
1155 int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv,
1156                                struct host_cmd_ds_command *cmd,
1157                                u16 cmd_action, uint16_t ps_bitmap,
1158                                void *data_buf)
1159 {
1160         struct host_cmd_ds_802_11_ps_mode_enh *psmode_enh =
1161                 &cmd->params.psmode_enh;
1162         u8 *tlv;
1163         u16 cmd_size = 0;
1164
1165         cmd->command = cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH);
1166         if (cmd_action == DIS_AUTO_PS) {
1167                 psmode_enh->action = cpu_to_le16(DIS_AUTO_PS);
1168                 psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap);
1169                 cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) +
1170                                 sizeof(psmode_enh->params.ps_bitmap));
1171         } else if (cmd_action == GET_PS) {
1172                 psmode_enh->action = cpu_to_le16(GET_PS);
1173                 psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap);
1174                 cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) +
1175                                 sizeof(psmode_enh->params.ps_bitmap));
1176         } else if (cmd_action == EN_AUTO_PS) {
1177                 psmode_enh->action = cpu_to_le16(EN_AUTO_PS);
1178                 psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap);
1179                 cmd_size = S_DS_GEN + sizeof(psmode_enh->action) +
1180                                 sizeof(psmode_enh->params.ps_bitmap);
1181                 tlv = (u8 *) cmd + cmd_size;
1182                 if (ps_bitmap & BITMAP_STA_PS) {
1183                         struct mwifiex_adapter *adapter = priv->adapter;
1184                         struct mwifiex_ie_types_ps_param *ps_tlv =
1185                                 (struct mwifiex_ie_types_ps_param *) tlv;
1186                         struct mwifiex_ps_param *ps_mode = &ps_tlv->param;
1187                         ps_tlv->header.type = cpu_to_le16(TLV_TYPE_PS_PARAM);
1188                         ps_tlv->header.len = cpu_to_le16(sizeof(*ps_tlv) -
1189                                         sizeof(struct mwifiex_ie_types_header));
1190                         cmd_size += sizeof(*ps_tlv);
1191                         tlv += sizeof(*ps_tlv);
1192                         dev_dbg(adapter->dev, "cmd: PS Command: Enter PS\n");
1193                         ps_mode->null_pkt_interval =
1194                                 cpu_to_le16(adapter->null_pkt_interval);
1195                         ps_mode->multiple_dtims =
1196                                 cpu_to_le16(adapter->multiple_dtim);
1197                         ps_mode->bcn_miss_timeout =
1198                                 cpu_to_le16(adapter->bcn_miss_time_out);
1199                         ps_mode->local_listen_interval =
1200                                 cpu_to_le16(adapter->local_listen_interval);
1201                         ps_mode->adhoc_wake_period =
1202                                 cpu_to_le16(adapter->adhoc_awake_period);
1203                         ps_mode->delay_to_ps =
1204                                 cpu_to_le16(adapter->delay_to_ps);
1205                         ps_mode->mode =
1206                                 cpu_to_le16(adapter->enhanced_ps_mode);
1207
1208                 }
1209                 if (ps_bitmap & BITMAP_AUTO_DS) {
1210                         struct mwifiex_ie_types_auto_ds_param *auto_ds_tlv =
1211                                 (struct mwifiex_ie_types_auto_ds_param *) tlv;
1212                         u16 idletime = 0;
1213
1214                         auto_ds_tlv->header.type =
1215                                 cpu_to_le16(TLV_TYPE_AUTO_DS_PARAM);
1216                         auto_ds_tlv->header.len =
1217                                 cpu_to_le16(sizeof(*auto_ds_tlv) -
1218                                         sizeof(struct mwifiex_ie_types_header));
1219                         cmd_size += sizeof(*auto_ds_tlv);
1220                         tlv += sizeof(*auto_ds_tlv);
1221                         if (data_buf)
1222                                 idletime = ((struct mwifiex_ds_auto_ds *)
1223                                              data_buf)->idle_time;
1224                         dev_dbg(priv->adapter->dev,
1225                                         "cmd: PS Command: Enter Auto Deep Sleep\n");
1226                         auto_ds_tlv->deep_sleep_timeout = cpu_to_le16(idletime);
1227                 }
1228                 cmd->size = cpu_to_le16(cmd_size);
1229         }
1230         return 0;
1231 }
1232
1233 /*
1234  * This function handles the command response of an enhanced power mode
1235  * command.
1236  *
1237  * Handling includes changing the header fields into CPU format
1238  * and setting the current enhanced power mode in driver.
1239  */
1240 int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv,
1241                                struct host_cmd_ds_command *resp,
1242                                void *data_buf)
1243 {
1244         struct mwifiex_adapter *adapter = priv->adapter;
1245         struct host_cmd_ds_802_11_ps_mode_enh *ps_mode =
1246                 &resp->params.psmode_enh;
1247         uint16_t action = le16_to_cpu(ps_mode->action);
1248         uint16_t ps_bitmap = le16_to_cpu(ps_mode->params.ps_bitmap);
1249         uint16_t auto_ps_bitmap =
1250                 le16_to_cpu(ps_mode->params.ps_bitmap);
1251
1252         dev_dbg(adapter->dev, "info: %s: PS_MODE cmd reply result=%#x action=%#X\n",
1253                                         __func__, resp->result, action);
1254         if (action == EN_AUTO_PS) {
1255                 if (auto_ps_bitmap & BITMAP_AUTO_DS) {
1256                         dev_dbg(adapter->dev, "cmd: Enabled auto deep sleep\n");
1257                         priv->adapter->is_deep_sleep = true;
1258                 }
1259                 if (auto_ps_bitmap & BITMAP_STA_PS) {
1260                         dev_dbg(adapter->dev, "cmd: Enabled STA power save\n");
1261                         if (adapter->sleep_period.period)
1262                                 dev_dbg(adapter->dev, "cmd: set to uapsd/pps mode\n");
1263                 }
1264         } else if (action == DIS_AUTO_PS) {
1265                 if (ps_bitmap & BITMAP_AUTO_DS) {
1266                         priv->adapter->is_deep_sleep = false;
1267                         dev_dbg(adapter->dev, "cmd: Disabled auto deep sleep\n");
1268                 }
1269                 if (ps_bitmap & BITMAP_STA_PS) {
1270                         dev_dbg(adapter->dev, "cmd: Disabled STA power save\n");
1271                         if (adapter->sleep_period.period) {
1272                                 adapter->delay_null_pkt = false;
1273                                 adapter->tx_lock_flag = false;
1274                                 adapter->pps_uapsd_mode = false;
1275                         }
1276                 }
1277         } else if (action == GET_PS) {
1278                 if (ps_bitmap & BITMAP_STA_PS)
1279                         adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
1280                 else
1281                         adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
1282
1283                 dev_dbg(adapter->dev, "cmd: ps_bitmap=%#x\n", ps_bitmap);
1284
1285                 if (data_buf) {
1286                         /* This section is for get power save mode */
1287                         struct mwifiex_ds_pm_cfg *pm_cfg =
1288                                         (struct mwifiex_ds_pm_cfg *)data_buf;
1289                         if (ps_bitmap & BITMAP_STA_PS)
1290                                 pm_cfg->param.ps_mode = 1;
1291                         else
1292                                 pm_cfg->param.ps_mode = 0;
1293                 }
1294         }
1295         return 0;
1296 }
1297
1298 /*
1299  * This function prepares command to get hardware specifications.
1300  *
1301  * Preparation includes -
1302  *      - Setting command ID, action and proper size
1303  *      - Setting permanent address parameter
1304  *      - Ensuring correct endian-ness
1305  */
1306 int mwifiex_cmd_get_hw_spec(struct mwifiex_private *priv,
1307                             struct host_cmd_ds_command *cmd)
1308 {
1309         struct host_cmd_ds_get_hw_spec *hw_spec = &cmd->params.hw_spec;
1310
1311         cmd->command = cpu_to_le16(HostCmd_CMD_GET_HW_SPEC);
1312         cmd->size =
1313                 cpu_to_le16(sizeof(struct host_cmd_ds_get_hw_spec) + S_DS_GEN);
1314         memcpy(hw_spec->permanent_addr, priv->curr_addr, ETH_ALEN);
1315
1316         return 0;
1317 }
1318
1319 /*
1320  * This function handles the command response of get hardware
1321  * specifications.
1322  *
1323  * Handling includes changing the header fields into CPU format
1324  * and saving/updating the following parameters in driver -
1325  *      - Firmware capability information
1326  *      - Firmware band settings
1327  *      - Ad-hoc start band and channel
1328  *      - Ad-hoc 11n activation status
1329  *      - Firmware release number
1330  *      - Number of antennas
1331  *      - Hardware address
1332  *      - Hardware interface version
1333  *      - Firmware version
1334  *      - Region code
1335  *      - 11n capabilities
1336  *      - MCS support fields
1337  *      - MP end port
1338  */
1339 int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
1340                             struct host_cmd_ds_command *resp)
1341 {
1342         struct host_cmd_ds_get_hw_spec *hw_spec = &resp->params.hw_spec;
1343         struct mwifiex_adapter *adapter = priv->adapter;
1344         int i;
1345
1346         adapter->fw_cap_info = le32_to_cpu(hw_spec->fw_cap_info);
1347
1348         if (IS_SUPPORT_MULTI_BANDS(adapter))
1349                 adapter->fw_bands = (u8) GET_FW_DEFAULT_BANDS(adapter);
1350         else
1351                 adapter->fw_bands = BAND_B;
1352
1353         adapter->config_bands = adapter->fw_bands;
1354
1355         if (adapter->fw_bands & BAND_A) {
1356                 if (adapter->fw_bands & BAND_GN) {
1357                         adapter->config_bands |= BAND_AN;
1358                         adapter->fw_bands |= BAND_AN;
1359                 }
1360                 if (adapter->fw_bands & BAND_AN) {
1361                         adapter->adhoc_start_band = BAND_A | BAND_AN;
1362                         adapter->adhoc_11n_enabled = true;
1363                 } else {
1364                         adapter->adhoc_start_band = BAND_A;
1365                 }
1366                 priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL_A;
1367         } else if (adapter->fw_bands & BAND_GN) {
1368                 adapter->adhoc_start_band = BAND_G | BAND_B | BAND_GN;
1369                 priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
1370                 adapter->adhoc_11n_enabled = true;
1371         } else if (adapter->fw_bands & BAND_G) {
1372                 adapter->adhoc_start_band = BAND_G | BAND_B;
1373                 priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
1374         } else if (adapter->fw_bands & BAND_B) {
1375                 adapter->adhoc_start_band = BAND_B;
1376                 priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
1377         }
1378
1379         adapter->fw_release_number = le32_to_cpu(hw_spec->fw_release_number);
1380         adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna);
1381
1382         dev_dbg(adapter->dev, "info: GET_HW_SPEC: fw_release_number- %#x\n",
1383                adapter->fw_release_number);
1384         dev_dbg(adapter->dev, "info: GET_HW_SPEC: permanent addr: %pM\n",
1385                                         hw_spec->permanent_addr);
1386         dev_dbg(adapter->dev, "info: GET_HW_SPEC: hw_if_version=%#x  version=%#x\n",
1387                 le16_to_cpu(hw_spec->hw_if_version),
1388                le16_to_cpu(hw_spec->version));
1389
1390         if (priv->curr_addr[0] == 0xff)
1391                 memmove(priv->curr_addr, hw_spec->permanent_addr, ETH_ALEN);
1392
1393         adapter->region_code = le16_to_cpu(hw_spec->region_code);
1394
1395         for (i = 0; i < MWIFIEX_MAX_REGION_CODE; i++)
1396                 /* Use the region code to search for the index */
1397                 if (adapter->region_code == region_code_index[i])
1398                         break;
1399
1400         /* If it's unidentified region code, use the default (USA) */
1401         if (i >= MWIFIEX_MAX_REGION_CODE) {
1402                 adapter->region_code = 0x10;
1403                 dev_dbg(adapter->dev, "cmd: unknown region code, use default (USA)\n");
1404         }
1405
1406         adapter->hw_dot_11n_dev_cap = le32_to_cpu(hw_spec->dot_11n_dev_cap);
1407         adapter->hw_dev_mcs_support = hw_spec->dev_mcs_support;
1408
1409         if (adapter->if_ops.update_mp_end_port)
1410                 adapter->if_ops.update_mp_end_port(adapter,
1411                                         le16_to_cpu(hw_spec->mp_end_port));
1412
1413         return 0;
1414 }