}
EXPORT_SYMBOL(sta_info_get);
-int sta_info_min_txrate_get(struct ieee80211_local *local)
-{
- struct sta_info *sta;
- struct ieee80211_hw_mode *mode;
- int min_txrate = 9999999;
- int i;
-
- read_lock_bh(&local->sta_lock);
- mode = local->oper_hw_mode;
- for (i = 0; i < STA_HASH_SIZE; i++) {
- sta = local->sta_hash[i];
- while (sta) {
- if (sta->txrate < min_txrate)
- min_txrate = sta->txrate;
- sta = sta->hnext;
- }
- }
- read_unlock_bh(&local->sta_lock);
- if (min_txrate == 9999999)
- min_txrate = 0;
-
- return mode->rates[min_txrate].rate;
-}
-
static void sta_info_release(struct kref *kref)
{
return sta;
}
+static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid)
+{
+ /*
+ * This format has been mandated by the IEEE specifications,
+ * so this line may not be changed to use the __set_bit() format.
+ */
+ bss->tim[aid / 8] |= (1 << (aid % 8));
+}
+
+static inline void __bss_tim_clear(struct ieee80211_if_ap *bss, u16 aid)
+{
+ /*
+ * This format has been mandated by the IEEE specifications,
+ * so this line may not be changed to use the __clear_bit() format.
+ */
+ bss->tim[aid / 8] &= ~(1 << (aid % 8));
+}
+
+static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss,
+ struct sta_info *sta)
+{
+ if (bss)
+ __bss_tim_set(bss, sta->aid);
+ if (sta->local->ops->set_tim)
+ sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 1);
+}
+
+void sta_info_set_tim_bit(struct sta_info *sta)
+{
+ struct ieee80211_sub_if_data *sdata;
+
+ sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev);
+
+ read_lock_bh(&sta->local->sta_lock);
+ __sta_info_set_tim_bit(sdata->bss, sta);
+ read_unlock_bh(&sta->local->sta_lock);
+}
+
+static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss,
+ struct sta_info *sta)
+{
+ if (bss)
+ __bss_tim_clear(bss, sta->aid);
+ if (sta->local->ops->set_tim)
+ sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 0);
+}
+
+void sta_info_clear_tim_bit(struct sta_info *sta)
+{
+ struct ieee80211_sub_if_data *sdata;
+
+ sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev);
+
+ read_lock_bh(&sta->local->sta_lock);
+ __sta_info_clear_tim_bit(sdata->bss, sta);
+ read_unlock_bh(&sta->local->sta_lock);
+}
+
/* Caller must hold local->sta_lock */
void sta_info_remove(struct sta_info *sta)
{
sta->flags &= ~WLAN_STA_PS;
if (sdata->bss)
atomic_dec(&sdata->bss->num_sta_ps);
+ __sta_info_clear_tim_bit(sdata->bss, sta);
}
local->num_sta--;
- sta_info_remove_aid_ptr(sta);
-
}
void sta_info_free(struct sta_info *sta)
{
unsigned long flags;
struct sk_buff *skb;
+ struct ieee80211_sub_if_data *sdata;
DECLARE_MAC_BUF(mac);
if (skb_queue_empty(&sta->ps_tx_buf))
for (;;) {
spin_lock_irqsave(&sta->ps_tx_buf.lock, flags);
skb = skb_peek(&sta->ps_tx_buf);
- if (sta_info_buffer_expired(local, sta, skb)) {
+ if (sta_info_buffer_expired(local, sta, skb))
skb = __skb_dequeue(&sta->ps_tx_buf);
- if (skb_queue_empty(&sta->ps_tx_buf))
- sta->flags &= ~WLAN_STA_TIM;
- } else
+ else
skb = NULL;
spin_unlock_irqrestore(&sta->ps_tx_buf.lock, flags);
- if (skb) {
- local->total_ps_buffered--;
- printk(KERN_DEBUG "Buffered frame expired (STA "
- "%s)\n", print_mac(mac, sta->addr));
- dev_kfree_skb(skb);
- } else
+ if (!skb)
break;
+
+ sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev);
+ local->total_ps_buffered--;
+ printk(KERN_DEBUG "Buffered frame expired (STA "
+ "%s)\n", print_mac(mac, sta->addr));
+ dev_kfree_skb(skb);
+
+ if (skb_queue_empty(&sta->ps_tx_buf))
+ sta_info_clear_tim_bit(sta);
}
}
sta_info_flush(local, NULL);
}
-void sta_info_remove_aid_ptr(struct sta_info *sta)
-{
- struct ieee80211_sub_if_data *sdata;
-
- if (sta->aid <= 0)
- return;
-
- sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev);
-
- if (sdata->local->ops->set_tim)
- sdata->local->ops->set_tim(local_to_hw(sdata->local),
- sta->aid, 0);
- if (sdata->bss)
- __bss_tim_clear(sdata->bss, sta->aid);
-}
-
-
/**
* sta_info_flush - flush matching STA entries from the STA table
* @local: local interface data