qtnfmac: add support for 4addr mode
Advertise WIPHY_FLAG_4ADDR_STATION capability to wireless core. Send use4addr interface change flag to firmware in change_virtual_intf cfg80211 callback. In order to enable adding wireless station interface to bridge one should turn on 4addr mode using the following command: $ iw dev wlan0 set 4addr on $ brctl addif br0 wlan0 If this commands succeeds, then interface can be added to bridge. Note that when wireless interface is added to bridge, wpa_supplicant should be started with appropriate -b <brname> parameter, e.g: $ wpa_supplicant -Dnl80211 -iwlan0 -c/path/to/wpa.conf -b br0 Signed-off-by: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:

committed by
Kalle Valo

parent
d1365e794e
commit
de624a355d
@@ -122,7 +122,8 @@ qtnf_change_virtual_intf(struct wiphy *wiphy,
|
|||||||
struct vif_params *params)
|
struct vif_params *params)
|
||||||
{
|
{
|
||||||
struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
|
struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
|
||||||
u8 *mac_addr;
|
u8 *mac_addr = NULL;
|
||||||
|
int use4addr = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = qtnf_validate_iface_combinations(wiphy, vif, type);
|
ret = qtnf_validate_iface_combinations(wiphy, vif, type);
|
||||||
@@ -132,14 +133,14 @@ qtnf_change_virtual_intf(struct wiphy *wiphy,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params)
|
if (params) {
|
||||||
mac_addr = params->macaddr;
|
mac_addr = params->macaddr;
|
||||||
else
|
use4addr = params->use_4addr;
|
||||||
mac_addr = NULL;
|
}
|
||||||
|
|
||||||
qtnf_scan_done(vif->mac, true);
|
qtnf_scan_done(vif->mac, true);
|
||||||
|
|
||||||
ret = qtnf_cmd_send_change_intf_type(vif, type, mac_addr);
|
ret = qtnf_cmd_send_change_intf_type(vif, type, use4addr, mac_addr);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("VIF%u.%u: failed to change type to %d\n",
|
pr_err("VIF%u.%u: failed to change type to %d\n",
|
||||||
vif->mac->macid, vif->vifid, type);
|
vif->mac->macid, vif->vifid, type);
|
||||||
@@ -190,6 +191,7 @@ 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 use4addr = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
mac = wiphy_priv(wiphy);
|
mac = wiphy_priv(wiphy);
|
||||||
@@ -225,10 +227,12 @@ static struct wireless_dev *qtnf_add_virtual_intf(struct wiphy *wiphy,
|
|||||||
return ERR_PTR(-ENOTSUPP);
|
return ERR_PTR(-ENOTSUPP);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params)
|
if (params) {
|
||||||
mac_addr = params->macaddr;
|
mac_addr = params->macaddr;
|
||||||
|
use4addr = params->use_4addr;
|
||||||
|
}
|
||||||
|
|
||||||
ret = qtnf_cmd_send_add_intf(vif, type, mac_addr);
|
ret = qtnf_cmd_send_add_intf(vif, type, use4addr, mac_addr);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("VIF%u.%u: failed to add VIF %pM\n",
|
pr_err("VIF%u.%u: failed to add VIF %pM\n",
|
||||||
mac->macid, vif->vifid, mac_addr);
|
mac->macid, vif->vifid, mac_addr);
|
||||||
@@ -1107,7 +1111,8 @@ int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac)
|
|||||||
wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
|
wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
|
||||||
WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
|
WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
|
||||||
WIPHY_FLAG_AP_UAPSD |
|
WIPHY_FLAG_AP_UAPSD |
|
||||||
WIPHY_FLAG_HAS_CHANNEL_SWITCH;
|
WIPHY_FLAG_HAS_CHANNEL_SWITCH |
|
||||||
|
WIPHY_FLAG_4ADDR_STATION;
|
||||||
wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
||||||
|
|
||||||
if (hw_info->hw_capab & QLINK_HW_CAPAB_DFS_OFFLOAD)
|
if (hw_info->hw_capab & QLINK_HW_CAPAB_DFS_OFFLOAD)
|
||||||
|
@@ -734,6 +734,7 @@ out:
|
|||||||
|
|
||||||
static int qtnf_cmd_send_add_change_intf(struct qtnf_vif *vif,
|
static int qtnf_cmd_send_add_change_intf(struct qtnf_vif *vif,
|
||||||
enum nl80211_iftype iftype,
|
enum nl80211_iftype iftype,
|
||||||
|
int use4addr,
|
||||||
u8 *mac_addr,
|
u8 *mac_addr,
|
||||||
enum qlink_cmd_type cmd_type)
|
enum qlink_cmd_type cmd_type)
|
||||||
{
|
{
|
||||||
@@ -751,6 +752,7 @@ static int qtnf_cmd_send_add_change_intf(struct qtnf_vif *vif,
|
|||||||
qtnf_bus_lock(vif->mac->bus);
|
qtnf_bus_lock(vif->mac->bus);
|
||||||
|
|
||||||
cmd = (struct qlink_cmd_manage_intf *)cmd_skb->data;
|
cmd = (struct qlink_cmd_manage_intf *)cmd_skb->data;
|
||||||
|
cmd->intf_info.use4addr = use4addr;
|
||||||
|
|
||||||
switch (iftype) {
|
switch (iftype) {
|
||||||
case NL80211_IFTYPE_AP:
|
case NL80211_IFTYPE_AP:
|
||||||
@@ -786,17 +788,19 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int qtnf_cmd_send_add_intf(struct qtnf_vif *vif,
|
int qtnf_cmd_send_add_intf(struct qtnf_vif *vif, enum nl80211_iftype iftype,
|
||||||
enum nl80211_iftype iftype, u8 *mac_addr)
|
int use4addr, u8 *mac_addr)
|
||||||
{
|
{
|
||||||
return qtnf_cmd_send_add_change_intf(vif, iftype, mac_addr,
|
return qtnf_cmd_send_add_change_intf(vif, iftype, use4addr, mac_addr,
|
||||||
QLINK_CMD_ADD_INTF);
|
QLINK_CMD_ADD_INTF);
|
||||||
}
|
}
|
||||||
|
|
||||||
int qtnf_cmd_send_change_intf_type(struct qtnf_vif *vif,
|
int qtnf_cmd_send_change_intf_type(struct qtnf_vif *vif,
|
||||||
enum nl80211_iftype iftype, u8 *mac_addr)
|
enum nl80211_iftype iftype,
|
||||||
|
int use4addr,
|
||||||
|
u8 *mac_addr)
|
||||||
{
|
{
|
||||||
return qtnf_cmd_send_add_change_intf(vif, iftype, mac_addr,
|
return qtnf_cmd_send_add_change_intf(vif, iftype, use4addr, mac_addr,
|
||||||
QLINK_CMD_CHANGE_INTF);
|
QLINK_CMD_CHANGE_INTF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -26,9 +26,11 @@ void qtnf_cmd_send_deinit_fw(struct qtnf_bus *bus);
|
|||||||
int qtnf_cmd_get_hw_info(struct qtnf_bus *bus);
|
int qtnf_cmd_get_hw_info(struct qtnf_bus *bus);
|
||||||
int qtnf_cmd_get_mac_info(struct qtnf_wmac *mac);
|
int qtnf_cmd_get_mac_info(struct qtnf_wmac *mac);
|
||||||
int qtnf_cmd_send_add_intf(struct qtnf_vif *vif, enum nl80211_iftype iftype,
|
int qtnf_cmd_send_add_intf(struct qtnf_vif *vif, enum nl80211_iftype iftype,
|
||||||
u8 *mac_addr);
|
int use4addr, u8 *mac_addr);
|
||||||
int qtnf_cmd_send_change_intf_type(struct qtnf_vif *vif,
|
int qtnf_cmd_send_change_intf_type(struct qtnf_vif *vif,
|
||||||
enum nl80211_iftype iftype, u8 *mac_addr);
|
enum nl80211_iftype iftype,
|
||||||
|
int use4addr,
|
||||||
|
u8 *mac_addr);
|
||||||
int qtnf_cmd_send_del_intf(struct qtnf_vif *vif);
|
int qtnf_cmd_send_del_intf(struct qtnf_vif *vif);
|
||||||
int qtnf_cmd_band_info_get(struct qtnf_wmac *mac,
|
int qtnf_cmd_band_info_get(struct qtnf_wmac *mac,
|
||||||
struct ieee80211_supported_band *band);
|
struct ieee80211_supported_band *band);
|
||||||
|
@@ -195,6 +195,7 @@ static int qtnf_netdev_set_mac_address(struct net_device *ndev, void *addr)
|
|||||||
qtnf_scan_done(vif->mac, true);
|
qtnf_scan_done(vif->mac, true);
|
||||||
|
|
||||||
ret = qtnf_cmd_send_change_intf_type(vif, vif->wdev.iftype,
|
ret = qtnf_cmd_send_change_intf_type(vif, vif->wdev.iftype,
|
||||||
|
vif->wdev.use_4addr,
|
||||||
sa->sa_data);
|
sa->sa_data);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
@@ -545,7 +546,8 @@ static int qtnf_core_mac_attach(struct qtnf_bus *bus, unsigned int macid)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = qtnf_cmd_send_add_intf(vif, vif->wdev.iftype, vif->mac_addr);
|
ret = qtnf_cmd_send_add_intf(vif, vif->wdev.iftype,
|
||||||
|
vif->wdev.use_4addr, vif->mac_addr);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("MAC%u: failed to add VIF\n", macid);
|
pr_err("MAC%u: failed to add VIF\n", macid);
|
||||||
goto error;
|
goto error;
|
||||||
|
@@ -105,7 +105,8 @@ struct qlink_intf_info {
|
|||||||
__le16 if_type;
|
__le16 if_type;
|
||||||
__le16 vlanid;
|
__le16 vlanid;
|
||||||
u8 mac_addr[ETH_ALEN];
|
u8 mac_addr[ETH_ALEN];
|
||||||
u8 rsvd[2];
|
u8 use4addr;
|
||||||
|
u8 rsvd[1];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
enum qlink_sta_flags {
|
enum qlink_sta_flags {
|
||||||
|
Reference in New Issue
Block a user