#include <net/mac80211.h>
#include "ieee80211_i.h"
+#include "driver-ops.h"
#include "rate.h"
#include "sta_info.h"
#include "debugfs_sta.h"
* When the insertion fails (sta_info_insert()) returns non-zero), the
* structure will have been freed by sta_info_insert()!
*
+ * sta entries are added by mac80211 when you establish a link with a
+ * peer. This means different things for the different type of interfaces
+ * we support. For a regular station this mean we add the AP sta when we
+ * receive an assocation response from the AP. For IBSS this occurs when
+ * we receive a probe response or a beacon from target IBSS network. For
+ * WDS we add the sta for the peer imediately upon device open. When using
+ * AP mode we add stations for each respective station upon request from
+ * userspace through nl80211.
+ *
* Because there are debugfs entries for each station, and adding those
* must be able to sleep, it is also possible to "pin" a station entry,
* that means it can be removed from the hash table but not be freed.
skb_queue_head_init(&sta->ps_tx_buf);
skb_queue_head_init(&sta->tx_filtered);
+ for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
+ sta->last_seq_ctrl[i] = cpu_to_le16(USHORT_MAX);
+
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
printk(KERN_DEBUG "%s: Allocated STA %pM\n",
wiphy_name(local->hw.wiphy), sta->sta.addr);
struct ieee80211_sub_if_data,
u.ap);
- local->ops->sta_notify(local_to_hw(local), &sdata->vif,
- STA_NOTIFY_ADD, &sta->sta);
+ drv_sta_notify(local, &sdata->vif, STA_NOTIFY_ADD, &sta->sta);
}
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
if (sta->local->ops->set_tim) {
sta->local->tim_in_locked_section = true;
- sta->local->ops->set_tim(local_to_hw(sta->local),
- &sta->sta, true);
+ drv_set_tim(sta->local, &sta->sta, true);
sta->local->tim_in_locked_section = false;
}
}
if (sta->local->ops->set_tim) {
sta->local->tim_in_locked_section = true;
- sta->local->ops->set_tim(local_to_hw(sta->local),
- &sta->sta, false);
+ drv_set_tim(sta->local, &sta->sta, false);
sta->local->tim_in_locked_section = false;
}
}
struct ieee80211_sub_if_data,
u.ap);
- local->ops->sta_notify(local_to_hw(local), &sdata->vif,
- STA_NOTIFY_REMOVE, &(*sta)->sta);
+ drv_sta_notify(local, &sdata->vif, STA_NOTIFY_REMOVE,
+ &(*sta)->sta);
}
if (ieee80211_vif_is_mesh(&sdata->vif)) {
spin_unlock_irqrestore(&local->sta_lock, flags);
}
-static inline int sta_info_buffer_expired(struct ieee80211_local *local,
- struct sta_info *sta,
- struct sk_buff *skb)
+static int sta_info_buffer_expired(struct sta_info *sta,
+ struct sk_buff *skb)
{
struct ieee80211_tx_info *info;
int timeout;
info = IEEE80211_SKB_CB(skb);
/* Timeout: (2 * listen_interval * beacon_int * 1024 / 1000000) sec */
- timeout = (sta->listen_interval * local->hw.conf.beacon_int * 32 /
- 15625) * HZ;
+ timeout = (sta->listen_interval *
+ sta->sdata->vif.bss_conf.beacon_int *
+ 32 / 15625) * HZ;
if (timeout < STA_TX_BUFFER_EXPIRE)
timeout = STA_TX_BUFFER_EXPIRE;
return time_after(jiffies, info->control.jiffies + timeout);
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(sta, skb))
skb = __skb_dequeue(&sta->ps_tx_buf);
else
skb = NULL;
sta_info_cleanup_expire_buffered(local, sta);
rcu_read_unlock();
+ if (local->quiescing)
+ return;
+
local->sta_cleanup.expires =
round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL);
add_timer(&local->sta_cleanup);