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 */ 30 int 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 } 40 EXPORT_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 */ 53 static 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 */ 67 static 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 */ 88 int 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 161 out: 162 lbs_deb_leave(LBS_DEB_CMD); 163 return ret; 164 } 165 166 static 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 183 int 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 } 222 EXPORT_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 */ 234 int 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 264 out: 265 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); 266 return ret; 267 } 268 269 int 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 311 static 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 329 int 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 365 static 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 376 int 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 */ 436 int 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 472 out: 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 */ 486 int 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 515 out: 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 */ 530 int 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 */ 563 int 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 */ 592 int 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 */ 622 static 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 640 out: 641 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); 642 return ret; 643 } 644 645 int 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 */ 669 int 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 692 out: 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 */ 706 int 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 * 737 * returns: 0 on success, error code on failure 738 */ 739 int lbs_set_11d_domain_info(struct lbs_private *priv) 740 { 741 struct wiphy *wiphy = priv->wdev->wiphy; 742 struct ieee80211_supported_band **bands = wiphy->bands; 743 struct cmd_ds_802_11d_domain_info cmd; 744 struct mrvl_ie_domain_param_set *domain = &cmd.domain; 745 struct ieee80211_country_ie_triplet *t; 746 enum nl80211_band band; 747 struct ieee80211_channel *ch; 748 u8 num_triplet = 0; 749 u8 num_parsed_chan = 0; 750 u8 first_channel = 0, next_chan = 0, max_pwr = 0; 751 u8 i, flag = 0; 752 size_t triplet_size; 753 int ret = 0; 754 755 lbs_deb_enter(LBS_DEB_11D); 756 if (!priv->country_code[0]) 757 goto out; 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 priv->country_code[0], priv->country_code[1]); 764 765 domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN); 766 767 /* Set country code */ 768 domain->country_code[0] = priv->country_code[0]; 769 domain->country_code[1] = priv->country_code[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 < NUM_NL80211_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 out: 852 lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret); 853 return ret; 854 } 855 856 /** 857 * lbs_get_reg - Read a MAC, Baseband, or RF register 858 * 859 * @priv: pointer to &struct lbs_private 860 * @reg: register command, one of CMD_MAC_REG_ACCESS, 861 * CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS 862 * @offset: byte offset of the register to get 863 * @value: on success, the value of the register at 'offset' 864 * 865 * returns: 0 on success, error code on failure 866 */ 867 int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value) 868 { 869 struct cmd_ds_reg_access cmd; 870 int ret = 0; 871 872 lbs_deb_enter(LBS_DEB_CMD); 873 874 BUG_ON(value == NULL); 875 876 memset(&cmd, 0, sizeof(cmd)); 877 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 878 cmd.action = cpu_to_le16(CMD_ACT_GET); 879 cmd.offset = cpu_to_le16(offset); 880 881 if (reg != CMD_MAC_REG_ACCESS && 882 reg != CMD_BBP_REG_ACCESS && 883 reg != CMD_RF_REG_ACCESS) { 884 ret = -EINVAL; 885 goto out; 886 } 887 888 ret = lbs_cmd_with_response(priv, reg, &cmd); 889 if (!ret) { 890 if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS) 891 *value = cmd.value.bbp_rf; 892 else if (reg == CMD_MAC_REG_ACCESS) 893 *value = le32_to_cpu(cmd.value.mac); 894 } 895 896 out: 897 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); 898 return ret; 899 } 900 901 /** 902 * lbs_set_reg - Write a MAC, Baseband, or RF register 903 * 904 * @priv: pointer to &struct lbs_private 905 * @reg: register command, one of CMD_MAC_REG_ACCESS, 906 * CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS 907 * @offset: byte offset of the register to set 908 * @value: the value to write to the register at 'offset' 909 * 910 * returns: 0 on success, error code on failure 911 */ 912 int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value) 913 { 914 struct cmd_ds_reg_access cmd; 915 int ret = 0; 916 917 lbs_deb_enter(LBS_DEB_CMD); 918 919 memset(&cmd, 0, sizeof(cmd)); 920 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 921 cmd.action = cpu_to_le16(CMD_ACT_SET); 922 cmd.offset = cpu_to_le16(offset); 923 924 if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS) 925 cmd.value.bbp_rf = (u8) (value & 0xFF); 926 else if (reg == CMD_MAC_REG_ACCESS) 927 cmd.value.mac = cpu_to_le32(value); 928 else { 929 ret = -EINVAL; 930 goto out; 931 } 932 933 ret = lbs_cmd_with_response(priv, reg, &cmd); 934 935 out: 936 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); 937 return ret; 938 } 939 940 static void lbs_queue_cmd(struct lbs_private *priv, 941 struct cmd_ctrl_node *cmdnode) 942 { 943 unsigned long flags; 944 int addtail = 1; 945 946 lbs_deb_enter(LBS_DEB_HOST); 947 948 if (!cmdnode) { 949 lbs_deb_host("QUEUE_CMD: cmdnode is NULL\n"); 950 goto done; 951 } 952 if (!cmdnode->cmdbuf->size) { 953 lbs_deb_host("DNLD_CMD: cmd size is zero\n"); 954 goto done; 955 } 956 cmdnode->result = 0; 957 958 /* Exit_PS command needs to be queued in the header always. */ 959 if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) { 960 struct cmd_ds_802_11_ps_mode *psm = (void *)cmdnode->cmdbuf; 961 962 if (psm->action == cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) { 963 if (priv->psstate != PS_STATE_FULL_POWER) 964 addtail = 0; 965 } 966 } 967 968 if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_WAKEUP_CONFIRM) 969 addtail = 0; 970 971 spin_lock_irqsave(&priv->driver_lock, flags); 972 973 if (addtail) 974 list_add_tail(&cmdnode->list, &priv->cmdpendingq); 975 else 976 list_add(&cmdnode->list, &priv->cmdpendingq); 977 978 spin_unlock_irqrestore(&priv->driver_lock, flags); 979 980 lbs_deb_host("QUEUE_CMD: inserted command 0x%04x into cmdpendingq\n", 981 le16_to_cpu(cmdnode->cmdbuf->command)); 982 983 done: 984 lbs_deb_leave(LBS_DEB_HOST); 985 } 986 987 static void lbs_submit_command(struct lbs_private *priv, 988 struct cmd_ctrl_node *cmdnode) 989 { 990 unsigned long flags; 991 struct cmd_header *cmd; 992 uint16_t cmdsize; 993 uint16_t command; 994 int timeo = 3 * HZ; 995 int ret; 996 997 lbs_deb_enter(LBS_DEB_HOST); 998 999 cmd = cmdnode->cmdbuf; 1000 1001 spin_lock_irqsave(&priv->driver_lock, flags); 1002 priv->seqnum++; 1003 cmd->seqnum = cpu_to_le16(priv->seqnum); 1004 priv->cur_cmd = cmdnode; 1005 spin_unlock_irqrestore(&priv->driver_lock, flags); 1006 1007 cmdsize = le16_to_cpu(cmd->size); 1008 command = le16_to_cpu(cmd->command); 1009 1010 /* These commands take longer */ 1011 if (command == CMD_802_11_SCAN || command == CMD_802_11_ASSOCIATE) 1012 timeo = 5 * HZ; 1013 1014 lbs_deb_cmd("DNLD_CMD: command 0x%04x, seq %d, size %d\n", 1015 command, le16_to_cpu(cmd->seqnum), cmdsize); 1016 lbs_deb_hex(LBS_DEB_CMD, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize); 1017 1018 ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize); 1019 1020 if (ret) { 1021 netdev_info(priv->dev, "DNLD_CMD: hw_host_to_card failed: %d\n", 1022 ret); 1023 /* Reset dnld state machine, report failure */ 1024 priv->dnld_sent = DNLD_RES_RECEIVED; 1025 lbs_complete_command(priv, cmdnode, ret); 1026 } 1027 1028 if (command == CMD_802_11_DEEP_SLEEP) { 1029 if (priv->is_auto_deep_sleep_enabled) { 1030 priv->wakeup_dev_required = 1; 1031 priv->dnld_sent = 0; 1032 } 1033 priv->is_deep_sleep = 1; 1034 lbs_complete_command(priv, cmdnode, 0); 1035 } else { 1036 /* Setup the timer after transmit command */ 1037 mod_timer(&priv->command_timer, jiffies + timeo); 1038 } 1039 1040 lbs_deb_leave(LBS_DEB_HOST); 1041 } 1042 1043 /* 1044 * This function inserts command node to cmdfreeq 1045 * after cleans it. Requires priv->driver_lock held. 1046 */ 1047 static void __lbs_cleanup_and_insert_cmd(struct lbs_private *priv, 1048 struct cmd_ctrl_node *cmdnode) 1049 { 1050 lbs_deb_enter(LBS_DEB_HOST); 1051 1052 if (!cmdnode) 1053 goto out; 1054 1055 cmdnode->callback = NULL; 1056 cmdnode->callback_arg = 0; 1057 1058 memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE); 1059 1060 list_add_tail(&cmdnode->list, &priv->cmdfreeq); 1061 out: 1062 lbs_deb_leave(LBS_DEB_HOST); 1063 } 1064 1065 static void lbs_cleanup_and_insert_cmd(struct lbs_private *priv, 1066 struct cmd_ctrl_node *ptempcmd) 1067 { 1068 unsigned long flags; 1069 1070 spin_lock_irqsave(&priv->driver_lock, flags); 1071 __lbs_cleanup_and_insert_cmd(priv, ptempcmd); 1072 spin_unlock_irqrestore(&priv->driver_lock, flags); 1073 } 1074 1075 void __lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd, 1076 int result) 1077 { 1078 /* 1079 * Normally, commands are removed from cmdpendingq before being 1080 * submitted. However, we can arrive here on alternative codepaths 1081 * where the command is still pending. Make sure the command really 1082 * isn't part of a list at this point. 1083 */ 1084 list_del_init(&cmd->list); 1085 1086 cmd->result = result; 1087 cmd->cmdwaitqwoken = 1; 1088 wake_up(&cmd->cmdwait_q); 1089 1090 if (!cmd->callback || cmd->callback == lbs_cmd_async_callback) 1091 __lbs_cleanup_and_insert_cmd(priv, cmd); 1092 priv->cur_cmd = NULL; 1093 wake_up(&priv->waitq); 1094 } 1095 1096 void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd, 1097 int result) 1098 { 1099 unsigned long flags; 1100 spin_lock_irqsave(&priv->driver_lock, flags); 1101 __lbs_complete_command(priv, cmd, result); 1102 spin_unlock_irqrestore(&priv->driver_lock, flags); 1103 } 1104 1105 int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on) 1106 { 1107 struct cmd_ds_802_11_radio_control cmd; 1108 int ret = -EINVAL; 1109 1110 lbs_deb_enter(LBS_DEB_CMD); 1111 1112 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 1113 cmd.action = cpu_to_le16(CMD_ACT_SET); 1114 cmd.control = 0; 1115 1116 /* Only v8 and below support setting the preamble */ 1117 if (priv->fwrelease < 0x09000000) { 1118 switch (preamble) { 1119 case RADIO_PREAMBLE_SHORT: 1120 case RADIO_PREAMBLE_AUTO: 1121 case RADIO_PREAMBLE_LONG: 1122 cmd.control = cpu_to_le16(preamble); 1123 break; 1124 default: 1125 goto out; 1126 } 1127 } 1128 1129 if (radio_on) 1130 cmd.control |= cpu_to_le16(0x1); 1131 else { 1132 cmd.control &= cpu_to_le16(~0x1); 1133 priv->txpower_cur = 0; 1134 } 1135 1136 lbs_deb_cmd("RADIO_CONTROL: radio %s, preamble %d\n", 1137 radio_on ? "ON" : "OFF", preamble); 1138 1139 priv->radio_on = radio_on; 1140 1141 ret = lbs_cmd_with_response(priv, CMD_802_11_RADIO_CONTROL, &cmd); 1142 1143 out: 1144 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); 1145 return ret; 1146 } 1147 1148 void lbs_set_mac_control(struct lbs_private *priv) 1149 { 1150 struct cmd_ds_mac_control cmd; 1151 1152 lbs_deb_enter(LBS_DEB_CMD); 1153 1154 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 1155 cmd.action = cpu_to_le16(priv->mac_control); 1156 cmd.reserved = 0; 1157 1158 lbs_cmd_async(priv, CMD_MAC_CONTROL, &cmd.hdr, sizeof(cmd)); 1159 1160 lbs_deb_leave(LBS_DEB_CMD); 1161 } 1162 1163 int lbs_set_mac_control_sync(struct lbs_private *priv) 1164 { 1165 struct cmd_ds_mac_control cmd; 1166 int ret = 0; 1167 1168 lbs_deb_enter(LBS_DEB_CMD); 1169 1170 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 1171 cmd.action = cpu_to_le16(priv->mac_control); 1172 cmd.reserved = 0; 1173 ret = lbs_cmd_with_response(priv, CMD_MAC_CONTROL, &cmd); 1174 1175 lbs_deb_leave(LBS_DEB_CMD); 1176 return ret; 1177 } 1178 1179 /** 1180 * lbs_allocate_cmd_buffer - allocates the command buffer and links 1181 * it to command free queue 1182 * 1183 * @priv: A pointer to &struct lbs_private structure 1184 * 1185 * returns: 0 for success or -1 on error 1186 */ 1187 int lbs_allocate_cmd_buffer(struct lbs_private *priv) 1188 { 1189 int ret = 0; 1190 u32 bufsize; 1191 u32 i; 1192 struct cmd_ctrl_node *cmdarray; 1193 1194 lbs_deb_enter(LBS_DEB_HOST); 1195 1196 /* Allocate and initialize the command array */ 1197 bufsize = sizeof(struct cmd_ctrl_node) * LBS_NUM_CMD_BUFFERS; 1198 if (!(cmdarray = kzalloc(bufsize, GFP_KERNEL))) { 1199 lbs_deb_host("ALLOC_CMD_BUF: tempcmd_array is NULL\n"); 1200 ret = -1; 1201 goto done; 1202 } 1203 priv->cmd_array = cmdarray; 1204 1205 /* Allocate and initialize each command buffer in the command array */ 1206 for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) { 1207 cmdarray[i].cmdbuf = kzalloc(LBS_CMD_BUFFER_SIZE, GFP_KERNEL); 1208 if (!cmdarray[i].cmdbuf) { 1209 lbs_deb_host("ALLOC_CMD_BUF: ptempvirtualaddr is NULL\n"); 1210 ret = -1; 1211 goto done; 1212 } 1213 } 1214 1215 for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) { 1216 init_waitqueue_head(&cmdarray[i].cmdwait_q); 1217 lbs_cleanup_and_insert_cmd(priv, &cmdarray[i]); 1218 } 1219 ret = 0; 1220 1221 done: 1222 lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret); 1223 return ret; 1224 } 1225 1226 /** 1227 * lbs_free_cmd_buffer - free the command buffer 1228 * 1229 * @priv: A pointer to &struct lbs_private structure 1230 * 1231 * returns: 0 for success 1232 */ 1233 int lbs_free_cmd_buffer(struct lbs_private *priv) 1234 { 1235 struct cmd_ctrl_node *cmdarray; 1236 unsigned int i; 1237 1238 lbs_deb_enter(LBS_DEB_HOST); 1239 1240 /* need to check if cmd array is allocated or not */ 1241 if (priv->cmd_array == NULL) { 1242 lbs_deb_host("FREE_CMD_BUF: cmd_array is NULL\n"); 1243 goto done; 1244 } 1245 1246 cmdarray = priv->cmd_array; 1247 1248 /* Release shared memory buffers */ 1249 for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) { 1250 if (cmdarray[i].cmdbuf) { 1251 kfree(cmdarray[i].cmdbuf); 1252 cmdarray[i].cmdbuf = NULL; 1253 } 1254 } 1255 1256 /* Release cmd_ctrl_node */ 1257 if (priv->cmd_array) { 1258 kfree(priv->cmd_array); 1259 priv->cmd_array = NULL; 1260 } 1261 1262 done: 1263 lbs_deb_leave(LBS_DEB_HOST); 1264 return 0; 1265 } 1266 1267 /** 1268 * lbs_get_free_cmd_node - gets a free command node if available in 1269 * command free queue 1270 * 1271 * @priv: A pointer to &struct lbs_private structure 1272 * 1273 * returns: A pointer to &cmd_ctrl_node structure on success 1274 * or %NULL on error 1275 */ 1276 static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv) 1277 { 1278 struct cmd_ctrl_node *tempnode; 1279 unsigned long flags; 1280 1281 lbs_deb_enter(LBS_DEB_HOST); 1282 1283 if (!priv) 1284 return NULL; 1285 1286 spin_lock_irqsave(&priv->driver_lock, flags); 1287 1288 if (!list_empty(&priv->cmdfreeq)) { 1289 tempnode = list_first_entry(&priv->cmdfreeq, 1290 struct cmd_ctrl_node, list); 1291 list_del_init(&tempnode->list); 1292 } else { 1293 lbs_deb_host("GET_CMD_NODE: cmd_ctrl_node is not available\n"); 1294 tempnode = NULL; 1295 } 1296 1297 spin_unlock_irqrestore(&priv->driver_lock, flags); 1298 1299 lbs_deb_leave(LBS_DEB_HOST); 1300 return tempnode; 1301 } 1302 1303 /** 1304 * lbs_execute_next_command - execute next command in command 1305 * pending queue. Will put firmware back to PS mode if applicable. 1306 * 1307 * @priv: A pointer to &struct lbs_private structure 1308 * 1309 * returns: 0 on success or -1 on error 1310 */ 1311 int lbs_execute_next_command(struct lbs_private *priv) 1312 { 1313 struct cmd_ctrl_node *cmdnode = NULL; 1314 struct cmd_header *cmd; 1315 unsigned long flags; 1316 int ret = 0; 1317 1318 /* Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the 1319 * only caller to us is lbs_thread() and we get even when a 1320 * data packet is received */ 1321 lbs_deb_enter(LBS_DEB_THREAD); 1322 1323 spin_lock_irqsave(&priv->driver_lock, flags); 1324 1325 if (priv->cur_cmd) { 1326 netdev_alert(priv->dev, 1327 "EXEC_NEXT_CMD: already processing command!\n"); 1328 spin_unlock_irqrestore(&priv->driver_lock, flags); 1329 ret = -1; 1330 goto done; 1331 } 1332 1333 if (!list_empty(&priv->cmdpendingq)) { 1334 cmdnode = list_first_entry(&priv->cmdpendingq, 1335 struct cmd_ctrl_node, list); 1336 } 1337 1338 spin_unlock_irqrestore(&priv->driver_lock, flags); 1339 1340 if (cmdnode) { 1341 cmd = cmdnode->cmdbuf; 1342 1343 if (is_command_allowed_in_ps(le16_to_cpu(cmd->command))) { 1344 if ((priv->psstate == PS_STATE_SLEEP) || 1345 (priv->psstate == PS_STATE_PRE_SLEEP)) { 1346 lbs_deb_host( 1347 "EXEC_NEXT_CMD: cannot send cmd 0x%04x in psstate %d\n", 1348 le16_to_cpu(cmd->command), 1349 priv->psstate); 1350 ret = -1; 1351 goto done; 1352 } 1353 lbs_deb_host("EXEC_NEXT_CMD: OK to send command " 1354 "0x%04x in psstate %d\n", 1355 le16_to_cpu(cmd->command), priv->psstate); 1356 } else if (priv->psstate != PS_STATE_FULL_POWER) { 1357 /* 1358 * 1. Non-PS command: 1359 * Queue it. set needtowakeup to TRUE if current state 1360 * is SLEEP, otherwise call send EXIT_PS. 1361 * 2. PS command but not EXIT_PS: 1362 * Ignore it. 1363 * 3. PS command EXIT_PS: 1364 * Set needtowakeup to TRUE if current state is SLEEP, 1365 * otherwise send this command down to firmware 1366 * immediately. 1367 */ 1368 if (cmd->command != cpu_to_le16(CMD_802_11_PS_MODE)) { 1369 /* Prepare to send Exit PS, 1370 * this non PS command will be sent later */ 1371 if ((priv->psstate == PS_STATE_SLEEP) 1372 || (priv->psstate == PS_STATE_PRE_SLEEP) 1373 ) { 1374 /* w/ new scheme, it will not reach here. 1375 since it is blocked in main_thread. */ 1376 priv->needtowakeup = 1; 1377 } else { 1378 lbs_set_ps_mode(priv, 1379 PS_MODE_ACTION_EXIT_PS, 1380 false); 1381 } 1382 1383 ret = 0; 1384 goto done; 1385 } else { 1386 /* 1387 * PS command. Ignore it if it is not Exit_PS. 1388 * otherwise send it down immediately. 1389 */ 1390 struct cmd_ds_802_11_ps_mode *psm = (void *)cmd; 1391 1392 lbs_deb_host( 1393 "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n", 1394 psm->action); 1395 if (psm->action != 1396 cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) { 1397 lbs_deb_host( 1398 "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n"); 1399 lbs_complete_command(priv, cmdnode, 0); 1400 1401 ret = 0; 1402 goto done; 1403 } 1404 1405 if ((priv->psstate == PS_STATE_SLEEP) || 1406 (priv->psstate == PS_STATE_PRE_SLEEP)) { 1407 lbs_deb_host( 1408 "EXEC_NEXT_CMD: ignore EXIT_PS cmd in sleep\n"); 1409 lbs_complete_command(priv, cmdnode, 0); 1410 priv->needtowakeup = 1; 1411 1412 ret = 0; 1413 goto done; 1414 } 1415 1416 lbs_deb_host( 1417 "EXEC_NEXT_CMD: sending EXIT_PS\n"); 1418 } 1419 } 1420 spin_lock_irqsave(&priv->driver_lock, flags); 1421 list_del_init(&cmdnode->list); 1422 spin_unlock_irqrestore(&priv->driver_lock, flags); 1423 lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n", 1424 le16_to_cpu(cmd->command)); 1425 lbs_submit_command(priv, cmdnode); 1426 } else { 1427 /* 1428 * check if in power save mode, if yes, put the device back 1429 * to PS mode 1430 */ 1431 if ((priv->psmode != LBS802_11POWERMODECAM) && 1432 (priv->psstate == PS_STATE_FULL_POWER) && 1433 (priv->connect_status == LBS_CONNECTED)) { 1434 lbs_deb_host( 1435 "EXEC_NEXT_CMD: cmdpendingq empty, go back to PS_SLEEP"); 1436 lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS, 1437 false); 1438 } 1439 } 1440 1441 ret = 0; 1442 done: 1443 lbs_deb_leave(LBS_DEB_THREAD); 1444 return ret; 1445 } 1446 1447 static void lbs_send_confirmsleep(struct lbs_private *priv) 1448 { 1449 unsigned long flags; 1450 int ret; 1451 1452 lbs_deb_enter(LBS_DEB_HOST); 1453 lbs_deb_hex(LBS_DEB_HOST, "sleep confirm", (u8 *) &confirm_sleep, 1454 sizeof(confirm_sleep)); 1455 1456 ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) &confirm_sleep, 1457 sizeof(confirm_sleep)); 1458 if (ret) { 1459 netdev_alert(priv->dev, "confirm_sleep failed\n"); 1460 goto out; 1461 } 1462 1463 spin_lock_irqsave(&priv->driver_lock, flags); 1464 1465 /* We don't get a response on the sleep-confirmation */ 1466 priv->dnld_sent = DNLD_RES_RECEIVED; 1467 1468 if (priv->is_host_sleep_configured) { 1469 priv->is_host_sleep_activated = 1; 1470 wake_up_interruptible(&priv->host_sleep_q); 1471 } 1472 1473 /* If nothing to do, go back to sleep (?) */ 1474 if (!kfifo_len(&priv->event_fifo) && !priv->resp_len[priv->resp_idx]) 1475 priv->psstate = PS_STATE_SLEEP; 1476 1477 spin_unlock_irqrestore(&priv->driver_lock, flags); 1478 1479 out: 1480 lbs_deb_leave(LBS_DEB_HOST); 1481 } 1482 1483 /** 1484 * lbs_ps_confirm_sleep - checks condition and prepares to 1485 * send sleep confirm command to firmware if ok 1486 * 1487 * @priv: A pointer to &struct lbs_private structure 1488 * 1489 * returns: n/a 1490 */ 1491 void lbs_ps_confirm_sleep(struct lbs_private *priv) 1492 { 1493 unsigned long flags =0; 1494 int allowed = 1; 1495 1496 lbs_deb_enter(LBS_DEB_HOST); 1497 1498 spin_lock_irqsave(&priv->driver_lock, flags); 1499 if (priv->dnld_sent) { 1500 allowed = 0; 1501 lbs_deb_host("dnld_sent was set\n"); 1502 } 1503 1504 /* In-progress command? */ 1505 if (priv->cur_cmd) { 1506 allowed = 0; 1507 lbs_deb_host("cur_cmd was set\n"); 1508 } 1509 1510 /* Pending events or command responses? */ 1511 if (kfifo_len(&priv->event_fifo) || priv->resp_len[priv->resp_idx]) { 1512 allowed = 0; 1513 lbs_deb_host("pending events or command responses\n"); 1514 } 1515 spin_unlock_irqrestore(&priv->driver_lock, flags); 1516 1517 if (allowed) { 1518 lbs_deb_host("sending lbs_ps_confirm_sleep\n"); 1519 lbs_send_confirmsleep(priv); 1520 } else { 1521 lbs_deb_host("sleep confirm has been delayed\n"); 1522 } 1523 1524 lbs_deb_leave(LBS_DEB_HOST); 1525 } 1526 1527 1528 /** 1529 * lbs_set_tpc_cfg - Configures the transmission power control functionality 1530 * 1531 * @priv: A pointer to &struct lbs_private structure 1532 * @enable: Transmission power control enable 1533 * @p0: Power level when link quality is good (dBm). 1534 * @p1: Power level when link quality is fair (dBm). 1535 * @p2: Power level when link quality is poor (dBm). 1536 * @usesnr: Use Signal to Noise Ratio in TPC 1537 * 1538 * returns: 0 on success 1539 */ 1540 int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1, 1541 int8_t p2, int usesnr) 1542 { 1543 struct cmd_ds_802_11_tpc_cfg cmd; 1544 int ret; 1545 1546 memset(&cmd, 0, sizeof(cmd)); 1547 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 1548 cmd.action = cpu_to_le16(CMD_ACT_SET); 1549 cmd.enable = !!enable; 1550 cmd.usesnr = !!usesnr; 1551 cmd.P0 = p0; 1552 cmd.P1 = p1; 1553 cmd.P2 = p2; 1554 1555 ret = lbs_cmd_with_response(priv, CMD_802_11_TPC_CFG, &cmd); 1556 1557 return ret; 1558 } 1559 1560 /** 1561 * lbs_set_power_adapt_cfg - Configures the power adaptation settings 1562 * 1563 * @priv: A pointer to &struct lbs_private structure 1564 * @enable: Power adaptation enable 1565 * @p0: Power level for 1, 2, 5.5 and 11 Mbps (dBm). 1566 * @p1: Power level for 6, 9, 12, 18, 22, 24 and 36 Mbps (dBm). 1567 * @p2: Power level for 48 and 54 Mbps (dBm). 1568 * 1569 * returns: 0 on Success 1570 */ 1571 1572 int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0, 1573 int8_t p1, int8_t p2) 1574 { 1575 struct cmd_ds_802_11_pa_cfg cmd; 1576 int ret; 1577 1578 memset(&cmd, 0, sizeof(cmd)); 1579 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 1580 cmd.action = cpu_to_le16(CMD_ACT_SET); 1581 cmd.enable = !!enable; 1582 cmd.P0 = p0; 1583 cmd.P1 = p1; 1584 cmd.P2 = p2; 1585 1586 ret = lbs_cmd_with_response(priv, CMD_802_11_PA_CFG , &cmd); 1587 1588 return ret; 1589 } 1590 1591 1592 struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, 1593 uint16_t command, struct cmd_header *in_cmd, int in_cmd_size, 1594 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *), 1595 unsigned long callback_arg) 1596 { 1597 struct cmd_ctrl_node *cmdnode; 1598 1599 lbs_deb_enter(LBS_DEB_HOST); 1600 1601 if (priv->surpriseremoved) { 1602 lbs_deb_host("PREP_CMD: card removed\n"); 1603 cmdnode = ERR_PTR(-ENOENT); 1604 goto done; 1605 } 1606 1607 /* No commands are allowed in Deep Sleep until we toggle the GPIO 1608 * to wake up the card and it has signaled that it's ready. 1609 */ 1610 if (!priv->is_auto_deep_sleep_enabled) { 1611 if (priv->is_deep_sleep) { 1612 lbs_deb_cmd("command not allowed in deep sleep\n"); 1613 cmdnode = ERR_PTR(-EBUSY); 1614 goto done; 1615 } 1616 } 1617 1618 cmdnode = lbs_get_free_cmd_node(priv); 1619 if (cmdnode == NULL) { 1620 lbs_deb_host("PREP_CMD: cmdnode is NULL\n"); 1621 1622 /* Wake up main thread to execute next command */ 1623 wake_up(&priv->waitq); 1624 cmdnode = ERR_PTR(-ENOBUFS); 1625 goto done; 1626 } 1627 1628 cmdnode->callback = callback; 1629 cmdnode->callback_arg = callback_arg; 1630 1631 /* Copy the incoming command to the buffer */ 1632 memcpy(cmdnode->cmdbuf, in_cmd, in_cmd_size); 1633 1634 /* Set command, clean result, move to buffer */ 1635 cmdnode->cmdbuf->command = cpu_to_le16(command); 1636 cmdnode->cmdbuf->size = cpu_to_le16(in_cmd_size); 1637 cmdnode->cmdbuf->result = 0; 1638 1639 lbs_deb_host("PREP_CMD: command 0x%04x\n", command); 1640 1641 cmdnode->cmdwaitqwoken = 0; 1642 lbs_queue_cmd(priv, cmdnode); 1643 wake_up(&priv->waitq); 1644 1645 done: 1646 lbs_deb_leave_args(LBS_DEB_HOST, "ret %p", cmdnode); 1647 return cmdnode; 1648 } 1649 1650 void lbs_cmd_async(struct lbs_private *priv, uint16_t command, 1651 struct cmd_header *in_cmd, int in_cmd_size) 1652 { 1653 lbs_deb_enter(LBS_DEB_CMD); 1654 __lbs_cmd_async(priv, command, in_cmd, in_cmd_size, 1655 lbs_cmd_async_callback, 0); 1656 lbs_deb_leave(LBS_DEB_CMD); 1657 } 1658 1659 int __lbs_cmd(struct lbs_private *priv, uint16_t command, 1660 struct cmd_header *in_cmd, int in_cmd_size, 1661 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *), 1662 unsigned long callback_arg) 1663 { 1664 struct cmd_ctrl_node *cmdnode; 1665 unsigned long flags; 1666 int ret = 0; 1667 1668 lbs_deb_enter(LBS_DEB_HOST); 1669 1670 cmdnode = __lbs_cmd_async(priv, command, in_cmd, in_cmd_size, 1671 callback, callback_arg); 1672 if (IS_ERR(cmdnode)) { 1673 ret = PTR_ERR(cmdnode); 1674 goto done; 1675 } 1676 1677 might_sleep(); 1678 1679 /* 1680 * Be careful with signals here. A signal may be received as the system 1681 * goes into suspend or resume. We do not want this to interrupt the 1682 * command, so we perform an uninterruptible sleep. 1683 */ 1684 wait_event(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken); 1685 1686 spin_lock_irqsave(&priv->driver_lock, flags); 1687 ret = cmdnode->result; 1688 if (ret) 1689 netdev_info(priv->dev, "PREP_CMD: command 0x%04x failed: %d\n", 1690 command, ret); 1691 1692 __lbs_cleanup_and_insert_cmd(priv, cmdnode); 1693 spin_unlock_irqrestore(&priv->driver_lock, flags); 1694 1695 done: 1696 lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret); 1697 return ret; 1698 } 1699 EXPORT_SYMBOL_GPL(__lbs_cmd); 1700