Commit 01efff52 authored by Sergey Matyukevich's avatar Sergey Matyukevich Committed by Kalle Valo

qtnfmac: validate interface combinations on changes

Validate new interface combinations using wireless core checks when new
interface is added or when the type of existing interface is modified.
This is performed to make sure that new interface combination is supported
by hardware. As a result, invalid interface combinations are rejected early,
rather than passed to hardware with sometimes unpredictable results.
Signed-off-by: default avatarSergey Matyukevich <sergey.matyukevich.os@quantenna.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 537faf26
...@@ -80,6 +80,41 @@ qtnf_mgmt_stypes[NUM_NL80211_IFTYPES] = { ...@@ -80,6 +80,41 @@ qtnf_mgmt_stypes[NUM_NL80211_IFTYPES] = {
}, },
}; };
static int
qtnf_validate_iface_combinations(struct wiphy *wiphy,
struct qtnf_vif *change_vif,
enum nl80211_iftype new_type)
{
struct qtnf_wmac *mac;
struct qtnf_vif *vif;
int i;
int ret = 0;
struct iface_combination_params params = {
.num_different_channels = 1,
};
mac = wiphy_priv(wiphy);
if (!mac)
return -EFAULT;
for (i = 0; i < QTNF_MAX_INTF; i++) {
vif = &mac->iflist[i];
if (vif->wdev.iftype != NL80211_IFTYPE_UNSPECIFIED)
params.iftype_num[vif->wdev.iftype]++;
}
if (change_vif) {
params.iftype_num[new_type]++;
params.iftype_num[change_vif->wdev.iftype]--;
} else {
params.iftype_num[new_type]++;
}
ret = cfg80211_check_combinations(wiphy, &params);
return ret;
}
static int static int
qtnf_change_virtual_intf(struct wiphy *wiphy, qtnf_change_virtual_intf(struct wiphy *wiphy,
struct net_device *dev, struct net_device *dev,
...@@ -90,6 +125,13 @@ qtnf_change_virtual_intf(struct wiphy *wiphy, ...@@ -90,6 +125,13 @@ qtnf_change_virtual_intf(struct wiphy *wiphy,
u8 *mac_addr; u8 *mac_addr;
int ret; int ret;
ret = qtnf_validate_iface_combinations(wiphy, vif, type);
if (ret) {
pr_err("VIF%u.%u combination check: failed to set type %d\n",
vif->mac->macid, vif->vifid, type);
return ret;
}
if (params) if (params)
mac_addr = params->macaddr; mac_addr = params->macaddr;
else else
...@@ -150,12 +192,20 @@ static struct wireless_dev *qtnf_add_virtual_intf(struct wiphy *wiphy, ...@@ -150,12 +192,20 @@ static struct wireless_dev *qtnf_add_virtual_intf(struct wiphy *wiphy,
struct qtnf_wmac *mac; struct qtnf_wmac *mac;
struct qtnf_vif *vif; struct qtnf_vif *vif;
u8 *mac_addr = NULL; u8 *mac_addr = NULL;
int ret;
mac = wiphy_priv(wiphy); mac = wiphy_priv(wiphy);
if (!mac) if (!mac)
return ERR_PTR(-EFAULT); return ERR_PTR(-EFAULT);
ret = qtnf_validate_iface_combinations(wiphy, NULL, type);
if (ret) {
pr_err("MAC%u invalid combination: failed to add type %d\n",
mac->macid, type);
return ERR_PTR(ret);
}
switch (type) { switch (type) {
case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment