From b4943d8113500ee783072ba2ba7506ad76df3726 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 8 Sep 2011 14:36:04 +0200 Subject: [PATCH] rt2x00: Introduce sta_add/remove callbacks This implements a basic sta_add and sta_remove callback. Introduce a new structure rt2x00_sta and ask mac80211 to allocate it as private part of its ieee80211_sta. rt2x00_sta only contains the WCID for now. The sta_add callback allows the driver to assign a WCID to a station that is currently being added. The same wcid is also passed to the sta_remove callback one mac80211 removes this STA. Signed-off-by: Helmut Schaa Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00.h | 22 +++++++++++++++++ drivers/net/wireless/rt2x00/rt2x00dev.c | 5 ++++ drivers/net/wireless/rt2x00/rt2x00mac.c | 33 +++++++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index d454ec8f5c6..3b71d792bbf 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -511,6 +511,19 @@ struct rt2x00intf_conf { __le32 bssid[2]; }; +/* + * Private structure for storing STA details + * wcid: Wireless Client ID + */ +struct rt2x00_sta { + int wcid; +}; + +static inline struct rt2x00_sta* sta_to_rt2x00_sta(struct ieee80211_sta *sta) +{ + return (struct rt2x00_sta *)sta->drv_priv; +} + /* * rt2x00lib callback functions. */ @@ -620,6 +633,11 @@ struct rt2x00lib_ops { void (*config) (struct rt2x00_dev *rt2x00dev, struct rt2x00lib_conf *libconf, const unsigned int changed_flags); + int (*sta_add) (struct rt2x00_dev *rt2x00dev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta); + int (*sta_remove) (struct rt2x00_dev *rt2x00dev, + int wcid); }; /* @@ -1267,6 +1285,10 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, #else #define rt2x00mac_set_key NULL #endif /* CONFIG_RT2X00_LIB_CRYPTO */ +int rt2x00mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); +int rt2x00mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta); void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw); void rt2x00mac_sw_scan_complete(struct ieee80211_hw *hw); int rt2x00mac_get_stats(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 634b084a652..e1fb2a8569b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -930,6 +930,11 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) else if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags)) rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE; + /* + * Tell mac80211 about the size of our private STA structure. + */ + rt2x00dev->hw->sta_data_size = sizeof(struct rt2x00_sta); + /* * Allocate tx status FIFO for driver use. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 9db9378820b..6a03f93e92a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -552,6 +552,39 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, EXPORT_SYMBOL_GPL(rt2x00mac_set_key); #endif /* CONFIG_RT2X00_LIB_CRYPTO */ +int rt2x00mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct rt2x00_dev *rt2x00dev = hw->priv; + struct rt2x00_sta *sta_priv = sta_to_rt2x00_sta(sta); + + /* + * If there's no space left in the device table store + * -1 as wcid but tell mac80211 everything went ok. + */ + if (rt2x00dev->ops->lib->sta_add(rt2x00dev, vif, sta)) + sta_priv->wcid = -1; + + return 0; +} +EXPORT_SYMBOL_GPL(rt2x00mac_sta_add); + +int rt2x00mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct rt2x00_dev *rt2x00dev = hw->priv; + struct rt2x00_sta *sta_priv = sta_to_rt2x00_sta(sta); + + /* + * If we never sent the STA to the device no need to clean it up. + */ + if (sta_priv->wcid < 0) + return 0; + + return rt2x00dev->ops->lib->sta_remove(rt2x00dev, sta_priv->wcid); +} +EXPORT_SYMBOL_GPL(rt2x00mac_sta_remove); + void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw) { struct rt2x00_dev *rt2x00dev = hw->priv; -- 2.20.1