aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-07-01 15:26:58 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-10 15:01:52 -0400
commitab737a4f7dbe57b12b73f482a7b973bf00b41942 (patch)
tree33f3c44073921b9fa4c96ea5501dbfcad59567ac
parentbc92afd92088ab41223383cc6863ab4792533c54 (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.h10
-rw-r--r--net/mac80211/cfg.c11
-rw-r--r--net/mac80211/wext.c26
-rw-r--r--net/wireless/wext-compat.c46
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
1625int cfg80211_wds_wext_siwap(struct net_device *dev,
1626 struct iw_request_info *info,
1627 struct sockaddr *addr, char *extra);
1628int 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
1372static 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
1372static void ieee80211_rfkill_poll(struct wiphy *wiphy) 1382static 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}
1049EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower); 1049EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower);
1050
1051int 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}
1079EXPORT_SYMBOL_GPL(cfg80211_wds_wext_siwap);
1080
1081int 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}
1095EXPORT_SYMBOL_GPL(cfg80211_wds_wext_giwap);