diff options
author | Lennert Buytenhek <buytenh@wantstofly.org> | 2010-01-04 15:55:12 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-01-05 17:13:24 -0500 |
commit | bbfd9128d3b4a80bea017ebdd47b31a80dc7eadf (patch) | |
tree | 3bd964d95bb2228ea6435060e526c928eb5420be /drivers/net/wireless/mwl8k.c | |
parent | 25d81b1e1a0cca41a71a08468a7d3a4c751c8565 (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/mwl8k.c')
-rw-r--r-- | drivers/net/wireless/mwl8k.c | 82 |
1 files changed, 73 insertions, 9 deletions
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 3dbdea904833..df0596ca710d 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 | ||
2643 | static int mwl8k_cmd_update_stadb(struct ieee80211_hw *hw, | 2647 | static 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 | ||
3142 | struct 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 | |||
3150 | static 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 | |||
3179 | static void | ||
3180 | mwl8k_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 | |||
3145 | static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue, | 3203 | static 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 | ||