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