aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwl8k.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/mwl8k.c')
-rw-r--r--drivers/net/wireless/mwl8k.c106
1 files changed, 22 insertions, 84 deletions
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 6497c841fb21..ac65e13eb0de 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -188,10 +188,6 @@ struct mwl8k_priv {
188 bool sniffer_enabled; 188 bool sniffer_enabled;
189 bool wmm_enabled; 189 bool wmm_enabled;
190 190
191 struct work_struct sta_notify_worker;
192 spinlock_t sta_notify_list_lock;
193 struct list_head sta_notify_list;
194
195 /* XXX need to convert this to handle multiple interfaces */ 191 /* XXX need to convert this to handle multiple interfaces */
196 bool capture_beacon; 192 bool capture_beacon;
197 u8 capture_bssid[ETH_ALEN]; 193 u8 capture_bssid[ETH_ALEN];
@@ -3706,90 +3702,36 @@ static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
3706 return mwl8k_cmd_set_rts_threshold(hw, value); 3702 return mwl8k_cmd_set_rts_threshold(hw, value);
3707} 3703}
3708 3704
3709struct mwl8k_sta_notify_item 3705static int mwl8k_sta_remove(struct ieee80211_hw *hw,
3710{ 3706 struct ieee80211_vif *vif,
3711 struct list_head list; 3707 struct ieee80211_sta *sta)
3712 struct ieee80211_vif *vif;
3713 enum sta_notify_cmd cmd;
3714 struct ieee80211_sta sta;
3715};
3716
3717static void
3718mwl8k_do_sta_notify(struct ieee80211_hw *hw, struct mwl8k_sta_notify_item *s)
3719{ 3708{
3720 struct mwl8k_priv *priv = hw->priv; 3709 struct mwl8k_priv *priv = hw->priv;
3721 3710
3722 /* 3711 if (priv->ap_fw)
3723 * STA firmware uses UPDATE_STADB, AP firmware uses SET_NEW_STN. 3712 return mwl8k_cmd_set_new_stn_del(hw, vif, sta->addr);
3724 */ 3713 else
3725 if (!priv->ap_fw && s->cmd == STA_NOTIFY_ADD) { 3714 return mwl8k_cmd_update_stadb_del(hw, vif, sta->addr);
3726 int rc;
3727
3728 rc = mwl8k_cmd_update_stadb_add(hw, s->vif, &s->sta);
3729 if (rc >= 0) {
3730 struct ieee80211_sta *sta;
3731
3732 rcu_read_lock();
3733 sta = ieee80211_find_sta(s->vif, s->sta.addr);
3734 if (sta != NULL)
3735 MWL8K_STA(sta)->peer_id = rc;
3736 rcu_read_unlock();
3737 }
3738 } else if (!priv->ap_fw && s->cmd == STA_NOTIFY_REMOVE) {
3739 mwl8k_cmd_update_stadb_del(hw, s->vif, s->sta.addr);
3740 } else if (priv->ap_fw && s->cmd == STA_NOTIFY_ADD) {
3741 mwl8k_cmd_set_new_stn_add(hw, s->vif, &s->sta);
3742 } else if (priv->ap_fw && s->cmd == STA_NOTIFY_REMOVE) {
3743 mwl8k_cmd_set_new_stn_del(hw, s->vif, s->sta.addr);
3744 }
3745}
3746
3747static void mwl8k_sta_notify_worker(struct work_struct *work)
3748{
3749 struct mwl8k_priv *priv =
3750 container_of(work, struct mwl8k_priv, sta_notify_worker);
3751 struct ieee80211_hw *hw = priv->hw;
3752
3753 spin_lock_bh(&priv->sta_notify_list_lock);
3754 while (!list_empty(&priv->sta_notify_list)) {
3755 struct mwl8k_sta_notify_item *s;
3756
3757 s = list_entry(priv->sta_notify_list.next,
3758 struct mwl8k_sta_notify_item, list);
3759 list_del(&s->list);
3760
3761 spin_unlock_bh(&priv->sta_notify_list_lock);
3762
3763 mwl8k_do_sta_notify(hw, s);
3764 kfree(s);
3765
3766 spin_lock_bh(&priv->sta_notify_list_lock);
3767 }
3768 spin_unlock_bh(&priv->sta_notify_list_lock);
3769} 3715}
3770 3716
3771static void 3717static int mwl8k_sta_add(struct ieee80211_hw *hw,
3772mwl8k_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 3718 struct ieee80211_vif *vif,
3773 enum sta_notify_cmd cmd, struct ieee80211_sta *sta) 3719 struct ieee80211_sta *sta)
3774{ 3720{
3775 struct mwl8k_priv *priv = hw->priv; 3721 struct mwl8k_priv *priv = hw->priv;
3776 struct mwl8k_sta_notify_item *s; 3722 int ret;
3777
3778 if (cmd != STA_NOTIFY_ADD && cmd != STA_NOTIFY_REMOVE)
3779 return;
3780
3781 s = kmalloc(sizeof(*s), GFP_ATOMIC);
3782 if (s != NULL) {
3783 s->vif = vif;
3784 s->cmd = cmd;
3785 s->sta = *sta;
3786 3723
3787 spin_lock_bh(&priv->sta_notify_list_lock); 3724 if (!priv->ap_fw) {
3788 list_add_tail(&s->list, &priv->sta_notify_list); 3725 ret = mwl8k_cmd_update_stadb_add(hw, vif, sta);
3789 spin_unlock_bh(&priv->sta_notify_list_lock); 3726 if (ret >= 0) {
3727 MWL8K_STA(sta)->peer_id = ret;
3728 return 0;
3729 }
3790 3730
3791 ieee80211_queue_work(hw, &priv->sta_notify_worker); 3731 return ret;
3792 } 3732 }
3733
3734 return mwl8k_cmd_set_new_stn_add(hw, vif, sta);
3793} 3735}
3794 3736
3795static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue, 3737static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
@@ -3849,7 +3791,8 @@ static const struct ieee80211_ops mwl8k_ops = {
3849 .prepare_multicast = mwl8k_prepare_multicast, 3791 .prepare_multicast = mwl8k_prepare_multicast,
3850 .configure_filter = mwl8k_configure_filter, 3792 .configure_filter = mwl8k_configure_filter,
3851 .set_rts_threshold = mwl8k_set_rts_threshold, 3793 .set_rts_threshold = mwl8k_set_rts_threshold,
3852 .sta_notify = mwl8k_sta_notify, 3794 .sta_add = mwl8k_sta_add,
3795 .sta_remove = mwl8k_sta_remove,
3853 .conf_tx = mwl8k_conf_tx, 3796 .conf_tx = mwl8k_conf_tx,
3854 .get_stats = mwl8k_get_stats, 3797 .get_stats = mwl8k_get_stats,
3855 .ampdu_action = mwl8k_ampdu_action, 3798 .ampdu_action = mwl8k_ampdu_action,
@@ -4051,11 +3994,6 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
4051 priv->radio_on = 0; 3994 priv->radio_on = 0;
4052 priv->radio_short_preamble = 0; 3995 priv->radio_short_preamble = 0;
4053 3996
4054 /* Station database handling */
4055 INIT_WORK(&priv->sta_notify_worker, mwl8k_sta_notify_worker);
4056 spin_lock_init(&priv->sta_notify_list_lock);
4057 INIT_LIST_HEAD(&priv->sta_notify_list);
4058
4059 /* Finalize join worker */ 3997 /* Finalize join worker */
4060 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker); 3998 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);
4061 3999