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 0cfdb9db66f7..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(&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(&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 | ||
