diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-07-01 15:26:58 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-07-10 15:01:52 -0400 |
commit | ab737a4f7dbe57b12b73f482a7b973bf00b41942 (patch) | |
tree | 33f3c44073921b9fa4c96ea5501dbfcad59567ac | |
parent | bc92afd92088ab41223383cc6863ab4792533c54 (diff) |
cfg80211: implement IWAP for WDS
This implements siocsiwap/giwap for WDS mode.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | include/net/cfg80211.h | 10 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 11 | ||||
-rw-r--r-- | net/mac80211/wext.c | 26 | ||||
-rw-r--r-- | net/wireless/wext-compat.c | 46 |
4 files changed, 71 insertions, 22 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 82b7d804f6da..b396d11564bc 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -1018,6 +1018,9 @@ struct cfg80211_ops { | |||
1018 | enum tx_power_setting type, int dbm); | 1018 | enum tx_power_setting type, int dbm); |
1019 | int (*get_tx_power)(struct wiphy *wiphy, int *dbm); | 1019 | int (*get_tx_power)(struct wiphy *wiphy, int *dbm); |
1020 | 1020 | ||
1021 | int (*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev, | ||
1022 | u8 *addr); | ||
1023 | |||
1021 | void (*rfkill_poll)(struct wiphy *wiphy); | 1024 | void (*rfkill_poll)(struct wiphy *wiphy); |
1022 | 1025 | ||
1023 | #ifdef CONFIG_NL80211_TESTMODE | 1026 | #ifdef CONFIG_NL80211_TESTMODE |
@@ -1619,6 +1622,13 @@ int cfg80211_wext_giwpower(struct net_device *dev, | |||
1619 | struct iw_request_info *info, | 1622 | struct iw_request_info *info, |
1620 | struct iw_param *wrq, char *extra); | 1623 | struct iw_param *wrq, char *extra); |
1621 | 1624 | ||
1625 | int cfg80211_wds_wext_siwap(struct net_device *dev, | ||
1626 | struct iw_request_info *info, | ||
1627 | struct sockaddr *addr, char *extra); | ||
1628 | int cfg80211_wds_wext_giwap(struct net_device *dev, | ||
1629 | struct iw_request_info *info, | ||
1630 | struct sockaddr *addr, char *extra); | ||
1631 | |||
1622 | /* | 1632 | /* |
1623 | * callbacks for asynchronous cfg80211 methods, notification | 1633 | * callbacks for asynchronous cfg80211 methods, notification |
1624 | * functions and BSS handling helpers | 1634 | * functions and BSS handling helpers |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 8c7b2cdbeeda..2cf5bf6378e4 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1369,6 +1369,16 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm) | |||
1369 | return 0; | 1369 | return 0; |
1370 | } | 1370 | } |
1371 | 1371 | ||
1372 | static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev, | ||
1373 | u8 *addr) | ||
1374 | { | ||
1375 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
1376 | |||
1377 | memcpy(&sdata->u.wds.remote_addr, addr, ETH_ALEN); | ||
1378 | |||
1379 | return 0; | ||
1380 | } | ||
1381 | |||
1372 | static void ieee80211_rfkill_poll(struct wiphy *wiphy) | 1382 | static void ieee80211_rfkill_poll(struct wiphy *wiphy) |
1373 | { | 1383 | { |
1374 | struct ieee80211_local *local = wiphy_priv(wiphy); | 1384 | struct ieee80211_local *local = wiphy_priv(wiphy); |
@@ -1454,6 +1464,7 @@ struct cfg80211_ops mac80211_config_ops = { | |||
1454 | .set_wiphy_params = ieee80211_set_wiphy_params, | 1464 | .set_wiphy_params = ieee80211_set_wiphy_params, |
1455 | .set_tx_power = ieee80211_set_tx_power, | 1465 | .set_tx_power = ieee80211_set_tx_power, |
1456 | .get_tx_power = ieee80211_get_tx_power, | 1466 | .get_tx_power = ieee80211_get_tx_power, |
1467 | .set_wds_peer = ieee80211_set_wds_peer, | ||
1457 | .rfkill_poll = ieee80211_rfkill_poll, | 1468 | .rfkill_poll = ieee80211_rfkill_poll, |
1458 | CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd) | 1469 | CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd) |
1459 | .set_power_mgmt = ieee80211_set_power_mgmt, | 1470 | .set_power_mgmt = ieee80211_set_power_mgmt, |
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index f77929802c7a..4053d766af2d 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c | |||
@@ -140,23 +140,8 @@ static int ieee80211_ioctl_siwap(struct net_device *dev, | |||
140 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | 140 | if (sdata->vif.type == NL80211_IFTYPE_STATION) |
141 | return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra); | 141 | return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra); |
142 | 142 | ||
143 | if (sdata->vif.type == NL80211_IFTYPE_WDS) { | 143 | if (sdata->vif.type == NL80211_IFTYPE_WDS) |
144 | /* | 144 | return cfg80211_wds_wext_siwap(dev, info, ap_addr, extra); |
145 | * If it is necessary to update the WDS peer address | ||
146 | * while the interface is running, then we need to do | ||
147 | * more work here, namely if it is running we need to | ||
148 | * add a new and remove the old STA entry, this is | ||
149 | * normally handled by _open() and _stop(). | ||
150 | */ | ||
151 | if (netif_running(dev)) | ||
152 | return -EBUSY; | ||
153 | |||
154 | memcpy(&sdata->u.wds.remote_addr, (u8 *) &ap_addr->sa_data, | ||
155 | ETH_ALEN); | ||
156 | |||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | return -EOPNOTSUPP; | 145 | return -EOPNOTSUPP; |
161 | } | 146 | } |
162 | 147 | ||
@@ -173,11 +158,8 @@ static int ieee80211_ioctl_giwap(struct net_device *dev, | |||
173 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | 158 | if (sdata->vif.type == NL80211_IFTYPE_STATION) |
174 | return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra); | 159 | return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra); |
175 | 160 | ||
176 | if (sdata->vif.type == NL80211_IFTYPE_WDS) { | 161 | if (sdata->vif.type == NL80211_IFTYPE_WDS) |
177 | ap_addr->sa_family = ARPHRD_ETHER; | 162 | return cfg80211_wds_wext_giwap(dev, info, ap_addr, extra); |
178 | memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN); | ||
179 | return 0; | ||
180 | } | ||
181 | 163 | ||
182 | return -EOPNOTSUPP; | 164 | return -EOPNOTSUPP; |
183 | } | 165 | } |
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 2e1ab78fb0d7..2f72dae2634f 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c | |||
@@ -1047,3 +1047,49 @@ int cfg80211_wext_giwpower(struct net_device *dev, | |||
1047 | return 0; | 1047 | return 0; |
1048 | } | 1048 | } |
1049 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower); | 1049 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower); |
1050 | |||
1051 | int cfg80211_wds_wext_siwap(struct net_device *dev, | ||
1052 | struct iw_request_info *info, | ||
1053 | struct sockaddr *addr, char *extra) | ||
1054 | { | ||
1055 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
1056 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | ||
1057 | int err; | ||
1058 | |||
1059 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_WDS)) | ||
1060 | return -EINVAL; | ||
1061 | |||
1062 | if (addr->sa_family != ARPHRD_ETHER) | ||
1063 | return -EINVAL; | ||
1064 | |||
1065 | if (netif_running(dev)) | ||
1066 | return -EBUSY; | ||
1067 | |||
1068 | if (!rdev->ops->set_wds_peer) | ||
1069 | return -EOPNOTSUPP; | ||
1070 | |||
1071 | err = rdev->ops->set_wds_peer(wdev->wiphy, dev, (u8 *) &addr->sa_data); | ||
1072 | if (err) | ||
1073 | return err; | ||
1074 | |||
1075 | memcpy(&wdev->wext.bssid, (u8 *) &addr->sa_data, ETH_ALEN); | ||
1076 | |||
1077 | return 0; | ||
1078 | } | ||
1079 | EXPORT_SYMBOL_GPL(cfg80211_wds_wext_siwap); | ||
1080 | |||
1081 | int cfg80211_wds_wext_giwap(struct net_device *dev, | ||
1082 | struct iw_request_info *info, | ||
1083 | struct sockaddr *addr, char *extra) | ||
1084 | { | ||
1085 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
1086 | |||
1087 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_WDS)) | ||
1088 | return -EINVAL; | ||
1089 | |||
1090 | addr->sa_family = ARPHRD_ETHER; | ||
1091 | memcpy(&addr->sa_data, wdev->wext.bssid, ETH_ALEN); | ||
1092 | |||
1093 | return 0; | ||
1094 | } | ||
1095 | EXPORT_SYMBOL_GPL(cfg80211_wds_wext_giwap); | ||