aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorLennert Buytenhek <buytenh@wantstofly.org>2010-01-04 15:55:12 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-01-05 17:13:24 -0500
commitbbfd9128d3b4a80bea017ebdd47b31a80dc7eadf (patch)
tree3bd964d95bb2228ea6435060e526c928eb5420be /drivers/net/wireless
parent25d81b1e1a0cca41a71a08468a7d3a4c751c8565 (diff)
mwl8k: handle station database update for AP's sta entry via ->sta_notify()
Inserting and removing a hardware station database entry for the AP when we are in managed mode is currently done in ->bss_info_changed(). To prepare for adding AP mode support, implement the ->sta_notify() driver method, and let that handle inserting and removing the hardware station database entry for our AP instead. Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/mwl8k.c82
1 files changed, 73 insertions, 9 deletions
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 3dbdea90483..df0596ca710 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -185,6 +185,10 @@ struct mwl8k_priv {
185 bool sniffer_enabled; 185 bool sniffer_enabled;
186 bool wmm_enabled; 186 bool wmm_enabled;
187 187
188 struct work_struct sta_notify_worker;
189 spinlock_t sta_notify_list_lock;
190 struct list_head sta_notify_list;
191
188 /* XXX need to convert this to handle multiple interfaces */ 192 /* XXX need to convert this to handle multiple interfaces */
189 bool capture_beacon; 193 bool capture_beacon;
190 u8 capture_bssid[ETH_ALEN]; 194 u8 capture_bssid[ETH_ALEN];
@@ -2641,7 +2645,7 @@ struct mwl8k_cmd_update_stadb {
2641} __attribute__((packed)); 2645} __attribute__((packed));
2642 2646
2643static int mwl8k_cmd_update_stadb(struct ieee80211_hw *hw, 2647static int mwl8k_cmd_update_stadb(struct ieee80211_hw *hw,
2644 struct ieee80211_vif *vif, __u32 action) 2648 struct ieee80211_vif *vif, __u32 action, u8 *addr)
2645{ 2649{
2646 struct mwl8k_vif *mv_vif = MWL8K_VIF(vif); 2650 struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
2647 struct mwl8k_cmd_update_stadb *cmd; 2651 struct mwl8k_cmd_update_stadb *cmd;
@@ -2657,7 +2661,7 @@ static int mwl8k_cmd_update_stadb(struct ieee80211_hw *hw,
2657 2661
2658 cmd->action = cpu_to_le32(action); 2662 cmd->action = cpu_to_le32(action);
2659 peer_info = &cmd->peer_info; 2663 peer_info = &cmd->peer_info;
2660 memcpy(cmd->peer_addr, mv_vif->bssid, ETH_ALEN); 2664 memcpy(cmd->peer_addr, addr, ETH_ALEN);
2661 2665
2662 switch (action) { 2666 switch (action) {
2663 case MWL8K_STA_DB_ADD_ENTRY: 2667 case MWL8K_STA_DB_ADD_ENTRY:
@@ -2978,12 +2982,6 @@ static void mwl8k_bss_info_changed(struct ieee80211_hw *hw,
2978 if (rc) 2982 if (rc)
2979 goto out; 2983 goto out;
2980 2984
2981 /* Update peer rate info */
2982 rc = mwl8k_cmd_update_stadb(hw, vif,
2983 MWL8K_STA_DB_MODIFY_ENTRY);
2984 if (rc)
2985 goto out;
2986
2987 /* Set AID */ 2985 /* Set AID */
2988 rc = mwl8k_cmd_set_aid(hw, vif); 2986 rc = mwl8k_cmd_set_aid(hw, vif);
2989 if (rc) 2987 if (rc)
@@ -2996,7 +2994,6 @@ static void mwl8k_bss_info_changed(struct ieee80211_hw *hw,
2996 memcpy(priv->capture_bssid, mwl8k_vif->bssid, ETH_ALEN); 2994 memcpy(priv->capture_bssid, mwl8k_vif->bssid, ETH_ALEN);
2997 priv->capture_beacon = true; 2995 priv->capture_beacon = true;
2998 } else { 2996 } else {
2999 rc = mwl8k_cmd_update_stadb(hw, vif, MWL8K_STA_DB_DEL_ENTRY);
3000 memset(mwl8k_vif->bssid, 0, ETH_ALEN); 2997 memset(mwl8k_vif->bssid, 0, ETH_ALEN);
3001 } 2998 }
3002 2999
@@ -3142,6 +3139,67 @@ static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
3142 return mwl8k_cmd_set_rts_threshold(hw, MWL8K_CMD_SET, value); 3139 return mwl8k_cmd_set_rts_threshold(hw, MWL8K_CMD_SET, value);
3143} 3140}
3144 3141
3142struct mwl8k_sta_notify_item
3143{
3144 struct list_head list;
3145 struct ieee80211_vif *vif;
3146 enum sta_notify_cmd cmd;
3147 u8 addr[ETH_ALEN];
3148};
3149
3150static void mwl8k_sta_notify_worker(struct work_struct *work)
3151{
3152 struct mwl8k_priv *priv =
3153 container_of(work, struct mwl8k_priv, sta_notify_worker);
3154
3155 spin_lock_bh(&priv->sta_notify_list_lock);
3156 while (!list_empty(&priv->sta_notify_list)) {
3157 struct mwl8k_sta_notify_item *s;
3158 int action;
3159
3160 s = list_entry(priv->sta_notify_list.next,
3161 struct mwl8k_sta_notify_item, list);
3162 list_del(&s->list);
3163
3164 spin_unlock_bh(&priv->sta_notify_list_lock);
3165
3166 if (s->cmd == STA_NOTIFY_ADD)
3167 action = MWL8K_STA_DB_MODIFY_ENTRY;
3168 else
3169 action = MWL8K_STA_DB_DEL_ENTRY;
3170 mwl8k_cmd_update_stadb(priv->hw, s->vif, action, s->addr);
3171
3172 kfree(s);
3173
3174 spin_lock_bh(&priv->sta_notify_list_lock);
3175 }
3176 spin_unlock_bh(&priv->sta_notify_list_lock);
3177}
3178
3179static void
3180mwl8k_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3181 enum sta_notify_cmd cmd, struct ieee80211_sta *sta)
3182{
3183 struct mwl8k_priv *priv = hw->priv;
3184 struct mwl8k_sta_notify_item *s;
3185
3186 if (cmd != STA_NOTIFY_ADD && cmd != STA_NOTIFY_REMOVE)
3187 return;
3188
3189 s = kmalloc(sizeof(*s), GFP_ATOMIC);
3190 if (s != NULL) {
3191 s->vif = vif;
3192 s->cmd = cmd;
3193 memcpy(s->addr, sta->addr, ETH_ALEN);
3194
3195 spin_lock(&priv->sta_notify_list_lock);
3196 list_add_tail(&s->list, &priv->sta_notify_list);
3197 spin_unlock(&priv->sta_notify_list_lock);
3198
3199 ieee80211_queue_work(hw, &priv->sta_notify_worker);
3200 }
3201}
3202
3145static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue, 3203static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
3146 const struct ieee80211_tx_queue_params *params) 3204 const struct ieee80211_tx_queue_params *params)
3147{ 3205{
@@ -3201,6 +3259,7 @@ static const struct ieee80211_ops mwl8k_ops = {
3201 .prepare_multicast = mwl8k_prepare_multicast, 3259 .prepare_multicast = mwl8k_prepare_multicast,
3202 .configure_filter = mwl8k_configure_filter, 3260 .configure_filter = mwl8k_configure_filter,
3203 .set_rts_threshold = mwl8k_set_rts_threshold, 3261 .set_rts_threshold = mwl8k_set_rts_threshold,
3262 .sta_notify = mwl8k_sta_notify,
3204 .conf_tx = mwl8k_conf_tx, 3263 .conf_tx = mwl8k_conf_tx,
3205 .get_tx_stats = mwl8k_get_tx_stats, 3264 .get_tx_stats = mwl8k_get_tx_stats,
3206 .get_stats = mwl8k_get_stats, 3265 .get_stats = mwl8k_get_stats,
@@ -3404,6 +3463,11 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3404 priv->radio_on = 0; 3463 priv->radio_on = 0;
3405 priv->radio_short_preamble = 0; 3464 priv->radio_short_preamble = 0;
3406 3465
3466 /* Station database handling */
3467 INIT_WORK(&priv->sta_notify_worker, mwl8k_sta_notify_worker);
3468 spin_lock_init(&priv->sta_notify_list_lock);
3469 INIT_LIST_HEAD(&priv->sta_notify_list);
3470
3407 /* Finalize join worker */ 3471 /* Finalize join worker */
3408 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker); 3472 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);
3409 3473