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