Commit 616f5701 authored by Sergey Matyukevich's avatar Sergey Matyukevich Committed by Kalle Valo

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: default avatarSergey Matyukevich <sergey.matyukevich.os@quantenna.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent c3d476d2
...@@ -1061,7 +1061,8 @@ static void qtnf_cfg80211_reg_notifier(struct wiphy *wiphy, ...@@ -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; struct wiphy *wiphy;
...@@ -1076,6 +1077,9 @@ struct wiphy *qtnf_wiphy_allocate(struct qtnf_bus *bus) ...@@ -1076,6 +1077,9 @@ struct wiphy *qtnf_wiphy_allocate(struct qtnf_bus *bus)
if (!wiphy) if (!wiphy)
return NULL; return NULL;
if (pdev)
set_wiphy_dev(wiphy, &pdev->dev);
else
set_wiphy_dev(wiphy, bus->dev); set_wiphy_dev(wiphy, bus->dev);
return wiphy; return wiphy;
......
...@@ -431,18 +431,28 @@ static void qtnf_vif_send_data_high_pri(struct work_struct *work) ...@@ -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, static struct qtnf_wmac *qtnf_core_mac_alloc(struct qtnf_bus *bus,
unsigned int macid) unsigned int macid)
{ {
struct platform_device *pdev = NULL;
struct qtnf_wmac *mac;
struct qtnf_vif *vif; struct qtnf_vif *vif;
struct wiphy *wiphy; struct wiphy *wiphy;
struct qtnf_wmac *mac;
unsigned int i; 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) if (!wiphy)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
mac = wiphy_priv(wiphy); mac = wiphy_priv(wiphy);
mac->macid = macid; mac->macid = macid;
mac->pdev = pdev;
mac->bus = bus; mac->bus = bus;
mutex_init(&mac->mac_lock); mutex_init(&mac->mac_lock);
INIT_DELAYED_WORK(&mac->scan_timeout, qtnf_mac_scan_timeout); 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, ...@@ -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_net_set(dev, wiphy_net(wiphy));
dev->ieee80211_ptr = &vif->wdev; dev->ieee80211_ptr = &vif->wdev;
ether_addr_copy(dev->dev_addr, vif->mac_addr); ether_addr_copy(dev->dev_addr, vif->mac_addr);
SET_NETDEV_DEV(dev, wiphy_dev(wiphy));
dev->flags |= IFF_BROADCAST | IFF_MULTICAST; dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
dev->watchdog_timeo = QTNF_DEF_WDOG_TIMEOUT; dev->watchdog_timeo = QTNF_DEF_WDOG_TIMEOUT;
dev->tx_queue_len = 100; dev->tx_queue_len = 100;
...@@ -505,7 +514,7 @@ int qtnf_core_net_attach(struct qtnf_wmac *mac, struct qtnf_vif *vif, ...@@ -505,7 +514,7 @@ int qtnf_core_net_attach(struct qtnf_wmac *mac, struct qtnf_vif *vif,
qdev_vif = netdev_priv(dev); qdev_vif = netdev_priv(dev);
*((void **)qdev_vif) = vif; *((void **)qdev_vif) = vif;
SET_NETDEV_DEV(dev, mac->bus->dev); SET_NETDEV_DEV(dev, wiphy_dev(wiphy));
ret = register_netdevice(dev); ret = register_netdevice(dev);
if (ret) { if (ret) {
...@@ -561,6 +570,7 @@ static void qtnf_core_mac_detach(struct qtnf_bus *bus, unsigned int macid) ...@@ -561,6 +570,7 @@ static void qtnf_core_mac_detach(struct qtnf_bus *bus, unsigned int macid)
wiphy->bands[band] = NULL; wiphy->bands[band] = NULL;
} }
platform_device_unregister(mac->pdev);
qtnf_mac_iface_comb_free(mac); qtnf_mac_iface_comb_free(mac);
qtnf_mac_ext_caps_free(mac); qtnf_mac_ext_caps_free(mac);
kfree(mac->macinfo.wowlan); kfree(mac->macinfo.wowlan);
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/platform_device.h>
#include "qlink.h" #include "qlink.h"
#include "trans.h" #include "trans.h"
...@@ -107,6 +108,7 @@ struct qtnf_wmac { ...@@ -107,6 +108,7 @@ struct qtnf_wmac {
struct mutex mac_lock; /* lock during wmac speicific ops */ struct mutex mac_lock; /* lock during wmac speicific ops */
struct delayed_work scan_timeout; struct delayed_work scan_timeout;
struct ieee80211_regdomain *rd; struct ieee80211_regdomain *rd;
struct platform_device *pdev;
}; };
struct qtnf_hw_info { struct qtnf_hw_info {
...@@ -127,7 +129,8 @@ void qtnf_mac_iface_comb_free(struct qtnf_wmac *mac); ...@@ -127,7 +129,8 @@ void qtnf_mac_iface_comb_free(struct qtnf_wmac *mac);
void qtnf_mac_ext_caps_free(struct qtnf_wmac *mac); void qtnf_mac_ext_caps_free(struct qtnf_wmac *mac);
bool qtnf_slave_radar_get(void); bool qtnf_slave_radar_get(void);
bool qtnf_dfs_offload_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, int qtnf_core_net_attach(struct qtnf_wmac *mac, struct qtnf_vif *priv,
const char *name, unsigned char name_assign_type); const char *name, unsigned char name_assign_type);
void qtnf_main_work_queue(struct work_struct *work); void qtnf_main_work_queue(struct work_struct *work);
......
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