From 4aebd3bdbd8a26ebcd2398289e2379472d17825f Mon Sep 17 00:00:00 2001 From: Lior David Date: Mon, 26 Feb 2018 20:12:14 +0200 Subject: wil6210: add support for adding and removing virtual interfaces Add generic support in cfg80211 operations add_virtual_intf and del_virtual_intf for adding/removing VIFs of any interface type, and fix change_virtual_intf to allow changing the interface type of a VIF. Previously these operations only worked for the P2P_DEVICE interface which is not a real VIF(it is management-only and shares radio with the main interface). Currently the interface combination is validated, the VIF is added/removed in the firmware and the appropriate net/wireless device is also added/removed. Added minimal support for proper interface up/down and module unload but most operations still work only on the main interface. Signed-off-by: Lior David Signed-off-by: Maya Erez Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/wil6210/pcie_bus.c | 39 +++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 7 deletions(-) (limited to 'drivers/net/wireless/ath/wil6210/pcie_bus.c') diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c index a61ffd9dce0f..1fd76148d6ff 100644 --- a/drivers/net/wireless/ath/wil6210/pcie_bus.c +++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c @@ -137,6 +137,20 @@ void wil_enable_irq(struct wil6210_priv *wil) enable_irq(wil->pdev->irq); } +static void wil_remove_all_additional_vifs(struct wil6210_priv *wil) +{ + struct wil6210_vif *vif; + int i; + + for (i = 1; i < wil->max_vifs; i++) { + vif = wil->vifs[i]; + if (vif) { + wil_vif_prepare_stop(wil, vif); + wil_vif_remove(wil, vif->mid); + } + } +} + /* Bus ops */ static int wil_if_pcie_enable(struct wil6210_priv *wil) { @@ -148,10 +162,8 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil) */ int msi_only = pdev->msi_enabled; bool _use_msi = use_msi; - bool wmi_only = test_bit(WMI_FW_CAPABILITY_WMI_ONLY, - wil->fw_capabilities); - wil_dbg_misc(wil, "if_pcie_enable, wmi_only %d\n", wmi_only); + wil_dbg_misc(wil, "if_pcie_enable\n"); pci_set_master(pdev); @@ -172,11 +184,9 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil) if (rc) goto stop_master; - /* need reset here to obtain MAC or in case of WMI-only FW, full reset - * and fw loading takes place - */ + /* need reset here to obtain MAC */ mutex_lock(&wil->mutex); - rc = wil_reset(wil, wmi_only); + rc = wil_reset(wil, false); mutex_unlock(&wil->mutex); if (rc) goto release_irq; @@ -356,6 +366,18 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto bus_disable; } + /* in case of WMI-only FW, perform full reset and FW loading */ + if (test_bit(WMI_FW_CAPABILITY_WMI_ONLY, wil->fw_capabilities)) { + wil_dbg_misc(wil, "Loading WMI only FW\n"); + mutex_lock(&wil->mutex); + rc = wil_reset(wil, true); + mutex_unlock(&wil->mutex); + if (rc) { + wil_err(wil, "failed to load WMI only FW\n"); + goto if_remove; + } + } + if (IS_ENABLED(CONFIG_PM)) wil->pm_notify.notifier_call = wil6210_pm_notify; @@ -372,6 +394,8 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) return 0; +if_remove: + wil_if_remove(wil); bus_disable: wil_if_pcie_disable(wil); err_iounmap: @@ -402,6 +426,7 @@ static void wil_pcie_remove(struct pci_dev *pdev) wil6210_debugfs_remove(wil); rtnl_lock(); wil_p2p_wdev_free(wil); + wil_remove_all_additional_vifs(wil); rtnl_unlock(); wil_if_remove(wil); wil_if_pcie_disable(wil); -- cgit v1.2.1