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