]> Pileus Git - ~andy/linux/blob - drivers/net/wireless/libertas_tf/cmd.c
Merge branch 'next/devel2' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/linux...
[~andy/linux] / drivers / net / wireless / libertas_tf / cmd.c
1 /*
2  *  Copyright (C) 2008, cozybit Inc.
3  *  Copyright (C) 2003-2006, Marvell International Ltd.
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or (at
8  *  your option) any later version.
9  */
10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11
12 #include <linux/hardirq.h>
13 #include <linux/slab.h>
14
15 #include "libertas_tf.h"
16
17 static const struct channel_range channel_ranges[] = {
18         { LBTF_REGDOMAIN_US,            1, 12 },
19         { LBTF_REGDOMAIN_CA,            1, 12 },
20         { LBTF_REGDOMAIN_EU,            1, 14 },
21         { LBTF_REGDOMAIN_JP,            1, 14 },
22         { LBTF_REGDOMAIN_SP,            1, 14 },
23         { LBTF_REGDOMAIN_FR,            1, 14 },
24 };
25
26 static u16 lbtf_region_code_to_index[MRVDRV_MAX_REGION_CODE] =
27 {
28         LBTF_REGDOMAIN_US, LBTF_REGDOMAIN_CA, LBTF_REGDOMAIN_EU,
29         LBTF_REGDOMAIN_SP, LBTF_REGDOMAIN_FR, LBTF_REGDOMAIN_JP,
30 };
31
32 static struct cmd_ctrl_node *lbtf_get_cmd_ctrl_node(struct lbtf_private *priv);
33
34
35 /**
36  *  lbtf_cmd_copyback - Simple callback that copies response back into command
37  *
38  *  @priv       A pointer to struct lbtf_private structure
39  *  @extra      A pointer to the original command structure for which
40  *              'resp' is a response
41  *  @resp       A pointer to the command response
42  *
43  *  Returns: 0 on success, error on failure
44  */
45 int lbtf_cmd_copyback(struct lbtf_private *priv, unsigned long extra,
46                      struct cmd_header *resp)
47 {
48         struct cmd_header *buf = (void *)extra;
49         uint16_t copy_len;
50
51         copy_len = min(le16_to_cpu(buf->size), le16_to_cpu(resp->size));
52         memcpy(buf, resp, copy_len);
53         return 0;
54 }
55 EXPORT_SYMBOL_GPL(lbtf_cmd_copyback);
56
57 #define CHAN_TO_IDX(chan) ((chan) - 1)
58
59 static void lbtf_geo_init(struct lbtf_private *priv)
60 {
61         const struct channel_range *range = channel_ranges;
62         u8 ch;
63         int i;
64
65         for (i = 0; i < ARRAY_SIZE(channel_ranges); i++)
66                 if (channel_ranges[i].regdomain == priv->regioncode) {
67                         range = &channel_ranges[i];
68                         break;
69                 }
70
71         for (ch = priv->range.start; ch < priv->range.end; ch++)
72                 priv->channels[CHAN_TO_IDX(ch)].flags = 0;
73 }
74
75 /**
76  *  lbtf_update_hw_spec: Updates the hardware details.
77  *
78  *  @priv       A pointer to struct lbtf_private structure
79  *
80  *  Returns: 0 on success, error on failure
81  */
82 int lbtf_update_hw_spec(struct lbtf_private *priv)
83 {
84         struct cmd_ds_get_hw_spec cmd;
85         int ret = -1;
86         u32 i;
87
88         lbtf_deb_enter(LBTF_DEB_CMD);
89
90         memset(&cmd, 0, sizeof(cmd));
91         cmd.hdr.size = cpu_to_le16(sizeof(cmd));
92         memcpy(cmd.permanentaddr, priv->current_addr, ETH_ALEN);
93         ret = lbtf_cmd_with_response(priv, CMD_GET_HW_SPEC, &cmd);
94         if (ret)
95                 goto out;
96
97         priv->fwcapinfo = le32_to_cpu(cmd.fwcapinfo);
98
99         /* The firmware release is in an interesting format: the patch
100          * level is in the most significant nibble ... so fix that: */
101         priv->fwrelease = le32_to_cpu(cmd.fwrelease);
102         priv->fwrelease = (priv->fwrelease << 8) |
103                 (priv->fwrelease >> 24 & 0xff);
104
105         printk(KERN_INFO "libertastf: %pM, fw %u.%u.%up%u, cap 0x%08x\n",
106                 cmd.permanentaddr,
107                 priv->fwrelease >> 24 & 0xff,
108                 priv->fwrelease >> 16 & 0xff,
109                 priv->fwrelease >>  8 & 0xff,
110                 priv->fwrelease       & 0xff,
111                 priv->fwcapinfo);
112         lbtf_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n",
113                     cmd.hwifversion, cmd.version);
114
115         /* Clamp region code to 8-bit since FW spec indicates that it should
116          * only ever be 8-bit, even though the field size is 16-bit.  Some
117          * firmware returns non-zero high 8 bits here.
118          */
119         priv->regioncode = le16_to_cpu(cmd.regioncode) & 0xFF;
120
121         for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
122                 /* use the region code to search for the index */
123                 if (priv->regioncode == lbtf_region_code_to_index[i])
124                         break;
125         }
126
127         /* if it's unidentified region code, use the default (USA) */
128         if (i >= MRVDRV_MAX_REGION_CODE) {
129                 priv->regioncode = 0x10;
130                 pr_info("unidentified region code; using the default (USA)\n");
131         }
132
133         if (priv->current_addr[0] == 0xff)
134                 memmove(priv->current_addr, cmd.permanentaddr, ETH_ALEN);
135
136         SET_IEEE80211_PERM_ADDR(priv->hw, priv->current_addr);
137
138         lbtf_geo_init(priv);
139 out:
140         lbtf_deb_leave(LBTF_DEB_CMD);
141         return ret;
142 }
143
144 /**
145  *  lbtf_set_channel: Set the radio channel
146  *
147  *  @priv       A pointer to struct lbtf_private structure
148  *  @channel    The desired channel, or 0 to clear a locked channel
149  *
150  *  Returns: 0 on success, error on failure
151  */
152 int lbtf_set_channel(struct lbtf_private *priv, u8 channel)
153 {
154         int ret = 0;
155         struct cmd_ds_802_11_rf_channel cmd;
156
157         lbtf_deb_enter(LBTF_DEB_CMD);
158
159         cmd.hdr.size = cpu_to_le16(sizeof(cmd));
160         cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_SET);
161         cmd.channel = cpu_to_le16(channel);
162
163         ret = lbtf_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd);
164         lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", ret);
165         return ret;
166 }
167
168 int lbtf_beacon_set(struct lbtf_private *priv, struct sk_buff *beacon)
169 {
170         struct cmd_ds_802_11_beacon_set cmd;
171         int size;
172
173         lbtf_deb_enter(LBTF_DEB_CMD);
174
175         if (beacon->len > MRVL_MAX_BCN_SIZE) {
176                 lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", -1);
177                 return -1;
178         }
179         size =  sizeof(cmd) - sizeof(cmd.beacon) + beacon->len;
180         cmd.hdr.size = cpu_to_le16(size);
181         cmd.len = cpu_to_le16(beacon->len);
182         memcpy(cmd.beacon, (u8 *) beacon->data, beacon->len);
183
184         lbtf_cmd_async(priv, CMD_802_11_BEACON_SET, &cmd.hdr, size);
185
186         lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", 0);
187         return 0;
188 }
189
190 int lbtf_beacon_ctrl(struct lbtf_private *priv, bool beacon_enable,
191                      int beacon_int)
192 {
193         struct cmd_ds_802_11_beacon_control cmd;
194         lbtf_deb_enter(LBTF_DEB_CMD);
195
196         cmd.hdr.size = cpu_to_le16(sizeof(cmd));
197         cmd.action = cpu_to_le16(CMD_ACT_SET);
198         cmd.beacon_enable = cpu_to_le16(beacon_enable);
199         cmd.beacon_period = cpu_to_le16(beacon_int);
200
201         lbtf_cmd_async(priv, CMD_802_11_BEACON_CTRL, &cmd.hdr, sizeof(cmd));
202
203         lbtf_deb_leave(LBTF_DEB_CMD);
204         return 0;
205 }
206
207 static void lbtf_queue_cmd(struct lbtf_private *priv,
208                           struct cmd_ctrl_node *cmdnode)
209 {
210         unsigned long flags;
211         lbtf_deb_enter(LBTF_DEB_HOST);
212
213         if (!cmdnode) {
214                 lbtf_deb_host("QUEUE_CMD: cmdnode is NULL\n");
215                 goto qcmd_done;
216         }
217
218         if (!cmdnode->cmdbuf->size) {
219                 lbtf_deb_host("DNLD_CMD: cmd size is zero\n");
220                 goto qcmd_done;
221         }
222
223         cmdnode->result = 0;
224         spin_lock_irqsave(&priv->driver_lock, flags);
225         list_add_tail(&cmdnode->list, &priv->cmdpendingq);
226         spin_unlock_irqrestore(&priv->driver_lock, flags);
227
228         lbtf_deb_host("QUEUE_CMD: inserted command 0x%04x into cmdpendingq\n",
229                      le16_to_cpu(cmdnode->cmdbuf->command));
230
231 qcmd_done:
232         lbtf_deb_leave(LBTF_DEB_HOST);
233 }
234
235 static void lbtf_submit_command(struct lbtf_private *priv,
236                                struct cmd_ctrl_node *cmdnode)
237 {
238         unsigned long flags;
239         struct cmd_header *cmd;
240         uint16_t cmdsize;
241         uint16_t command;
242         int timeo = 5 * HZ;
243         int ret;
244
245         lbtf_deb_enter(LBTF_DEB_HOST);
246
247         cmd = cmdnode->cmdbuf;
248
249         spin_lock_irqsave(&priv->driver_lock, flags);
250         priv->cur_cmd = cmdnode;
251         cmdsize = le16_to_cpu(cmd->size);
252         command = le16_to_cpu(cmd->command);
253
254         lbtf_deb_cmd("DNLD_CMD: command 0x%04x, seq %d, size %d\n",
255                      command, le16_to_cpu(cmd->seqnum), cmdsize);
256         lbtf_deb_hex(LBTF_DEB_CMD, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize);
257
258         ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize);
259         spin_unlock_irqrestore(&priv->driver_lock, flags);
260
261         if (ret) {
262                 pr_info("DNLD_CMD: hw_host_to_card failed: %d\n", ret);
263                 /* Let the timer kick in and retry, and potentially reset
264                    the whole thing if the condition persists */
265                 timeo = HZ;
266         }
267
268         /* Setup the timer after transmit command */
269         mod_timer(&priv->command_timer, jiffies + timeo);
270
271         lbtf_deb_leave(LBTF_DEB_HOST);
272 }
273
274 /**
275  *  This function inserts command node to cmdfreeq
276  *  after cleans it. Requires priv->driver_lock held.
277  */
278 static void __lbtf_cleanup_and_insert_cmd(struct lbtf_private *priv,
279                                          struct cmd_ctrl_node *cmdnode)
280 {
281         lbtf_deb_enter(LBTF_DEB_HOST);
282
283         if (!cmdnode)
284                 goto cl_ins_out;
285
286         cmdnode->callback = NULL;
287         cmdnode->callback_arg = 0;
288
289         memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE);
290
291         list_add_tail(&cmdnode->list, &priv->cmdfreeq);
292
293 cl_ins_out:
294         lbtf_deb_leave(LBTF_DEB_HOST);
295 }
296
297 static void lbtf_cleanup_and_insert_cmd(struct lbtf_private *priv,
298         struct cmd_ctrl_node *ptempcmd)
299 {
300         unsigned long flags;
301
302         spin_lock_irqsave(&priv->driver_lock, flags);
303         __lbtf_cleanup_and_insert_cmd(priv, ptempcmd);
304         spin_unlock_irqrestore(&priv->driver_lock, flags);
305 }
306
307 void lbtf_complete_command(struct lbtf_private *priv, struct cmd_ctrl_node *cmd,
308                           int result)
309 {
310         cmd->result = result;
311         cmd->cmdwaitqwoken = 1;
312         wake_up_interruptible(&cmd->cmdwait_q);
313
314         if (!cmd->callback)
315                 __lbtf_cleanup_and_insert_cmd(priv, cmd);
316         priv->cur_cmd = NULL;
317 }
318
319 int lbtf_cmd_set_mac_multicast_addr(struct lbtf_private *priv)
320 {
321         struct cmd_ds_mac_multicast_addr cmd;
322
323         lbtf_deb_enter(LBTF_DEB_CMD);
324
325         cmd.hdr.size = cpu_to_le16(sizeof(cmd));
326         cmd.action = cpu_to_le16(CMD_ACT_SET);
327
328         cmd.nr_of_adrs = cpu_to_le16((u16) priv->nr_of_multicastmacaddr);
329
330         lbtf_deb_cmd("MULTICAST_ADR: setting %d addresses\n", cmd.nr_of_adrs);
331
332         memcpy(cmd.maclist, priv->multicastlist,
333                priv->nr_of_multicastmacaddr * ETH_ALEN);
334
335         lbtf_cmd_async(priv, CMD_MAC_MULTICAST_ADR, &cmd.hdr, sizeof(cmd));
336
337         lbtf_deb_leave(LBTF_DEB_CMD);
338         return 0;
339 }
340
341 void lbtf_set_mode(struct lbtf_private *priv, enum lbtf_mode mode)
342 {
343         struct cmd_ds_set_mode cmd;
344         lbtf_deb_enter(LBTF_DEB_WEXT);
345
346         cmd.hdr.size = cpu_to_le16(sizeof(cmd));
347         cmd.mode = cpu_to_le16(mode);
348         lbtf_deb_wext("Switching to mode: 0x%x\n", mode);
349         lbtf_cmd_async(priv, CMD_802_11_SET_MODE, &cmd.hdr, sizeof(cmd));
350
351         lbtf_deb_leave(LBTF_DEB_WEXT);
352 }
353
354 void lbtf_set_bssid(struct lbtf_private *priv, bool activate, const u8 *bssid)
355 {
356         struct cmd_ds_set_bssid cmd;
357         lbtf_deb_enter(LBTF_DEB_CMD);
358
359         cmd.hdr.size = cpu_to_le16(sizeof(cmd));
360         cmd.activate = activate ? 1 : 0;
361         if (activate)
362                 memcpy(cmd.bssid, bssid, ETH_ALEN);
363
364         lbtf_cmd_async(priv, CMD_802_11_SET_BSSID, &cmd.hdr, sizeof(cmd));
365         lbtf_deb_leave(LBTF_DEB_CMD);
366 }
367
368 int lbtf_set_mac_address(struct lbtf_private *priv, uint8_t *mac_addr)
369 {
370         struct cmd_ds_802_11_mac_address cmd;
371         lbtf_deb_enter(LBTF_DEB_CMD);
372
373         cmd.hdr.size = cpu_to_le16(sizeof(cmd));
374         cmd.action = cpu_to_le16(CMD_ACT_SET);
375
376         memcpy(cmd.macadd, mac_addr, ETH_ALEN);
377
378         lbtf_cmd_async(priv, CMD_802_11_MAC_ADDRESS, &cmd.hdr, sizeof(cmd));
379         lbtf_deb_leave(LBTF_DEB_CMD);
380         return 0;
381 }
382
383 int lbtf_set_radio_control(struct lbtf_private *priv)
384 {
385         int ret = 0;
386         struct cmd_ds_802_11_radio_control cmd;
387
388         lbtf_deb_enter(LBTF_DEB_CMD);
389
390         cmd.hdr.size = cpu_to_le16(sizeof(cmd));
391         cmd.action = cpu_to_le16(CMD_ACT_SET);
392
393         switch (priv->preamble) {
394         case CMD_TYPE_SHORT_PREAMBLE:
395                 cmd.control = cpu_to_le16(SET_SHORT_PREAMBLE);
396                 break;
397
398         case CMD_TYPE_LONG_PREAMBLE:
399                 cmd.control = cpu_to_le16(SET_LONG_PREAMBLE);
400                 break;
401
402         case CMD_TYPE_AUTO_PREAMBLE:
403         default:
404                 cmd.control = cpu_to_le16(SET_AUTO_PREAMBLE);
405                 break;
406         }
407
408         if (priv->radioon)
409                 cmd.control |= cpu_to_le16(TURN_ON_RF);
410         else
411                 cmd.control &= cpu_to_le16(~TURN_ON_RF);
412
413         lbtf_deb_cmd("RADIO_SET: radio %d, preamble %d\n", priv->radioon,
414                     priv->preamble);
415
416         ret = lbtf_cmd_with_response(priv, CMD_802_11_RADIO_CONTROL, &cmd);
417
418         lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", ret);
419         return ret;
420 }
421
422 void lbtf_set_mac_control(struct lbtf_private *priv)
423 {
424         struct cmd_ds_mac_control cmd;
425         lbtf_deb_enter(LBTF_DEB_CMD);
426
427         cmd.hdr.size = cpu_to_le16(sizeof(cmd));
428         cmd.action = cpu_to_le16(priv->mac_control);
429         cmd.reserved = 0;
430
431         lbtf_cmd_async(priv, CMD_MAC_CONTROL,
432                 &cmd.hdr, sizeof(cmd));
433
434         lbtf_deb_leave(LBTF_DEB_CMD);
435 }
436
437 /**
438  *  lbtf_allocate_cmd_buffer - Allocates cmd buffer, links it to free cmd queue
439  *
440  *  @priv       A pointer to struct lbtf_private structure
441  *
442  *  Returns: 0 on success.
443  */
444 int lbtf_allocate_cmd_buffer(struct lbtf_private *priv)
445 {
446         int ret = 0;
447         u32 bufsize;
448         u32 i;
449         struct cmd_ctrl_node *cmdarray;
450
451         lbtf_deb_enter(LBTF_DEB_HOST);
452
453         /* Allocate and initialize the command array */
454         bufsize = sizeof(struct cmd_ctrl_node) * LBS_NUM_CMD_BUFFERS;
455         cmdarray = kzalloc(bufsize, GFP_KERNEL);
456         if (!cmdarray) {
457                 lbtf_deb_host("ALLOC_CMD_BUF: tempcmd_array is NULL\n");
458                 ret = -1;
459                 goto done;
460         }
461         priv->cmd_array = cmdarray;
462
463         /* Allocate and initialize each command buffer in the command array */
464         for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
465                 cmdarray[i].cmdbuf = kzalloc(LBS_CMD_BUFFER_SIZE, GFP_KERNEL);
466                 if (!cmdarray[i].cmdbuf) {
467                         lbtf_deb_host("ALLOC_CMD_BUF: ptempvirtualaddr is NULL\n");
468                         ret = -1;
469                         goto done;
470                 }
471         }
472
473         for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
474                 init_waitqueue_head(&cmdarray[i].cmdwait_q);
475                 lbtf_cleanup_and_insert_cmd(priv, &cmdarray[i]);
476         }
477
478         ret = 0;
479
480 done:
481         lbtf_deb_leave_args(LBTF_DEB_HOST, "ret %d", ret);
482         return ret;
483 }
484
485 /**
486  *  lbtf_free_cmd_buffer - Frees the cmd buffer.
487  *
488  *  @priv       A pointer to struct lbtf_private structure
489  *
490  *  Returns: 0
491  */
492 int lbtf_free_cmd_buffer(struct lbtf_private *priv)
493 {
494         struct cmd_ctrl_node *cmdarray;
495         unsigned int i;
496
497         lbtf_deb_enter(LBTF_DEB_HOST);
498
499         /* need to check if cmd array is allocated or not */
500         if (priv->cmd_array == NULL) {
501                 lbtf_deb_host("FREE_CMD_BUF: cmd_array is NULL\n");
502                 goto done;
503         }
504
505         cmdarray = priv->cmd_array;
506
507         /* Release shared memory buffers */
508         for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
509                 kfree(cmdarray[i].cmdbuf);
510                 cmdarray[i].cmdbuf = NULL;
511         }
512
513         /* Release cmd_ctrl_node */
514         kfree(priv->cmd_array);
515         priv->cmd_array = NULL;
516
517 done:
518         lbtf_deb_leave(LBTF_DEB_HOST);
519         return 0;
520 }
521
522 /**
523  *  lbtf_get_cmd_ctrl_node - Gets free cmd node from free cmd queue.
524  *
525  *  @priv               A pointer to struct lbtf_private structure
526  *
527  *  Returns: pointer to a struct cmd_ctrl_node or NULL if none available.
528  */
529 static struct cmd_ctrl_node *lbtf_get_cmd_ctrl_node(struct lbtf_private *priv)
530 {
531         struct cmd_ctrl_node *tempnode;
532         unsigned long flags;
533
534         lbtf_deb_enter(LBTF_DEB_HOST);
535
536         if (!priv)
537                 return NULL;
538
539         spin_lock_irqsave(&priv->driver_lock, flags);
540
541         if (!list_empty(&priv->cmdfreeq)) {
542                 tempnode = list_first_entry(&priv->cmdfreeq,
543                                             struct cmd_ctrl_node, list);
544                 list_del(&tempnode->list);
545         } else {
546                 lbtf_deb_host("GET_CMD_NODE: cmd_ctrl_node is not available\n");
547                 tempnode = NULL;
548         }
549
550         spin_unlock_irqrestore(&priv->driver_lock, flags);
551
552         lbtf_deb_leave(LBTF_DEB_HOST);
553         return tempnode;
554 }
555
556 /**
557  *  lbtf_execute_next_command: execute next command in cmd pending queue.
558  *
559  *  @priv     A pointer to struct lbtf_private structure
560  *
561  *  Returns: 0 on success.
562  */
563 int lbtf_execute_next_command(struct lbtf_private *priv)
564 {
565         struct cmd_ctrl_node *cmdnode = NULL;
566         struct cmd_header *cmd;
567         unsigned long flags;
568         int ret = 0;
569
570         /* Debug group is lbtf_deb_THREAD and not lbtf_deb_HOST, because the
571          * only caller to us is lbtf_thread() and we get even when a
572          * data packet is received */
573         lbtf_deb_enter(LBTF_DEB_THREAD);
574
575         spin_lock_irqsave(&priv->driver_lock, flags);
576
577         if (priv->cur_cmd) {
578                 pr_alert("EXEC_NEXT_CMD: already processing command!\n");
579                 spin_unlock_irqrestore(&priv->driver_lock, flags);
580                 ret = -1;
581                 goto done;
582         }
583
584         if (!list_empty(&priv->cmdpendingq)) {
585                 cmdnode = list_first_entry(&priv->cmdpendingq,
586                                            struct cmd_ctrl_node, list);
587         }
588
589         if (cmdnode) {
590                 cmd = cmdnode->cmdbuf;
591
592                 list_del(&cmdnode->list);
593                 lbtf_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n",
594                             le16_to_cpu(cmd->command));
595                 spin_unlock_irqrestore(&priv->driver_lock, flags);
596                 lbtf_submit_command(priv, cmdnode);
597         } else
598                 spin_unlock_irqrestore(&priv->driver_lock, flags);
599
600         ret = 0;
601 done:
602         lbtf_deb_leave(LBTF_DEB_THREAD);
603         return ret;
604 }
605
606 static struct cmd_ctrl_node *__lbtf_cmd_async(struct lbtf_private *priv,
607         uint16_t command, struct cmd_header *in_cmd, int in_cmd_size,
608         int (*callback)(struct lbtf_private *, unsigned long,
609                         struct cmd_header *),
610         unsigned long callback_arg)
611 {
612         struct cmd_ctrl_node *cmdnode;
613
614         lbtf_deb_enter(LBTF_DEB_HOST);
615
616         if (priv->surpriseremoved) {
617                 lbtf_deb_host("PREP_CMD: card removed\n");
618                 cmdnode = ERR_PTR(-ENOENT);
619                 goto done;
620         }
621
622         cmdnode = lbtf_get_cmd_ctrl_node(priv);
623         if (cmdnode == NULL) {
624                 lbtf_deb_host("PREP_CMD: cmdnode is NULL\n");
625
626                 /* Wake up main thread to execute next command */
627                 queue_work(lbtf_wq, &priv->cmd_work);
628                 cmdnode = ERR_PTR(-ENOBUFS);
629                 goto done;
630         }
631
632         cmdnode->callback = callback;
633         cmdnode->callback_arg = callback_arg;
634
635         /* Copy the incoming command to the buffer */
636         memcpy(cmdnode->cmdbuf, in_cmd, in_cmd_size);
637
638         /* Set sequence number, clean result, move to buffer */
639         priv->seqnum++;
640         cmdnode->cmdbuf->command = cpu_to_le16(command);
641         cmdnode->cmdbuf->size    = cpu_to_le16(in_cmd_size);
642         cmdnode->cmdbuf->seqnum  = cpu_to_le16(priv->seqnum);
643         cmdnode->cmdbuf->result  = 0;
644
645         lbtf_deb_host("PREP_CMD: command 0x%04x\n", command);
646
647         cmdnode->cmdwaitqwoken = 0;
648         lbtf_queue_cmd(priv, cmdnode);
649         queue_work(lbtf_wq, &priv->cmd_work);
650
651  done:
652         lbtf_deb_leave_args(LBTF_DEB_HOST, "ret %p", cmdnode);
653         return cmdnode;
654 }
655
656 void lbtf_cmd_async(struct lbtf_private *priv, uint16_t command,
657         struct cmd_header *in_cmd, int in_cmd_size)
658 {
659         lbtf_deb_enter(LBTF_DEB_CMD);
660         __lbtf_cmd_async(priv, command, in_cmd, in_cmd_size, NULL, 0);
661         lbtf_deb_leave(LBTF_DEB_CMD);
662 }
663
664 int __lbtf_cmd(struct lbtf_private *priv, uint16_t command,
665               struct cmd_header *in_cmd, int in_cmd_size,
666               int (*callback)(struct lbtf_private *,
667                               unsigned long, struct cmd_header *),
668               unsigned long callback_arg)
669 {
670         struct cmd_ctrl_node *cmdnode;
671         unsigned long flags;
672         int ret = 0;
673
674         lbtf_deb_enter(LBTF_DEB_HOST);
675
676         cmdnode = __lbtf_cmd_async(priv, command, in_cmd, in_cmd_size,
677                                   callback, callback_arg);
678         if (IS_ERR(cmdnode)) {
679                 ret = PTR_ERR(cmdnode);
680                 goto done;
681         }
682
683         might_sleep();
684         ret = wait_event_interruptible(cmdnode->cmdwait_q,
685                                        cmdnode->cmdwaitqwoken);
686         if (ret) {
687                 pr_info("PREP_CMD: command 0x%04x interrupted by signal: %d\n",
688                             command, ret);
689                 goto done;
690         }
691
692         spin_lock_irqsave(&priv->driver_lock, flags);
693         ret = cmdnode->result;
694         if (ret)
695                 pr_info("PREP_CMD: command 0x%04x failed: %d\n",
696                             command, ret);
697
698         __lbtf_cleanup_and_insert_cmd(priv, cmdnode);
699         spin_unlock_irqrestore(&priv->driver_lock, flags);
700
701 done:
702         lbtf_deb_leave_args(LBTF_DEB_HOST, "ret %d", ret);
703         return ret;
704 }
705 EXPORT_SYMBOL_GPL(__lbtf_cmd);
706
707 /* Call holding driver_lock */
708 void lbtf_cmd_response_rx(struct lbtf_private *priv)
709 {
710         priv->cmd_response_rxed = 1;
711         queue_work(lbtf_wq, &priv->cmd_work);
712 }
713 EXPORT_SYMBOL_GPL(lbtf_cmd_response_rx);
714
715 int lbtf_process_rx_command(struct lbtf_private *priv)
716 {
717         uint16_t respcmd, curcmd;
718         struct cmd_header *resp;
719         int ret = 0;
720         unsigned long flags;
721         uint16_t result;
722
723         lbtf_deb_enter(LBTF_DEB_CMD);
724
725         mutex_lock(&priv->lock);
726         spin_lock_irqsave(&priv->driver_lock, flags);
727
728         if (!priv->cur_cmd) {
729                 ret = -1;
730                 spin_unlock_irqrestore(&priv->driver_lock, flags);
731                 goto done;
732         }
733
734         resp = (void *)priv->cmd_resp_buff;
735         curcmd = le16_to_cpu(priv->cur_cmd->cmdbuf->command);
736         respcmd = le16_to_cpu(resp->command);
737         result = le16_to_cpu(resp->result);
738
739         if (net_ratelimit())
740                 pr_info("libertastf: cmd response 0x%04x, seq %d, size %d\n",
741                         respcmd, le16_to_cpu(resp->seqnum),
742                         le16_to_cpu(resp->size));
743
744         if (resp->seqnum != priv->cur_cmd->cmdbuf->seqnum) {
745                 spin_unlock_irqrestore(&priv->driver_lock, flags);
746                 ret = -1;
747                 goto done;
748         }
749         if (respcmd != CMD_RET(curcmd)) {
750                 spin_unlock_irqrestore(&priv->driver_lock, flags);
751                 ret = -1;
752                 goto done;
753         }
754
755         if (resp->result == cpu_to_le16(0x0004)) {
756                 /* 0x0004 means -EAGAIN. Drop the response, let it time out
757                    and be resubmitted */
758                 spin_unlock_irqrestore(&priv->driver_lock, flags);
759                 ret = -1;
760                 goto done;
761         }
762
763         /* Now we got response from FW, cancel the command timer */
764         del_timer(&priv->command_timer);
765         priv->cmd_timed_out = 0;
766         if (priv->nr_retries)
767                 priv->nr_retries = 0;
768
769         /* If the command is not successful, cleanup and return failure */
770         if ((result != 0 || !(respcmd & 0x8000))) {
771                 /*
772                  * Handling errors here
773                  */
774                 switch (respcmd) {
775                 case CMD_RET(CMD_GET_HW_SPEC):
776                 case CMD_RET(CMD_802_11_RESET):
777                         pr_info("libertastf: reset failed\n");
778                         break;
779
780                 }
781                 lbtf_complete_command(priv, priv->cur_cmd, result);
782                 spin_unlock_irqrestore(&priv->driver_lock, flags);
783
784                 ret = -1;
785                 goto done;
786         }
787
788         spin_unlock_irqrestore(&priv->driver_lock, flags);
789
790         if (priv->cur_cmd && priv->cur_cmd->callback) {
791                 ret = priv->cur_cmd->callback(priv, priv->cur_cmd->callback_arg,
792                                 resp);
793         }
794         spin_lock_irqsave(&priv->driver_lock, flags);
795
796         if (priv->cur_cmd) {
797                 /* Clean up and Put current command back to cmdfreeq */
798                 lbtf_complete_command(priv, priv->cur_cmd, result);
799         }
800         spin_unlock_irqrestore(&priv->driver_lock, flags);
801
802 done:
803         mutex_unlock(&priv->lock);
804         lbtf_deb_leave_args(LBTF_DEB_CMD, "ret %d", ret);
805         return ret;
806 }