aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/cmd.c
diff options
context:
space:
mode:
authorEliad Peller <eliad@wizery.com>2011-08-14 06:17:07 -0400
committerLuciano Coelho <coelho@ti.com>2011-08-22 05:35:24 -0400
commitc690ec816f9fa2ab2b6200c5b79b6933acca49a4 (patch)
tree984c89b9708b81724daee5f5a77eb9b4d1e2284d /drivers/net/wireless/wl12xx/cmd.c
parent7f097988f1bff42177b99cb4c8ec62e818d0b1a6 (diff)
wl12xx: update commands & events
Change the commands and events according to the new fw api (fw >= 6/7.3.0.0.75). The main change is the replacement of JOIN/DISCONNECT commands, with ROLE_START/ROLE_STOP commands. The use of these commands should be preceded by the ROLE_ENABLE command (allocating role resources), and followed by the ROLE_DISABLE command (freeing role resources). Signed-off-by: Eliad Peller <eliad@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx/cmd.c')
-rw-r--r--drivers/net/wireless/wl12xx/cmd.c515
1 files changed, 301 insertions, 214 deletions
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
index b6ef65a57b71..b13eed129a92 100644
--- a/drivers/net/wireless/wl12xx/cmd.c
+++ b/drivers/net/wireless/wl12xx/cmd.c
@@ -363,61 +363,294 @@ static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
363 return 0; 363 return 0;
364} 364}
365 365
366int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type) 366int wl12xx_cmd_role_enable(struct wl1271 *wl, u8 role_type, u8 *role_id)
367{ 367{
368 struct wl1271_cmd_join *join; 368 struct wl12xx_cmd_role_enable *cmd;
369 int ret, i; 369 int ret;
370 u8 *bssid; 370
371 wl1271_debug(DEBUG_CMD, "cmd role enable");
372
373 if (WARN_ON(*role_id != WL12XX_INVALID_ROLE_ID))
374 return -EBUSY;
375
376 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
377 if (!cmd) {
378 ret = -ENOMEM;
379 goto out;
380 }
381
382 /* get role id */
383 cmd->role_id = find_first_zero_bit(wl->roles_map, WL12XX_MAX_ROLES);
384 if (cmd->role_id >= WL12XX_MAX_ROLES) {
385 ret = -EBUSY;
386 goto out_free;
387 }
388
389 memcpy(cmd->mac_address, wl->mac_addr, ETH_ALEN);
390 cmd->role_type = role_type;
391
392 ret = wl1271_cmd_send(wl, CMD_ROLE_ENABLE, cmd, sizeof(*cmd), 0);
393 if (ret < 0) {
394 wl1271_error("failed to initiate cmd role enable");
395 goto out_free;
396 }
397
398 __set_bit(cmd->role_id, wl->roles_map);
399 *role_id = cmd->role_id;
371 400
372 join = kzalloc(sizeof(*join), GFP_KERNEL); 401out_free:
373 if (!join) { 402 kfree(cmd);
403
404out:
405 return ret;
406}
407
408int wl12xx_cmd_role_disable(struct wl1271 *wl, u8 *role_id)
409{
410 struct wl12xx_cmd_role_disable *cmd;
411 int ret;
412
413 wl1271_debug(DEBUG_CMD, "cmd role disable");
414
415 if (WARN_ON(*role_id == WL12XX_INVALID_ROLE_ID))
416 return -ENOENT;
417
418 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
419 if (!cmd) {
374 ret = -ENOMEM; 420 ret = -ENOMEM;
375 goto out; 421 goto out;
376 } 422 }
423 cmd->role_id = *role_id;
424
425 ret = wl1271_cmd_send(wl, CMD_ROLE_DISABLE, cmd, sizeof(*cmd), 0);
426 if (ret < 0) {
427 wl1271_error("failed to initiate cmd role disable");
428 goto out_free;
429 }
377 430
378 wl1271_debug(DEBUG_CMD, "cmd join"); 431 __clear_bit(*role_id, wl->roles_map);
432 *role_id = WL12XX_INVALID_ROLE_ID;
379 433
380 /* Reverse order BSSID */ 434out_free:
381 bssid = (u8 *) &join->bssid_lsb; 435 kfree(cmd);
382 for (i = 0; i < ETH_ALEN; i++) 436
383 bssid[i] = wl->bssid[ETH_ALEN - i - 1]; 437out:
438 return ret;
439}
440
441static int wl12xx_allocate_link(struct wl1271 *wl, u8 *hlid)
442{
443 u8 link = find_first_zero_bit(wl->links_map, WL12XX_MAX_LINKS);
444 if (link >= WL12XX_MAX_LINKS)
445 return -EBUSY;
446
447 __set_bit(link, wl->links_map);
448 *hlid = link;
449 return 0;
450}
451
452static void wl12xx_free_link(struct wl1271 *wl, u8 *hlid)
453{
454 if (*hlid == WL12XX_INVALID_LINK_ID)
455 return;
456
457 __clear_bit(*hlid, wl->links_map);
458 *hlid = WL12XX_INVALID_LINK_ID;
459}
460
461int wl12xx_cmd_role_start_sta(struct wl1271 *wl)
462{
463 struct wl12xx_cmd_role_start *cmd;
464 int ret;
384 465
385 join->bss_type = bss_type; 466 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
386 join->basic_rate_set = cpu_to_le32(wl->basic_rate_set); 467 if (!cmd) {
387 join->supported_rate_set = cpu_to_le32(wl->rate_set); 468 ret = -ENOMEM;
469 goto out;
470 }
388 471
472 wl1271_debug(DEBUG_CMD, "cmd role start sta %d", wl->role_id);
473
474 cmd->role_id = wl->role_id;
389 if (wl->band == IEEE80211_BAND_5GHZ) 475 if (wl->band == IEEE80211_BAND_5GHZ)
390 join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ; 476 cmd->band = WL12XX_BAND_5GHZ;
477 cmd->channel = wl->channel;
478 cmd->sta.basic_rate_set = cpu_to_le32(wl->basic_rate_set);
479 cmd->sta.beacon_interval = cpu_to_le16(wl->beacon_int);
480 cmd->sta.ssid_type = WL12XX_SSID_TYPE_ANY;
481 cmd->sta.ssid_len = wl->ssid_len;
482 memcpy(cmd->sta.ssid, wl->ssid, wl->ssid_len);
483 memcpy(cmd->sta.bssid, wl->bssid, ETH_ALEN);
484 cmd->sta.local_rates = cpu_to_le32(wl->rate_set);
485
486 if (wl->sta_hlid == WL12XX_INVALID_LINK_ID) {
487 ret = wl12xx_allocate_link(wl, &wl->sta_hlid);
488 if (ret)
489 goto out_free;
490 }
491 cmd->sta.hlid = wl->sta_hlid;
492 cmd->sta.session = wl->session_counter;
493 cmd->sta.remote_rates = cpu_to_le32(wl->rate_set);
494
495 wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d "
496 "basic_rate_set: 0x%x, remote_rates: 0x%x",
497 wl->role_id, cmd->sta.hlid, cmd->sta.session,
498 wl->basic_rate_set, wl->rate_set);
499
500 ret = wl1271_cmd_send(wl, CMD_ROLE_START, cmd, sizeof(*cmd), 0);
501 if (ret < 0) {
502 wl1271_error("failed to initiate cmd role start sta");
503 goto err_hlid;
504 }
505
506 goto out_free;
507
508err_hlid:
509 /* clear links on error. */
510 wl12xx_free_link(wl, &wl->sta_hlid);
511
512out_free:
513 kfree(cmd);
514
515out:
516 return ret;
517}
391 518
392 join->beacon_interval = cpu_to_le16(wl->beacon_int); 519int wl12xx_cmd_role_stop_sta(struct wl1271 *wl)
393 join->dtim_interval = WL1271_DEFAULT_DTIM_PERIOD; 520{
521 struct wl12xx_cmd_role_stop *cmd;
522 int ret;
523
524 if (WARN_ON(wl->sta_hlid == WL12XX_INVALID_LINK_ID))
525 return -EINVAL;
526
527 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
528 if (!cmd) {
529 ret = -ENOMEM;
530 goto out;
531 }
394 532
395 join->channel = wl->channel; 533 wl1271_debug(DEBUG_CMD, "cmd role stop sta %d", wl->role_id);
396 join->ssid_len = wl->ssid_len;
397 memcpy(join->ssid, wl->ssid, wl->ssid_len);
398 534
399 join->ctrl |= wl->session_counter << WL1271_JOIN_CMD_TX_SESSION_OFFSET; 535 cmd->role_id = wl->role_id;
536 cmd->disc_type = DISCONNECT_IMMEDIATE;
537 cmd->reason = cpu_to_le16(WLAN_REASON_UNSPECIFIED);
400 538
401 wl1271_debug(DEBUG_CMD, "cmd join: basic_rate_set=0x%x, rate_set=0x%x", 539 ret = wl1271_cmd_send(wl, CMD_ROLE_STOP, cmd, sizeof(*cmd), 0);
402 join->basic_rate_set, join->supported_rate_set); 540 if (ret < 0) {
541 wl1271_error("failed to initiate cmd role stop sta");
542 goto out_free;
543 }
403 544
404 ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join), 0); 545 ret = wl1271_cmd_wait_for_event(wl, DISCONNECT_EVENT_COMPLETE_ID);
405 if (ret < 0) { 546 if (ret < 0) {
406 wl1271_error("failed to initiate cmd join"); 547 wl1271_error("cmd role stop sta event completion error");
407 goto out_free; 548 goto out_free;
408 } 549 }
409 550
410 ret = wl1271_cmd_wait_for_event(wl, JOIN_EVENT_COMPLETE_ID); 551 wl12xx_free_link(wl, &wl->sta_hlid);
411 if (ret < 0) 552
412 wl1271_error("cmd join event completion error"); 553out_free:
554 kfree(cmd);
555
556out:
557 return ret;
558}
559
560int wl12xx_cmd_role_start_ap(struct wl1271 *wl)
561{
562 struct wl12xx_cmd_role_start *cmd;
563 struct ieee80211_bss_conf *bss_conf = &wl->vif->bss_conf;
564 int ret;
565
566 wl1271_debug(DEBUG_CMD, "cmd role start ap %d", wl->role_id);
567
568 /*
569 * We currently do not support hidden SSID. The real SSID
570 * should be fetched from mac80211 first.
571 */
572 if (wl->ssid_len == 0) {
573 wl1271_warning("Hidden SSID currently not supported for AP");
574 ret = -EINVAL;
575 goto out;
576 }
577
578 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
579 if (!cmd) {
580 ret = -ENOMEM;
581 goto out;
582 }
583
584 cmd->role_id = wl->role_id;
585 cmd->ap.aging_period = cpu_to_le16(wl->conf.tx.ap_aging_period);
586 cmd->ap.bss_index = WL1271_AP_BSS_INDEX;
587 cmd->ap.global_hlid = WL1271_AP_GLOBAL_HLID;
588 cmd->ap.broadcast_hlid = WL1271_AP_BROADCAST_HLID;
589 cmd->ap.basic_rate_set = cpu_to_le32(wl->basic_rate_set);
590 cmd->ap.beacon_interval = cpu_to_le16(wl->beacon_int);
591 cmd->ap.dtim_interval = bss_conf->dtim_period;
592 cmd->ap.beacon_expiry = WL1271_AP_DEF_BEACON_EXP;
593 cmd->channel = wl->channel;
594 cmd->ap.ssid_len = wl->ssid_len;
595 cmd->ap.ssid_type = WL12XX_SSID_TYPE_PUBLIC;
596 memcpy(cmd->ap.ssid, wl->ssid, wl->ssid_len);
597 cmd->ap.local_rates = cpu_to_le32(0xffffffff);
598
599 switch (wl->band) {
600 case IEEE80211_BAND_2GHZ:
601 cmd->band = RADIO_BAND_2_4GHZ;
602 break;
603 case IEEE80211_BAND_5GHZ:
604 cmd->band = RADIO_BAND_5GHZ;
605 break;
606 default:
607 wl1271_warning("ap start - unknown band: %d", (int)wl->band);
608 cmd->band = RADIO_BAND_2_4GHZ;
609 break;
610 }
611
612 ret = wl1271_cmd_send(wl, CMD_ROLE_START, cmd, sizeof(*cmd), 0);
613 if (ret < 0) {
614 wl1271_error("failed to initiate cmd role start ap");
615 goto out_free;
616 }
413 617
414out_free: 618out_free:
415 kfree(join); 619 kfree(cmd);
416 620
417out: 621out:
418 return ret; 622 return ret;
419} 623}
420 624
625int wl12xx_cmd_role_stop_ap(struct wl1271 *wl)
626{
627 struct wl12xx_cmd_role_stop *cmd;
628 int ret;
629
630 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
631 if (!cmd) {
632 ret = -ENOMEM;
633 goto out;
634 }
635
636 wl1271_debug(DEBUG_CMD, "cmd role stop ap %d", wl->role_id);
637
638 cmd->role_id = wl->role_id;
639
640 ret = wl1271_cmd_send(wl, CMD_ROLE_STOP, cmd, sizeof(*cmd), 0);
641 if (ret < 0) {
642 wl1271_error("failed to initiate cmd role stop ap");
643 goto out_free;
644 }
645
646out_free:
647 kfree(cmd);
648
649out:
650 return ret;
651}
652
653
421/** 654/**
422 * send test command to firmware 655 * send test command to firmware
423 * 656 *
@@ -565,6 +798,7 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode)
565 goto out; 798 goto out;
566 } 799 }
567 800
801 ps_params->role_id = wl->role_id;
568 ps_params->ps_mode = ps_mode; 802 ps_params->ps_mode = ps_mode;
569 803
570 ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params, 804 ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
@@ -811,9 +1045,9 @@ int wl1271_build_qos_null_data(struct wl1271 *wl)
811 wl->basic_rate); 1045 wl->basic_rate);
812} 1046}
813 1047
814int wl1271_cmd_set_sta_default_wep_key(struct wl1271 *wl, u8 id) 1048int wl12xx_cmd_set_default_wep_key(struct wl1271 *wl, u8 id, u8 hlid)
815{ 1049{
816 struct wl1271_cmd_set_sta_keys *cmd; 1050 struct wl1271_cmd_set_keys *cmd;
817 int ret = 0; 1051 int ret = 0;
818 1052
819 wl1271_debug(DEBUG_CMD, "cmd set_default_wep_key %d", id); 1053 wl1271_debug(DEBUG_CMD, "cmd set_default_wep_key %d", id);
@@ -824,36 +1058,7 @@ int wl1271_cmd_set_sta_default_wep_key(struct wl1271 *wl, u8 id)
824 goto out; 1058 goto out;
825 } 1059 }
826 1060
827 cmd->id = id; 1061 cmd->hlid = hlid;
828 cmd->key_action = cpu_to_le16(KEY_SET_ID);
829 cmd->key_type = KEY_WEP;
830
831 ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0);
832 if (ret < 0) {
833 wl1271_warning("cmd set_default_wep_key failed: %d", ret);
834 goto out;
835 }
836
837out:
838 kfree(cmd);
839
840 return ret;
841}
842
843int wl1271_cmd_set_ap_default_wep_key(struct wl1271 *wl, u8 id)
844{
845 struct wl1271_cmd_set_ap_keys *cmd;
846 int ret = 0;
847
848 wl1271_debug(DEBUG_CMD, "cmd set_ap_default_wep_key %d", id);
849
850 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
851 if (!cmd) {
852 ret = -ENOMEM;
853 goto out;
854 }
855
856 cmd->hlid = WL1271_AP_BROADCAST_HLID;
857 cmd->key_id = id; 1062 cmd->key_id = id;
858 cmd->lid_key_type = WEP_DEFAULT_LID_TYPE; 1063 cmd->lid_key_type = WEP_DEFAULT_LID_TYPE;
859 cmd->key_action = cpu_to_le16(KEY_SET_ID); 1064 cmd->key_action = cpu_to_le16(KEY_SET_ID);
@@ -861,7 +1066,7 @@ int wl1271_cmd_set_ap_default_wep_key(struct wl1271 *wl, u8 id)
861 1066
862 ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0); 1067 ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0);
863 if (ret < 0) { 1068 if (ret < 0) {
864 wl1271_warning("cmd set_ap_default_wep_key failed: %d", ret); 1069 wl1271_warning("cmd set_default_wep_key failed: %d", ret);
865 goto out; 1070 goto out;
866 } 1071 }
867 1072
@@ -875,7 +1080,7 @@ int wl1271_cmd_set_sta_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
875 u8 key_size, const u8 *key, const u8 *addr, 1080 u8 key_size, const u8 *key, const u8 *addr,
876 u32 tx_seq_32, u16 tx_seq_16) 1081 u32 tx_seq_32, u16 tx_seq_16)
877{ 1082{
878 struct wl1271_cmd_set_sta_keys *cmd; 1083 struct wl1271_cmd_set_keys *cmd;
879 int ret = 0; 1084 int ret = 0;
880 1085
881 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1086 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
@@ -884,8 +1089,14 @@ int wl1271_cmd_set_sta_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
884 goto out; 1089 goto out;
885 } 1090 }
886 1091
887 if (key_type != KEY_WEP) 1092 cmd->hlid = wl->sta_hlid;
888 memcpy(cmd->addr, addr, ETH_ALEN); 1093
1094 if (key_type == KEY_WEP)
1095 cmd->lid_key_type = WEP_DEFAULT_LID_TYPE;
1096 else if (is_broadcast_ether_addr(addr))
1097 cmd->lid_key_type = BROADCAST_LID_TYPE;
1098 else
1099 cmd->lid_key_type = UNICAST_LID_TYPE;
889 1100
890 cmd->key_action = cpu_to_le16(action); 1101 cmd->key_action = cpu_to_le16(action);
891 cmd->key_size = key_size; 1102 cmd->key_size = key_size;
@@ -894,10 +1105,7 @@ int wl1271_cmd_set_sta_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
894 cmd->ac_seq_num16[0] = cpu_to_le16(tx_seq_16); 1105 cmd->ac_seq_num16[0] = cpu_to_le16(tx_seq_16);
895 cmd->ac_seq_num32[0] = cpu_to_le32(tx_seq_32); 1106 cmd->ac_seq_num32[0] = cpu_to_le32(tx_seq_32);
896 1107
897 /* we have only one SSID profile */ 1108 cmd->key_id = id;
898 cmd->ssid_profile = 0;
899
900 cmd->id = id;
901 1109
902 if (key_type == KEY_TKIP) { 1110 if (key_type == KEY_TKIP) {
903 /* 1111 /*
@@ -928,11 +1136,15 @@ out:
928 return ret; 1136 return ret;
929} 1137}
930 1138
1139/*
1140 * TODO: merge with sta/ibss into 1 set_key function.
1141 * note there are slight diffs
1142 */
931int wl1271_cmd_set_ap_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, 1143int wl1271_cmd_set_ap_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
932 u8 key_size, const u8 *key, u8 hlid, u32 tx_seq_32, 1144 u8 key_size, const u8 *key, u8 hlid, u32 tx_seq_32,
933 u16 tx_seq_16) 1145 u16 tx_seq_16)
934{ 1146{
935 struct wl1271_cmd_set_ap_keys *cmd; 1147 struct wl1271_cmd_set_keys *cmd;
936 int ret = 0; 1148 int ret = 0;
937 u8 lid_type; 1149 u8 lid_type;
938 1150
@@ -989,45 +1201,12 @@ out:
989 return ret; 1201 return ret;
990} 1202}
991 1203
992int wl1271_cmd_disconnect(struct wl1271 *wl) 1204int wl12xx_cmd_set_peer_state(struct wl1271 *wl)
993{
994 struct wl1271_cmd_disconnect *cmd;
995 int ret = 0;
996
997 wl1271_debug(DEBUG_CMD, "cmd disconnect");
998
999 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1000 if (!cmd) {
1001 ret = -ENOMEM;
1002 goto out;
1003 }
1004
1005 /* disconnect reason is not used in immediate disconnections */
1006 cmd->type = DISCONNECT_IMMEDIATE;
1007
1008 ret = wl1271_cmd_send(wl, CMD_DISCONNECT, cmd, sizeof(*cmd), 0);
1009 if (ret < 0) {
1010 wl1271_error("failed to send disconnect command");
1011 goto out_free;
1012 }
1013
1014 ret = wl1271_cmd_wait_for_event(wl, DISCONNECT_EVENT_COMPLETE_ID);
1015 if (ret < 0)
1016 wl1271_error("cmd disconnect event completion error");
1017
1018out_free:
1019 kfree(cmd);
1020
1021out:
1022 return ret;
1023}
1024
1025int wl1271_cmd_set_sta_state(struct wl1271 *wl)
1026{ 1205{
1027 struct wl1271_cmd_set_sta_state *cmd; 1206 struct wl12xx_cmd_set_peer_state *cmd;
1028 int ret = 0; 1207 int ret = 0;
1029 1208
1030 wl1271_debug(DEBUG_CMD, "cmd set sta state"); 1209 wl1271_debug(DEBUG_CMD, "cmd set peer state (hlid=%d)", wl->sta_hlid);
1031 1210
1032 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1211 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1033 if (!cmd) { 1212 if (!cmd) {
@@ -1035,11 +1214,12 @@ int wl1271_cmd_set_sta_state(struct wl1271 *wl)
1035 goto out; 1214 goto out;
1036 } 1215 }
1037 1216
1217 cmd->hlid = wl->sta_hlid;
1038 cmd->state = WL1271_CMD_STA_STATE_CONNECTED; 1218 cmd->state = WL1271_CMD_STA_STATE_CONNECTED;
1039 1219
1040 ret = wl1271_cmd_send(wl, CMD_SET_STA_STATE, cmd, sizeof(*cmd), 0); 1220 ret = wl1271_cmd_send(wl, CMD_SET_PEER_STATE, cmd, sizeof(*cmd), 0);
1041 if (ret < 0) { 1221 if (ret < 0) {
1042 wl1271_error("failed to send set STA state command"); 1222 wl1271_error("failed to send set peer state command");
1043 goto out_free; 1223 goto out_free;
1044 } 1224 }
1045 1225
@@ -1049,106 +1229,12 @@ out_free:
1049out: 1229out:
1050 return ret; 1230 return ret;
1051} 1231}
1052 1232int wl12xx_cmd_add_peer(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid)
1053int wl1271_cmd_start_bss(struct wl1271 *wl)
1054{
1055 struct wl1271_cmd_bss_start *cmd;
1056 struct ieee80211_bss_conf *bss_conf = &wl->vif->bss_conf;
1057 int ret;
1058
1059 wl1271_debug(DEBUG_CMD, "cmd start bss");
1060
1061 /*
1062 * FIXME: We currently do not support hidden SSID. The real SSID
1063 * should be fetched from mac80211 first.
1064 */
1065 if (wl->ssid_len == 0) {
1066 wl1271_warning("Hidden SSID currently not supported for AP");
1067 ret = -EINVAL;
1068 goto out;
1069 }
1070
1071 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1072 if (!cmd) {
1073 ret = -ENOMEM;
1074 goto out;
1075 }
1076
1077 memcpy(cmd->bssid, bss_conf->bssid, ETH_ALEN);
1078
1079 cmd->aging_period = cpu_to_le16(wl->conf.tx.ap_aging_period);
1080 cmd->bss_index = WL1271_AP_BSS_INDEX;
1081 cmd->global_hlid = WL1271_AP_GLOBAL_HLID;
1082 cmd->broadcast_hlid = WL1271_AP_BROADCAST_HLID;
1083 cmd->basic_rate_set = cpu_to_le32(wl->basic_rate_set);
1084 cmd->beacon_interval = cpu_to_le16(wl->beacon_int);
1085 cmd->dtim_interval = bss_conf->dtim_period;
1086 cmd->beacon_expiry = WL1271_AP_DEF_BEACON_EXP;
1087 cmd->channel = wl->channel;
1088 cmd->ssid_len = wl->ssid_len;
1089 cmd->ssid_type = SSID_TYPE_PUBLIC;
1090 memcpy(cmd->ssid, wl->ssid, wl->ssid_len);
1091
1092 switch (wl->band) {
1093 case IEEE80211_BAND_2GHZ:
1094 cmd->band = RADIO_BAND_2_4GHZ;
1095 break;
1096 case IEEE80211_BAND_5GHZ:
1097 cmd->band = RADIO_BAND_5GHZ;
1098 break;
1099 default:
1100 wl1271_warning("bss start - unknown band: %d", (int)wl->band);
1101 cmd->band = RADIO_BAND_2_4GHZ;
1102 break;
1103 }
1104
1105 ret = wl1271_cmd_send(wl, CMD_BSS_START, cmd, sizeof(*cmd), 0);
1106 if (ret < 0) {
1107 wl1271_error("failed to initiate cmd start bss");
1108 goto out_free;
1109 }
1110
1111out_free:
1112 kfree(cmd);
1113
1114out:
1115 return ret;
1116}
1117
1118int wl1271_cmd_stop_bss(struct wl1271 *wl)
1119{
1120 struct wl1271_cmd_bss_start *cmd;
1121 int ret;
1122
1123 wl1271_debug(DEBUG_CMD, "cmd stop bss");
1124
1125 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1126 if (!cmd) {
1127 ret = -ENOMEM;
1128 goto out;
1129 }
1130
1131 cmd->bss_index = WL1271_AP_BSS_INDEX;
1132
1133 ret = wl1271_cmd_send(wl, CMD_BSS_STOP, cmd, sizeof(*cmd), 0);
1134 if (ret < 0) {
1135 wl1271_error("failed to initiate cmd stop bss");
1136 goto out_free;
1137 }
1138
1139out_free:
1140 kfree(cmd);
1141
1142out:
1143 return ret;
1144}
1145
1146int wl1271_cmd_add_sta(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid)
1147{ 1233{
1148 struct wl1271_cmd_add_sta *cmd; 1234 struct wl12xx_cmd_add_peer *cmd;
1149 int ret; 1235 int ret;
1150 1236
1151 wl1271_debug(DEBUG_CMD, "cmd add sta %d", (int)hlid); 1237 wl1271_debug(DEBUG_CMD, "cmd add peer %d", (int)hlid);
1152 1238
1153 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1239 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1154 if (!cmd) { 1240 if (!cmd) {
@@ -1168,11 +1254,11 @@ int wl1271_cmd_add_sta(struct wl1271 *wl, struct ieee80211_sta *sta, u8 hlid)
1168 cmd->supported_rates = cpu_to_le32(wl1271_tx_enabled_rates_get(wl, 1254 cmd->supported_rates = cpu_to_le32(wl1271_tx_enabled_rates_get(wl,
1169 sta->supp_rates[wl->band])); 1255 sta->supp_rates[wl->band]));
1170 1256
1171 wl1271_debug(DEBUG_CMD, "new sta rates: 0x%x", cmd->supported_rates); 1257 wl1271_debug(DEBUG_CMD, "new peer rates: 0x%x", cmd->supported_rates);
1172 1258
1173 ret = wl1271_cmd_send(wl, CMD_ADD_STA, cmd, sizeof(*cmd), 0); 1259 ret = wl1271_cmd_send(wl, CMD_ADD_PEER, cmd, sizeof(*cmd), 0);
1174 if (ret < 0) { 1260 if (ret < 0) {
1175 wl1271_error("failed to initiate cmd add sta"); 1261 wl1271_error("failed to initiate cmd add peer");
1176 goto out_free; 1262 goto out_free;
1177 } 1263 }
1178 1264
@@ -1183,12 +1269,12 @@ out:
1183 return ret; 1269 return ret;
1184} 1270}
1185 1271
1186int wl1271_cmd_remove_sta(struct wl1271 *wl, u8 hlid) 1272int wl12xx_cmd_remove_peer(struct wl1271 *wl, u8 hlid)
1187{ 1273{
1188 struct wl1271_cmd_remove_sta *cmd; 1274 struct wl12xx_cmd_remove_peer *cmd;
1189 int ret; 1275 int ret;
1190 1276
1191 wl1271_debug(DEBUG_CMD, "cmd remove sta %d", (int)hlid); 1277 wl1271_debug(DEBUG_CMD, "cmd remove peer %d", (int)hlid);
1192 1278
1193 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1279 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1194 if (!cmd) { 1280 if (!cmd) {
@@ -1201,9 +1287,9 @@ int wl1271_cmd_remove_sta(struct wl1271 *wl, u8 hlid)
1201 cmd->reason_opcode = 0; 1287 cmd->reason_opcode = 0;
1202 cmd->send_deauth_flag = 0; 1288 cmd->send_deauth_flag = 0;
1203 1289
1204 ret = wl1271_cmd_send(wl, CMD_REMOVE_STA, cmd, sizeof(*cmd), 0); 1290 ret = wl1271_cmd_send(wl, CMD_REMOVE_PEER, cmd, sizeof(*cmd), 0);
1205 if (ret < 0) { 1291 if (ret < 0) {
1206 wl1271_error("failed to initiate cmd remove sta"); 1292 wl1271_error("failed to initiate cmd remove peer");
1207 goto out_free; 1293 goto out_free;
1208 } 1294 }
1209 1295
@@ -1211,7 +1297,8 @@ int wl1271_cmd_remove_sta(struct wl1271 *wl, u8 hlid)
1211 * We are ok with a timeout here. The event is sometimes not sent 1297 * We are ok with a timeout here. The event is sometimes not sent
1212 * due to a firmware bug. 1298 * due to a firmware bug.
1213 */ 1299 */
1214 wl1271_cmd_wait_for_event_or_timeout(wl, STA_REMOVE_COMPLETE_EVENT_ID); 1300 wl1271_cmd_wait_for_event_or_timeout(wl,
1301 PEER_REMOVE_COMPLETE_EVENT_ID);
1215 1302
1216out_free: 1303out_free:
1217 kfree(cmd); 1304 kfree(cmd);