1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * This file contains the handling of command. 4 * It prepares command and sends it to firmware when it is ready. 5 */ 6 7 #include <linux/hardirq.h> 8 #include <linux/kfifo.h> 9 #include <linux/sched.h> 10 #include <linux/slab.h> 11 #include <linux/if_arp.h> 12 #include <linux/export.h> 13 14 #include "decl.h" 15 #include "cfg.h" 16 #include "cmd.h" 17 18 #define CAL_NF(nf) ((s32)(-(s32)(nf))) 19 #define CAL_RSSI(snr, nf) ((s32)((s32)(snr) + CAL_NF(nf))) 20 21 /** 22 * lbs_cmd_copyback - Simple callback that copies response back into command 23 * 24 * @priv: A pointer to &struct lbs_private structure 25 * @extra: A pointer to the original command structure for which 26 * 'resp' is a response 27 * @resp: A pointer to the command response 28 * 29 * returns: 0 on success, error on failure 30 */ 31 int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra, 32 struct cmd_header *resp) 33 { 34 struct cmd_header *buf = (void *)extra; 35 uint16_t copy_len; 36 37 copy_len = min(le16_to_cpu(buf->size), le16_to_cpu(resp->size)); 38 memcpy(buf, resp, copy_len); 39 return 0; 40 } 41 EXPORT_SYMBOL_GPL(lbs_cmd_copyback); 42 43 /** 44 * lbs_cmd_async_callback - Simple callback that ignores the result. 45 * Use this if you just want to send a command to the hardware, but don't 46 * care for the result. 47 * 48 * @priv: ignored 49 * @extra: ignored 50 * @resp: ignored 51 * 52 * returns: 0 for success 53 */ 54 static int lbs_cmd_async_callback(struct lbs_private *priv, unsigned long extra, 55 struct cmd_header *resp) 56 { 57 return 0; 58 } 59 60 61 /** 62 * is_command_allowed_in_ps - tests if a command is allowed in Power Save mode 63 * 64 * @cmd: the command ID 65 * 66 * returns: 1 if allowed, 0 if not allowed 67 */ 68 static u8 is_command_allowed_in_ps(u16 cmd) 69 { 70 switch (cmd) { 71 case CMD_802_11_RSSI: 72 return 1; 73 case CMD_802_11_HOST_SLEEP_CFG: 74 return 1; 75 default: 76 break; 77 } 78 return 0; 79 } 80 81 /** 82 * lbs_update_hw_spec - Updates the hardware details like MAC address 83 * and regulatory region 84 * 85 * @priv: A pointer to &struct lbs_private structure 86 * 87 * returns: 0 on success, error on failure 88 */ 89 int lbs_update_hw_spec(struct lbs_private *priv) 90 { 91 struct cmd_ds_get_hw_spec cmd; 92 int ret = -1; 93 u32 i; 94 95 memset(&cmd, 0, sizeof(cmd)); 96 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 97 memcpy(cmd.permanentaddr, priv->current_addr, ETH_ALEN); 98 ret = lbs_cmd_with_response(priv, CMD_GET_HW_SPEC, &cmd); 99 if (ret) 100 goto out; 101 102 priv->fwcapinfo = le32_to_cpu(cmd.fwcapinfo); 103 104 /* The firmware release is in an interesting format: the patch 105 * level is in the most significant nibble ... so fix that: */ 106 priv->fwrelease = le32_to_cpu(cmd.fwrelease); 107 priv->fwrelease = (priv->fwrelease << 8) | 108 (priv->fwrelease >> 24 & 0xff); 109 110 /* Some firmware capabilities: 111 * CF card firmware 5.0.16p0: cap 0x00000303 112 * USB dongle firmware 5.110.17p2: cap 0x00000303 113 */ 114 netdev_info(priv->dev, "%pM, fw %u.%u.%up%u, cap 0x%08x\n", 115 cmd.permanentaddr, 116 priv->fwrelease >> 24 & 0xff, 117 priv->fwrelease >> 16 & 0xff, 118 priv->fwrelease >> 8 & 0xff, 119 priv->fwrelease & 0xff, 120 priv->fwcapinfo); 121 lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n", 122 cmd.hwifversion, cmd.version); 123 124 /* Clamp region code to 8-bit since FW spec indicates that it should 125 * only ever be 8-bit, even though the field size is 16-bit. Some firmware 126 * returns non-zero high 8 bits here. 127 * 128 * Firmware version 4.0.102 used in CF8381 has region code shifted. We 129 * need to check for this problem and handle it properly. 130 */ 131 if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V4) 132 priv->regioncode = (le16_to_cpu(cmd.regioncode) >> 8) & 0xFF; 133 else 134 priv->regioncode = le16_to_cpu(cmd.regioncode) & 0xFF; 135 136 for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) { 137 /* use the region code to search for the index */ 138 if (priv->regioncode == lbs_region_code_to_index[i]) 139 break; 140 } 141 142 /* if it's unidentified region code, use the default (USA) */ 143 if (i >= MRVDRV_MAX_REGION_CODE) { 144 priv->regioncode = 0x10; 145 netdev_info(priv->dev, 146 "unidentified region code; using the default (USA)\n"); 147 } 148 149 if (priv->current_addr[0] == 0xff) 150 memmove(priv->current_addr, cmd.permanentaddr, ETH_ALEN); 151 152 if (!priv->copied_hwaddr) { 153 memcpy(priv->dev->dev_addr, priv->current_addr, ETH_ALEN); 154 if (priv->mesh_dev) 155 memcpy(priv->mesh_dev->dev_addr, 156 priv->current_addr, ETH_ALEN); 157 priv->copied_hwaddr = 1; 158 } 159 160 out: 161 return ret; 162 } 163 164 static int lbs_ret_host_sleep_cfg(struct lbs_private *priv, unsigned long dummy, 165 struct cmd_header *resp) 166 { 167 if (priv->is_host_sleep_activated) { 168 priv->is_host_sleep_configured = 0; 169 if (priv->psstate == PS_STATE_FULL_POWER) { 170 priv->is_host_sleep_activated = 0; 171 wake_up_interruptible(&priv->host_sleep_q); 172 } 173 } else { 174 priv->is_host_sleep_configured = 1; 175 } 176 177 return 0; 178 } 179 180 int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria, 181 struct wol_config *p_wol_config) 182 { 183 struct cmd_ds_host_sleep cmd_config; 184 int ret; 185 186 /* 187 * Certain firmware versions do not support EHS_REMOVE_WAKEUP command 188 * and the card will return a failure. Since we need to be 189 * able to reset the mask, in those cases we set a 0 mask instead. 190 */ 191 if (criteria == EHS_REMOVE_WAKEUP && !priv->ehs_remove_supported) 192 criteria = 0; 193 194 cmd_config.hdr.size = cpu_to_le16(sizeof(cmd_config)); 195 cmd_config.criteria = cpu_to_le32(criteria); 196 cmd_config.gpio = priv->wol_gpio; 197 cmd_config.gap = priv->wol_gap; 198 199 if (p_wol_config != NULL) 200 memcpy((uint8_t *)&cmd_config.wol_conf, (uint8_t *)p_wol_config, 201 sizeof(struct wol_config)); 202 else 203 cmd_config.wol_conf.action = CMD_ACT_ACTION_NONE; 204 205 ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config.hdr, 206 le16_to_cpu(cmd_config.hdr.size), 207 lbs_ret_host_sleep_cfg, 0); 208 if (!ret) { 209 if (p_wol_config) 210 memcpy((uint8_t *) p_wol_config, 211 (uint8_t *)&cmd_config.wol_conf, 212 sizeof(struct wol_config)); 213 } else { 214 netdev_info(priv->dev, "HOST_SLEEP_CFG failed %d\n", ret); 215 } 216 217 return ret; 218 } 219 EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg); 220 221 /** 222 * lbs_set_ps_mode - Sets the Power Save mode 223 * 224 * @priv: A pointer to &struct lbs_private structure 225 * @cmd_action: The Power Save operation (PS_MODE_ACTION_ENTER_PS or 226 * PS_MODE_ACTION_EXIT_PS) 227 * @block: Whether to block on a response or not 228 * 229 * returns: 0 on success, error on failure 230 */ 231 int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block) 232 { 233 struct cmd_ds_802_11_ps_mode cmd; 234 int ret = 0; 235 236 memset(&cmd, 0, sizeof(cmd)); 237 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 238 cmd.action = cpu_to_le16(cmd_action); 239 240 if (cmd_action == PS_MODE_ACTION_ENTER_PS) { 241 lbs_deb_cmd("PS_MODE: action ENTER_PS\n"); 242 cmd.multipledtim = cpu_to_le16(1); /* Default DTIM multiple */ 243 } else if (cmd_action == PS_MODE_ACTION_EXIT_PS) { 244 lbs_deb_cmd("PS_MODE: action EXIT_PS\n"); 245 } else { 246 /* We don't handle CONFIRM_SLEEP here because it needs to 247 * be fastpathed to the firmware. 248 */ 249 lbs_deb_cmd("PS_MODE: unknown action 0x%X\n", cmd_action); 250 ret = -EOPNOTSUPP; 251 goto out; 252 } 253 254 if (block) 255 ret = lbs_cmd_with_response(priv, CMD_802_11_PS_MODE, &cmd); 256 else 257 lbs_cmd_async(priv, CMD_802_11_PS_MODE, &cmd.hdr, sizeof (cmd)); 258 259 out: 260 return ret; 261 } 262 263 int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action, 264 struct sleep_params *sp) 265 { 266 struct cmd_ds_802_11_sleep_params cmd; 267 int ret; 268 269 if (cmd_action == CMD_ACT_GET) { 270 memset(&cmd, 0, sizeof(cmd)); 271 } else { 272 cmd.error = cpu_to_le16(sp->sp_error); 273 cmd.offset = cpu_to_le16(sp->sp_offset); 274 cmd.stabletime = cpu_to_le16(sp->sp_stabletime); 275 cmd.calcontrol = sp->sp_calcontrol; 276 cmd.externalsleepclk = sp->sp_extsleepclk; 277 cmd.reserved = cpu_to_le16(sp->sp_reserved); 278 } 279 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 280 cmd.action = cpu_to_le16(cmd_action); 281 282 ret = lbs_cmd_with_response(priv, CMD_802_11_SLEEP_PARAMS, &cmd); 283 284 if (!ret) { 285 lbs_deb_cmd("error 0x%x, offset 0x%x, stabletime 0x%x, " 286 "calcontrol 0x%x extsleepclk 0x%x\n", 287 le16_to_cpu(cmd.error), le16_to_cpu(cmd.offset), 288 le16_to_cpu(cmd.stabletime), cmd.calcontrol, 289 cmd.externalsleepclk); 290 291 sp->sp_error = le16_to_cpu(cmd.error); 292 sp->sp_offset = le16_to_cpu(cmd.offset); 293 sp->sp_stabletime = le16_to_cpu(cmd.stabletime); 294 sp->sp_calcontrol = cmd.calcontrol; 295 sp->sp_extsleepclk = cmd.externalsleepclk; 296 sp->sp_reserved = le16_to_cpu(cmd.reserved); 297 } 298 299 return ret; 300 } 301 302 static int lbs_wait_for_ds_awake(struct lbs_private *priv) 303 { 304 int ret = 0; 305 306 if (priv->is_deep_sleep) { 307 if (!wait_event_interruptible_timeout(priv->ds_awake_q, 308 !priv->is_deep_sleep, (10 * HZ))) { 309 netdev_err(priv->dev, "ds_awake_q: timer expired\n"); 310 ret = -1; 311 } 312 } 313 314 return ret; 315 } 316 317 int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep) 318 { 319 int ret = 0; 320 321 if (deep_sleep) { 322 if (priv->is_deep_sleep != 1) { 323 lbs_deb_cmd("deep sleep: sleep\n"); 324 BUG_ON(!priv->enter_deep_sleep); 325 ret = priv->enter_deep_sleep(priv); 326 if (!ret) { 327 netif_stop_queue(priv->dev); 328 netif_carrier_off(priv->dev); 329 } 330 } else { 331 netdev_err(priv->dev, "deep sleep: already enabled\n"); 332 } 333 } else { 334 if (priv->is_deep_sleep) { 335 lbs_deb_cmd("deep sleep: wakeup\n"); 336 BUG_ON(!priv->exit_deep_sleep); 337 ret = priv->exit_deep_sleep(priv); 338 if (!ret) { 339 ret = lbs_wait_for_ds_awake(priv); 340 if (ret) 341 netdev_err(priv->dev, 342 "deep sleep: wakeup failed\n"); 343 } 344 } 345 } 346 347 return ret; 348 } 349 350 static int lbs_ret_host_sleep_activate(struct lbs_private *priv, 351 unsigned long dummy, 352 struct cmd_header *cmd) 353 { 354 priv->is_host_sleep_activated = 1; 355 wake_up_interruptible(&priv->host_sleep_q); 356 357 return 0; 358 } 359 360 int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep) 361 { 362 struct cmd_header cmd; 363 int ret = 0; 364 uint32_t criteria = EHS_REMOVE_WAKEUP; 365 366 if (host_sleep) { 367 if (priv->is_host_sleep_activated != 1) { 368 memset(&cmd, 0, sizeof(cmd)); 369 ret = lbs_host_sleep_cfg(priv, priv->wol_criteria, 370 (struct wol_config *)NULL); 371 if (ret) { 372 netdev_info(priv->dev, 373 "Host sleep configuration failed: %d\n", 374 ret); 375 return ret; 376 } 377 if (priv->psstate == PS_STATE_FULL_POWER) { 378 ret = __lbs_cmd(priv, 379 CMD_802_11_HOST_SLEEP_ACTIVATE, 380 &cmd, 381 sizeof(cmd), 382 lbs_ret_host_sleep_activate, 0); 383 if (ret) 384 netdev_info(priv->dev, 385 "HOST_SLEEP_ACTIVATE failed: %d\n", 386 ret); 387 } 388 389 if (!wait_event_interruptible_timeout( 390 priv->host_sleep_q, 391 priv->is_host_sleep_activated, 392 (10 * HZ))) { 393 netdev_err(priv->dev, 394 "host_sleep_q: timer expired\n"); 395 ret = -1; 396 } 397 } else { 398 netdev_err(priv->dev, "host sleep: already enabled\n"); 399 } 400 } else { 401 if (priv->is_host_sleep_activated) 402 ret = lbs_host_sleep_cfg(priv, criteria, 403 (struct wol_config *)NULL); 404 } 405 406 return ret; 407 } 408 409 /** 410 * lbs_set_snmp_mib - Set an SNMP MIB value 411 * 412 * @priv: A pointer to &struct lbs_private structure 413 * @oid: The OID to set in the firmware 414 * @val: Value to set the OID to 415 * 416 * returns: 0 on success, error on failure 417 */ 418 int lbs_set_snmp_mib(struct lbs_private *priv, u32 oid, u16 val) 419 { 420 struct cmd_ds_802_11_snmp_mib cmd; 421 int ret; 422 423 memset(&cmd, 0, sizeof (cmd)); 424 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 425 cmd.action = cpu_to_le16(CMD_ACT_SET); 426 cmd.oid = cpu_to_le16((u16) oid); 427 428 switch (oid) { 429 case SNMP_MIB_OID_BSS_TYPE: 430 cmd.bufsize = cpu_to_le16(sizeof(u8)); 431 cmd.value[0] = val; 432 break; 433 case SNMP_MIB_OID_11D_ENABLE: 434 case SNMP_MIB_OID_FRAG_THRESHOLD: 435 case SNMP_MIB_OID_RTS_THRESHOLD: 436 case SNMP_MIB_OID_SHORT_RETRY_LIMIT: 437 case SNMP_MIB_OID_LONG_RETRY_LIMIT: 438 cmd.bufsize = cpu_to_le16(sizeof(u16)); 439 *((__le16 *)(&cmd.value)) = cpu_to_le16(val); 440 break; 441 default: 442 lbs_deb_cmd("SNMP_CMD: (set) unhandled OID 0x%x\n", oid); 443 ret = -EINVAL; 444 goto out; 445 } 446 447 lbs_deb_cmd("SNMP_CMD: (set) oid 0x%x, oid size 0x%x, value 0x%x\n", 448 le16_to_cpu(cmd.oid), le16_to_cpu(cmd.bufsize), val); 449 450 ret = lbs_cmd_with_response(priv, CMD_802_11_SNMP_MIB, &cmd); 451 452 out: 453 return ret; 454 } 455 456 /** 457 * lbs_get_snmp_mib - Get an SNMP MIB value 458 * 459 * @priv: A pointer to &struct lbs_private structure 460 * @oid: The OID to retrieve from the firmware 461 * @out_val: Location for the returned value 462 * 463 * returns: 0 on success, error on failure 464 */ 465 int lbs_get_snmp_mib(struct lbs_private *priv, u32 oid, u16 *out_val) 466 { 467 struct cmd_ds_802_11_snmp_mib cmd; 468 int ret; 469 470 memset(&cmd, 0, sizeof (cmd)); 471 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 472 cmd.action = cpu_to_le16(CMD_ACT_GET); 473 cmd.oid = cpu_to_le16(oid); 474 475 ret = lbs_cmd_with_response(priv, CMD_802_11_SNMP_MIB, &cmd); 476 if (ret) 477 goto out; 478 479 switch (le16_to_cpu(cmd.bufsize)) { 480 case sizeof(u8): 481 *out_val = cmd.value[0]; 482 break; 483 case sizeof(u16): 484 *out_val = le16_to_cpu(*((__le16 *)(&cmd.value))); 485 break; 486 default: 487 lbs_deb_cmd("SNMP_CMD: (get) unhandled OID 0x%x size %d\n", 488 oid, le16_to_cpu(cmd.bufsize)); 489 break; 490 } 491 492 out: 493 return ret; 494 } 495 496 /** 497 * lbs_get_tx_power - Get the min, max, and current TX power 498 * 499 * @priv: A pointer to &struct lbs_private structure 500 * @curlevel: Current power level in dBm 501 * @minlevel: Minimum supported power level in dBm (optional) 502 * @maxlevel: Maximum supported power level in dBm (optional) 503 * 504 * returns: 0 on success, error on failure 505 */ 506 int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel, 507 s16 *maxlevel) 508 { 509 struct cmd_ds_802_11_rf_tx_power cmd; 510 int ret; 511 512 memset(&cmd, 0, sizeof(cmd)); 513 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 514 cmd.action = cpu_to_le16(CMD_ACT_GET); 515 516 ret = lbs_cmd_with_response(priv, CMD_802_11_RF_TX_POWER, &cmd); 517 if (ret == 0) { 518 *curlevel = le16_to_cpu(cmd.curlevel); 519 if (minlevel) 520 *minlevel = cmd.minlevel; 521 if (maxlevel) 522 *maxlevel = cmd.maxlevel; 523 } 524 525 return ret; 526 } 527 528 /** 529 * lbs_set_tx_power - Set the TX power 530 * 531 * @priv: A pointer to &struct lbs_private structure 532 * @dbm: The desired power level in dBm 533 * 534 * returns: 0 on success, error on failure 535 */ 536 int lbs_set_tx_power(struct lbs_private *priv, s16 dbm) 537 { 538 struct cmd_ds_802_11_rf_tx_power cmd; 539 int ret; 540 541 memset(&cmd, 0, sizeof(cmd)); 542 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 543 cmd.action = cpu_to_le16(CMD_ACT_SET); 544 cmd.curlevel = cpu_to_le16(dbm); 545 546 lbs_deb_cmd("SET_RF_TX_POWER: %d dBm\n", dbm); 547 548 ret = lbs_cmd_with_response(priv, CMD_802_11_RF_TX_POWER, &cmd); 549 550 return ret; 551 } 552 553 /** 554 * lbs_set_monitor_mode - Enable or disable monitor mode 555 * (only implemented on OLPC usb8388 FW) 556 * 557 * @priv: A pointer to &struct lbs_private structure 558 * @enable: 1 to enable monitor mode, 0 to disable 559 * 560 * returns: 0 on success, error on failure 561 */ 562 int lbs_set_monitor_mode(struct lbs_private *priv, int enable) 563 { 564 struct cmd_ds_802_11_monitor_mode cmd; 565 int ret; 566 567 memset(&cmd, 0, sizeof(cmd)); 568 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 569 cmd.action = cpu_to_le16(CMD_ACT_SET); 570 if (enable) 571 cmd.mode = cpu_to_le16(0x1); 572 573 lbs_deb_cmd("SET_MONITOR_MODE: %d\n", enable); 574 575 ret = lbs_cmd_with_response(priv, CMD_802_11_MONITOR_MODE, &cmd); 576 if (ret == 0) { 577 priv->dev->type = enable ? ARPHRD_IEEE80211_RADIOTAP : 578 ARPHRD_ETHER; 579 } 580 581 return ret; 582 } 583 584 /** 585 * lbs_get_channel - Get the radio channel 586 * 587 * @priv: A pointer to &struct lbs_private structure 588 * 589 * returns: The channel on success, error on failure 590 */ 591 static int lbs_get_channel(struct lbs_private *priv) 592 { 593 struct cmd_ds_802_11_rf_channel cmd; 594 int ret = 0; 595 596 memset(&cmd, 0, sizeof(cmd)); 597 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 598 cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_GET); 599 600 ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd); 601 if (ret) 602 goto out; 603 604 ret = le16_to_cpu(cmd.channel); 605 lbs_deb_cmd("current radio channel is %d\n", ret); 606 607 out: 608 return ret; 609 } 610 611 int lbs_update_channel(struct lbs_private *priv) 612 { 613 int ret; 614 615 /* the channel in f/w could be out of sync; get the current channel */ 616 ret = lbs_get_channel(priv); 617 if (ret > 0) { 618 priv->channel = ret; 619 ret = 0; 620 } 621 622 return ret; 623 } 624 625 /** 626 * lbs_set_channel - Set the radio channel 627 * 628 * @priv: A pointer to &struct lbs_private structure 629 * @channel: The desired channel, or 0 to clear a locked channel 630 * 631 * returns: 0 on success, error on failure 632 */ 633 int lbs_set_channel(struct lbs_private *priv, u8 channel) 634 { 635 struct cmd_ds_802_11_rf_channel cmd; 636 #ifdef DEBUG 637 u8 old_channel = priv->channel; 638 #endif 639 int ret = 0; 640 641 memset(&cmd, 0, sizeof(cmd)); 642 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 643 cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_SET); 644 cmd.channel = cpu_to_le16(channel); 645 646 ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd); 647 if (ret) 648 goto out; 649 650 priv->channel = (uint8_t) le16_to_cpu(cmd.channel); 651 lbs_deb_cmd("channel switch from %d to %d\n", old_channel, 652 priv->channel); 653 654 out: 655 return ret; 656 } 657 658 /** 659 * lbs_get_rssi - Get current RSSI and noise floor 660 * 661 * @priv: A pointer to &struct lbs_private structure 662 * @rssi: On successful return, signal level in mBm 663 * @nf: On successful return, Noise floor 664 * 665 * returns: The channel on success, error on failure 666 */ 667 int lbs_get_rssi(struct lbs_private *priv, s8 *rssi, s8 *nf) 668 { 669 struct cmd_ds_802_11_rssi cmd; 670 int ret = 0; 671 672 BUG_ON(rssi == NULL); 673 BUG_ON(nf == NULL); 674 675 memset(&cmd, 0, sizeof(cmd)); 676 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 677 /* Average SNR over last 8 beacons */ 678 cmd.n_or_snr = cpu_to_le16(8); 679 680 ret = lbs_cmd_with_response(priv, CMD_802_11_RSSI, &cmd); 681 if (ret == 0) { 682 *nf = CAL_NF(le16_to_cpu(cmd.nf)); 683 *rssi = CAL_RSSI(le16_to_cpu(cmd.n_or_snr), le16_to_cpu(cmd.nf)); 684 } 685 686 return ret; 687 } 688 689 /** 690 * lbs_set_11d_domain_info - Send regulatory and 802.11d domain information 691 * to the firmware 692 * 693 * @priv: pointer to &struct lbs_private 694 * 695 * returns: 0 on success, error code on failure 696 */ 697 int lbs_set_11d_domain_info(struct lbs_private *priv) 698 { 699 struct wiphy *wiphy = priv->wdev->wiphy; 700 struct ieee80211_supported_band **bands = wiphy->bands; 701 struct cmd_ds_802_11d_domain_info cmd; 702 struct mrvl_ie_domain_param_set *domain = &cmd.domain; 703 struct ieee80211_country_ie_triplet *t; 704 enum nl80211_band band; 705 struct ieee80211_channel *ch; 706 u8 num_triplet = 0; 707 u8 num_parsed_chan = 0; 708 u8 first_channel = 0, next_chan = 0, max_pwr = 0; 709 u8 i, flag = 0; 710 size_t triplet_size; 711 int ret = 0; 712 713 if (!priv->country_code[0]) 714 goto out; 715 716 memset(&cmd, 0, sizeof(cmd)); 717 cmd.action = cpu_to_le16(CMD_ACT_SET); 718 719 lbs_deb_11d("Setting country code '%c%c'\n", 720 priv->country_code[0], priv->country_code[1]); 721 722 domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN); 723 724 /* Set country code */ 725 domain->country_code[0] = priv->country_code[0]; 726 domain->country_code[1] = priv->country_code[1]; 727 domain->country_code[2] = ' '; 728 729 /* Now set up the channel triplets; firmware is somewhat picky here 730 * and doesn't validate channel numbers and spans; hence it would 731 * interpret a triplet of (36, 4, 20) as channels 36, 37, 38, 39. Since 732 * the last 3 aren't valid channels, the driver is responsible for 733 * splitting that up into 4 triplet pairs of (36, 1, 20) + (40, 1, 20) 734 * etc. 735 */ 736 for (band = 0; 737 (band < NUM_NL80211_BANDS) && (num_triplet < MAX_11D_TRIPLETS); 738 band++) { 739 740 if (!bands[band]) 741 continue; 742 743 for (i = 0; 744 (i < bands[band]->n_channels) && (num_triplet < MAX_11D_TRIPLETS); 745 i++) { 746 ch = &bands[band]->channels[i]; 747 if (ch->flags & IEEE80211_CHAN_DISABLED) 748 continue; 749 750 if (!flag) { 751 flag = 1; 752 next_chan = first_channel = (u32) ch->hw_value; 753 max_pwr = ch->max_power; 754 num_parsed_chan = 1; 755 continue; 756 } 757 758 if ((ch->hw_value == next_chan + 1) && 759 (ch->max_power == max_pwr)) { 760 /* Consolidate adjacent channels */ 761 next_chan++; 762 num_parsed_chan++; 763 } else { 764 /* Add this triplet */ 765 lbs_deb_11d("11D triplet (%d, %d, %d)\n", 766 first_channel, num_parsed_chan, 767 max_pwr); 768 t = &domain->triplet[num_triplet]; 769 t->chans.first_channel = first_channel; 770 t->chans.num_channels = num_parsed_chan; 771 t->chans.max_power = max_pwr; 772 num_triplet++; 773 flag = 0; 774 } 775 } 776 777 if (flag) { 778 /* Add last triplet */ 779 lbs_deb_11d("11D triplet (%d, %d, %d)\n", first_channel, 780 num_parsed_chan, max_pwr); 781 t = &domain->triplet[num_triplet]; 782 t->chans.first_channel = first_channel; 783 t->chans.num_channels = num_parsed_chan; 784 t->chans.max_power = max_pwr; 785 num_triplet++; 786 } 787 } 788 789 lbs_deb_11d("# triplets %d\n", num_triplet); 790 791 /* Set command header sizes */ 792 triplet_size = num_triplet * sizeof(struct ieee80211_country_ie_triplet); 793 domain->header.len = cpu_to_le16(sizeof(domain->country_code) + 794 triplet_size); 795 796 lbs_deb_hex(LBS_DEB_11D, "802.11D domain param set", 797 (u8 *) &cmd.domain.country_code, 798 le16_to_cpu(domain->header.len)); 799 800 cmd.hdr.size = cpu_to_le16(sizeof(cmd.hdr) + 801 sizeof(cmd.action) + 802 sizeof(cmd.domain.header) + 803 sizeof(cmd.domain.country_code) + 804 triplet_size); 805 806 ret = lbs_cmd_with_response(priv, CMD_802_11D_DOMAIN_INFO, &cmd); 807 808 out: 809 return ret; 810 } 811 812 /** 813 * lbs_get_reg - Read a MAC, Baseband, or RF register 814 * 815 * @priv: pointer to &struct lbs_private 816 * @reg: register command, one of CMD_MAC_REG_ACCESS, 817 * CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS 818 * @offset: byte offset of the register to get 819 * @value: on success, the value of the register at 'offset' 820 * 821 * returns: 0 on success, error code on failure 822 */ 823 int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value) 824 { 825 struct cmd_ds_reg_access cmd; 826 int ret = 0; 827 828 BUG_ON(value == NULL); 829 830 memset(&cmd, 0, sizeof(cmd)); 831 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 832 cmd.action = cpu_to_le16(CMD_ACT_GET); 833 cmd.offset = cpu_to_le16(offset); 834 835 if (reg != CMD_MAC_REG_ACCESS && 836 reg != CMD_BBP_REG_ACCESS && 837 reg != CMD_RF_REG_ACCESS) { 838 ret = -EINVAL; 839 goto out; 840 } 841 842 ret = lbs_cmd_with_response(priv, reg, &cmd); 843 if (!ret) { 844 if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS) 845 *value = cmd.value.bbp_rf; 846 else if (reg == CMD_MAC_REG_ACCESS) 847 *value = le32_to_cpu(cmd.value.mac); 848 } 849 850 out: 851 return ret; 852 } 853 854 /** 855 * lbs_set_reg - Write a MAC, Baseband, or RF register 856 * 857 * @priv: pointer to &struct lbs_private 858 * @reg: register command, one of CMD_MAC_REG_ACCESS, 859 * CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS 860 * @offset: byte offset of the register to set 861 * @value: the value to write to the register at 'offset' 862 * 863 * returns: 0 on success, error code on failure 864 */ 865 int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value) 866 { 867 struct cmd_ds_reg_access cmd; 868 int ret = 0; 869 870 memset(&cmd, 0, sizeof(cmd)); 871 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 872 cmd.action = cpu_to_le16(CMD_ACT_SET); 873 cmd.offset = cpu_to_le16(offset); 874 875 if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS) 876 cmd.value.bbp_rf = (u8) (value & 0xFF); 877 else if (reg == CMD_MAC_REG_ACCESS) 878 cmd.value.mac = cpu_to_le32(value); 879 else { 880 ret = -EINVAL; 881 goto out; 882 } 883 884 ret = lbs_cmd_with_response(priv, reg, &cmd); 885 886 out: 887 return ret; 888 } 889 890 static void lbs_queue_cmd(struct lbs_private *priv, 891 struct cmd_ctrl_node *cmdnode) 892 { 893 unsigned long flags; 894 int addtail = 1; 895 896 if (!cmdnode) { 897 lbs_deb_host("QUEUE_CMD: cmdnode is NULL\n"); 898 return; 899 } 900 if (!cmdnode->cmdbuf->size) { 901 lbs_deb_host("DNLD_CMD: cmd size is zero\n"); 902 return; 903 } 904 cmdnode->result = 0; 905 906 /* Exit_PS command needs to be queued in the header always. */ 907 if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) { 908 struct cmd_ds_802_11_ps_mode *psm = (void *)cmdnode->cmdbuf; 909 910 if (psm->action == cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) { 911 if (priv->psstate != PS_STATE_FULL_POWER) 912 addtail = 0; 913 } 914 } 915 916 if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_WAKEUP_CONFIRM) 917 addtail = 0; 918 919 spin_lock_irqsave(&priv->driver_lock, flags); 920 921 if (addtail) 922 list_add_tail(&cmdnode->list, &priv->cmdpendingq); 923 else 924 list_add(&cmdnode->list, &priv->cmdpendingq); 925 926 spin_unlock_irqrestore(&priv->driver_lock, flags); 927 928 lbs_deb_host("QUEUE_CMD: inserted command 0x%04x into cmdpendingq\n", 929 le16_to_cpu(cmdnode->cmdbuf->command)); 930 } 931 932 static void lbs_submit_command(struct lbs_private *priv, 933 struct cmd_ctrl_node *cmdnode) 934 { 935 unsigned long flags; 936 struct cmd_header *cmd; 937 uint16_t cmdsize; 938 uint16_t command; 939 int timeo = 3 * HZ; 940 int ret; 941 942 cmd = cmdnode->cmdbuf; 943 944 spin_lock_irqsave(&priv->driver_lock, flags); 945 priv->seqnum++; 946 cmd->seqnum = cpu_to_le16(priv->seqnum); 947 priv->cur_cmd = cmdnode; 948 spin_unlock_irqrestore(&priv->driver_lock, flags); 949 950 cmdsize = le16_to_cpu(cmd->size); 951 command = le16_to_cpu(cmd->command); 952 953 /* These commands take longer */ 954 if (command == CMD_802_11_SCAN || command == CMD_802_11_ASSOCIATE) 955 timeo = 5 * HZ; 956 957 lbs_deb_cmd("DNLD_CMD: command 0x%04x, seq %d, size %d\n", 958 command, le16_to_cpu(cmd->seqnum), cmdsize); 959 lbs_deb_hex(LBS_DEB_CMD, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize); 960 961 ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize); 962 963 if (ret) { 964 netdev_info(priv->dev, "DNLD_CMD: hw_host_to_card failed: %d\n", 965 ret); 966 /* Reset dnld state machine, report failure */ 967 priv->dnld_sent = DNLD_RES_RECEIVED; 968 lbs_complete_command(priv, cmdnode, ret); 969 } 970 971 if (command == CMD_802_11_DEEP_SLEEP) { 972 if (priv->is_auto_deep_sleep_enabled) { 973 priv->wakeup_dev_required = 1; 974 priv->dnld_sent = 0; 975 } 976 priv->is_deep_sleep = 1; 977 lbs_complete_command(priv, cmdnode, 0); 978 } else { 979 /* Setup the timer after transmit command */ 980 mod_timer(&priv->command_timer, jiffies + timeo); 981 } 982 } 983 984 /* 985 * This function inserts command node to cmdfreeq 986 * after cleans it. Requires priv->driver_lock held. 987 */ 988 static void __lbs_cleanup_and_insert_cmd(struct lbs_private *priv, 989 struct cmd_ctrl_node *cmdnode) 990 { 991 if (!cmdnode) 992 return; 993 994 cmdnode->callback = NULL; 995 cmdnode->callback_arg = 0; 996 997 memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE); 998 999 list_add_tail(&cmdnode->list, &priv->cmdfreeq); 1000 } 1001 1002 static void lbs_cleanup_and_insert_cmd(struct lbs_private *priv, 1003 struct cmd_ctrl_node *ptempcmd) 1004 { 1005 unsigned long flags; 1006 1007 spin_lock_irqsave(&priv->driver_lock, flags); 1008 __lbs_cleanup_and_insert_cmd(priv, ptempcmd); 1009 spin_unlock_irqrestore(&priv->driver_lock, flags); 1010 } 1011 1012 void __lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd, 1013 int result) 1014 { 1015 /* 1016 * Normally, commands are removed from cmdpendingq before being 1017 * submitted. However, we can arrive here on alternative codepaths 1018 * where the command is still pending. Make sure the command really 1019 * isn't part of a list at this point. 1020 */ 1021 list_del_init(&cmd->list); 1022 1023 cmd->result = result; 1024 cmd->cmdwaitqwoken = 1; 1025 wake_up(&cmd->cmdwait_q); 1026 1027 if (!cmd->callback || cmd->callback == lbs_cmd_async_callback) 1028 __lbs_cleanup_and_insert_cmd(priv, cmd); 1029 priv->cur_cmd = NULL; 1030 wake_up(&priv->waitq); 1031 } 1032 1033 void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd, 1034 int result) 1035 { 1036 unsigned long flags; 1037 spin_lock_irqsave(&priv->driver_lock, flags); 1038 __lbs_complete_command(priv, cmd, result); 1039 spin_unlock_irqrestore(&priv->driver_lock, flags); 1040 } 1041 1042 int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on) 1043 { 1044 struct cmd_ds_802_11_radio_control cmd; 1045 int ret = -EINVAL; 1046 1047 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 1048 cmd.action = cpu_to_le16(CMD_ACT_SET); 1049 cmd.control = 0; 1050 1051 /* Only v8 and below support setting the preamble */ 1052 if (priv->fwrelease < 0x09000000) { 1053 switch (preamble) { 1054 case RADIO_PREAMBLE_SHORT: 1055 case RADIO_PREAMBLE_AUTO: 1056 case RADIO_PREAMBLE_LONG: 1057 cmd.control = cpu_to_le16(preamble); 1058 break; 1059 default: 1060 goto out; 1061 } 1062 } 1063 1064 if (radio_on) 1065 cmd.control |= cpu_to_le16(0x1); 1066 else { 1067 cmd.control &= cpu_to_le16(~0x1); 1068 priv->txpower_cur = 0; 1069 } 1070 1071 lbs_deb_cmd("RADIO_CONTROL: radio %s, preamble %d\n", 1072 radio_on ? "ON" : "OFF", preamble); 1073 1074 priv->radio_on = radio_on; 1075 1076 ret = lbs_cmd_with_response(priv, CMD_802_11_RADIO_CONTROL, &cmd); 1077 1078 out: 1079 return ret; 1080 } 1081 1082 void lbs_set_mac_control(struct lbs_private *priv) 1083 { 1084 struct cmd_ds_mac_control cmd; 1085 1086 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 1087 cmd.action = cpu_to_le16(priv->mac_control); 1088 cmd.reserved = 0; 1089 1090 lbs_cmd_async(priv, CMD_MAC_CONTROL, &cmd.hdr, sizeof(cmd)); 1091 } 1092 1093 int lbs_set_mac_control_sync(struct lbs_private *priv) 1094 { 1095 struct cmd_ds_mac_control cmd; 1096 int ret = 0; 1097 1098 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 1099 cmd.action = cpu_to_le16(priv->mac_control); 1100 cmd.reserved = 0; 1101 ret = lbs_cmd_with_response(priv, CMD_MAC_CONTROL, &cmd); 1102 1103 return ret; 1104 } 1105 1106 /** 1107 * lbs_allocate_cmd_buffer - allocates the command buffer and links 1108 * it to command free queue 1109 * 1110 * @priv: A pointer to &struct lbs_private structure 1111 * 1112 * returns: 0 for success or -1 on error 1113 */ 1114 int lbs_allocate_cmd_buffer(struct lbs_private *priv) 1115 { 1116 int ret = 0; 1117 u32 bufsize; 1118 u32 i; 1119 struct cmd_ctrl_node *cmdarray; 1120 1121 /* Allocate and initialize the command array */ 1122 bufsize = sizeof(struct cmd_ctrl_node) * LBS_NUM_CMD_BUFFERS; 1123 if (!(cmdarray = kzalloc(bufsize, GFP_KERNEL))) { 1124 lbs_deb_host("ALLOC_CMD_BUF: tempcmd_array is NULL\n"); 1125 ret = -1; 1126 goto done; 1127 } 1128 priv->cmd_array = cmdarray; 1129 1130 /* Allocate and initialize each command buffer in the command array */ 1131 for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) { 1132 cmdarray[i].cmdbuf = kzalloc(LBS_CMD_BUFFER_SIZE, GFP_KERNEL); 1133 if (!cmdarray[i].cmdbuf) { 1134 lbs_deb_host("ALLOC_CMD_BUF: ptempvirtualaddr is NULL\n"); 1135 ret = -1; 1136 goto done; 1137 } 1138 } 1139 1140 for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) { 1141 init_waitqueue_head(&cmdarray[i].cmdwait_q); 1142 lbs_cleanup_and_insert_cmd(priv, &cmdarray[i]); 1143 } 1144 ret = 0; 1145 1146 done: 1147 return ret; 1148 } 1149 1150 /** 1151 * lbs_free_cmd_buffer - free the command buffer 1152 * 1153 * @priv: A pointer to &struct lbs_private structure 1154 * 1155 * returns: 0 for success 1156 */ 1157 int lbs_free_cmd_buffer(struct lbs_private *priv) 1158 { 1159 struct cmd_ctrl_node *cmdarray; 1160 unsigned int i; 1161 1162 /* need to check if cmd array is allocated or not */ 1163 if (priv->cmd_array == NULL) { 1164 lbs_deb_host("FREE_CMD_BUF: cmd_array is NULL\n"); 1165 goto done; 1166 } 1167 1168 cmdarray = priv->cmd_array; 1169 1170 /* Release shared memory buffers */ 1171 for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) { 1172 if (cmdarray[i].cmdbuf) { 1173 kfree(cmdarray[i].cmdbuf); 1174 cmdarray[i].cmdbuf = NULL; 1175 } 1176 } 1177 1178 /* Release cmd_ctrl_node */ 1179 if (priv->cmd_array) { 1180 kfree(priv->cmd_array); 1181 priv->cmd_array = NULL; 1182 } 1183 1184 done: 1185 return 0; 1186 } 1187 1188 /** 1189 * lbs_get_free_cmd_node - gets a free command node if available in 1190 * command free queue 1191 * 1192 * @priv: A pointer to &struct lbs_private structure 1193 * 1194 * returns: A pointer to &cmd_ctrl_node structure on success 1195 * or %NULL on error 1196 */ 1197 static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv) 1198 { 1199 struct cmd_ctrl_node *tempnode; 1200 unsigned long flags; 1201 1202 if (!priv) 1203 return NULL; 1204 1205 spin_lock_irqsave(&priv->driver_lock, flags); 1206 1207 if (!list_empty(&priv->cmdfreeq)) { 1208 tempnode = list_first_entry(&priv->cmdfreeq, 1209 struct cmd_ctrl_node, list); 1210 list_del_init(&tempnode->list); 1211 } else { 1212 lbs_deb_host("GET_CMD_NODE: cmd_ctrl_node is not available\n"); 1213 tempnode = NULL; 1214 } 1215 1216 spin_unlock_irqrestore(&priv->driver_lock, flags); 1217 1218 return tempnode; 1219 } 1220 1221 /** 1222 * lbs_execute_next_command - execute next command in command 1223 * pending queue. Will put firmware back to PS mode if applicable. 1224 * 1225 * @priv: A pointer to &struct lbs_private structure 1226 * 1227 * returns: 0 on success or -1 on error 1228 */ 1229 int lbs_execute_next_command(struct lbs_private *priv) 1230 { 1231 struct cmd_ctrl_node *cmdnode = NULL; 1232 struct cmd_header *cmd; 1233 unsigned long flags; 1234 int ret = 0; 1235 1236 /* Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the 1237 * only caller to us is lbs_thread() and we get even when a 1238 * data packet is received */ 1239 spin_lock_irqsave(&priv->driver_lock, flags); 1240 1241 if (priv->cur_cmd) { 1242 netdev_alert(priv->dev, 1243 "EXEC_NEXT_CMD: already processing command!\n"); 1244 spin_unlock_irqrestore(&priv->driver_lock, flags); 1245 ret = -1; 1246 goto done; 1247 } 1248 1249 if (!list_empty(&priv->cmdpendingq)) { 1250 cmdnode = list_first_entry(&priv->cmdpendingq, 1251 struct cmd_ctrl_node, list); 1252 } 1253 1254 spin_unlock_irqrestore(&priv->driver_lock, flags); 1255 1256 if (cmdnode) { 1257 cmd = cmdnode->cmdbuf; 1258 1259 if (is_command_allowed_in_ps(le16_to_cpu(cmd->command))) { 1260 if ((priv->psstate == PS_STATE_SLEEP) || 1261 (priv->psstate == PS_STATE_PRE_SLEEP)) { 1262 lbs_deb_host( 1263 "EXEC_NEXT_CMD: cannot send cmd 0x%04x in psstate %d\n", 1264 le16_to_cpu(cmd->command), 1265 priv->psstate); 1266 ret = -1; 1267 goto done; 1268 } 1269 lbs_deb_host("EXEC_NEXT_CMD: OK to send command " 1270 "0x%04x in psstate %d\n", 1271 le16_to_cpu(cmd->command), priv->psstate); 1272 } else if (priv->psstate != PS_STATE_FULL_POWER) { 1273 /* 1274 * 1. Non-PS command: 1275 * Queue it. set needtowakeup to TRUE if current state 1276 * is SLEEP, otherwise call send EXIT_PS. 1277 * 2. PS command but not EXIT_PS: 1278 * Ignore it. 1279 * 3. PS command EXIT_PS: 1280 * Set needtowakeup to TRUE if current state is SLEEP, 1281 * otherwise send this command down to firmware 1282 * immediately. 1283 */ 1284 if (cmd->command != cpu_to_le16(CMD_802_11_PS_MODE)) { 1285 /* Prepare to send Exit PS, 1286 * this non PS command will be sent later */ 1287 if ((priv->psstate == PS_STATE_SLEEP) 1288 || (priv->psstate == PS_STATE_PRE_SLEEP) 1289 ) { 1290 /* w/ new scheme, it will not reach here. 1291 since it is blocked in main_thread. */ 1292 priv->needtowakeup = 1; 1293 } else { 1294 lbs_set_ps_mode(priv, 1295 PS_MODE_ACTION_EXIT_PS, 1296 false); 1297 } 1298 1299 ret = 0; 1300 goto done; 1301 } else { 1302 /* 1303 * PS command. Ignore it if it is not Exit_PS. 1304 * otherwise send it down immediately. 1305 */ 1306 struct cmd_ds_802_11_ps_mode *psm = (void *)cmd; 1307 1308 lbs_deb_host( 1309 "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n", 1310 psm->action); 1311 if (psm->action != 1312 cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) { 1313 lbs_deb_host( 1314 "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n"); 1315 lbs_complete_command(priv, cmdnode, 0); 1316 1317 ret = 0; 1318 goto done; 1319 } 1320 1321 if ((priv->psstate == PS_STATE_SLEEP) || 1322 (priv->psstate == PS_STATE_PRE_SLEEP)) { 1323 lbs_deb_host( 1324 "EXEC_NEXT_CMD: ignore EXIT_PS cmd in sleep\n"); 1325 lbs_complete_command(priv, cmdnode, 0); 1326 priv->needtowakeup = 1; 1327 1328 ret = 0; 1329 goto done; 1330 } 1331 1332 lbs_deb_host( 1333 "EXEC_NEXT_CMD: sending EXIT_PS\n"); 1334 } 1335 } 1336 spin_lock_irqsave(&priv->driver_lock, flags); 1337 list_del_init(&cmdnode->list); 1338 spin_unlock_irqrestore(&priv->driver_lock, flags); 1339 lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n", 1340 le16_to_cpu(cmd->command)); 1341 lbs_submit_command(priv, cmdnode); 1342 } else { 1343 /* 1344 * check if in power save mode, if yes, put the device back 1345 * to PS mode 1346 */ 1347 if ((priv->psmode != LBS802_11POWERMODECAM) && 1348 (priv->psstate == PS_STATE_FULL_POWER) && 1349 (priv->connect_status == LBS_CONNECTED)) { 1350 lbs_deb_host( 1351 "EXEC_NEXT_CMD: cmdpendingq empty, go back to PS_SLEEP"); 1352 lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS, 1353 false); 1354 } 1355 } 1356 1357 ret = 0; 1358 done: 1359 return ret; 1360 } 1361 1362 static void lbs_send_confirmsleep(struct lbs_private *priv) 1363 { 1364 unsigned long flags; 1365 int ret; 1366 1367 lbs_deb_hex(LBS_DEB_HOST, "sleep confirm", (u8 *) &confirm_sleep, 1368 sizeof(confirm_sleep)); 1369 1370 ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) &confirm_sleep, 1371 sizeof(confirm_sleep)); 1372 if (ret) { 1373 netdev_alert(priv->dev, "confirm_sleep failed\n"); 1374 return; 1375 } 1376 1377 spin_lock_irqsave(&priv->driver_lock, flags); 1378 1379 /* We don't get a response on the sleep-confirmation */ 1380 priv->dnld_sent = DNLD_RES_RECEIVED; 1381 1382 if (priv->is_host_sleep_configured) { 1383 priv->is_host_sleep_activated = 1; 1384 wake_up_interruptible(&priv->host_sleep_q); 1385 } 1386 1387 /* If nothing to do, go back to sleep (?) */ 1388 if (!kfifo_len(&priv->event_fifo) && !priv->resp_len[priv->resp_idx]) 1389 priv->psstate = PS_STATE_SLEEP; 1390 1391 spin_unlock_irqrestore(&priv->driver_lock, flags); 1392 } 1393 1394 /** 1395 * lbs_ps_confirm_sleep - checks condition and prepares to 1396 * send sleep confirm command to firmware if ok 1397 * 1398 * @priv: A pointer to &struct lbs_private structure 1399 * 1400 * returns: n/a 1401 */ 1402 void lbs_ps_confirm_sleep(struct lbs_private *priv) 1403 { 1404 unsigned long flags =0; 1405 int allowed = 1; 1406 1407 spin_lock_irqsave(&priv->driver_lock, flags); 1408 if (priv->dnld_sent) { 1409 allowed = 0; 1410 lbs_deb_host("dnld_sent was set\n"); 1411 } 1412 1413 /* In-progress command? */ 1414 if (priv->cur_cmd) { 1415 allowed = 0; 1416 lbs_deb_host("cur_cmd was set\n"); 1417 } 1418 1419 /* Pending events or command responses? */ 1420 if (kfifo_len(&priv->event_fifo) || priv->resp_len[priv->resp_idx]) { 1421 allowed = 0; 1422 lbs_deb_host("pending events or command responses\n"); 1423 } 1424 spin_unlock_irqrestore(&priv->driver_lock, flags); 1425 1426 if (allowed) { 1427 lbs_deb_host("sending lbs_ps_confirm_sleep\n"); 1428 lbs_send_confirmsleep(priv); 1429 } else { 1430 lbs_deb_host("sleep confirm has been delayed\n"); 1431 } 1432 } 1433 1434 1435 /** 1436 * lbs_set_tpc_cfg - Configures the transmission power control functionality 1437 * 1438 * @priv: A pointer to &struct lbs_private structure 1439 * @enable: Transmission power control enable 1440 * @p0: Power level when link quality is good (dBm). 1441 * @p1: Power level when link quality is fair (dBm). 1442 * @p2: Power level when link quality is poor (dBm). 1443 * @usesnr: Use Signal to Noise Ratio in TPC 1444 * 1445 * returns: 0 on success 1446 */ 1447 int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1, 1448 int8_t p2, int usesnr) 1449 { 1450 struct cmd_ds_802_11_tpc_cfg cmd; 1451 int ret; 1452 1453 memset(&cmd, 0, sizeof(cmd)); 1454 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 1455 cmd.action = cpu_to_le16(CMD_ACT_SET); 1456 cmd.enable = !!enable; 1457 cmd.usesnr = !!usesnr; 1458 cmd.P0 = p0; 1459 cmd.P1 = p1; 1460 cmd.P2 = p2; 1461 1462 ret = lbs_cmd_with_response(priv, CMD_802_11_TPC_CFG, &cmd); 1463 1464 return ret; 1465 } 1466 1467 /** 1468 * lbs_set_power_adapt_cfg - Configures the power adaptation settings 1469 * 1470 * @priv: A pointer to &struct lbs_private structure 1471 * @enable: Power adaptation enable 1472 * @p0: Power level for 1, 2, 5.5 and 11 Mbps (dBm). 1473 * @p1: Power level for 6, 9, 12, 18, 22, 24 and 36 Mbps (dBm). 1474 * @p2: Power level for 48 and 54 Mbps (dBm). 1475 * 1476 * returns: 0 on Success 1477 */ 1478 1479 int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0, 1480 int8_t p1, int8_t p2) 1481 { 1482 struct cmd_ds_802_11_pa_cfg cmd; 1483 int ret; 1484 1485 memset(&cmd, 0, sizeof(cmd)); 1486 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 1487 cmd.action = cpu_to_le16(CMD_ACT_SET); 1488 cmd.enable = !!enable; 1489 cmd.P0 = p0; 1490 cmd.P1 = p1; 1491 cmd.P2 = p2; 1492 1493 ret = lbs_cmd_with_response(priv, CMD_802_11_PA_CFG , &cmd); 1494 1495 return ret; 1496 } 1497 1498 1499 struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, 1500 uint16_t command, struct cmd_header *in_cmd, int in_cmd_size, 1501 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *), 1502 unsigned long callback_arg) 1503 { 1504 struct cmd_ctrl_node *cmdnode; 1505 1506 if (priv->surpriseremoved) { 1507 lbs_deb_host("PREP_CMD: card removed\n"); 1508 cmdnode = ERR_PTR(-ENOENT); 1509 goto done; 1510 } 1511 1512 /* No commands are allowed in Deep Sleep until we toggle the GPIO 1513 * to wake up the card and it has signaled that it's ready. 1514 */ 1515 if (!priv->is_auto_deep_sleep_enabled) { 1516 if (priv->is_deep_sleep) { 1517 lbs_deb_cmd("command not allowed in deep sleep\n"); 1518 cmdnode = ERR_PTR(-EBUSY); 1519 goto done; 1520 } 1521 } 1522 1523 cmdnode = lbs_get_free_cmd_node(priv); 1524 if (cmdnode == NULL) { 1525 lbs_deb_host("PREP_CMD: cmdnode is NULL\n"); 1526 1527 /* Wake up main thread to execute next command */ 1528 wake_up(&priv->waitq); 1529 cmdnode = ERR_PTR(-ENOBUFS); 1530 goto done; 1531 } 1532 1533 cmdnode->callback = callback; 1534 cmdnode->callback_arg = callback_arg; 1535 1536 /* Copy the incoming command to the buffer */ 1537 memcpy(cmdnode->cmdbuf, in_cmd, in_cmd_size); 1538 1539 /* Set command, clean result, move to buffer */ 1540 cmdnode->cmdbuf->command = cpu_to_le16(command); 1541 cmdnode->cmdbuf->size = cpu_to_le16(in_cmd_size); 1542 cmdnode->cmdbuf->result = 0; 1543 1544 lbs_deb_host("PREP_CMD: command 0x%04x\n", command); 1545 1546 cmdnode->cmdwaitqwoken = 0; 1547 lbs_queue_cmd(priv, cmdnode); 1548 wake_up(&priv->waitq); 1549 1550 done: 1551 return cmdnode; 1552 } 1553 1554 void lbs_cmd_async(struct lbs_private *priv, uint16_t command, 1555 struct cmd_header *in_cmd, int in_cmd_size) 1556 { 1557 __lbs_cmd_async(priv, command, in_cmd, in_cmd_size, 1558 lbs_cmd_async_callback, 0); 1559 } 1560 1561 int __lbs_cmd(struct lbs_private *priv, uint16_t command, 1562 struct cmd_header *in_cmd, int in_cmd_size, 1563 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *), 1564 unsigned long callback_arg) 1565 { 1566 struct cmd_ctrl_node *cmdnode; 1567 unsigned long flags; 1568 int ret = 0; 1569 1570 cmdnode = __lbs_cmd_async(priv, command, in_cmd, in_cmd_size, 1571 callback, callback_arg); 1572 if (IS_ERR(cmdnode)) { 1573 ret = PTR_ERR(cmdnode); 1574 goto done; 1575 } 1576 1577 might_sleep(); 1578 1579 /* 1580 * Be careful with signals here. A signal may be received as the system 1581 * goes into suspend or resume. We do not want this to interrupt the 1582 * command, so we perform an uninterruptible sleep. 1583 */ 1584 wait_event(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken); 1585 1586 spin_lock_irqsave(&priv->driver_lock, flags); 1587 ret = cmdnode->result; 1588 if (ret) 1589 netdev_info(priv->dev, "PREP_CMD: command 0x%04x failed: %d\n", 1590 command, ret); 1591 1592 __lbs_cleanup_and_insert_cmd(priv, cmdnode); 1593 spin_unlock_irqrestore(&priv->driver_lock, flags); 1594 1595 done: 1596 return ret; 1597 } 1598 EXPORT_SYMBOL_GPL(__lbs_cmd); 1599