aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/libertas/cmd.c')
-rw-r--r--drivers/net/wireless/libertas/cmd.c430
1 files changed, 234 insertions, 196 deletions
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 75427e61898d..a912fb68c099 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -480,181 +480,166 @@ int lbs_cmd_802_11_key_material(struct lbs_private *priv, uint16_t cmd_action,
480 return ret; 480 return ret;
481} 481}
482 482
483static int lbs_cmd_802_11_reset(struct cmd_ds_command *cmd, int cmd_action) 483/**
484{ 484 * @brief Set an SNMP MIB value
485 struct cmd_ds_802_11_reset *reset = &cmd->params.reset; 485 *
486 486 * @param priv A pointer to struct lbs_private structure
487 lbs_deb_enter(LBS_DEB_CMD); 487 * @param oid The OID to set in the firmware
488 488 * @param val Value to set the OID to
489 cmd->command = cpu_to_le16(CMD_802_11_RESET); 489 *
490 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_reset) + S_DS_GEN); 490 * @return 0 on success, error on failure
491 reset->action = cpu_to_le16(cmd_action); 491 */
492 492int lbs_set_snmp_mib(struct lbs_private *priv, u32 oid, u16 val)
493 lbs_deb_leave(LBS_DEB_CMD);
494 return 0;
495}
496
497static int lbs_cmd_802_11_snmp_mib(struct lbs_private *priv,
498 struct cmd_ds_command *cmd,
499 int cmd_action,
500 int cmd_oid, void *pdata_buf)
501{ 493{
502 struct cmd_ds_802_11_snmp_mib *pSNMPMIB = &cmd->params.smib; 494 struct cmd_ds_802_11_snmp_mib cmd;
503 u8 ucTemp; 495 int ret;
504 496
505 lbs_deb_enter(LBS_DEB_CMD); 497 lbs_deb_enter(LBS_DEB_CMD);
506 498
507 lbs_deb_cmd("SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid); 499 memset(&cmd, 0, sizeof (cmd));
508 500 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
509 cmd->command = cpu_to_le16(CMD_802_11_SNMP_MIB); 501 cmd.action = cpu_to_le16(CMD_ACT_SET);
510 cmd->size = cpu_to_le16(sizeof(*pSNMPMIB) + S_DS_GEN); 502 cmd.oid = cpu_to_le16((u16) oid);
511
512 switch (cmd_oid) {
513 case OID_802_11_INFRASTRUCTURE_MODE:
514 {
515 u8 mode = (u8) (size_t) pdata_buf;
516 pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET);
517 pSNMPMIB->oid = cpu_to_le16((u16) DESIRED_BSSTYPE_I);
518 pSNMPMIB->bufsize = cpu_to_le16(sizeof(u8));
519 if (mode == IW_MODE_ADHOC) {
520 ucTemp = SNMP_MIB_VALUE_ADHOC;
521 } else {
522 /* Infra and Auto modes */
523 ucTemp = SNMP_MIB_VALUE_INFRA;
524 }
525
526 memmove(pSNMPMIB->value, &ucTemp, sizeof(u8));
527 503
504 switch (oid) {
505 case SNMP_MIB_OID_BSS_TYPE:
506 cmd.bufsize = cpu_to_le16(sizeof(u8));
507 cmd.value[0] = (val == IW_MODE_ADHOC) ? 2 : 1;
528 break; 508 break;
509 case SNMP_MIB_OID_11D_ENABLE:
510 case SNMP_MIB_OID_FRAG_THRESHOLD:
511 case SNMP_MIB_OID_RTS_THRESHOLD:
512 case SNMP_MIB_OID_SHORT_RETRY_LIMIT:
513 case SNMP_MIB_OID_LONG_RETRY_LIMIT:
514 cmd.bufsize = cpu_to_le16(sizeof(u16));
515 *((__le16 *)(&cmd.value)) = cpu_to_le16(val);
516 break;
517 default:
518 lbs_deb_cmd("SNMP_CMD: (set) unhandled OID 0x%x\n", oid);
519 ret = -EINVAL;
520 goto out;
529 } 521 }
530 522
531 case OID_802_11D_ENABLE: 523 lbs_deb_cmd("SNMP_CMD: (set) oid 0x%x, oid size 0x%x, value 0x%x\n",
532 { 524 le16_to_cpu(cmd.oid), le16_to_cpu(cmd.bufsize), val);
533 u32 ulTemp;
534
535 pSNMPMIB->oid = cpu_to_le16((u16) DOT11D_I);
536
537 if (cmd_action == CMD_ACT_SET) {
538 pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET);
539 pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
540 ulTemp = *(u32 *)pdata_buf;
541 *((__le16 *)(pSNMPMIB->value)) =
542 cpu_to_le16((u16) ulTemp);
543 }
544 break;
545 }
546
547 case OID_802_11_FRAGMENTATION_THRESHOLD:
548 {
549 u32 ulTemp;
550
551 pSNMPMIB->oid = cpu_to_le16((u16) FRAGTHRESH_I);
552
553 if (cmd_action == CMD_ACT_GET) {
554 pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_GET);
555 } else if (cmd_action == CMD_ACT_SET) {
556 pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET);
557 pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
558 ulTemp = *((u32 *) pdata_buf);
559 *((__le16 *)(pSNMPMIB->value)) =
560 cpu_to_le16((u16) ulTemp);
561 525
562 } 526 ret = lbs_cmd_with_response(priv, CMD_802_11_SNMP_MIB, &cmd);
563 527
564 break; 528out:
565 } 529 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
530 return ret;
531}
566 532
567 case OID_802_11_RTS_THRESHOLD: 533/**
568 { 534 * @brief Get an SNMP MIB value
535 *
536 * @param priv A pointer to struct lbs_private structure
537 * @param oid The OID to retrieve from the firmware
538 * @param out_val Location for the returned value
539 *
540 * @return 0 on success, error on failure
541 */
542int lbs_get_snmp_mib(struct lbs_private *priv, u32 oid, u16 *out_val)
543{
544 struct cmd_ds_802_11_snmp_mib cmd;
545 int ret;
569 546
570 u32 ulTemp; 547 lbs_deb_enter(LBS_DEB_CMD);
571 pSNMPMIB->oid = cpu_to_le16(RTSTHRESH_I);
572 548
573 if (cmd_action == CMD_ACT_GET) { 549 memset(&cmd, 0, sizeof (cmd));
574 pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_GET); 550 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
575 } else if (cmd_action == CMD_ACT_SET) { 551 cmd.action = cpu_to_le16(CMD_ACT_GET);
576 pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET); 552 cmd.oid = cpu_to_le16(oid);
577 pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
578 ulTemp = *((u32 *)pdata_buf);
579 *(__le16 *)(pSNMPMIB->value) =
580 cpu_to_le16((u16) ulTemp);
581 553
582 } 554 ret = lbs_cmd_with_response(priv, CMD_802_11_SNMP_MIB, &cmd);
583 break; 555 if (ret)
584 } 556 goto out;
585 case OID_802_11_TX_RETRYCOUNT:
586 pSNMPMIB->oid = cpu_to_le16((u16) SHORT_RETRYLIM_I);
587
588 if (cmd_action == CMD_ACT_GET) {
589 pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_GET);
590 } else if (cmd_action == CMD_ACT_SET) {
591 pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET);
592 pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
593 *((__le16 *)(pSNMPMIB->value)) =
594 cpu_to_le16((u16) priv->txretrycount);
595 }
596 557
558 switch (le16_to_cpu(cmd.bufsize)) {
559 case sizeof(u8):
560 if (oid == SNMP_MIB_OID_BSS_TYPE) {
561 if (cmd.value[0] == 2)
562 *out_val = IW_MODE_ADHOC;
563 else
564 *out_val = IW_MODE_INFRA;
565 } else
566 *out_val = cmd.value[0];
567 break;
568 case sizeof(u16):
569 *out_val = le16_to_cpu(*((__le16 *)(&cmd.value)));
597 break; 570 break;
598 default: 571 default:
572 lbs_deb_cmd("SNMP_CMD: (get) unhandled OID 0x%x size %d\n",
573 oid, le16_to_cpu(cmd.bufsize));
599 break; 574 break;
600 } 575 }
601 576
602 lbs_deb_cmd( 577out:
603 "SNMP_CMD: command=0x%x, size=0x%x, seqnum=0x%x, result=0x%x\n", 578 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
604 le16_to_cpu(cmd->command), le16_to_cpu(cmd->size), 579 return ret;
605 le16_to_cpu(cmd->seqnum), le16_to_cpu(cmd->result));
606
607 lbs_deb_cmd(
608 "SNMP_CMD: action 0x%x, oid 0x%x, oidsize 0x%x, value 0x%x\n",
609 le16_to_cpu(pSNMPMIB->querytype), le16_to_cpu(pSNMPMIB->oid),
610 le16_to_cpu(pSNMPMIB->bufsize),
611 le16_to_cpu(*(__le16 *) pSNMPMIB->value));
612
613 lbs_deb_leave(LBS_DEB_CMD);
614 return 0;
615} 580}
616 581
617static int lbs_cmd_802_11_rf_tx_power(struct cmd_ds_command *cmd, 582/**
618 u16 cmd_action, void *pdata_buf) 583 * @brief Get the min, max, and current TX power
584 *
585 * @param priv A pointer to struct lbs_private structure
586 * @param curlevel Current power level in dBm
587 * @param minlevel Minimum supported power level in dBm (optional)
588 * @param maxlevel Maximum supported power level in dBm (optional)
589 *
590 * @return 0 on success, error on failure
591 */
592int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel,
593 s16 *maxlevel)
619{ 594{
620 595 struct cmd_ds_802_11_rf_tx_power cmd;
621 struct cmd_ds_802_11_rf_tx_power *prtp = &cmd->params.txp; 596 int ret;
622 597
623 lbs_deb_enter(LBS_DEB_CMD); 598 lbs_deb_enter(LBS_DEB_CMD);
624 599
625 cmd->size = 600 memset(&cmd, 0, sizeof(cmd));
626 cpu_to_le16((sizeof(struct cmd_ds_802_11_rf_tx_power)) + S_DS_GEN); 601 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
627 cmd->command = cpu_to_le16(CMD_802_11_RF_TX_POWER); 602 cmd.action = cpu_to_le16(CMD_ACT_GET);
628 prtp->action = cpu_to_le16(cmd_action); 603
604 ret = lbs_cmd_with_response(priv, CMD_802_11_RF_TX_POWER, &cmd);
605 if (ret == 0) {
606 *curlevel = le16_to_cpu(cmd.curlevel);
607 if (minlevel)
608 *minlevel = le16_to_cpu(cmd.minlevel);
609 if (maxlevel)
610 *maxlevel = le16_to_cpu(cmd.maxlevel);
611 }
629 612
630 lbs_deb_cmd("RF_TX_POWER_CMD: size:%d cmd:0x%x Act:%d\n", 613 lbs_deb_leave(LBS_DEB_CMD);
631 le16_to_cpu(cmd->size), le16_to_cpu(cmd->command), 614 return ret;
632 le16_to_cpu(prtp->action)); 615}
633 616
634 switch (cmd_action) { 617/**
635 case CMD_ACT_TX_POWER_OPT_GET: 618 * @brief Set the TX power
636 prtp->action = cpu_to_le16(CMD_ACT_GET); 619 *
637 prtp->currentlevel = 0; 620 * @param priv A pointer to struct lbs_private structure
638 break; 621 * @param dbm The desired power level in dBm
622 *
623 * @return 0 on success, error on failure
624 */
625int lbs_set_tx_power(struct lbs_private *priv, s16 dbm)
626{
627 struct cmd_ds_802_11_rf_tx_power cmd;
628 int ret;
639 629
640 case CMD_ACT_TX_POWER_OPT_SET_HIGH: 630 lbs_deb_enter(LBS_DEB_CMD);
641 prtp->action = cpu_to_le16(CMD_ACT_SET);
642 prtp->currentlevel = cpu_to_le16(CMD_ACT_TX_POWER_INDEX_HIGH);
643 break;
644 631
645 case CMD_ACT_TX_POWER_OPT_SET_MID: 632 memset(&cmd, 0, sizeof(cmd));
646 prtp->action = cpu_to_le16(CMD_ACT_SET); 633 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
647 prtp->currentlevel = cpu_to_le16(CMD_ACT_TX_POWER_INDEX_MID); 634 cmd.action = cpu_to_le16(CMD_ACT_SET);
648 break; 635 cmd.curlevel = cpu_to_le16(dbm);
649 636
650 case CMD_ACT_TX_POWER_OPT_SET_LOW: 637 lbs_deb_cmd("SET_RF_TX_POWER: %d dBm\n", dbm);
651 prtp->action = cpu_to_le16(CMD_ACT_SET); 638
652 prtp->currentlevel = cpu_to_le16(*((u16 *) pdata_buf)); 639 ret = lbs_cmd_with_response(priv, CMD_802_11_RF_TX_POWER, &cmd);
653 break;
654 }
655 640
656 lbs_deb_leave(LBS_DEB_CMD); 641 lbs_deb_leave(LBS_DEB_CMD);
657 return 0; 642 return ret;
658} 643}
659 644
660static int lbs_cmd_802_11_monitor_mode(struct cmd_ds_command *cmd, 645static int lbs_cmd_802_11_monitor_mode(struct cmd_ds_command *cmd,
@@ -1033,9 +1018,9 @@ int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
1033 return ret; 1018 return ret;
1034} 1019}
1035 1020
1036int lbs_mesh_config_send(struct lbs_private *priv, 1021static int __lbs_mesh_config_send(struct lbs_private *priv,
1037 struct cmd_ds_mesh_config *cmd, 1022 struct cmd_ds_mesh_config *cmd,
1038 uint16_t action, uint16_t type) 1023 uint16_t action, uint16_t type)
1039{ 1024{
1040 int ret; 1025 int ret;
1041 1026
@@ -1054,6 +1039,19 @@ int lbs_mesh_config_send(struct lbs_private *priv,
1054 return ret; 1039 return ret;
1055} 1040}
1056 1041
1042int lbs_mesh_config_send(struct lbs_private *priv,
1043 struct cmd_ds_mesh_config *cmd,
1044 uint16_t action, uint16_t type)
1045{
1046 int ret;
1047
1048 if (!(priv->fwcapinfo & FW_CAPINFO_PERSISTENT_CONFIG))
1049 return -EOPNOTSUPP;
1050
1051 ret = __lbs_mesh_config_send(priv, cmd, action, type);
1052 return ret;
1053}
1054
1057/* This function is the CMD_MESH_CONFIG legacy function. It only handles the 1055/* This function is the CMD_MESH_CONFIG legacy function. It only handles the
1058 * START and STOP actions. The extended actions supported by CMD_MESH_CONFIG 1056 * START and STOP actions. The extended actions supported by CMD_MESH_CONFIG
1059 * are all handled by preparing a struct cmd_ds_mesh_config and passing it to 1057 * are all handled by preparing a struct cmd_ds_mesh_config and passing it to
@@ -1095,7 +1093,7 @@ int lbs_mesh_config(struct lbs_private *priv, uint16_t action, uint16_t chan)
1095 action, priv->mesh_tlv, chan, 1093 action, priv->mesh_tlv, chan,
1096 escape_essid(priv->mesh_ssid, priv->mesh_ssid_len)); 1094 escape_essid(priv->mesh_ssid, priv->mesh_ssid_len));
1097 1095
1098 return lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv); 1096 return __lbs_mesh_config_send(priv, &cmd, action, priv->mesh_tlv);
1099} 1097}
1100 1098
1101static int lbs_cmd_bcn_ctrl(struct lbs_private * priv, 1099static int lbs_cmd_bcn_ctrl(struct lbs_private * priv,
@@ -1256,41 +1254,47 @@ void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
1256 priv->cur_cmd = NULL; 1254 priv->cur_cmd = NULL;
1257} 1255}
1258 1256
1259int lbs_set_radio_control(struct lbs_private *priv) 1257int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on)
1260{ 1258{
1261 int ret = 0;
1262 struct cmd_ds_802_11_radio_control cmd; 1259 struct cmd_ds_802_11_radio_control cmd;
1260 int ret = -EINVAL;
1263 1261
1264 lbs_deb_enter(LBS_DEB_CMD); 1262 lbs_deb_enter(LBS_DEB_CMD);
1265 1263
1266 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 1264 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1267 cmd.action = cpu_to_le16(CMD_ACT_SET); 1265 cmd.action = cpu_to_le16(CMD_ACT_SET);
1268 1266
1269 switch (priv->preamble) { 1267 /* Only v8 and below support setting the preamble */
1270 case CMD_TYPE_SHORT_PREAMBLE: 1268 if (priv->fwrelease < 0x09000000) {
1271 cmd.control = cpu_to_le16(SET_SHORT_PREAMBLE); 1269 switch (preamble) {
1272 break; 1270 case RADIO_PREAMBLE_SHORT:
1273 1271 if (!(priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE))
1274 case CMD_TYPE_LONG_PREAMBLE: 1272 goto out;
1275 cmd.control = cpu_to_le16(SET_LONG_PREAMBLE); 1273 /* Fall through */
1276 break; 1274 case RADIO_PREAMBLE_AUTO:
1275 case RADIO_PREAMBLE_LONG:
1276 cmd.control = cpu_to_le16(preamble);
1277 break;
1278 default:
1279 goto out;
1280 }
1281 }
1277 1282
1278 case CMD_TYPE_AUTO_PREAMBLE: 1283 if (radio_on)
1279 default: 1284 cmd.control |= cpu_to_le16(0x1);
1280 cmd.control = cpu_to_le16(SET_AUTO_PREAMBLE); 1285 else {
1281 break; 1286 cmd.control &= cpu_to_le16(~0x1);
1287 priv->txpower_cur = 0;
1282 } 1288 }
1283 1289
1284 if (priv->radioon) 1290 lbs_deb_cmd("RADIO_CONTROL: radio %s, preamble %d\n",
1285 cmd.control |= cpu_to_le16(TURN_ON_RF); 1291 radio_on ? "ON" : "OFF", preamble);
1286 else
1287 cmd.control &= cpu_to_le16(~TURN_ON_RF);
1288 1292
1289 lbs_deb_cmd("RADIO_SET: radio %d, preamble %d\n", priv->radioon, 1293 priv->radio_on = radio_on;
1290 priv->preamble);
1291 1294
1292 ret = lbs_cmd_with_response(priv, CMD_802_11_RADIO_CONTROL, &cmd); 1295 ret = lbs_cmd_with_response(priv, CMD_802_11_RADIO_CONTROL, &cmd);
1293 1296
1297out:
1294 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); 1298 lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
1295 return ret; 1299 return ret;
1296} 1300}
@@ -1380,55 +1384,25 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
1380 ret = lbs_cmd_80211_associate(priv, cmdptr, pdata_buf); 1384 ret = lbs_cmd_80211_associate(priv, cmdptr, pdata_buf);
1381 break; 1385 break;
1382 1386
1383 case CMD_802_11_DEAUTHENTICATE:
1384 ret = lbs_cmd_80211_deauthenticate(priv, cmdptr);
1385 break;
1386
1387 case CMD_802_11_AD_HOC_START:
1388 ret = lbs_cmd_80211_ad_hoc_start(priv, cmdptr, pdata_buf);
1389 break;
1390
1391 case CMD_802_11_RESET:
1392 ret = lbs_cmd_802_11_reset(cmdptr, cmd_action);
1393 break;
1394
1395 case CMD_802_11_AUTHENTICATE: 1387 case CMD_802_11_AUTHENTICATE:
1396 ret = lbs_cmd_80211_authenticate(priv, cmdptr, pdata_buf); 1388 ret = lbs_cmd_80211_authenticate(priv, cmdptr, pdata_buf);
1397 break; 1389 break;
1398 1390
1399 case CMD_802_11_SNMP_MIB:
1400 ret = lbs_cmd_802_11_snmp_mib(priv, cmdptr,
1401 cmd_action, cmd_oid, pdata_buf);
1402 break;
1403
1404 case CMD_MAC_REG_ACCESS: 1391 case CMD_MAC_REG_ACCESS:
1405 case CMD_BBP_REG_ACCESS: 1392 case CMD_BBP_REG_ACCESS:
1406 case CMD_RF_REG_ACCESS: 1393 case CMD_RF_REG_ACCESS:
1407 ret = lbs_cmd_reg_access(cmdptr, cmd_action, pdata_buf); 1394 ret = lbs_cmd_reg_access(cmdptr, cmd_action, pdata_buf);
1408 break; 1395 break;
1409 1396
1410 case CMD_802_11_RF_TX_POWER:
1411 ret = lbs_cmd_802_11_rf_tx_power(cmdptr,
1412 cmd_action, pdata_buf);
1413 break;
1414
1415 case CMD_802_11_MONITOR_MODE: 1397 case CMD_802_11_MONITOR_MODE:
1416 ret = lbs_cmd_802_11_monitor_mode(cmdptr, 1398 ret = lbs_cmd_802_11_monitor_mode(cmdptr,
1417 cmd_action, pdata_buf); 1399 cmd_action, pdata_buf);
1418 break; 1400 break;
1419 1401
1420 case CMD_802_11_AD_HOC_JOIN:
1421 ret = lbs_cmd_80211_ad_hoc_join(priv, cmdptr, pdata_buf);
1422 break;
1423
1424 case CMD_802_11_RSSI: 1402 case CMD_802_11_RSSI:
1425 ret = lbs_cmd_802_11_rssi(priv, cmdptr); 1403 ret = lbs_cmd_802_11_rssi(priv, cmdptr);
1426 break; 1404 break;
1427 1405
1428 case CMD_802_11_AD_HOC_STOP:
1429 ret = lbs_cmd_80211_ad_hoc_stop(cmdptr);
1430 break;
1431
1432 case CMD_802_11_SET_AFC: 1406 case CMD_802_11_SET_AFC:
1433 case CMD_802_11_GET_AFC: 1407 case CMD_802_11_GET_AFC:
1434 1408
@@ -1953,6 +1927,70 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv)
1953} 1927}
1954 1928
1955 1929
1930/**
1931 * @brief Configures the transmission power control functionality.
1932 *
1933 * @param priv A pointer to struct lbs_private structure
1934 * @param enable Transmission power control enable
1935 * @param p0 Power level when link quality is good (dBm).
1936 * @param p1 Power level when link quality is fair (dBm).
1937 * @param p2 Power level when link quality is poor (dBm).
1938 * @param usesnr Use Signal to Noise Ratio in TPC
1939 *
1940 * @return 0 on success
1941 */
1942int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1,
1943 int8_t p2, int usesnr)
1944{
1945 struct cmd_ds_802_11_tpc_cfg cmd;
1946 int ret;
1947
1948 memset(&cmd, 0, sizeof(cmd));
1949 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1950 cmd.action = cpu_to_le16(CMD_ACT_SET);
1951 cmd.enable = !!enable;
1952 cmd.usesnr = !!usesnr;
1953 cmd.P0 = p0;
1954 cmd.P1 = p1;
1955 cmd.P2 = p2;
1956
1957 ret = lbs_cmd_with_response(priv, CMD_802_11_TPC_CFG, &cmd);
1958
1959 return ret;
1960}
1961
1962/**
1963 * @brief Configures the power adaptation settings.
1964 *
1965 * @param priv A pointer to struct lbs_private structure
1966 * @param enable Power adaptation enable
1967 * @param p0 Power level for 1, 2, 5.5 and 11 Mbps (dBm).
1968 * @param p1 Power level for 6, 9, 12, 18, 22, 24 and 36 Mbps (dBm).
1969 * @param p2 Power level for 48 and 54 Mbps (dBm).
1970 *
1971 * @return 0 on Success
1972 */
1973
1974int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0,
1975 int8_t p1, int8_t p2)
1976{
1977 struct cmd_ds_802_11_pa_cfg cmd;
1978 int ret;
1979
1980 memset(&cmd, 0, sizeof(cmd));
1981 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1982 cmd.action = cpu_to_le16(CMD_ACT_SET);
1983 cmd.enable = !!enable;
1984 cmd.P0 = p0;
1985 cmd.P1 = p1;
1986 cmd.P2 = p2;
1987
1988 ret = lbs_cmd_with_response(priv, CMD_802_11_PA_CFG , &cmd);
1989
1990 return ret;
1991}
1992
1993
1956static struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, 1994static struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv,
1957 uint16_t command, struct cmd_header *in_cmd, int in_cmd_size, 1995 uint16_t command, struct cmd_header *in_cmd, int in_cmd_size,
1958 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *), 1996 int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),