summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Matyukevich <sergey.matyukevich.os@quantenna.com>2020-02-13 11:45:31 +0000
committerKalle Valo <kvalo@codeaurora.org>2020-03-12 15:38:58 +0200
commit616f5701f4ab7deb89a6534a481c8c5b5658278f (patch)
tree2230ab0fb068ce474e57ea233db27bdc3bc7d82a
parentc3d476d21851d96aaf5b354786d4570c405788e5 (diff)
qtnfmac: assign each wiphy to its own virtual platform device
Quantenna Pearl device exposes multiple (up to 3) radio interfaces under single PCIe function. So far all the wiphy devices were attached to the same pcie device. As a result, all different wireless network devices were reported under the same sysfs directory for pcie device, e.g.: $ ls /sys/class/net/wlan0/device/net/ wlan0 wlan1 It turns out that such behavior may confuse various users of wireless subsystem. For instance, it turned out to be the case for: - Linux init systems, e.g. for renaming based on parent device - OpenWRT configuration scripts Suggested solution is to add an intermediate virtual platform device for each radio interface. Signed-off-by: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-rw-r--r--drivers/net/wireless/quantenna/qtnfmac/cfg80211.c8
-rw-r--r--drivers/net/wireless/quantenna/qtnfmac/core.c18
-rw-r--r--drivers/net/wireless/quantenna/qtnfmac/core.h5
3 files changed, 24 insertions, 7 deletions
diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
index 722d5caefe3c..018d3ed75fda 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
@@ -1061,7 +1061,8 @@ static void qtnf_cfg80211_reg_notifier(struct wiphy *wiphy,
}
}
-struct wiphy *qtnf_wiphy_allocate(struct qtnf_bus *bus)
+struct wiphy *qtnf_wiphy_allocate(struct qtnf_bus *bus,
+ struct platform_device *pdev)
{
struct wiphy *wiphy;
@@ -1076,7 +1077,10 @@ struct wiphy *qtnf_wiphy_allocate(struct qtnf_bus *bus)
if (!wiphy)
return NULL;
- set_wiphy_dev(wiphy, bus->dev);
+ if (pdev)
+ set_wiphy_dev(wiphy, &pdev->dev);
+ else
+ set_wiphy_dev(wiphy, bus->dev);
return wiphy;
}
diff --git a/drivers/net/wireless/quantenna/qtnfmac/core.c b/drivers/net/wireless/quantenna/qtnfmac/core.c
index 9e666fac8b5f..eea777f8acea 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/core.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/core.c
@@ -431,18 +431,28 @@ static void qtnf_vif_send_data_high_pri(struct work_struct *work)
static struct qtnf_wmac *qtnf_core_mac_alloc(struct qtnf_bus *bus,
unsigned int macid)
{
+ struct platform_device *pdev = NULL;
+ struct qtnf_wmac *mac;
struct qtnf_vif *vif;
struct wiphy *wiphy;
- struct qtnf_wmac *mac;
unsigned int i;
- wiphy = qtnf_wiphy_allocate(bus);
+ if (bus->hw_info.num_mac > 1) {
+ pdev = platform_device_register_data(bus->dev,
+ dev_name(bus->dev),
+ macid, NULL, 0);
+ if (IS_ERR(pdev))
+ return ERR_PTR(-EINVAL);
+ }
+
+ wiphy = qtnf_wiphy_allocate(bus, pdev);
if (!wiphy)
return ERR_PTR(-ENOMEM);
mac = wiphy_priv(wiphy);
mac->macid = macid;
+ mac->pdev = pdev;
mac->bus = bus;
mutex_init(&mac->mac_lock);
INIT_DELAYED_WORK(&mac->scan_timeout, qtnf_mac_scan_timeout);
@@ -493,7 +503,6 @@ int qtnf_core_net_attach(struct qtnf_wmac *mac, struct qtnf_vif *vif,
dev_net_set(dev, wiphy_net(wiphy));
dev->ieee80211_ptr = &vif->wdev;
ether_addr_copy(dev->dev_addr, vif->mac_addr);
- SET_NETDEV_DEV(dev, wiphy_dev(wiphy));
dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
dev->watchdog_timeo = QTNF_DEF_WDOG_TIMEOUT;
dev->tx_queue_len = 100;
@@ -505,7 +514,7 @@ int qtnf_core_net_attach(struct qtnf_wmac *mac, struct qtnf_vif *vif,
qdev_vif = netdev_priv(dev);
*((void **)qdev_vif) = vif;
- SET_NETDEV_DEV(dev, mac->bus->dev);
+ SET_NETDEV_DEV(dev, wiphy_dev(wiphy));
ret = register_netdevice(dev);
if (ret) {
@@ -561,6 +570,7 @@ static void qtnf_core_mac_detach(struct qtnf_bus *bus, unsigned int macid)
wiphy->bands[band] = NULL;
}
+ platform_device_unregister(mac->pdev);
qtnf_mac_iface_comb_free(mac);
qtnf_mac_ext_caps_free(mac);
kfree(mac->macinfo.wowlan);
diff --git a/drivers/net/wireless/quantenna/qtnfmac/core.h b/drivers/net/wireless/quantenna/qtnfmac/core.h
index b993f9ca14c5..269ce12cf8bf 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/core.h
+++ b/drivers/net/wireless/quantenna/qtnfmac/core.h
@@ -20,6 +20,7 @@
#include <linux/ctype.h>
#include <linux/workqueue.h>
#include <linux/slab.h>
+#include <linux/platform_device.h>
#include "qlink.h"
#include "trans.h"
@@ -107,6 +108,7 @@ struct qtnf_wmac {
struct mutex mac_lock; /* lock during wmac speicific ops */
struct delayed_work scan_timeout;
struct ieee80211_regdomain *rd;
+ struct platform_device *pdev;
};
struct qtnf_hw_info {
@@ -127,7 +129,8 @@ void qtnf_mac_iface_comb_free(struct qtnf_wmac *mac);
void qtnf_mac_ext_caps_free(struct qtnf_wmac *mac);
bool qtnf_slave_radar_get(void);
bool qtnf_dfs_offload_get(void);
-struct wiphy *qtnf_wiphy_allocate(struct qtnf_bus *bus);
+struct wiphy *qtnf_wiphy_allocate(struct qtnf_bus *bus,
+ struct platform_device *pdev);
int qtnf_core_net_attach(struct qtnf_wmac *mac, struct qtnf_vif *priv,
const char *name, unsigned char name_assign_type);
void qtnf_main_work_queue(struct work_struct *work);