Commit da08fdfa authored by Eliad Peller's avatar Eliad Peller Committed by John W. Linville

wlcore/wl12xx/wl18xx: configure num_links per-hw

Upcoming fw versions will have different max links support
(according to the hw). Get ready for it by configuring
wl->num_links per-hw, instead of using the const WL12XX_MAX_LINKS.

However, continue using WLCORE_MAX_LINKS in order to simplify
structs declarations (we use it in multiple bitmaps, and converting
them to dynamic arrays is just cumbersome).
Signed-off-by: default avatarEliad Peller <eliad@wizery.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 75fb4df7
...@@ -1749,9 +1749,12 @@ static int wl12xx_setup(struct wl1271 *wl) ...@@ -1749,9 +1749,12 @@ static int wl12xx_setup(struct wl1271 *wl)
struct wlcore_platdev_data *pdev_data = dev_get_platdata(&wl->pdev->dev); struct wlcore_platdev_data *pdev_data = dev_get_platdata(&wl->pdev->dev);
struct wl12xx_platform_data *pdata = pdev_data->pdata; struct wl12xx_platform_data *pdata = pdev_data->pdata;
BUILD_BUG_ON(WL12XX_MAX_LINKS > WLCORE_MAX_LINKS);
wl->rtable = wl12xx_rtable; wl->rtable = wl12xx_rtable;
wl->num_tx_desc = WL12XX_NUM_TX_DESCRIPTORS; wl->num_tx_desc = WL12XX_NUM_TX_DESCRIPTORS;
wl->num_rx_desc = WL12XX_NUM_RX_DESCRIPTORS; wl->num_rx_desc = WL12XX_NUM_RX_DESCRIPTORS;
wl->num_links = WL12XX_MAX_LINKS;
wl->num_channels = 1; wl->num_channels = 1;
wl->num_mac_addr = WL12XX_NUM_MAC_ADDRESSES; wl->num_mac_addr = WL12XX_NUM_MAC_ADDRESSES;
wl->band_rate_to_idx = wl12xx_band_rate_to_idx; wl->band_rate_to_idx = wl12xx_band_rate_to_idx;
......
...@@ -65,6 +65,8 @@ ...@@ -65,6 +65,8 @@
#define WL12XX_RX_BA_MAX_SESSIONS 3 #define WL12XX_RX_BA_MAX_SESSIONS 3
#define WL12XX_MAX_LINKS 12
struct wl127x_rx_mem_pool_addr { struct wl127x_rx_mem_pool_addr {
u32 addr; u32 addr;
u32 addr_extra; u32 addr_extra;
......
...@@ -1752,9 +1752,12 @@ static int wl18xx_setup(struct wl1271 *wl) ...@@ -1752,9 +1752,12 @@ static int wl18xx_setup(struct wl1271 *wl)
struct wl18xx_priv *priv = wl->priv; struct wl18xx_priv *priv = wl->priv;
int ret; int ret;
BUILD_BUG_ON(WL18XX_MAX_LINKS > WLCORE_MAX_LINKS);
wl->rtable = wl18xx_rtable; wl->rtable = wl18xx_rtable;
wl->num_tx_desc = WL18XX_NUM_TX_DESCRIPTORS; wl->num_tx_desc = WL18XX_NUM_TX_DESCRIPTORS;
wl->num_rx_desc = WL18XX_NUM_RX_DESCRIPTORS; wl->num_rx_desc = WL18XX_NUM_RX_DESCRIPTORS;
wl->num_links = WL18XX_MAX_LINKS;
wl->num_channels = 2; wl->num_channels = 2;
wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES; wl->num_mac_addr = WL18XX_NUM_MAC_ADDRESSES;
wl->band_rate_to_idx = wl18xx_band_rate_to_idx; wl->band_rate_to_idx = wl18xx_band_rate_to_idx;
......
...@@ -42,6 +42,8 @@ ...@@ -42,6 +42,8 @@
#define WL18XX_RX_BA_MAX_SESSIONS 5 #define WL18XX_RX_BA_MAX_SESSIONS 5
#define WL18XX_MAX_LINKS 12
struct wl18xx_priv { struct wl18xx_priv {
/* buffer for sending commands to FW */ /* buffer for sending commands to FW */
u8 cmd_buf[WL18XX_CMD_MAX_SIZE]; u8 cmd_buf[WL18XX_CMD_MAX_SIZE];
...@@ -114,7 +116,7 @@ struct wl18xx_fw_packet_counters { ...@@ -114,7 +116,7 @@ struct wl18xx_fw_packet_counters {
u8 tx_released_pkts[NUM_TX_QUEUES]; u8 tx_released_pkts[NUM_TX_QUEUES];
/* Cumulative counter of freed packets per HLID */ /* Cumulative counter of freed packets per HLID */
u8 tx_lnk_free_pkts[WL12XX_MAX_LINKS]; u8 tx_lnk_free_pkts[WL18XX_MAX_LINKS];
/* Cumulative counter of released Voice memory blocks */ /* Cumulative counter of released Voice memory blocks */
u8 tx_voice_released_blks; u8 tx_voice_released_blks;
......
...@@ -312,8 +312,8 @@ static int wlcore_get_new_session_id(struct wl1271 *wl, u8 hlid) ...@@ -312,8 +312,8 @@ static int wlcore_get_new_session_id(struct wl1271 *wl, u8 hlid)
int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid) int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
{ {
unsigned long flags; unsigned long flags;
u8 link = find_first_zero_bit(wl->links_map, WL12XX_MAX_LINKS); u8 link = find_first_zero_bit(wl->links_map, wl->num_links);
if (link >= WL12XX_MAX_LINKS) if (link >= wl->num_links)
return -EBUSY; return -EBUSY;
wl->session_ids[link] = wlcore_get_new_session_id(wl, link); wl->session_ids[link] = wlcore_get_new_session_id(wl, link);
......
...@@ -67,7 +67,7 @@ static void wl1271_stop_ba_event(struct wl1271 *wl, struct wl12xx_vif *wlvif) ...@@ -67,7 +67,7 @@ static void wl1271_stop_ba_event(struct wl1271 *wl, struct wl12xx_vif *wlvif)
u8 hlid; u8 hlid;
struct wl1271_link *lnk; struct wl1271_link *lnk;
for_each_set_bit(hlid, wlvif->ap.sta_hlid_map, for_each_set_bit(hlid, wlvif->ap.sta_hlid_map,
WL12XX_MAX_LINKS) { wl->num_links) {
lnk = &wl->links[hlid]; lnk = &wl->links[hlid];
if (!lnk->ba_bitmap) if (!lnk->ba_bitmap)
continue; continue;
...@@ -172,7 +172,7 @@ static void wlcore_disconnect_sta(struct wl1271 *wl, unsigned long sta_bitmap) ...@@ -172,7 +172,7 @@ static void wlcore_disconnect_sta(struct wl1271 *wl, unsigned long sta_bitmap)
const u8 *addr; const u8 *addr;
int h; int h;
for_each_set_bit(h, &sta_bitmap, WL12XX_MAX_LINKS) { for_each_set_bit(h, &sta_bitmap, wl->num_links) {
bool found = false; bool found = false;
/* find the ap vif connected to this sta */ /* find the ap vif connected to this sta */
wl12xx_for_each_wlvif_ap(wl, wlvif) { wl12xx_for_each_wlvif_ap(wl, wlvif) {
......
...@@ -372,7 +372,7 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl, ...@@ -372,7 +372,7 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl,
wl->ap_fw_ps_map = cur_fw_ps_map; wl->ap_fw_ps_map = cur_fw_ps_map;
} }
for_each_set_bit(hlid, wlvif->ap.sta_hlid_map, WL12XX_MAX_LINKS) for_each_set_bit(hlid, wlvif->ap.sta_hlid_map, wl->num_links)
wl12xx_irq_ps_regulate_link(wl, wlvif, hlid, wl12xx_irq_ps_regulate_link(wl, wlvif, hlid,
wl->links[hlid].allocated_pkts); wl->links[hlid].allocated_pkts);
} }
...@@ -412,7 +412,7 @@ static int wlcore_fw_status(struct wl1271 *wl, struct wl_fw_status *status) ...@@ -412,7 +412,7 @@ static int wlcore_fw_status(struct wl1271 *wl, struct wl_fw_status *status)
} }
for_each_set_bit(i, wl->links_map, WL12XX_MAX_LINKS) { for_each_set_bit(i, wl->links_map, wl->num_links) {
u8 diff; u8 diff;
lnk = &wl->links[i]; lnk = &wl->links[i];
...@@ -5855,7 +5855,7 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size, ...@@ -5855,7 +5855,7 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size,
int i, j, ret; int i, j, ret;
unsigned int order; unsigned int order;
BUILD_BUG_ON(AP_MAX_STATIONS > WL12XX_MAX_LINKS); BUILD_BUG_ON(AP_MAX_STATIONS > WLCORE_MAX_LINKS);
hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops);
if (!hw) { if (!hw) {
...@@ -5878,8 +5878,12 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size, ...@@ -5878,8 +5878,12 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size,
wl->hw = hw; wl->hw = hw;
/*
* wl->num_links is not configured yet, so just use WLCORE_MAX_LINKS.
* we don't allocate any additional resource here, so that's fine.
*/
for (i = 0; i < NUM_TX_QUEUES; i++) for (i = 0; i < NUM_TX_QUEUES; i++)
for (j = 0; j < WL12XX_MAX_LINKS; j++) for (j = 0; j < WLCORE_MAX_LINKS; j++)
skb_queue_head_init(&wl->links[j].tx_queue[i]); skb_queue_head_init(&wl->links[j].tx_queue[i]);
skb_queue_head_init(&wl->deferred_rx_queue); skb_queue_head_init(&wl->deferred_rx_queue);
......
...@@ -205,7 +205,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length, ...@@ -205,7 +205,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
int wlcore_rx(struct wl1271 *wl, struct wl_fw_status *status) int wlcore_rx(struct wl1271 *wl, struct wl_fw_status *status)
{ {
unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0}; unsigned long active_hlids[BITS_TO_LONGS(WLCORE_MAX_LINKS)] = {0};
u32 buf_size; u32 buf_size;
u32 fw_rx_counter = status->fw_rx_counter % wl->num_rx_desc; u32 fw_rx_counter = status->fw_rx_counter % wl->num_rx_desc;
u32 drv_rx_counter = wl->rx_counter % wl->num_rx_desc; u32 drv_rx_counter = wl->rx_counter % wl->num_rx_desc;
...@@ -263,12 +263,12 @@ int wlcore_rx(struct wl1271 *wl, struct wl_fw_status *status) ...@@ -263,12 +263,12 @@ int wlcore_rx(struct wl1271 *wl, struct wl_fw_status *status)
wl->aggr_buf + pkt_offset, wl->aggr_buf + pkt_offset,
pkt_len, rx_align, pkt_len, rx_align,
&hlid) == 1) { &hlid) == 1) {
if (hlid < WL12XX_MAX_LINKS) if (hlid < wl->num_links)
__set_bit(hlid, active_hlids); __set_bit(hlid, active_hlids);
else else
WARN(1, WARN(1,
"hlid exceeded WL12XX_MAX_LINKS " "hlid (%d) exceeded MAX_LINKS\n",
"(%d)\n", hlid); hlid);
} }
wl->rx_counter++; wl->rx_counter++;
......
...@@ -565,11 +565,11 @@ static struct sk_buff *wlcore_vif_dequeue_high_prio(struct wl1271 *wl, ...@@ -565,11 +565,11 @@ static struct sk_buff *wlcore_vif_dequeue_high_prio(struct wl1271 *wl,
int i, h, start_hlid; int i, h, start_hlid;
/* start from the link after the last one */ /* start from the link after the last one */
start_hlid = (wlvif->last_tx_hlid + 1) % WL12XX_MAX_LINKS; start_hlid = (wlvif->last_tx_hlid + 1) % wl->num_links;
/* dequeue according to AC, round robin on each link */ /* dequeue according to AC, round robin on each link */
for (i = 0; i < WL12XX_MAX_LINKS; i++) { for (i = 0; i < wl->num_links; i++) {
h = (start_hlid + i) % WL12XX_MAX_LINKS; h = (start_hlid + i) % wl->num_links;
/* only consider connected stations */ /* only consider connected stations */
if (!test_bit(h, wlvif->links_map)) if (!test_bit(h, wlvif->links_map))
...@@ -693,8 +693,8 @@ static void wl1271_skb_queue_head(struct wl1271 *wl, struct wl12xx_vif *wlvif, ...@@ -693,8 +693,8 @@ static void wl1271_skb_queue_head(struct wl1271 *wl, struct wl12xx_vif *wlvif,
skb_queue_head(&wl->links[hlid].tx_queue[q], skb); skb_queue_head(&wl->links[hlid].tx_queue[q], skb);
/* make sure we dequeue the same packet next time */ /* make sure we dequeue the same packet next time */
wlvif->last_tx_hlid = (hlid + WL12XX_MAX_LINKS - 1) % wlvif->last_tx_hlid = (hlid + wl->num_links - 1) %
WL12XX_MAX_LINKS; wl->num_links;
} }
spin_lock_irqsave(&wl->wl_lock, flags); spin_lock_irqsave(&wl->wl_lock, flags);
...@@ -727,7 +727,7 @@ void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids) ...@@ -727,7 +727,7 @@ void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids)
timeout = wl->conf.rx_streaming.duration; timeout = wl->conf.rx_streaming.duration;
wl12xx_for_each_wlvif_sta(wl, wlvif) { wl12xx_for_each_wlvif_sta(wl, wlvif) {
bool found = false; bool found = false;
for_each_set_bit(hlid, active_hlids, WL12XX_MAX_LINKS) { for_each_set_bit(hlid, active_hlids, wl->num_links) {
if (test_bit(hlid, wlvif->links_map)) { if (test_bit(hlid, wlvif->links_map)) {
found = true; found = true;
break; break;
...@@ -764,7 +764,7 @@ int wlcore_tx_work_locked(struct wl1271 *wl) ...@@ -764,7 +764,7 @@ int wlcore_tx_work_locked(struct wl1271 *wl)
struct wl1271_tx_hw_descr *desc; struct wl1271_tx_hw_descr *desc;
u32 buf_offset = 0, last_len = 0; u32 buf_offset = 0, last_len = 0;
bool sent_packets = false; bool sent_packets = false;
unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0}; unsigned long active_hlids[BITS_TO_LONGS(WLCORE_MAX_LINKS)] = {0};
int ret = 0; int ret = 0;
int bus_ret = 0; int bus_ret = 0;
u8 hlid; u8 hlid;
...@@ -1066,7 +1066,7 @@ void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif) ...@@ -1066,7 +1066,7 @@ void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif)
int i; int i;
/* TX failure */ /* TX failure */
for_each_set_bit(i, wlvif->links_map, WL12XX_MAX_LINKS) { for_each_set_bit(i, wlvif->links_map, wl->num_links) {
if (wlvif->bss_type == BSS_TYPE_AP_BSS && if (wlvif->bss_type == BSS_TYPE_AP_BSS &&
i != wlvif->ap.bcast_hlid && i != wlvif->ap.global_hlid) { i != wlvif->ap.bcast_hlid && i != wlvif->ap.global_hlid) {
/* this calls wl12xx_free_link */ /* this calls wl12xx_free_link */
...@@ -1090,7 +1090,7 @@ void wl12xx_tx_reset(struct wl1271 *wl) ...@@ -1090,7 +1090,7 @@ void wl12xx_tx_reset(struct wl1271 *wl)
/* only reset the queues if something bad happened */ /* only reset the queues if something bad happened */
if (wl1271_tx_total_queue_count(wl) != 0) { if (wl1271_tx_total_queue_count(wl) != 0) {
for (i = 0; i < WL12XX_MAX_LINKS; i++) for (i = 0; i < wl->num_links; i++)
wl1271_tx_reset_link_queues(wl, i); wl1271_tx_reset_link_queues(wl, i);
for (i = 0; i < NUM_TX_QUEUES; i++) for (i = 0; i < NUM_TX_QUEUES; i++)
...@@ -1183,7 +1183,7 @@ void wl1271_tx_flush(struct wl1271 *wl) ...@@ -1183,7 +1183,7 @@ void wl1271_tx_flush(struct wl1271 *wl)
WL1271_TX_FLUSH_TIMEOUT / 1000); WL1271_TX_FLUSH_TIMEOUT / 1000);
/* forcibly flush all Tx buffers on our queues */ /* forcibly flush all Tx buffers on our queues */
for (i = 0; i < WL12XX_MAX_LINKS; i++) for (i = 0; i < wl->num_links; i++)
wl1271_tx_reset_link_queues(wl, i); wl1271_tx_reset_link_queues(wl, i);
out_wake: out_wake:
......
...@@ -222,7 +222,7 @@ struct wl1271 { ...@@ -222,7 +222,7 @@ struct wl1271 {
int channel; int channel;
u8 system_hlid; u8 system_hlid;
unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)]; unsigned long links_map[BITS_TO_LONGS(WLCORE_MAX_LINKS)];
unsigned long roles_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)]; unsigned long roles_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)];
unsigned long roc_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)]; unsigned long roc_map[BITS_TO_LONGS(WL12XX_MAX_ROLES)];
unsigned long rate_policies_map[ unsigned long rate_policies_map[
...@@ -230,7 +230,7 @@ struct wl1271 { ...@@ -230,7 +230,7 @@ struct wl1271 {
unsigned long klv_templates_map[ unsigned long klv_templates_map[
BITS_TO_LONGS(WLCORE_MAX_KLV_TEMPLATES)]; BITS_TO_LONGS(WLCORE_MAX_KLV_TEMPLATES)];
u8 session_ids[WL12XX_MAX_LINKS]; u8 session_ids[WLCORE_MAX_LINKS];
struct list_head wlvif_list; struct list_head wlvif_list;
...@@ -378,7 +378,7 @@ struct wl1271 { ...@@ -378,7 +378,7 @@ struct wl1271 {
* AP-mode - links indexed by HLID. The global and broadcast links * AP-mode - links indexed by HLID. The global and broadcast links
* are always active. * are always active.
*/ */
struct wl1271_link links[WL12XX_MAX_LINKS]; struct wl1271_link links[WLCORE_MAX_LINKS];
/* number of currently active links */ /* number of currently active links */
int active_link_count; int active_link_count;
...@@ -436,6 +436,8 @@ struct wl1271 { ...@@ -436,6 +436,8 @@ struct wl1271 {
u32 num_tx_desc; u32 num_tx_desc;
/* number of RX descriptors the HW supports. */ /* number of RX descriptors the HW supports. */
u32 num_rx_desc; u32 num_rx_desc;
/* number of links the HW supports */
u8 num_links;
/* translate HW Tx rates to standard rate-indices */ /* translate HW Tx rates to standard rate-indices */
const u8 **band_rate_to_idx; const u8 **band_rate_to_idx;
......
...@@ -58,10 +58,15 @@ ...@@ -58,10 +58,15 @@
#define WL1271_DEFAULT_DTIM_PERIOD 1 #define WL1271_DEFAULT_DTIM_PERIOD 1
#define WL12XX_MAX_ROLES 4 #define WL12XX_MAX_ROLES 4
#define WL12XX_MAX_LINKS 12
#define WL12XX_INVALID_ROLE_ID 0xff #define WL12XX_INVALID_ROLE_ID 0xff
#define WL12XX_INVALID_LINK_ID 0xff #define WL12XX_INVALID_LINK_ID 0xff
/*
* max number of links allowed by all HWs.
* this is NOT the actual max links supported by the current hw.
*/
#define WLCORE_MAX_LINKS 12
/* the driver supports the 2.4Ghz and 5Ghz bands */ /* the driver supports the 2.4Ghz and 5Ghz bands */
#define WLCORE_NUM_BANDS 2 #define WLCORE_NUM_BANDS 2
...@@ -156,7 +161,7 @@ struct wl_fw_status { ...@@ -156,7 +161,7 @@ struct wl_fw_status {
/* /*
* Cumulative counter of freed packets per HLID * Cumulative counter of freed packets per HLID
* (length of the array is WL12XX_MAX_LINKS) * (length of the array is wl->num_links)
*/ */
u8 *tx_lnk_free_pkts; u8 *tx_lnk_free_pkts;
...@@ -357,7 +362,7 @@ struct wl12xx_vif { ...@@ -357,7 +362,7 @@ struct wl12xx_vif {
/* HLIDs bitmap of associated stations */ /* HLIDs bitmap of associated stations */
unsigned long sta_hlid_map[BITS_TO_LONGS( unsigned long sta_hlid_map[BITS_TO_LONGS(
WL12XX_MAX_LINKS)]; WLCORE_MAX_LINKS)];
/* recoreded keys - set here before AP startup */ /* recoreded keys - set here before AP startup */
struct wl1271_ap_key *recorded_keys[MAX_NUM_KEYS]; struct wl1271_ap_key *recorded_keys[MAX_NUM_KEYS];
...@@ -374,7 +379,7 @@ struct wl12xx_vif { ...@@ -374,7 +379,7 @@ struct wl12xx_vif {
/* counters of packets per AC, across all links in the vif */ /* counters of packets per AC, across all links in the vif */
int tx_queue_count[NUM_TX_QUEUES]; int tx_queue_count[NUM_TX_QUEUES];
unsigned long links_map[BITS_TO_LONGS(WL12XX_MAX_LINKS)]; unsigned long links_map[BITS_TO_LONGS(WLCORE_MAX_LINKS)];
u8 ssid[IEEE80211_MAX_SSID_LEN + 1]; u8 ssid[IEEE80211_MAX_SSID_LEN + 1];
u8 ssid_len; u8 ssid_len;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment