[PATCH] d80211: get rid of sta_aid in favour of keeping track of TIM
This patch gets rid of the HUGE sta_aid array that was there in the access point structure and instead keeps track of the TIM. Also reduces stack usage of the ieee80211_beacon_add_tim() function considerably, and fixes a bug where removing a station that had frames buffered wouldn't update the hardware TIM (if necessary). Signed-off-by: Johannes Berg [EMAIL PROTECTED] --- wireless-dev.orig/net/d80211/ieee80211.c2006-08-23 10:35:02.0 +0200 +++ wireless-dev/net/d80211/ieee80211.c 2006-08-23 10:35:03.0 +0200 @@ -22,6 +22,7 @@ #include linux/mutex.h #include net/iw_handler.h #include linux/compiler.h +#include linux/bitmap.h #include net/d80211.h #include net/d80211_common.h @@ -1044,8 +1045,12 @@ ieee80211_tx_h_unicast_ps_buf(struct iee } else tx-local-total_ps_buffered++; /* Queue frame to be sent after STA sends an PS Poll frame */ - if (skb_queue_empty(sta-ps_tx_buf) tx-local-hw-set_tim) - tx-local-hw-set_tim(tx-dev, sta-aid, 1); + if (skb_queue_empty(sta-ps_tx_buf)) { + if (tx-local-hw-set_tim) + tx-local-hw-set_tim(tx-dev, sta-aid, 1); + if (tx-sdata-bss) + bss_tim_set(tx-local, tx-sdata-bss, sta-aid); + } pkt_data = (struct ieee80211_tx_packet_data *)tx-skb-cb; pkt_data-jiffies = jiffies; skb_queue_tail(sta-ps_tx_buf, tx-skb); @@ -1676,25 +1681,16 @@ static void ieee80211_beacon_add_tim(str { u8 *pos, *tim; int aid0 = 0; - int i, num_bits = 0, n1, n2; - u8 bitmap[251]; + int i, have_bits = 0, n1, n2; /* Generate bitmap for TIM only if there are any STAs in power save * mode. */ - if (atomic_read(bss-num_sta_ps) 0 bss-max_aid 0) { - memset(bitmap, 0, sizeof(bitmap)); - spin_lock_bh(local-sta_lock); - for (i = 0; i bss-max_aid; i++) { - if (bss-sta_aid[i] - (!skb_queue_empty(bss-sta_aid[i]-ps_tx_buf) || -!skb_queue_empty(bss-sta_aid[i]-tx_filtered))) - { - bitmap[(i + 1) / 8] |= 1 (i + 1) % 8; - num_bits++; - } - } - spin_unlock_bh(local-sta_lock); - } + spin_lock_bh(local-sta_lock); + if (atomic_read(bss-num_sta_ps) 0) + /* in the hope that this is faster than +* checking byte-for-byte */ + have_bits = !bitmap_empty((unsigned long*)bss-tim, + MAX_AID_TABLE_SIZE+1); if (bss-dtim_count == 0) bss-dtim_count = bss-dtim_period - 1; @@ -1707,40 +1703,40 @@ static void ieee80211_beacon_add_tim(str *pos++ = bss-dtim_count; *pos++ = bss-dtim_period; - if (bss-dtim_count == 0 !skb_queue_empty(bss-ps_bc_buf)) { + if (bss-dtim_count == 0 !skb_queue_empty(bss-ps_bc_buf)) aid0 = 1; - } - if (num_bits) { + if (have_bits) { /* Find largest even number N1 so that bits numbered 1 through * (N1 x 8) - 1 in the bitmap are 0 and number N2 so that bits * (N2 + 1) x 8 through 2007 are 0. */ n1 = 0; - for (i = 0; i sizeof(bitmap); i++) { - if (bitmap[i]) { + for (i = 0; i IEEE80211_MAX_TIM_LEN; i++) { + if (bss-tim[i]) { n1 = i 0xfe; break; } } n2 = n1; - for (i = sizeof(bitmap) - 1; i = n1; i--) { - if (bitmap[i]) { + for (i = IEEE80211_MAX_TIM_LEN - 1; i = n1; i--) { + if (bss-tim[i]) { n2 = i; break; } } /* Bitmap control */ - *pos++ = n1 | (aid0 ? 1 : 0); + *pos++ = n1 | aid0; /* Part Virt Bitmap */ - memcpy(pos, bitmap + n1, n2 - n1 + 1); + memcpy(pos, bss-tim + n1, n2 - n1 + 1); tim[1] = n2 - n1 + 4; skb_put(skb, n2 - n1); } else { - *pos++ = aid0 ? 1 : 0; /* Bitmap control */ + *pos++ = aid0; /* Bitmap control */ *pos++ = 0; /* Part Virt Bitmap */ } + spin_unlock_bh(local-sta_lock); } @@ -2702,8 +2698,12 @@ static int ap_sta_ps_end(struct net_devi atomic_dec(sdata-bss-num_sta_ps); sta-flags = ~(WLAN_STA_PS | WLAN_STA_TIM); sta-pspoll = 0; - if
Re: [PATCH] d80211: get rid of sta_aid in favour of keeping track of TIM
On Wed, 2006-08-23 at 12:04 +0200, Johannes Berg wrote: +/* miscellaneous IEEE 802.11 constants */ #define IEEE80211_MAX_FRAG_THRESHOLD 2346 #define IEEE80211_MAX_RTS_THRESHOLD 2347 +#define IEEE80211_MAX_TIM_LEN 251 Nice, but I'm using it wrongly :) I'll send a fixed patch. johannes - To unsubscribe from this list: send the line unsubscribe netdev in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH ] d80211: get rid of sta_aid in favour of keeping track of TIM
This patch gets rid of the HUGE sta_aid array that was there in the access point structure and instead keeps track of the TIM. Also reduces stack usage of the ieee80211_beacon_add_tim() function considerably, and fixes a bug where removing a station that had frames buffered wouldn't update the hardware TIM (if necessary). It also removes the MAX_AID_TABLE_SIZE pseudo-configuration option (it was a define with a comment indicating it could be changed) since now having all AIDs available is no longer expensive. Signed-off-by: Johannes Berg [EMAIL PROTECTED] --- wireless-dev.orig/net/d80211/ieee80211.c2006-08-23 10:58:26.0 +0200 +++ wireless-dev/net/d80211/ieee80211.c 2006-08-23 12:09:53.0 +0200 @@ -22,6 +22,7 @@ #include linux/mutex.h #include net/iw_handler.h #include linux/compiler.h +#include linux/bitmap.h #include net/d80211.h #include net/d80211_common.h @@ -1044,8 +1045,12 @@ ieee80211_tx_h_unicast_ps_buf(struct iee } else tx-local-total_ps_buffered++; /* Queue frame to be sent after STA sends an PS Poll frame */ - if (skb_queue_empty(sta-ps_tx_buf) tx-local-hw-set_tim) - tx-local-hw-set_tim(tx-dev, sta-aid, 1); + if (skb_queue_empty(sta-ps_tx_buf)) { + if (tx-local-hw-set_tim) + tx-local-hw-set_tim(tx-dev, sta-aid, 1); + if (tx-sdata-bss) + bss_tim_set(tx-local, tx-sdata-bss, sta-aid); + } pkt_data = (struct ieee80211_tx_packet_data *)tx-skb-cb; pkt_data-jiffies = jiffies; skb_queue_tail(sta-ps_tx_buf, tx-skb); @@ -1676,25 +1681,16 @@ static void ieee80211_beacon_add_tim(str { u8 *pos, *tim; int aid0 = 0; - int i, num_bits = 0, n1, n2; - u8 bitmap[251]; + int i, have_bits = 0, n1, n2; /* Generate bitmap for TIM only if there are any STAs in power save * mode. */ - if (atomic_read(bss-num_sta_ps) 0 bss-max_aid 0) { - memset(bitmap, 0, sizeof(bitmap)); - spin_lock_bh(local-sta_lock); - for (i = 0; i bss-max_aid; i++) { - if (bss-sta_aid[i] - (!skb_queue_empty(bss-sta_aid[i]-ps_tx_buf) || -!skb_queue_empty(bss-sta_aid[i]-tx_filtered))) - { - bitmap[(i + 1) / 8] |= 1 (i + 1) % 8; - num_bits++; - } - } - spin_unlock_bh(local-sta_lock); - } + spin_lock_bh(local-sta_lock); + if (atomic_read(bss-num_sta_ps) 0) + /* in the hope that this is faster than +* checking byte-for-byte */ + have_bits = !bitmap_empty((unsigned long*)bss-tim, + IEEE80211_MAX_AID+1); if (bss-dtim_count == 0) bss-dtim_count = bss-dtim_period - 1; @@ -1707,40 +1703,40 @@ static void ieee80211_beacon_add_tim(str *pos++ = bss-dtim_count; *pos++ = bss-dtim_period; - if (bss-dtim_count == 0 !skb_queue_empty(bss-ps_bc_buf)) { + if (bss-dtim_count == 0 !skb_queue_empty(bss-ps_bc_buf)) aid0 = 1; - } - if (num_bits) { + if (have_bits) { /* Find largest even number N1 so that bits numbered 1 through * (N1 x 8) - 1 in the bitmap are 0 and number N2 so that bits * (N2 + 1) x 8 through 2007 are 0. */ n1 = 0; - for (i = 0; i sizeof(bitmap); i++) { - if (bitmap[i]) { + for (i = 0; i IEEE80211_MAX_TIM_LEN; i++) { + if (bss-tim[i]) { n1 = i 0xfe; break; } } n2 = n1; - for (i = sizeof(bitmap) - 1; i = n1; i--) { - if (bitmap[i]) { + for (i = IEEE80211_MAX_TIM_LEN - 1; i = n1; i--) { + if (bss-tim[i]) { n2 = i; break; } } /* Bitmap control */ - *pos++ = n1 | (aid0 ? 1 : 0); + *pos++ = n1 | aid0; /* Part Virt Bitmap */ - memcpy(pos, bitmap + n1, n2 - n1 + 1); + memcpy(pos, bss-tim + n1, n2 - n1 + 1); tim[1] = n2 - n1 + 4; skb_put(skb, n2 - n1); } else { - *pos++ = aid0 ? 1 : 0; /* Bitmap control */ + *pos++ = aid0; /* Bitmap control */ *pos++ = 0; /* Part Virt Bitmap */ } + spin_unlock_bh(local-sta_lock); } @@ -2702,8 +2698,12 @@