diff options
Diffstat (limited to 'drivers/net/wireless/mwl8k.c')
-rw-r--r-- | drivers/net/wireless/mwl8k.c | 106 |
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 | ||
3709 | struct mwl8k_sta_notify_item | 3705 | static 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 | |||
3717 | static void | ||
3718 | mwl8k_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 | |||
3747 | static 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 | ||
3771 | static void | 3717 | static int mwl8k_sta_add(struct ieee80211_hw *hw, |
3772 | mwl8k_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 | ||
3795 | static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue, | 3737 | static 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 | ||