[PATCH] d80211: get rid of sta_aid in favour of keeping track of TIM

2006-08-23 Thread Johannes Berg
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

2006-08-23 Thread Johannes Berg
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

2006-08-23 Thread Johannes Berg
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 @@