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