aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2011-08-14 06:17:21 -0400
committerLuciano Coelho <coelho@ti.com>2011-08-22 05:35:27 -0400
commite51ae9be2e313b63a43f1f93578d9a71d38a77ea (patch)
tree299037f68be2ced8bece8546cccdcc25a4c70f60 /drivers/net/wireless/wl12xx
parent712e9bf750c5d0db63040c5695dacf38aed4f42c (diff)
wl12xx: use dynamic hlids for AP-mode
Using hlid=0 in AP mode is a bug. Dynamically allocate HLIDs. Set the "first sta hlid" as 3. This will have to be changed when multiple vifs will be supported. Signed-off-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: Eliad Peller <eliad@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx')
-rw-r--r--drivers/net/wireless/wl12xx/cmd.c27
-rw-r--r--drivers/net/wireless/wl12xx/main.c9
-rw-r--r--drivers/net/wireless/wl12xx/tx.c17
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h13
4 files changed, 46 insertions, 20 deletions
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
index 7c5d73845361..025fb14184d6 100644
--- a/drivers/net/wireless/wl12xx/cmd.c
+++ b/drivers/net/wireless/wl12xx/cmd.c
@@ -682,11 +682,19 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl)
682 goto out; 682 goto out;
683 } 683 }
684 684
685 ret = wl12xx_allocate_link(wl, &wl->ap_global_hlid);
686 if (ret < 0)
687 goto out_free;
688
689 ret = wl12xx_allocate_link(wl, &wl->ap_bcast_hlid);
690 if (ret < 0)
691 goto out_free_global;
692
685 cmd->role_id = wl->role_id; 693 cmd->role_id = wl->role_id;
686 cmd->ap.aging_period = cpu_to_le16(wl->conf.tx.ap_aging_period); 694 cmd->ap.aging_period = cpu_to_le16(wl->conf.tx.ap_aging_period);
687 cmd->ap.bss_index = WL1271_AP_BSS_INDEX; 695 cmd->ap.bss_index = WL1271_AP_BSS_INDEX;
688 cmd->ap.global_hlid = WL1271_AP_GLOBAL_HLID; 696 cmd->ap.global_hlid = wl->ap_global_hlid;
689 cmd->ap.broadcast_hlid = WL1271_AP_BROADCAST_HLID; 697 cmd->ap.broadcast_hlid = wl->ap_bcast_hlid;
690 cmd->ap.basic_rate_set = cpu_to_le32(wl->basic_rate_set); 698 cmd->ap.basic_rate_set = cpu_to_le32(wl->basic_rate_set);
691 cmd->ap.beacon_interval = cpu_to_le16(wl->beacon_int); 699 cmd->ap.beacon_interval = cpu_to_le16(wl->beacon_int);
692 cmd->ap.dtim_interval = bss_conf->dtim_period; 700 cmd->ap.dtim_interval = bss_conf->dtim_period;
@@ -713,9 +721,17 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl)
713 ret = wl1271_cmd_send(wl, CMD_ROLE_START, cmd, sizeof(*cmd), 0); 721 ret = wl1271_cmd_send(wl, CMD_ROLE_START, cmd, sizeof(*cmd), 0);
714 if (ret < 0) { 722 if (ret < 0) {
715 wl1271_error("failed to initiate cmd role start ap"); 723 wl1271_error("failed to initiate cmd role start ap");
716 goto out_free; 724 goto out_free_bcast;
717 } 725 }
718 726
727 goto out_free;
728
729out_free_bcast:
730 wl12xx_free_link(wl, &wl->ap_bcast_hlid);
731
732out_free_global:
733 wl12xx_free_link(wl, &wl->ap_global_hlid);
734
719out_free: 735out_free:
720 kfree(cmd); 736 kfree(cmd);
721 737
@@ -744,6 +760,9 @@ int wl12xx_cmd_role_stop_ap(struct wl1271 *wl)
744 goto out_free; 760 goto out_free;
745 } 761 }
746 762
763 wl12xx_free_link(wl, &wl->ap_bcast_hlid);
764 wl12xx_free_link(wl, &wl->ap_global_hlid);
765
747out_free: 766out_free:
748 kfree(cmd); 767 kfree(cmd);
749 768
@@ -1253,7 +1272,7 @@ int wl1271_cmd_set_ap_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
1253 if (!cmd) 1272 if (!cmd)
1254 return -ENOMEM; 1273 return -ENOMEM;
1255 1274
1256 if (hlid == WL1271_AP_BROADCAST_HLID) { 1275 if (hlid == wl->ap_bcast_hlid) {
1257 if (key_type == KEY_WEP) 1276 if (key_type == KEY_WEP)
1258 lid_type = WEP_DEFAULT_LID_TYPE; 1277 lid_type = WEP_DEFAULT_LID_TYPE;
1259 else 1278 else
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 157c46237d9f..ea150b5ff9f5 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -1972,8 +1972,11 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
1972 wl1271_ps_elp_sleep(wl); 1972 wl1271_ps_elp_sleep(wl);
1973 } 1973 }
1974deinit: 1974deinit:
1975 /* clear all hlids (except system_hlid) */
1975 wl->sta_hlid = WL12XX_INVALID_LINK_ID; 1976 wl->sta_hlid = WL12XX_INVALID_LINK_ID;
1976 wl->dev_hlid = WL12XX_INVALID_LINK_ID; 1977 wl->dev_hlid = WL12XX_INVALID_LINK_ID;
1978 wl->ap_bcast_hlid = WL12XX_INVALID_LINK_ID;
1979 wl->ap_global_hlid = WL12XX_INVALID_LINK_ID;
1977 1980
1978 /* 1981 /*
1979 * this must be before the cancel_work calls below, so that the work 1982 * this must be before the cancel_work calls below, so that the work
@@ -2538,7 +2541,7 @@ static int wl1271_ap_init_hwenc(struct wl1271 *wl)
2538 2541
2539 if (wep_key_added) { 2542 if (wep_key_added) {
2540 ret = wl12xx_cmd_set_default_wep_key(wl, wl->default_key, 2543 ret = wl12xx_cmd_set_default_wep_key(wl, wl->default_key,
2541 WL1271_AP_BROADCAST_HLID); 2544 wl->ap_bcast_hlid);
2542 if (ret < 0) 2545 if (ret < 0)
2543 goto out; 2546 goto out;
2544 } 2547 }
@@ -2563,7 +2566,7 @@ static int wl1271_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
2563 wl_sta = (struct wl1271_station *)sta->drv_priv; 2566 wl_sta = (struct wl1271_station *)sta->drv_priv;
2564 hlid = wl_sta->hlid; 2567 hlid = wl_sta->hlid;
2565 } else { 2568 } else {
2566 hlid = WL1271_AP_BROADCAST_HLID; 2569 hlid = wl->ap_bcast_hlid;
2567 } 2570 }
2568 2571
2569 if (!test_bit(WL1271_FLAG_AP_STARTED, &wl->flags)) { 2572 if (!test_bit(WL1271_FLAG_AP_STARTED, &wl->flags)) {
@@ -4449,6 +4452,8 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
4449 wl->dev_role_id = WL12XX_INVALID_ROLE_ID; 4452 wl->dev_role_id = WL12XX_INVALID_ROLE_ID;
4450 wl->dev_hlid = WL12XX_INVALID_LINK_ID; 4453 wl->dev_hlid = WL12XX_INVALID_LINK_ID;
4451 wl->session_counter = 0; 4454 wl->session_counter = 0;
4455 wl->ap_bcast_hlid = WL12XX_INVALID_LINK_ID;
4456 wl->ap_global_hlid = WL12XX_INVALID_LINK_ID;
4452 setup_timer(&wl->rx_streaming_timer, wl1271_rx_streaming_timer, 4457 setup_timer(&wl->rx_streaming_timer, wl1271_rx_streaming_timer,
4453 (unsigned long) wl); 4458 (unsigned long) wl);
4454 wl->fwlog_size = 0; 4459 wl->fwlog_size = 0;
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
index 057db6f86bee..1240f4094a8b 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -38,7 +38,7 @@ static int wl1271_set_default_wep_key(struct wl1271 *wl, u8 id)
38 38
39 if (is_ap) 39 if (is_ap)
40 ret = wl12xx_cmd_set_default_wep_key(wl, id, 40 ret = wl12xx_cmd_set_default_wep_key(wl, id,
41 WL1271_AP_BROADCAST_HLID); 41 wl->ap_bcast_hlid);
42 else 42 else
43 ret = wl12xx_cmd_set_default_wep_key(wl, id, wl->sta_hlid); 43 ret = wl12xx_cmd_set_default_wep_key(wl, id, wl->sta_hlid);
44 44
@@ -168,9 +168,9 @@ u8 wl12xx_tx_get_hlid_ap(struct wl1271 *wl, struct sk_buff *skb)
168 168
169 hdr = (struct ieee80211_hdr *)skb->data; 169 hdr = (struct ieee80211_hdr *)skb->data;
170 if (ieee80211_is_mgmt(hdr->frame_control)) 170 if (ieee80211_is_mgmt(hdr->frame_control))
171 return WL1271_AP_GLOBAL_HLID; 171 return wl->ap_global_hlid;
172 else 172 else
173 return WL1271_AP_BROADCAST_HLID; 173 return wl->ap_bcast_hlid;
174 } 174 }
175} 175}
176 176
@@ -317,17 +317,12 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
317 else 317 else
318 rate_idx = ACX_TX_BASIC_RATE; 318 rate_idx = ACX_TX_BASIC_RATE;
319 } else { 319 } else {
320 switch (hlid) { 320 if (hlid == wl->ap_global_hlid)
321 case WL1271_AP_GLOBAL_HLID:
322 rate_idx = ACX_TX_AP_MODE_MGMT_RATE; 321 rate_idx = ACX_TX_AP_MODE_MGMT_RATE;
323 break; 322 else if (hlid == wl->ap_bcast_hlid)
324 case WL1271_AP_BROADCAST_HLID:
325 rate_idx = ACX_TX_AP_MODE_BCST_RATE; 323 rate_idx = ACX_TX_AP_MODE_BCST_RATE;
326 break; 324 else
327 default:
328 rate_idx = ac; 325 rate_idx = ac;
329 break;
330 }
331 } 326 }
332 327
333 tx_attr |= rate_idx << TX_HW_ATTR_OFST_RATE_POLICY; 328 tx_attr |= rate_idx << TX_HW_ATTR_OFST_RATE_POLICY;
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index a136795352c8..1313dc5b855e 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -141,10 +141,15 @@ extern u32 wl12xx_debug_level;
141#define WL12XX_MAX_LINKS 8 141#define WL12XX_MAX_LINKS 8
142#define WL12XX_INVALID_ROLE_ID 0xff 142#define WL12XX_INVALID_ROLE_ID 0xff
143#define WL12XX_INVALID_LINK_ID 0xff 143#define WL12XX_INVALID_LINK_ID 0xff
144
145/* Defined by FW as 0. Will not be freed or allocated. */
144#define WL12XX_SYSTEM_HLID 0 146#define WL12XX_SYSTEM_HLID 0
145#define WL1271_AP_GLOBAL_HLID 0 147
146#define WL1271_AP_BROADCAST_HLID 1 148/*
147#define WL1271_AP_STA_HLID_START 2 149 * TODO: we currently don't support multirole. remove
150 * this constant from the code when we do.
151 */
152#define WL1271_AP_STA_HLID_START 3
148 153
149/* 154/*
150 * When in AP-mode, we allow (at least) this number of mem-blocks 155 * When in AP-mode, we allow (at least) this number of mem-blocks
@@ -398,6 +403,8 @@ struct wl1271 {
398 u8 system_hlid; 403 u8 system_hlid;
399 u8 sta_hlid; 404 u8 sta_hlid;
400 u8 dev_hlid; 405 u8 dev_hlid;
406 u8 ap_global_hlid;
407 u8 ap_bcast_hlid;
401 408
402 unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)]; 409 unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)];
403 unsigned long roles_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)]; 410 unsigned long roles_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)];