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>
This commit is contained in:
parent
bc92afd920
commit
ab737a4f7d
@ -1018,6 +1018,9 @@ struct cfg80211_ops {
|
|||||||
enum tx_power_setting type, int dbm);
|
enum tx_power_setting type, int dbm);
|
||||||
int (*get_tx_power)(struct wiphy *wiphy, int *dbm);
|
int (*get_tx_power)(struct wiphy *wiphy, int *dbm);
|
||||||
|
|
||||||
|
int (*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev,
|
||||||
|
u8 *addr);
|
||||||
|
|
||||||
void (*rfkill_poll)(struct wiphy *wiphy);
|
void (*rfkill_poll)(struct wiphy *wiphy);
|
||||||
|
|
||||||
#ifdef CONFIG_NL80211_TESTMODE
|
#ifdef CONFIG_NL80211_TESTMODE
|
||||||
@ -1619,6 +1622,13 @@ int cfg80211_wext_giwpower(struct net_device *dev,
|
|||||||
struct iw_request_info *info,
|
struct iw_request_info *info,
|
||||||
struct iw_param *wrq, char *extra);
|
struct iw_param *wrq, char *extra);
|
||||||
|
|
||||||
|
int cfg80211_wds_wext_siwap(struct net_device *dev,
|
||||||
|
struct iw_request_info *info,
|
||||||
|
struct sockaddr *addr, char *extra);
|
||||||
|
int cfg80211_wds_wext_giwap(struct net_device *dev,
|
||||||
|
struct iw_request_info *info,
|
||||||
|
struct sockaddr *addr, char *extra);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* callbacks for asynchronous cfg80211 methods, notification
|
* callbacks for asynchronous cfg80211 methods, notification
|
||||||
* functions and BSS handling helpers
|
* functions and BSS handling helpers
|
||||||
|
@ -1369,6 +1369,16 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
|
||||||
|
u8 *addr)
|
||||||
|
{
|
||||||
|
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||||
|
|
||||||
|
memcpy(&sdata->u.wds.remote_addr, addr, ETH_ALEN);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void ieee80211_rfkill_poll(struct wiphy *wiphy)
|
static void ieee80211_rfkill_poll(struct wiphy *wiphy)
|
||||||
{
|
{
|
||||||
struct ieee80211_local *local = wiphy_priv(wiphy);
|
struct ieee80211_local *local = wiphy_priv(wiphy);
|
||||||
@ -1454,6 +1464,7 @@ struct cfg80211_ops mac80211_config_ops = {
|
|||||||
.set_wiphy_params = ieee80211_set_wiphy_params,
|
.set_wiphy_params = ieee80211_set_wiphy_params,
|
||||||
.set_tx_power = ieee80211_set_tx_power,
|
.set_tx_power = ieee80211_set_tx_power,
|
||||||
.get_tx_power = ieee80211_get_tx_power,
|
.get_tx_power = ieee80211_get_tx_power,
|
||||||
|
.set_wds_peer = ieee80211_set_wds_peer,
|
||||||
.rfkill_poll = ieee80211_rfkill_poll,
|
.rfkill_poll = ieee80211_rfkill_poll,
|
||||||
CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
|
CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
|
||||||
.set_power_mgmt = ieee80211_set_power_mgmt,
|
.set_power_mgmt = ieee80211_set_power_mgmt,
|
||||||
|
@ -140,23 +140,8 @@ static int ieee80211_ioctl_siwap(struct net_device *dev,
|
|||||||
if (sdata->vif.type == NL80211_IFTYPE_STATION)
|
if (sdata->vif.type == NL80211_IFTYPE_STATION)
|
||||||
return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra);
|
return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra);
|
||||||
|
|
||||||
if (sdata->vif.type == NL80211_IFTYPE_WDS) {
|
if (sdata->vif.type == NL80211_IFTYPE_WDS)
|
||||||
/*
|
return cfg80211_wds_wext_siwap(dev, info, ap_addr, extra);
|
||||||
* If it is necessary to update the WDS peer address
|
|
||||||
* while the interface is running, then we need to do
|
|
||||||
* more work here, namely if it is running we need to
|
|
||||||
* add a new and remove the old STA entry, this is
|
|
||||||
* normally handled by _open() and _stop().
|
|
||||||
*/
|
|
||||||
if (netif_running(dev))
|
|
||||||
return -EBUSY;
|
|
||||||
|
|
||||||
memcpy(&sdata->u.wds.remote_addr, (u8 *) &ap_addr->sa_data,
|
|
||||||
ETH_ALEN);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,11 +158,8 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
|
|||||||
if (sdata->vif.type == NL80211_IFTYPE_STATION)
|
if (sdata->vif.type == NL80211_IFTYPE_STATION)
|
||||||
return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra);
|
return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra);
|
||||||
|
|
||||||
if (sdata->vif.type == NL80211_IFTYPE_WDS) {
|
if (sdata->vif.type == NL80211_IFTYPE_WDS)
|
||||||
ap_addr->sa_family = ARPHRD_ETHER;
|
return cfg80211_wds_wext_giwap(dev, info, ap_addr, extra);
|
||||||
memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
@ -1047,3 +1047,49 @@ int cfg80211_wext_giwpower(struct net_device *dev,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower);
|
EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower);
|
||||||
|
|
||||||
|
int cfg80211_wds_wext_siwap(struct net_device *dev,
|
||||||
|
struct iw_request_info *info,
|
||||||
|
struct sockaddr *addr, char *extra)
|
||||||
|
{
|
||||||
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||||
|
struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (WARN_ON(wdev->iftype != NL80211_IFTYPE_WDS))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (addr->sa_family != ARPHRD_ETHER)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (netif_running(dev))
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
|
if (!rdev->ops->set_wds_peer)
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
err = rdev->ops->set_wds_peer(wdev->wiphy, dev, (u8 *) &addr->sa_data);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
memcpy(&wdev->wext.bssid, (u8 *) &addr->sa_data, ETH_ALEN);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(cfg80211_wds_wext_siwap);
|
||||||
|
|
||||||
|
int cfg80211_wds_wext_giwap(struct net_device *dev,
|
||||||
|
struct iw_request_info *info,
|
||||||
|
struct sockaddr *addr, char *extra)
|
||||||
|
{
|
||||||
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||||
|
|
||||||
|
if (WARN_ON(wdev->iftype != NL80211_IFTYPE_WDS))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
addr->sa_family = ARPHRD_ETHER;
|
||||||
|
memcpy(&addr->sa_data, wdev->wext.bssid, ETH_ALEN);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(cfg80211_wds_wext_giwap);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user