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_s.conf -b br0

Signed-off-by: Sergey Matyukevich <[email protected]>
---
 drivers/net/wireless/quantenna/qtnfmac/cfg80211.c |  8 +++++---
 drivers/net/wireless/quantenna/qtnfmac/commands.c | 14 +++++++++-----
 drivers/net/wireless/quantenna/qtnfmac/commands.h |  6 ++++--
 drivers/net/wireless/quantenna/qtnfmac/core.c     |  4 +++-
 drivers/net/wireless/quantenna/qtnfmac/qlink.h    |  3 ++-
 5 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c 
b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
index 51b33ec78fac..9e0ac1744be7 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
@@ -139,7 +139,8 @@ qtnf_change_virtual_intf(struct wiphy *wiphy,
 
        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, params->use_4addr,
+                                            mac_addr);
        if (ret) {
                pr_err("VIF%u.%u: failed to change type to %d\n",
                       vif->mac->macid, vif->vifid, type);
@@ -228,7 +229,7 @@ static struct wireless_dev *qtnf_add_virtual_intf(struct 
wiphy *wiphy,
        if (params)
                mac_addr = params->macaddr;
 
-       ret = qtnf_cmd_send_add_intf(vif, type, mac_addr);
+       ret = qtnf_cmd_send_add_intf(vif, type, params->use_4addr, mac_addr);
        if (ret) {
                pr_err("VIF%u.%u: failed to add VIF %pM\n",
                       mac->macid, vif->vifid, mac_addr);
@@ -1107,7 +1108,8 @@ int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, 
struct qtnf_wmac *mac)
        wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
                        WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
                        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;
 
        if (hw_info->hw_capab & QLINK_HW_CAPAB_DFS_OFFLOAD)
diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c 
b/drivers/net/wireless/quantenna/qtnfmac/commands.c
index c2f085589f54..0748a756cc1c 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c
@@ -734,6 +734,7 @@ int qtnf_cmd_get_sta_info(struct qtnf_vif *vif, const u8 
*sta_mac,
 
 static int qtnf_cmd_send_add_change_intf(struct qtnf_vif *vif,
                                         enum nl80211_iftype iftype,
+                                        int use4addr,
                                         u8 *mac_addr,
                                         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);
 
        cmd = (struct qlink_cmd_manage_intf *)cmd_skb->data;
+       cmd->intf_info.use4addr = use4addr;
 
        switch (iftype) {
        case NL80211_IFTYPE_AP:
@@ -786,17 +788,19 @@ static int qtnf_cmd_send_add_change_intf(struct qtnf_vif 
*vif,
        return ret;
 }
 
-int qtnf_cmd_send_add_intf(struct qtnf_vif *vif,
-                          enum nl80211_iftype iftype, u8 *mac_addr)
+int qtnf_cmd_send_add_intf(struct qtnf_vif *vif, 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_ADD_INTF);
 }
 
 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);
 }
 
diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.h 
b/drivers/net/wireless/quantenna/qtnfmac/commands.h
index 1ac41156c192..1c25e7905e9a 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/commands.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/commands.h
@@ -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_mac_info(struct qtnf_wmac *mac);
 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,
-                                  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_band_info_get(struct qtnf_wmac *mac,
                           struct ieee80211_supported_band *band);
diff --git a/drivers/net/wireless/quantenna/qtnfmac/core.c 
b/drivers/net/wireless/quantenna/qtnfmac/core.c
index 5d18a4a917c9..29258acfa8dc 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/core.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/core.c
@@ -195,6 +195,7 @@ static int qtnf_netdev_set_mac_address(struct net_device 
*ndev, void *addr)
        qtnf_scan_done(vif->mac, true);
 
        ret = qtnf_cmd_send_change_intf_type(vif, vif->wdev.iftype,
+                                            vif->wdev.use_4addr,
                                             sa->sa_data);
 
        if (ret)
@@ -545,7 +546,8 @@ static int qtnf_core_mac_attach(struct qtnf_bus *bus, 
unsigned int macid)
                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) {
                pr_err("MAC%u: failed to add VIF\n", macid);
                goto error;
diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink.h 
b/drivers/net/wireless/quantenna/qtnfmac/qlink.h
index f9c7f87afaf8..a78cb9e05068 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/qlink.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/qlink.h
@@ -105,7 +105,8 @@ struct qlink_intf_info {
        __le16 if_type;
        __le16 vlanid;
        u8 mac_addr[ETH_ALEN];
-       u8 rsvd[2];
+       u8 use4addr;
+       u8 rsvd[1];
 } __packed;
 
 enum qlink_sta_flags {
-- 
2.11.0

Reply via email to