aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/wl12xx/cmd.c')
-rw-r--r--drivers/net/wireless/wl12xx/cmd.c866
1 files changed, 656 insertions, 210 deletions
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
index 97dd237a9580..a52299e548fa 100644
--- a/drivers/net/wireless/wl12xx/cmd.c
+++ b/drivers/net/wireless/wl12xx/cmd.c
@@ -134,11 +134,6 @@ int wl1271_cmd_general_parms(struct wl1271 *wl)
134 /* Override the REF CLK from the NVS with the one from platform data */ 134 /* Override the REF CLK from the NVS with the one from platform data */
135 gen_parms->general_params.ref_clock = wl->ref_clock; 135 gen_parms->general_params.ref_clock = wl->ref_clock;
136 136
137 /* LPD mode enable (bits 6-7) in WL1271 AP mode only */
138 if (wl->quirks & WL12XX_QUIRK_LPD_MODE)
139 gen_parms->general_params.general_settings |=
140 GENERAL_SETTINGS_DRPW_LPD;
141
142 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer); 137 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
143 if (ret < 0) { 138 if (ret < 0) {
144 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed"); 139 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
@@ -363,63 +358,476 @@ static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
363 return 0; 358 return 0;
364} 359}
365 360
366int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type) 361int wl12xx_cmd_role_enable(struct wl1271 *wl, u8 role_type, u8 *role_id)
367{ 362{
368 struct wl1271_cmd_join *join; 363 struct wl12xx_cmd_role_enable *cmd;
369 int ret, i; 364 int ret;
370 u8 *bssid; 365
366 wl1271_debug(DEBUG_CMD, "cmd role enable");
367
368 if (WARN_ON(*role_id != WL12XX_INVALID_ROLE_ID))
369 return -EBUSY;
371 370
372 join = kzalloc(sizeof(*join), GFP_KERNEL); 371 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
373 if (!join) { 372 if (!cmd) {
374 ret = -ENOMEM; 373 ret = -ENOMEM;
375 goto out; 374 goto out;
376 } 375 }
377 376
378 wl1271_debug(DEBUG_CMD, "cmd join"); 377 /* get role id */
378 cmd->role_id = find_first_zero_bit(wl->roles_map, WL12XX_MAX_ROLES);
379 if (cmd->role_id >= WL12XX_MAX_ROLES) {
380 ret = -EBUSY;
381 goto out_free;
382 }
383
384 memcpy(cmd->mac_address, wl->mac_addr, ETH_ALEN);
385 cmd->role_type = role_type;
386
387 ret = wl1271_cmd_send(wl, CMD_ROLE_ENABLE, cmd, sizeof(*cmd), 0);
388 if (ret < 0) {
389 wl1271_error("failed to initiate cmd role enable");
390 goto out_free;
391 }
392
393 __set_bit(cmd->role_id, wl->roles_map);
394 *role_id = cmd->role_id;
395
396out_free:
397 kfree(cmd);
398
399out:
400 return ret;
401}
402
403int wl12xx_cmd_role_disable(struct wl1271 *wl, u8 *role_id)
404{
405 struct wl12xx_cmd_role_disable *cmd;
406 int ret;
407
408 wl1271_debug(DEBUG_CMD, "cmd role disable");
409
410 if (WARN_ON(*role_id == WL12XX_INVALID_ROLE_ID))
411 return -ENOENT;
412
413 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
414 if (!cmd) {
415 ret = -ENOMEM;
416 goto out;
417 }
418 cmd->role_id = *role_id;
419
420 ret = wl1271_cmd_send(wl, CMD_ROLE_DISABLE, cmd, sizeof(*cmd), 0);
421 if (ret < 0) {
422 wl1271_error("failed to initiate cmd role disable");
423 goto out_free;
424 }
425
426 __clear_bit(*role_id, wl->roles_map);
427 *role_id = WL12XX_INVALID_ROLE_ID;
428
429out_free:
430 kfree(cmd);
431
432out:
433 return ret;
434}
435
436static int wl12xx_allocate_link(struct wl1271 *wl, u8 *hlid)
437{
438 u8 link = find_first_zero_bit(wl->links_map, WL12XX_MAX_LINKS);
439 if (link >= WL12XX_MAX_LINKS)
440 return -EBUSY;
441
442 __set_bit(link, wl->links_map);
443 *hlid = link;
444 return 0;
445}
446
447static void wl12xx_free_link(struct wl1271 *wl, u8 *hlid)
448{
449 if (*hlid == WL12XX_INVALID_LINK_ID)
450 return;
451
452 __clear_bit(*hlid, wl->links_map);
453 *hlid = WL12XX_INVALID_LINK_ID;
454}
455
456static int wl12xx_get_new_session_id(struct wl1271 *wl)
457{
458 if (wl->session_counter >= SESSION_COUNTER_MAX)
459 wl->session_counter = 0;
460
461 wl->session_counter++;
462
463 return wl->session_counter;
464}
379 465
380 /* Reverse order BSSID */ 466int wl12xx_cmd_role_start_dev(struct wl1271 *wl)
381 bssid = (u8 *) &join->bssid_lsb; 467{
382 for (i = 0; i < ETH_ALEN; i++) 468 struct wl12xx_cmd_role_start *cmd;
383 bssid[i] = wl->bssid[ETH_ALEN - i - 1]; 469 int ret;
384 470
385 join->rx_config_options = cpu_to_le32(wl->rx_config); 471 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
386 join->rx_filter_options = cpu_to_le32(wl->rx_filter); 472 if (!cmd) {
387 join->bss_type = bss_type; 473 ret = -ENOMEM;
388 join->basic_rate_set = cpu_to_le32(wl->basic_rate_set); 474 goto out;
389 join->supported_rate_set = cpu_to_le32(wl->rate_set); 475 }
390 476
477 wl1271_debug(DEBUG_CMD, "cmd role start dev %d", wl->dev_role_id);
478
479 cmd->role_id = wl->dev_role_id;
391 if (wl->band == IEEE80211_BAND_5GHZ) 480 if (wl->band == IEEE80211_BAND_5GHZ)
392 join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ; 481 cmd->band = WL12XX_BAND_5GHZ;
482 cmd->channel = wl->channel;
483
484 if (wl->dev_hlid == WL12XX_INVALID_LINK_ID) {
485 ret = wl12xx_allocate_link(wl, &wl->dev_hlid);
486 if (ret)
487 goto out_free;
488 }
489 cmd->device.hlid = wl->dev_hlid;
490 cmd->device.session = wl->session_counter;
393 491
394 join->beacon_interval = cpu_to_le16(wl->beacon_int); 492 wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d",
395 join->dtim_interval = WL1271_DEFAULT_DTIM_PERIOD; 493 cmd->role_id, cmd->device.hlid, cmd->device.session);
494
495 ret = wl1271_cmd_send(wl, CMD_ROLE_START, cmd, sizeof(*cmd), 0);
496 if (ret < 0) {
497 wl1271_error("failed to initiate cmd role enable");
498 goto err_hlid;
499 }
396 500
397 join->channel = wl->channel; 501 goto out_free;
398 join->ssid_len = wl->ssid_len;
399 memcpy(join->ssid, wl->ssid, wl->ssid_len);
400 502
401 join->ctrl |= wl->session_counter << WL1271_JOIN_CMD_TX_SESSION_OFFSET; 503err_hlid:
504 /* clear links on error */
505 __clear_bit(wl->dev_hlid, wl->links_map);
506 wl->dev_hlid = WL12XX_INVALID_LINK_ID;
402 507
403 wl1271_debug(DEBUG_CMD, "cmd join: basic_rate_set=0x%x, rate_set=0x%x",
404 join->basic_rate_set, join->supported_rate_set);
405 508
406 ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join), 0); 509out_free:
510 kfree(cmd);
511
512out:
513 return ret;
514}
515
516int wl12xx_cmd_role_stop_dev(struct wl1271 *wl)
517{
518 struct wl12xx_cmd_role_stop *cmd;
519 int ret;
520
521 if (WARN_ON(wl->dev_hlid == WL12XX_INVALID_LINK_ID))
522 return -EINVAL;
523
524 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
525 if (!cmd) {
526 ret = -ENOMEM;
527 goto out;
528 }
529
530 wl1271_debug(DEBUG_CMD, "cmd role stop dev");
531
532 cmd->role_id = wl->dev_role_id;
533 cmd->disc_type = DISCONNECT_IMMEDIATE;
534 cmd->reason = cpu_to_le16(WLAN_REASON_UNSPECIFIED);
535
536 ret = wl1271_cmd_send(wl, CMD_ROLE_STOP, cmd, sizeof(*cmd), 0);
537 if (ret < 0) {
538 wl1271_error("failed to initiate cmd role stop");
539 goto out_free;
540 }
541
542 ret = wl1271_cmd_wait_for_event(wl, DISCONNECT_EVENT_COMPLETE_ID);
407 if (ret < 0) { 543 if (ret < 0) {
408 wl1271_error("failed to initiate cmd join"); 544 wl1271_error("cmd role stop dev event completion error");
409 goto out_free; 545 goto out_free;
410 } 546 }
411 547
412 ret = wl1271_cmd_wait_for_event(wl, JOIN_EVENT_COMPLETE_ID); 548 wl12xx_free_link(wl, &wl->dev_hlid);
549
550out_free:
551 kfree(cmd);
552
553out:
554 return ret;
555}
556
557int wl12xx_cmd_role_start_sta(struct wl1271 *wl)
558{
559 struct wl12xx_cmd_role_start *cmd;
560 int ret;
561
562 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
563 if (!cmd) {
564 ret = -ENOMEM;
565 goto out;
566 }
567
568 wl1271_debug(DEBUG_CMD, "cmd role start sta %d", wl->role_id);
569
570 cmd->role_id = wl->role_id;
571 if (wl->band == IEEE80211_BAND_5GHZ)
572 cmd->band = WL12XX_BAND_5GHZ;
573 cmd->channel = wl->channel;
574 cmd->sta.basic_rate_set = cpu_to_le32(wl->basic_rate_set);
575 cmd->sta.beacon_interval = cpu_to_le16(wl->beacon_int);
576 cmd->sta.ssid_type = WL12XX_SSID_TYPE_ANY;
577 cmd->sta.ssid_len = wl->ssid_len;
578 memcpy(cmd->sta.ssid, wl->ssid, wl->ssid_len);
579 memcpy(cmd->sta.bssid, wl->bssid, ETH_ALEN);
580 cmd->sta.local_rates = cpu_to_le32(wl->rate_set);
581
582 if (wl->sta_hlid == WL12XX_INVALID_LINK_ID) {
583 ret = wl12xx_allocate_link(wl, &wl->sta_hlid);
584 if (ret)
585 goto out_free;
586 }
587 cmd->sta.hlid = wl->sta_hlid;
588 cmd->sta.session = wl12xx_get_new_session_id(wl);
589 cmd->sta.remote_rates = cpu_to_le32(wl->rate_set);
590
591 wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d "
592 "basic_rate_set: 0x%x, remote_rates: 0x%x",
593 wl->role_id, cmd->sta.hlid, cmd->sta.session,
594 wl->basic_rate_set, wl->rate_set);
595
596 ret = wl1271_cmd_send(wl, CMD_ROLE_START, cmd, sizeof(*cmd), 0);
597 if (ret < 0) {
598 wl1271_error("failed to initiate cmd role start sta");
599 goto err_hlid;
600 }
601
602 goto out_free;
603
604err_hlid:
605 /* clear links on error. */
606 wl12xx_free_link(wl, &wl->sta_hlid);
607
608out_free:
609 kfree(cmd);
610
611out:
612 return ret;
613}
614
615/* use this function to stop ibss as well */
616int wl12xx_cmd_role_stop_sta(struct wl1271 *wl)
617{
618 struct wl12xx_cmd_role_stop *cmd;
619 int ret;
620
621 if (WARN_ON(wl->sta_hlid == WL12XX_INVALID_LINK_ID))
622 return -EINVAL;
623
624 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
625 if (!cmd) {
626 ret = -ENOMEM;
627 goto out;
628 }
629
630 wl1271_debug(DEBUG_CMD, "cmd role stop sta %d", wl->role_id);
631
632 cmd->role_id = wl->role_id;
633 cmd->disc_type = DISCONNECT_IMMEDIATE;
634 cmd->reason = cpu_to_le16(WLAN_REASON_UNSPECIFIED);
635
636 ret = wl1271_cmd_send(wl, CMD_ROLE_STOP, cmd, sizeof(*cmd), 0);
637 if (ret < 0) {
638 wl1271_error("failed to initiate cmd role stop sta");
639 goto out_free;
640 }
641
642 wl12xx_free_link(wl, &wl->sta_hlid);
643
644out_free:
645 kfree(cmd);
646
647out:
648 return ret;
649}
650
651int wl12xx_cmd_role_start_ap(struct wl1271 *wl)
652{
653 struct wl12xx_cmd_role_start *cmd;
654 struct ieee80211_bss_conf *bss_conf = &wl->vif->bss_conf;
655 int ret;
656
657 wl1271_debug(DEBUG_CMD, "cmd role start ap %d", wl->role_id);
658
659 /* trying to use hidden SSID with an old hostapd version */
660 if (wl->ssid_len == 0 && !bss_conf->hidden_ssid) {
661 wl1271_error("got a null SSID from beacon/bss");
662 ret = -EINVAL;
663 goto out;
664 }
665
666 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
667 if (!cmd) {
668 ret = -ENOMEM;
669 goto out;
670 }
671
672 ret = wl12xx_allocate_link(wl, &wl->ap_global_hlid);
413 if (ret < 0) 673 if (ret < 0)
414 wl1271_error("cmd join event completion error"); 674 goto out_free;
675
676 ret = wl12xx_allocate_link(wl, &wl->ap_bcast_hlid);
677 if (ret < 0)
678 goto out_free_global;
679
680 cmd->role_id = wl->role_id;
681 cmd->ap.aging_period = cpu_to_le16(wl->conf.tx.ap_aging_period);
682 cmd->ap.bss_index = WL1271_AP_BSS_INDEX;
683 cmd->ap.global_hlid = wl->ap_global_hlid;
684 cmd->ap.broadcast_hlid = wl->ap_bcast_hlid;
685 cmd->ap.basic_rate_set = cpu_to_le32(wl->basic_rate_set);
686 cmd->ap.beacon_interval = cpu_to_le16(wl->beacon_int);
687 cmd->ap.dtim_interval = bss_conf->dtim_period;
688 cmd->ap.beacon_expiry = WL1271_AP_DEF_BEACON_EXP;
689 cmd->channel = wl->channel;
690
691 if (!bss_conf->hidden_ssid) {
692 /* take the SSID from the beacon for backward compatibility */
693 cmd->ap.ssid_type = WL12XX_SSID_TYPE_PUBLIC;
694 cmd->ap.ssid_len = wl->ssid_len;
695 memcpy(cmd->ap.ssid, wl->ssid, wl->ssid_len);
696 } else {
697 cmd->ap.ssid_type = WL12XX_SSID_TYPE_HIDDEN;
698 cmd->ap.ssid_len = bss_conf->ssid_len;
699 memcpy(cmd->ap.ssid, bss_conf->ssid, bss_conf->ssid_len);
700 }
701
702 cmd->ap.local_rates = cpu_to_le32(0xffffffff);
703
704 switch (wl->band) {
705 case IEEE80211_BAND_2GHZ:
706 cmd->band = RADIO_BAND_2_4GHZ;
707 break;
708 case IEEE80211_BAND_5GHZ:
709 cmd->band = RADIO_BAND_5GHZ;
710 break;
711 default:
712 wl1271_warning("ap start - unknown band: %d", (int)wl->band);
713 cmd->band = RADIO_BAND_2_4GHZ;
714 break;
715 }
716
717 ret = wl1271_cmd_send(wl, CMD_ROLE_START, cmd, sizeof(*cmd), 0);
718 if (ret < 0) {
719 wl1271_error("failed to initiate cmd role start ap");
720 goto out_free_bcast;
721 }
722
723 goto out_free;
724
725out_free_bcast:
726 wl12xx_free_link(wl, &wl->ap_bcast_hlid);
727
728out_free_global:
729 wl12xx_free_link(wl, &wl->ap_global_hlid);
730
731out_free:
732 kfree(cmd);
733
734out:
735 return ret;
736}
737
738int wl12xx_cmd_role_stop_ap(struct wl1271 *wl)
739{
740 struct wl12xx_cmd_role_stop *cmd;
741 int ret;
742
743 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
744 if (!cmd) {
745 ret = -ENOMEM;
746 goto out;
747 }
748
749 wl1271_debug(DEBUG_CMD, "cmd role stop ap %d", wl->role_id);
750
751 cmd->role_id = wl->role_id;
752
753 ret = wl1271_cmd_send(wl, CMD_ROLE_STOP, cmd, sizeof(*cmd), 0);
754 if (ret < 0) {
755 wl1271_error("failed to initiate cmd role stop ap");
756 goto out_free;
757 }
758
759 wl12xx_free_link(wl, &wl->ap_bcast_hlid);
760 wl12xx_free_link(wl, &wl->ap_global_hlid);
761
762out_free:
763 kfree(cmd);
764
765out:
766 return ret;
767}
768
769int wl12xx_cmd_role_start_ibss(struct wl1271 *wl)
770{
771 struct wl12xx_cmd_role_start *cmd;
772 struct ieee80211_bss_conf *bss_conf = &wl->vif->bss_conf;
773 int ret;
774
775 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
776 if (!cmd) {
777 ret = -ENOMEM;
778 goto out;
779 }
780
781 wl1271_debug(DEBUG_CMD, "cmd role start ibss %d", wl->role_id);
782
783 cmd->role_id = wl->role_id;
784 if (wl->band == IEEE80211_BAND_5GHZ)
785 cmd->band = WL12XX_BAND_5GHZ;
786 cmd->channel = wl->channel;
787 cmd->ibss.basic_rate_set = cpu_to_le32(wl->basic_rate_set);
788 cmd->ibss.beacon_interval = cpu_to_le16(wl->beacon_int);
789 cmd->ibss.dtim_interval = bss_conf->dtim_period;
790 cmd->ibss.ssid_type = WL12XX_SSID_TYPE_ANY;
791 cmd->ibss.ssid_len = wl->ssid_len;
792 memcpy(cmd->ibss.ssid, wl->ssid, wl->ssid_len);
793 memcpy(cmd->ibss.bssid, wl->bssid, ETH_ALEN);
794 cmd->sta.local_rates = cpu_to_le32(wl->rate_set);
795
796 if (wl->sta_hlid == WL12XX_INVALID_LINK_ID) {
797 ret = wl12xx_allocate_link(wl, &wl->sta_hlid);
798 if (ret)
799 goto out_free;
800 }
801 cmd->ibss.hlid = wl->sta_hlid;
802 cmd->ibss.remote_rates = cpu_to_le32(wl->rate_set);
803
804 wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d "
805 "basic_rate_set: 0x%x, remote_rates: 0x%x",
806 wl->role_id, cmd->sta.hlid, cmd->sta.session,
807 wl->basic_rate_set, wl->rate_set);
808
809 wl1271_debug(DEBUG_CMD, "wl->bssid = %pM", wl->bssid);
810
811 ret = wl1271_cmd_send(wl, CMD_ROLE_START, cmd, sizeof(*cmd), 0);
812 if (ret < 0) {
813 wl1271_error("failed to initiate cmd role enable");
814 goto err_hlid;
815 }
816
817 goto out_free;
818
819err_hlid:
820 /* clear links on error. */
821 wl12xx_free_link(wl, &wl->sta_hlid);
415 822
416out_free: 823out_free:
417 kfree(join); 824 kfree(cmd);
418 825
419out: 826out:
420 return ret; 827 return ret;
421} 828}
422 829
830
423/** 831/**
424 * send test command to firmware 832 * send test command to firmware
425 * 833 *
@@ -488,7 +896,7 @@ int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len)
488 struct acx_header *acx = buf; 896 struct acx_header *acx = buf;
489 int ret; 897 int ret;
490 898
491 wl1271_debug(DEBUG_CMD, "cmd configure"); 899 wl1271_debug(DEBUG_CMD, "cmd configure (%d)", id);
492 900
493 acx->id = cpu_to_le16(id); 901 acx->id = cpu_to_le16(id);
494 902
@@ -567,6 +975,7 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode)
567 goto out; 975 goto out;
568 } 976 }
569 977
978 ps_params->role_id = wl->role_id;
570 ps_params->ps_mode = ps_mode; 979 ps_params->ps_mode = ps_mode;
571 980
572 ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params, 981 ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
@@ -698,6 +1107,7 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl,
698{ 1107{
699 struct sk_buff *skb; 1108 struct sk_buff *skb;
700 int ret; 1109 int ret;
1110 u32 rate;
701 1111
702 skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len, 1112 skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len,
703 ie, ie_len); 1113 ie, ie_len);
@@ -708,14 +1118,13 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl,
708 1118
709 wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len); 1119 wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len);
710 1120
1121 rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[band]);
711 if (band == IEEE80211_BAND_2GHZ) 1122 if (band == IEEE80211_BAND_2GHZ)
712 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, 1123 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
713 skb->data, skb->len, 0, 1124 skb->data, skb->len, 0, rate);
714 wl->conf.tx.basic_rate);
715 else 1125 else
716 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, 1126 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
717 skb->data, skb->len, 0, 1127 skb->data, skb->len, 0, rate);
718 wl->conf.tx.basic_rate_5);
719 1128
720out: 1129out:
721 dev_kfree_skb(skb); 1130 dev_kfree_skb(skb);
@@ -726,6 +1135,7 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
726 struct sk_buff *skb) 1135 struct sk_buff *skb)
727{ 1136{
728 int ret; 1137 int ret;
1138 u32 rate;
729 1139
730 if (!skb) 1140 if (!skb)
731 skb = ieee80211_ap_probereq_get(wl->hw, wl->vif); 1141 skb = ieee80211_ap_probereq_get(wl->hw, wl->vif);
@@ -734,14 +1144,13 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
734 1144
735 wl1271_dump(DEBUG_SCAN, "AP PROBE REQ: ", skb->data, skb->len); 1145 wl1271_dump(DEBUG_SCAN, "AP PROBE REQ: ", skb->data, skb->len);
736 1146
1147 rate = wl1271_tx_min_rate_get(wl, wl->bitrate_masks[wl->band]);
737 if (wl->band == IEEE80211_BAND_2GHZ) 1148 if (wl->band == IEEE80211_BAND_2GHZ)
738 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, 1149 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
739 skb->data, skb->len, 0, 1150 skb->data, skb->len, 0, rate);
740 wl->conf.tx.basic_rate);
741 else 1151 else
742 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, 1152 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
743 skb->data, skb->len, 0, 1153 skb->data, skb->len, 0, rate);
744 wl->conf.tx.basic_rate_5);
745 1154
746 if (ret < 0) 1155 if (ret < 0)
747 wl1271_error("Unable to set ap probe request template."); 1156 wl1271_error("Unable to set ap probe request template.");
@@ -813,9 +1222,9 @@ int wl1271_build_qos_null_data(struct wl1271 *wl)
813 wl->basic_rate); 1222 wl->basic_rate);
814} 1223}
815 1224
816int wl1271_cmd_set_sta_default_wep_key(struct wl1271 *wl, u8 id) 1225int wl12xx_cmd_set_default_wep_key(struct wl1271 *wl, u8 id, u8 hlid)
817{ 1226{
818 struct wl1271_cmd_set_sta_keys *cmd; 1227 struct wl1271_cmd_set_keys *cmd;
819 int ret = 0; 1228 int ret = 0;
820 1229
821 wl1271_debug(DEBUG_CMD, "cmd set_default_wep_key %d", id); 1230 wl1271_debug(DEBUG_CMD, "cmd set_default_wep_key %d", id);
@@ -826,36 +1235,7 @@ int wl1271_cmd_set_sta_default_wep_key(struct wl1271 *wl, u8 id)
826 goto out; 1235 goto out;
827 } 1236 }
828 1237
829 cmd->id = id; 1238 cmd->hlid = hlid;
830 cmd->key_action = cpu_to_le16(KEY_SET_ID);
831 cmd->key_type = KEY_WEP;
832
833 ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0);
834 if (ret < 0) {
835 wl1271_warning("cmd set_default_wep_key failed: %d", ret);
836 goto out;
837 }
838
839out:
840 kfree(cmd);
841
842 return ret;
843}
844
845int wl1271_cmd_set_ap_default_wep_key(struct wl1271 *wl, u8 id)
846{
847 struct wl1271_cmd_set_ap_keys *cmd;
848 int ret = 0;
849
850 wl1271_debug(DEBUG_CMD, "cmd set_ap_default_wep_key %d", id);
851
852 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
853 if (!cmd) {
854 ret = -ENOMEM;
855 goto out;
856 }
857
858 cmd->hlid = WL1271_AP_BROADCAST_HLID;
859 cmd->key_id = id; 1239 cmd->key_id = id;
860 cmd->lid_key_type = WEP_DEFAULT_LID_TYPE; 1240 cmd->lid_key_type = WEP_DEFAULT_LID_TYPE;
861 cmd->key_action = cpu_to_le16(KEY_SET_ID); 1241 cmd->key_action = cpu_to_le16(KEY_SET_ID);
@@ -863,7 +1243,7 @@ int wl1271_cmd_set_ap_default_wep_key(struct wl1271 *wl, u8 id)
863 1243
864 ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0); 1244 ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0);
865 if (ret < 0) { 1245 if (ret < 0) {
866 wl1271_warning("cmd set_ap_default_wep_key failed: %d", ret); 1246 wl1271_warning("cmd set_default_wep_key failed: %d", ret);
867 goto out; 1247 goto out;
868 } 1248 }
869 1249
@@ -877,17 +1257,27 @@ int wl1271_cmd_set_sta_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
877 u8 key_size, const u8 *key, const u8 *addr, 1257 u8 key_size, const u8 *key, const u8 *addr,
878 u32 tx_seq_32, u16 tx_seq_16) 1258 u32 tx_seq_32, u16 tx_seq_16)
879{ 1259{
880 struct wl1271_cmd_set_sta_keys *cmd; 1260 struct wl1271_cmd_set_keys *cmd;
881 int ret = 0; 1261 int ret = 0;
882 1262
1263 /* hlid might have already been deleted */
1264 if (wl->sta_hlid == WL12XX_INVALID_LINK_ID)
1265 return 0;
1266
883 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1267 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
884 if (!cmd) { 1268 if (!cmd) {
885 ret = -ENOMEM; 1269 ret = -ENOMEM;
886 goto out; 1270 goto out;
887 } 1271 }
888 1272
889 if (key_type != KEY_WEP) 1273 cmd->hlid = wl->sta_hlid;
890 memcpy(cmd->addr, addr, ETH_ALEN); 1274
1275 if (key_type == KEY_WEP)
1276 cmd->lid_key_type = WEP_DEFAULT_LID_TYPE;
1277 else if (is_broadcast_ether_addr(addr))
1278 cmd->lid_key_type = BROADCAST_LID_TYPE;
1279 else
1280 cmd->lid_key_type = UNICAST_LID_TYPE;
891 1281
892 cmd->key_action = cpu_to_le16(action); 1282 cmd->key_action = cpu_to_le16(action);
893 cmd->key_size = key_size; 1283 cmd->key_size = key_size;
@@ -896,10 +1286,7 @@ int wl1271_cmd_set_sta_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
896 cmd->ac_seq_num16[0] = cpu_to_le16(tx_seq_16); 1286 cmd->ac_seq_num16[0] = cpu_to_le16(tx_seq_16);
897 cmd->ac_seq_num32[0] = cpu_to_le32(tx_seq_32); 1287 cmd->ac_seq_num32[0] = cpu_to_le32(tx_seq_32);
898 1288
899 /* we have only one SSID profile */ 1289 cmd->key_id = id;
900 cmd->ssid_profile = 0;
901
902 cmd->id = id;
903 1290
904 if (key_type == KEY_TKIP) { 1291 if (key_type == KEY_TKIP) {
905 /* 1292 /*
@@ -930,11 +1317,15 @@ out:
930 return ret; 1317 return ret;
931} 1318}
932 1319
1320/*
1321 * TODO: merge with sta/ibss into 1 set_key function.
1322 * note there are slight diffs
1323 */
933int wl1271_cmd_set_ap_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, 1324int wl1271_cmd_set_ap_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
934 u8 key_size, const u8 *key, u8 hlid, u32 tx_seq_32, 1325 u8 key_size, const u8 *key, u8 hlid, u32 tx_seq_32,
935 u16 tx_seq_16) 1326 u16 tx_seq_16)
936{ 1327{
937 struct wl1271_cmd_set_ap_keys *cmd; 1328 struct wl1271_cmd_set_keys *cmd;
938 int ret = 0; 1329 int ret = 0;
939 u8 lid_type; 1330 u8 lid_type;
940 1331
@@ -942,7 +1333,7 @@ int wl1271_cmd_set_ap_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
942 if (!cmd) 1333 if (!cmd)
943 return -ENOMEM; 1334 return -ENOMEM;
944 1335
945 if (hlid == WL1271_AP_BROADCAST_HLID) { 1336 if (hlid == wl->ap_bcast_hlid) {
946 if (key_type == KEY_WEP) 1337 if (key_type == KEY_WEP)
947 lid_type = WEP_DEFAULT_LID_TYPE; 1338 lid_type = WEP_DEFAULT_LID_TYPE;
948 else 1339 else
@@ -991,12 +1382,12 @@ out:
991 return ret; 1382 return ret;
992} 1383}
993 1384
994int wl1271_cmd_disconnect(struct wl1271 *wl) 1385int wl12xx_cmd_set_peer_state(struct wl1271 *wl, u8 hlid)
995{ 1386{
996 struct wl1271_cmd_disconnect *cmd; 1387 struct wl12xx_cmd_set_peer_state *cmd;
997 int ret = 0; 1388 int ret = 0;
998 1389
999 wl1271_debug(DEBUG_CMD, "cmd disconnect"); 1390 wl1271_debug(DEBUG_CMD, "cmd set peer state (hlid=%d)", hlid);
1000 1391
1001 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1392 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1002 if (!cmd) { 1393 if (!cmd) {
@@ -1004,21 +1395,15 @@ int wl1271_cmd_disconnect(struct wl1271 *wl)
1004 goto out; 1395 goto out;
1005 } 1396 }
1006 1397
1007 cmd->rx_config_options = cpu_to_le32(wl->rx_config); 1398 cmd->hlid = hlid;
1008 cmd->rx_filter_options = cpu_to_le32(wl->rx_filter); 1399 cmd->state = WL1271_CMD_STA_STATE_CONNECTED;
1009 /* disconnect reason is not used in immediate disconnections */
1010 cmd->type = DISCONNECT_IMMEDIATE;
1011 1400
1012 ret = wl1271_cmd_send(wl, CMD_DISCONNECT, cmd, sizeof(*cmd), 0); 1401 ret = wl1271_cmd_send(wl, CMD_SET_PEER_STATE, cmd, sizeof(*cmd), 0);
1013 if (ret < 0) { 1402 if (ret < 0) {
1014 wl1271_error("failed to send disconnect command"); 1403 wl1271_error("failed to send set peer state command");
1015 goto out_free; 1404 goto out_free;
1016 } 1405 }
1017 1406
1018 ret = wl1271_cmd_wait_for_event(wl, DISCONNECT_EVENT_COMPLETE_ID);
1019 if (ret < 0)
1020 wl1271_error("cmd disconnect event completion error");
1021
1022out_free: 1407out_free:
1023 kfree(cmd); 1408 kfree(cmd);
1024 1409
@@ -1026,12 +1411,13 @@ out:
1026 return ret; 1411 return ret;
1027} 1412}
1028 1413
1029int wl1271_cmd_set_sta_state(struct wl1271 *wl) 1414int wl12xx_cmd_add_peer(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid)
1030{ 1415{
1031 struct wl1271_cmd_set_sta_state *cmd; 1416 struct wl12xx_cmd_add_peer *cmd;
1032 int ret = 0; 1417 int i, ret;
1418 u32 sta_rates;
1033 1419
1034 wl1271_debug(DEBUG_CMD, "cmd set sta state"); 1420 wl1271_debug(DEBUG_CMD, "cmd add peer %d", (int)hlid);
1035 1421
1036 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1422 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1037 if (!cmd) { 1423 if (!cmd) {
@@ -1039,11 +1425,33 @@ int wl1271_cmd_set_sta_state(struct wl1271 *wl)
1039 goto out; 1425 goto out;
1040 } 1426 }
1041 1427
1042 cmd->state = WL1271_CMD_STA_STATE_CONNECTED; 1428 memcpy(cmd->addr, sta->addr, ETH_ALEN);
1429 cmd->bss_index = WL1271_AP_BSS_INDEX;
1430 cmd->aid = sta->aid;
1431 cmd->hlid = hlid;
1432 cmd->sp_len = sta->max_sp;
1433 cmd->wmm = sta->wme ? 1 : 0;
1434
1435 for (i = 0; i < NUM_ACCESS_CATEGORIES_COPY; i++)
1436 if (sta->wme && (sta->uapsd_queues & BIT(i)))
1437 cmd->psd_type[i] = WL1271_PSD_UPSD_TRIGGER;
1438 else
1439 cmd->psd_type[i] = WL1271_PSD_LEGACY;
1440
1441 sta_rates = sta->supp_rates[wl->band];
1442 if (sta->ht_cap.ht_supported)
1443 sta_rates |= sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET;
1043 1444
1044 ret = wl1271_cmd_send(wl, CMD_SET_STA_STATE, cmd, sizeof(*cmd), 0); 1445 cmd->supported_rates =
1446 cpu_to_le32(wl1271_tx_enabled_rates_get(wl, sta_rates,
1447 wl->band));
1448
1449 wl1271_debug(DEBUG_CMD, "new peer rates=0x%x queues=0x%x",
1450 cmd->supported_rates, sta->uapsd_queues);
1451
1452 ret = wl1271_cmd_send(wl, CMD_ADD_PEER, cmd, sizeof(*cmd), 0);
1045 if (ret < 0) { 1453 if (ret < 0) {
1046 wl1271_error("failed to send set STA state command"); 1454 wl1271_error("failed to initiate cmd add peer");
1047 goto out_free; 1455 goto out_free;
1048 } 1456 }
1049 1457
@@ -1054,23 +1462,12 @@ out:
1054 return ret; 1462 return ret;
1055} 1463}
1056 1464
1057int wl1271_cmd_start_bss(struct wl1271 *wl) 1465int wl12xx_cmd_remove_peer(struct wl1271 *wl, u8 hlid)
1058{ 1466{
1059 struct wl1271_cmd_bss_start *cmd; 1467 struct wl12xx_cmd_remove_peer *cmd;
1060 struct ieee80211_bss_conf *bss_conf = &wl->vif->bss_conf;
1061 int ret; 1468 int ret;
1062 1469
1063 wl1271_debug(DEBUG_CMD, "cmd start bss"); 1470 wl1271_debug(DEBUG_CMD, "cmd remove peer %d", (int)hlid);
1064
1065 /*
1066 * FIXME: We currently do not support hidden SSID. The real SSID
1067 * should be fetched from mac80211 first.
1068 */
1069 if (wl->ssid_len == 0) {
1070 wl1271_warning("Hidden SSID currently not supported for AP");
1071 ret = -EINVAL;
1072 goto out;
1073 }
1074 1471
1075 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1472 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1076 if (!cmd) { 1473 if (!cmd) {
@@ -1078,40 +1475,24 @@ int wl1271_cmd_start_bss(struct wl1271 *wl)
1078 goto out; 1475 goto out;
1079 } 1476 }
1080 1477
1081 memcpy(cmd->bssid, bss_conf->bssid, ETH_ALEN); 1478 cmd->hlid = hlid;
1082 1479 /* We never send a deauth, mac80211 is in charge of this */
1083 cmd->aging_period = cpu_to_le16(wl->conf.tx.ap_aging_period); 1480 cmd->reason_opcode = 0;
1084 cmd->bss_index = WL1271_AP_BSS_INDEX; 1481 cmd->send_deauth_flag = 0;
1085 cmd->global_hlid = WL1271_AP_GLOBAL_HLID;
1086 cmd->broadcast_hlid = WL1271_AP_BROADCAST_HLID;
1087 cmd->basic_rate_set = cpu_to_le32(wl->basic_rate_set);
1088 cmd->beacon_interval = cpu_to_le16(wl->beacon_int);
1089 cmd->dtim_interval = bss_conf->dtim_period;
1090 cmd->beacon_expiry = WL1271_AP_DEF_BEACON_EXP;
1091 cmd->channel = wl->channel;
1092 cmd->ssid_len = wl->ssid_len;
1093 cmd->ssid_type = SSID_TYPE_PUBLIC;
1094 memcpy(cmd->ssid, wl->ssid, wl->ssid_len);
1095
1096 switch (wl->band) {
1097 case IEEE80211_BAND_2GHZ:
1098 cmd->band = RADIO_BAND_2_4GHZ;
1099 break;
1100 case IEEE80211_BAND_5GHZ:
1101 cmd->band = RADIO_BAND_5GHZ;
1102 break;
1103 default:
1104 wl1271_warning("bss start - unknown band: %d", (int)wl->band);
1105 cmd->band = RADIO_BAND_2_4GHZ;
1106 break;
1107 }
1108 1482
1109 ret = wl1271_cmd_send(wl, CMD_BSS_START, cmd, sizeof(*cmd), 0); 1483 ret = wl1271_cmd_send(wl, CMD_REMOVE_PEER, cmd, sizeof(*cmd), 0);
1110 if (ret < 0) { 1484 if (ret < 0) {
1111 wl1271_error("failed to initiate cmd start bss"); 1485 wl1271_error("failed to initiate cmd remove peer");
1112 goto out_free; 1486 goto out_free;
1113 } 1487 }
1114 1488
1489 /*
1490 * We are ok with a timeout here. The event is sometimes not sent
1491 * due to a firmware bug.
1492 */
1493 wl1271_cmd_wait_for_event_or_timeout(wl,
1494 PEER_REMOVE_COMPLETE_EVENT_ID);
1495
1115out_free: 1496out_free:
1116 kfree(cmd); 1497 kfree(cmd);
1117 1498
@@ -1119,12 +1500,12 @@ out:
1119 return ret; 1500 return ret;
1120} 1501}
1121 1502
1122int wl1271_cmd_stop_bss(struct wl1271 *wl) 1503int wl12xx_cmd_config_fwlog(struct wl1271 *wl)
1123{ 1504{
1124 struct wl1271_cmd_bss_start *cmd; 1505 struct wl12xx_cmd_config_fwlog *cmd;
1125 int ret; 1506 int ret = 0;
1126 1507
1127 wl1271_debug(DEBUG_CMD, "cmd stop bss"); 1508 wl1271_debug(DEBUG_CMD, "cmd config firmware logger");
1128 1509
1129 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1510 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1130 if (!cmd) { 1511 if (!cmd) {
@@ -1132,11 +1513,15 @@ int wl1271_cmd_stop_bss(struct wl1271 *wl)
1132 goto out; 1513 goto out;
1133 } 1514 }
1134 1515
1135 cmd->bss_index = WL1271_AP_BSS_INDEX; 1516 cmd->logger_mode = wl->conf.fwlog.mode;
1517 cmd->log_severity = wl->conf.fwlog.severity;
1518 cmd->timestamp = wl->conf.fwlog.timestamp;
1519 cmd->output = wl->conf.fwlog.output;
1520 cmd->threshold = wl->conf.fwlog.threshold;
1136 1521
1137 ret = wl1271_cmd_send(wl, CMD_BSS_STOP, cmd, sizeof(*cmd), 0); 1522 ret = wl1271_cmd_send(wl, CMD_CONFIG_FWLOGGER, cmd, sizeof(*cmd), 0);
1138 if (ret < 0) { 1523 if (ret < 0) {
1139 wl1271_error("failed to initiate cmd stop bss"); 1524 wl1271_error("failed to send config firmware logger command");
1140 goto out_free; 1525 goto out_free;
1141 } 1526 }
1142 1527
@@ -1147,12 +1532,12 @@ out:
1147 return ret; 1532 return ret;
1148} 1533}
1149 1534
1150int wl1271_cmd_add_sta(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid) 1535int wl12xx_cmd_start_fwlog(struct wl1271 *wl)
1151{ 1536{
1152 struct wl1271_cmd_add_sta *cmd; 1537 struct wl12xx_cmd_start_fwlog *cmd;
1153 int ret; 1538 int ret = 0;
1154 1539
1155 wl1271_debug(DEBUG_CMD, "cmd add sta %d", (int)hlid); 1540 wl1271_debug(DEBUG_CMD, "cmd start firmware logger");
1156 1541
1157 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1542 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1158 if (!cmd) { 1543 if (!cmd) {
@@ -1160,23 +1545,35 @@ int wl1271_cmd_add_sta(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid)
1160 goto out; 1545 goto out;
1161 } 1546 }
1162 1547
1163 /* currently we don't support UAPSD */ 1548 ret = wl1271_cmd_send(wl, CMD_START_FWLOGGER, cmd, sizeof(*cmd), 0);
1164 cmd->sp_len = 0; 1549 if (ret < 0) {
1550 wl1271_error("failed to send start firmware logger command");
1551 goto out_free;
1552 }
1165 1553
1166 memcpy(cmd->addr, sta->addr, ETH_ALEN); 1554out_free:
1167 cmd->bss_index = WL1271_AP_BSS_INDEX; 1555 kfree(cmd);
1168 cmd->aid = sta->aid;
1169 cmd->hlid = hlid;
1170 cmd->wmm = sta->wme ? 1 : 0;
1171 1556
1172 cmd->supported_rates = cpu_to_le32(wl1271_tx_enabled_rates_get(wl, 1557out:
1173 sta->supp_rates[wl->band])); 1558 return ret;
1559}
1174 1560
1175 wl1271_debug(DEBUG_CMD, "new sta rates: 0x%x", cmd->supported_rates); 1561int wl12xx_cmd_stop_fwlog(struct wl1271 *wl)
1562{
1563 struct wl12xx_cmd_stop_fwlog *cmd;
1564 int ret = 0;
1176 1565
1177 ret = wl1271_cmd_send(wl, CMD_ADD_STA, cmd, sizeof(*cmd), 0); 1566 wl1271_debug(DEBUG_CMD, "cmd stop firmware logger");
1567
1568 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1569 if (!cmd) {
1570 ret = -ENOMEM;
1571 goto out;
1572 }
1573
1574 ret = wl1271_cmd_send(wl, CMD_STOP_FWLOGGER, cmd, sizeof(*cmd), 0);
1178 if (ret < 0) { 1575 if (ret < 0) {
1179 wl1271_error("failed to initiate cmd add sta"); 1576 wl1271_error("failed to send stop firmware logger command");
1180 goto out_free; 1577 goto out_free;
1181 } 1578 }
1182 1579
@@ -1187,12 +1584,15 @@ out:
1187 return ret; 1584 return ret;
1188} 1585}
1189 1586
1190int wl1271_cmd_remove_sta(struct wl1271 *wl, u8 hlid) 1587static int wl12xx_cmd_roc(struct wl1271 *wl, u8 role_id)
1191{ 1588{
1192 struct wl1271_cmd_remove_sta *cmd; 1589 struct wl12xx_cmd_roc *cmd;
1193 int ret; 1590 int ret = 0;
1194 1591
1195 wl1271_debug(DEBUG_CMD, "cmd remove sta %d", (int)hlid); 1592 wl1271_debug(DEBUG_CMD, "cmd roc %d (%d)", wl->channel, role_id);
1593
1594 if (WARN_ON(role_id == WL12XX_INVALID_ROLE_ID))
1595 return -EINVAL;
1196 1596
1197 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1597 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1198 if (!cmd) { 1598 if (!cmd) {
@@ -1200,23 +1600,28 @@ int wl1271_cmd_remove_sta(struct wl1271 *wl, u8 hlid)
1200 goto out; 1600 goto out;
1201 } 1601 }
1202 1602
1203 cmd->hlid = hlid; 1603 cmd->role_id = role_id;
1204 /* We never send a deauth, mac80211 is in charge of this */ 1604 cmd->channel = wl->channel;
1205 cmd->reason_opcode = 0; 1605 switch (wl->band) {
1206 cmd->send_deauth_flag = 0; 1606 case IEEE80211_BAND_2GHZ:
1607 cmd->band = RADIO_BAND_2_4GHZ;
1608 break;
1609 case IEEE80211_BAND_5GHZ:
1610 cmd->band = RADIO_BAND_5GHZ;
1611 break;
1612 default:
1613 wl1271_error("roc - unknown band: %d", (int)wl->band);
1614 ret = -EINVAL;
1615 goto out_free;
1616 }
1207 1617
1208 ret = wl1271_cmd_send(wl, CMD_REMOVE_STA, cmd, sizeof(*cmd), 0); 1618
1619 ret = wl1271_cmd_send(wl, CMD_REMAIN_ON_CHANNEL, cmd, sizeof(*cmd), 0);
1209 if (ret < 0) { 1620 if (ret < 0) {
1210 wl1271_error("failed to initiate cmd remove sta"); 1621 wl1271_error("failed to send ROC command");
1211 goto out_free; 1622 goto out_free;
1212 } 1623 }
1213 1624
1214 /*
1215 * We are ok with a timeout here. The event is sometimes not sent
1216 * due to a firmware bug.
1217 */
1218 wl1271_cmd_wait_for_event_or_timeout(wl, STA_REMOVE_COMPLETE_EVENT_ID);
1219
1220out_free: 1625out_free:
1221 kfree(cmd); 1626 kfree(cmd);
1222 1627
@@ -1224,28 +1629,24 @@ out:
1224 return ret; 1629 return ret;
1225} 1630}
1226 1631
1227int wl12xx_cmd_config_fwlog(struct wl1271 *wl) 1632static int wl12xx_cmd_croc(struct wl1271 *wl, u8 role_id)
1228{ 1633{
1229 struct wl12xx_cmd_config_fwlog *cmd; 1634 struct wl12xx_cmd_croc *cmd;
1230 int ret = 0; 1635 int ret = 0;
1231 1636
1232 wl1271_debug(DEBUG_CMD, "cmd config firmware logger"); 1637 wl1271_debug(DEBUG_CMD, "cmd croc (%d)", role_id);
1233 1638
1234 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1639 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1235 if (!cmd) { 1640 if (!cmd) {
1236 ret = -ENOMEM; 1641 ret = -ENOMEM;
1237 goto out; 1642 goto out;
1238 } 1643 }
1644 cmd->role_id = role_id;
1239 1645
1240 cmd->logger_mode = wl->conf.fwlog.mode; 1646 ret = wl1271_cmd_send(wl, CMD_CANCEL_REMAIN_ON_CHANNEL, cmd,
1241 cmd->log_severity = wl->conf.fwlog.severity; 1647 sizeof(*cmd), 0);
1242 cmd->timestamp = wl->conf.fwlog.timestamp;
1243 cmd->output = wl->conf.fwlog.output;
1244 cmd->threshold = wl->conf.fwlog.threshold;
1245
1246 ret = wl1271_cmd_send(wl, CMD_CONFIG_FWLOGGER, cmd, sizeof(*cmd), 0);
1247 if (ret < 0) { 1648 if (ret < 0) {
1248 wl1271_error("failed to send config firmware logger command"); 1649 wl1271_error("failed to send ROC command");
1249 goto out_free; 1650 goto out_free;
1250 } 1651 }
1251 1652
@@ -1256,12 +1657,52 @@ out:
1256 return ret; 1657 return ret;
1257} 1658}
1258 1659
1259int wl12xx_cmd_start_fwlog(struct wl1271 *wl) 1660int wl12xx_roc(struct wl1271 *wl, u8 role_id)
1260{ 1661{
1261 struct wl12xx_cmd_start_fwlog *cmd;
1262 int ret = 0; 1662 int ret = 0;
1263 1663
1264 wl1271_debug(DEBUG_CMD, "cmd start firmware logger"); 1664 if (WARN_ON(test_bit(role_id, wl->roc_map)))
1665 return 0;
1666
1667 ret = wl12xx_cmd_roc(wl, role_id);
1668 if (ret < 0)
1669 goto out;
1670
1671 ret = wl1271_cmd_wait_for_event(wl,
1672 REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID);
1673 if (ret < 0) {
1674 wl1271_error("cmd roc event completion error");
1675 goto out;
1676 }
1677
1678 __set_bit(role_id, wl->roc_map);
1679out:
1680 return ret;
1681}
1682
1683int wl12xx_croc(struct wl1271 *wl, u8 role_id)
1684{
1685 int ret = 0;
1686
1687 if (WARN_ON(!test_bit(role_id, wl->roc_map)))
1688 return 0;
1689
1690 ret = wl12xx_cmd_croc(wl, role_id);
1691 if (ret < 0)
1692 goto out;
1693
1694 __clear_bit(role_id, wl->roc_map);
1695out:
1696 return ret;
1697}
1698
1699int wl12xx_cmd_channel_switch(struct wl1271 *wl,
1700 struct ieee80211_channel_switch *ch_switch)
1701{
1702 struct wl12xx_cmd_channel_switch *cmd;
1703 int ret;
1704
1705 wl1271_debug(DEBUG_ACX, "cmd channel switch");
1265 1706
1266 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1707 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1267 if (!cmd) { 1708 if (!cmd) {
@@ -1269,9 +1710,14 @@ int wl12xx_cmd_start_fwlog(struct wl1271 *wl)
1269 goto out; 1710 goto out;
1270 } 1711 }
1271 1712
1272 ret = wl1271_cmd_send(wl, CMD_START_FWLOGGER, cmd, sizeof(*cmd), 0); 1713 cmd->channel = ch_switch->channel->hw_value;
1714 cmd->switch_time = ch_switch->count;
1715 cmd->tx_suspend = ch_switch->block_tx;
1716 cmd->flush = 0; /* this value is ignored by the FW */
1717
1718 ret = wl1271_cmd_send(wl, CMD_CHANNEL_SWITCH, cmd, sizeof(*cmd), 0);
1273 if (ret < 0) { 1719 if (ret < 0) {
1274 wl1271_error("failed to send start firmware logger command"); 1720 wl1271_error("failed to send channel switch command");
1275 goto out_free; 1721 goto out_free;
1276 } 1722 }
1277 1723
@@ -1282,12 +1728,12 @@ out:
1282 return ret; 1728 return ret;
1283} 1729}
1284 1730
1285int wl12xx_cmd_stop_fwlog(struct wl1271 *wl) 1731int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl)
1286{ 1732{
1287 struct wl12xx_cmd_stop_fwlog *cmd; 1733 struct wl12xx_cmd_stop_channel_switch *cmd;
1288 int ret = 0; 1734 int ret;
1289 1735
1290 wl1271_debug(DEBUG_CMD, "cmd stop firmware logger"); 1736 wl1271_debug(DEBUG_ACX, "cmd stop channel switch");
1291 1737
1292 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1738 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1293 if (!cmd) { 1739 if (!cmd) {
@@ -1295,9 +1741,9 @@ int wl12xx_cmd_stop_fwlog(struct wl1271 *wl)
1295 goto out; 1741 goto out;
1296 } 1742 }
1297 1743
1298 ret = wl1271_cmd_send(wl, CMD_STOP_FWLOGGER, cmd, sizeof(*cmd), 0); 1744 ret = wl1271_cmd_send(wl, CMD_STOP_CHANNEL_SWICTH, cmd, sizeof(*cmd), 0);
1299 if (ret < 0) { 1745 if (ret < 0) {
1300 wl1271_error("failed to send stop firmware logger command"); 1746 wl1271_error("failed to stop channel switch command");
1301 goto out_free; 1747 goto out_free;
1302 } 1748 }
1303 1749