diff options
Diffstat (limited to 'drivers/staging/wilc1000')
-rw-r--r-- | drivers/staging/wilc1000/wilc_mon.c | 9 | ||||
-rw-r--r-- | drivers/staging/wilc1000/wilc_netdev.c | 269 | ||||
-rw-r--r-- | drivers/staging/wilc1000/wilc_sdio.c | 7 | ||||
-rw-r--r-- | drivers/staging/wilc1000/wilc_spi.c | 3 | ||||
-rw-r--r-- | drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 535 | ||||
-rw-r--r-- | drivers/staging/wilc1000/wilc_wfi_cfgoperations.h | 13 | ||||
-rw-r--r-- | drivers/staging/wilc1000/wilc_wfi_netdevice.h | 20 | ||||
-rw-r--r-- | drivers/staging/wilc1000/wilc_wlan.c | 20 | ||||
-rw-r--r-- | drivers/staging/wilc1000/wilc_wlan.h | 6 |
9 files changed, 492 insertions, 390 deletions
diff --git a/drivers/staging/wilc1000/wilc_mon.c b/drivers/staging/wilc1000/wilc_mon.c index 9fe19a3e1dd4..7d7933d40924 100644 --- a/drivers/staging/wilc1000/wilc_mon.c +++ b/drivers/staging/wilc1000/wilc_mon.c @@ -233,6 +233,7 @@ struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl, strncpy(wl->monitor_dev->name, name, IFNAMSIZ); wl->monitor_dev->name[IFNAMSIZ - 1] = 0; wl->monitor_dev->netdev_ops = &wilc_wfi_netdev_ops; + wl->monitor_dev->needs_free_netdev = true; if (register_netdevice(wl->monitor_dev)) { netdev_err(real_dev, "register_netdevice failed\n"); @@ -247,12 +248,14 @@ struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl, return wl->monitor_dev; } -void wilc_wfi_deinit_mon_interface(struct wilc *wl) +void wilc_wfi_deinit_mon_interface(struct wilc *wl, bool rtnl_locked) { if (!wl->monitor_dev) return; - unregister_netdev(wl->monitor_dev); - free_netdev(wl->monitor_dev); + if (rtnl_locked) + unregister_netdevice(wl->monitor_dev); + else + unregister_netdev(wl->monitor_dev); wl->monitor_dev = NULL; } diff --git a/drivers/staging/wilc1000/wilc_netdev.c b/drivers/staging/wilc1000/wilc_netdev.c index 0e0a4eec5486..900611136a84 100644 --- a/drivers/staging/wilc1000/wilc_netdev.c +++ b/drivers/staging/wilc1000/wilc_netdev.c @@ -97,22 +97,29 @@ static struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header) { u8 *bssid, *bssid1; int i = 0; + struct net_device *ndev = NULL; bssid = mac_header + 10; bssid1 = mac_header + 4; + mutex_lock(&wilc->vif_mutex); for (i = 0; i < wilc->vif_num; i++) { if (wilc->vif[i]->mode == WILC_STATION_MODE) if (ether_addr_equal_unaligned(bssid, - wilc->vif[i]->bssid)) - return wilc->vif[i]->ndev; + wilc->vif[i]->bssid)) { + ndev = wilc->vif[i]->ndev; + goto out; + } if (wilc->vif[i]->mode == WILC_AP_MODE) if (ether_addr_equal_unaligned(bssid1, - wilc->vif[i]->bssid)) - return wilc->vif[i]->ndev; + wilc->vif[i]->bssid)) { + ndev = wilc->vif[i]->ndev; + goto out; + } } - - return NULL; +out: + mutex_unlock(&wilc->vif_mutex); + return ndev; } void wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid, u8 mode) @@ -143,9 +150,7 @@ static int wilc_txq_task(void *vp) { int ret; u32 txq_count; - struct net_device *dev = vp; - struct wilc_vif *vif = netdev_priv(dev); - struct wilc *wl = vif->wilc; + struct wilc *wl = vp; complete(&wl->txq_thread_started); while (1) { @@ -159,14 +164,18 @@ static int wilc_txq_task(void *vp) break; } do { - ret = wilc_wlan_handle_txq(dev, &txq_count); + ret = wilc_wlan_handle_txq(wl, &txq_count); if (txq_count < FLOW_CONTROL_LOWER_THRESHOLD) { - if (wl->vif[0]->mac_opened && - netif_queue_stopped(wl->vif[0]->ndev)) - netif_wake_queue(wl->vif[0]->ndev); - if (wl->vif[1]->mac_opened && - netif_queue_stopped(wl->vif[1]->ndev)) - netif_wake_queue(wl->vif[1]->ndev); + int i; + struct wilc_vif *ifc; + + mutex_lock(&wl->vif_mutex); + for (i = 0; i < wl->vif_num; i++) { + ifc = wl->vif[i]; + if (ifc->mac_opened && ifc->ndev) + netif_wake_queue(ifc->ndev); + } + mutex_unlock(&wl->vif_mutex); } } while (ret == -ENOBUFS && !wl->close); } @@ -245,14 +254,13 @@ static int wilc1000_firmware_download(struct net_device *dev) static int wilc_init_fw_config(struct net_device *dev, struct wilc_vif *vif) { - struct wilc_priv *priv; + struct wilc_priv *priv = &vif->priv; struct host_if_drv *hif_drv; u8 b; u16 hw; u32 w; netdev_dbg(dev, "Start configuring Firmware\n"); - priv = wiphy_priv(dev->ieee80211_ptr->wiphy); hif_drv = (struct host_if_drv *)priv->hif_drv; netdev_dbg(dev, "Host = %p\n", hif_drv); @@ -424,6 +432,7 @@ static void wlan_deinit_locks(struct net_device *dev) mutex_destroy(&wilc->rxq_cs); mutex_destroy(&wilc->cfg_cmd_lock); mutex_destroy(&wilc->txq_add_to_head_cs); + mutex_destroy(&wilc->vif_mutex); } static void wlan_deinitialize_threads(struct net_device *dev) @@ -477,31 +486,12 @@ static void wilc_wlan_deinitialize(struct net_device *dev) } } -static void wlan_init_locks(struct net_device *dev) -{ - struct wilc_vif *vif = netdev_priv(dev); - struct wilc *wl = vif->wilc; - - mutex_init(&wl->hif_cs); - mutex_init(&wl->rxq_cs); - mutex_init(&wl->cfg_cmd_lock); - - spin_lock_init(&wl->txq_spinlock); - mutex_init(&wl->txq_add_to_head_cs); - - init_completion(&wl->txq_event); - - init_completion(&wl->cfg_event); - init_completion(&wl->sync_event); - init_completion(&wl->txq_thread_started); -} - static int wlan_initialize_threads(struct net_device *dev) { struct wilc_vif *vif = netdev_priv(dev); struct wilc *wilc = vif->wilc; - wilc->txq_thread = kthread_run(wilc_txq_task, (void *)dev, + wilc->txq_thread = kthread_run(wilc_txq_task, (void *)wilc, "K_TXQ_TASK"); if (IS_ERR(wilc->txq_thread)) { netdev_err(dev, "couldn't create TXQ thread\n"); @@ -513,6 +503,12 @@ static int wlan_initialize_threads(struct net_device *dev) return 0; } +static int dev_state_ev_handler(struct notifier_block *this, + unsigned long event, void *ptr); +static struct notifier_block g_dev_notifier = { + .notifier_call = dev_state_ev_handler +}; + static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif) { int ret = 0; @@ -522,13 +518,9 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif) wl->mac_status = WILC_MAC_STATUS_INIT; wl->close = 0; - wlan_init_locks(dev); - ret = wilc_wlan_init(dev); - if (ret < 0) { - ret = -EIO; - goto fail_locks; - } + if (ret < 0) + return -EIO; ret = wlan_initialize_threads(dev); if (ret < 0) { @@ -582,7 +574,7 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif) ret = -EIO; goto fail_fw_start; } - + register_inetaddr_notifier(&g_dev_notifier); wl->initialized = true; return 0; @@ -600,8 +592,6 @@ fail_threads: wlan_deinitialize_threads(dev); fail_wilc_wlan: wilc_wlan_cleanup(dev); -fail_locks: - wlan_deinit_locks(dev); netdev_err(dev, "WLAN initialization FAILED\n"); } else { netdev_dbg(dev, "wilc1000 already initialized\n"); @@ -758,16 +748,19 @@ netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev) vif->netstats.tx_packets++; vif->netstats.tx_bytes += tx_data->size; - tx_data->bssid = wilc->vif[vif->idx]->bssid; queue_count = wilc_wlan_txq_add_net_pkt(ndev, (void *)tx_data, tx_data->buff, tx_data->size, wilc_tx_complete); if (queue_count > FLOW_CONTROL_UPPER_THRESHOLD) { - if (wilc->vif[0]->mac_opened) - netif_stop_queue(wilc->vif[0]->ndev); - if (wilc->vif[1]->mac_opened) - netif_stop_queue(wilc->vif[1]->ndev); + int i; + + mutex_lock(&wilc->vif_mutex); + for (i = 0; i < wilc->vif_num; i++) { + if (wilc->vif[i]->mac_opened) + netif_stop_queue(wilc->vif[i]->ndev); + } + mutex_unlock(&wilc->vif_mutex); } return 0; @@ -794,6 +787,7 @@ static int wilc_mac_close(struct net_device *ndev) if (wl->open_ifcs == 0) { netdev_dbg(ndev, "Deinitializing wilc1000\n"); wl->close = 1; + unregister_inetaddr_notifier(&g_dev_notifier); wilc_wlan_deinitialize(ndev); } @@ -848,18 +842,23 @@ void wilc_wfi_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size) int i = 0; struct wilc_vif *vif; + mutex_lock(&wilc->vif_mutex); for (i = 0; i < wilc->vif_num; i++) { + u16 type = le16_to_cpup((__le16 *)buff); + vif = netdev_priv(wilc->vif[i]->ndev); + if ((type == vif->frame_reg[0].type && vif->frame_reg[0].reg) || + (type == vif->frame_reg[1].type && vif->frame_reg[1].reg)) { + wilc_wfi_p2p_rx(vif, buff, size); + break; + } + if (vif->monitor_flag) { wilc_wfi_monitor_rx(wilc->monitor_dev, buff, size); - return; + break; } } - - vif = netdev_priv(wilc->vif[1]->ndev); - if ((buff[0] == vif->frame_reg[0].type && vif->frame_reg[0].reg) || - (buff[0] == vif->frame_reg[1].type && vif->frame_reg[1].reg)) - wilc_wfi_p2p_rx(wilc->vif[1]->ndev, buff, size); + mutex_unlock(&wilc->vif_mutex); } static const struct net_device_ops wilc_netdev_ops = { @@ -890,14 +889,10 @@ static int dev_state_ev_handler(struct notifier_block *this, if (!dev->ieee80211_ptr || !dev->ieee80211_ptr->wiphy) return NOTIFY_DONE; - priv = wiphy_priv(dev->ieee80211_ptr->wiphy); - if (!priv) - return NOTIFY_DONE; + vif = netdev_priv(dev); + priv = &vif->priv; hif_drv = (struct host_if_drv *)priv->hif_drv; - vif = netdev_priv(dev); - if (!vif || !hif_drv) - return NOTIFY_DONE; switch (event) { case NETDEV_UP: @@ -932,10 +927,6 @@ static int dev_state_ev_handler(struct notifier_block *this, return NOTIFY_DONE; } -static struct notifier_block g_dev_notifier = { - .notifier_call = dev_state_ev_handler -}; - void wilc_netdev_cleanup(struct wilc *wilc) { int i; @@ -943,136 +934,72 @@ void wilc_netdev_cleanup(struct wilc *wilc) if (!wilc) return; - if (wilc->vif[0]->ndev || wilc->vif[1]->ndev) - unregister_inetaddr_notifier(&g_dev_notifier); - if (wilc->firmware) { release_firmware(wilc->firmware); wilc->firmware = NULL; } - for (i = 0; i < WILC_NUM_CONCURRENT_IFC; i++) { - if (wilc->vif[i] && wilc->vif[i]->ndev) { + for (i = 0; i < wilc->vif_num; i++) { + if (wilc->vif[i] && wilc->vif[i]->ndev) unregister_netdev(wilc->vif[i]->ndev); - wilc_free_wiphy(wilc->vif[i]->ndev); - free_netdev(wilc->vif[i]->ndev); - } } - wilc_wfi_deinit_mon_interface(wilc); + wilc_wfi_deinit_mon_interface(wilc, false); flush_workqueue(wilc->hif_workqueue); destroy_workqueue(wilc->hif_workqueue); wilc_wlan_cfg_deinit(wilc); kfree(wilc->bus_data); - kfree(wilc); + wiphy_unregister(wilc->wiphy); + wiphy_free(wilc->wiphy); } EXPORT_SYMBOL_GPL(wilc_netdev_cleanup); -int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, - const struct wilc_hif_func *ops) +struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name, + int vif_type, enum nl80211_iftype type, + bool rtnl_locked) { - int i, ret; - struct wilc_vif *vif; struct net_device *ndev; - struct wilc *wl; - - wl = kzalloc(sizeof(*wl), GFP_KERNEL); - if (!wl) - return -ENOMEM; - - ret = wilc_wlan_cfg_init(wl); - if (ret) - goto free_wl; - - *wilc = wl; - wl->io_type = io_type; - wl->hif_func = ops; - wl->enable_ps = true; - wl->chip_ps_state = WILC_CHIP_WAKEDUP; - INIT_LIST_HEAD(&wl->txq_head.list); - INIT_LIST_HEAD(&wl->rxq_head.list); - - wl->hif_workqueue = create_singlethread_workqueue("WILC_wq"); - if (!wl->hif_workqueue) { - ret = -ENOMEM; - goto free_cfg; - } - - register_inetaddr_notifier(&g_dev_notifier); - - for (i = 0; i < WILC_NUM_CONCURRENT_IFC; i++) { - struct wireless_dev *wdev; + struct wilc_vif *vif; + int ret; - ndev = alloc_etherdev(sizeof(struct wilc_vif)); - if (!ndev) { - ret = -ENOMEM; - goto free_ndev; - } + ndev = alloc_etherdev(sizeof(*vif)); + if (!ndev) + return ERR_PTR(-ENOMEM); - vif = netdev_priv(ndev); + vif = netdev_priv(ndev); + ndev->ieee80211_ptr = &vif->priv.wdev; + strcpy(ndev->name, name); + vif->wilc = wl; + vif->ndev = ndev; + ndev->ml_priv = vif; - if (i == 0) { - strcpy(ndev->name, "wlan%d"); - vif->ifc_id = 1; - } else { - strcpy(ndev->name, "p2p%d"); - vif->ifc_id = 0; - } - vif->wilc = *wilc; - vif->ndev = ndev; - wl->vif[i] = vif; - wl->vif_num = i + 1; - vif->idx = i; - - ndev->netdev_ops = &wilc_netdev_ops; - - wdev = wilc_create_wiphy(ndev, dev); - if (!wdev) { - netdev_err(ndev, "Can't register WILC Wiphy\n"); - ret = -ENOMEM; - goto free_ndev; - } + ndev->netdev_ops = &wilc_netdev_ops; - SET_NETDEV_DEV(ndev, dev); + SET_NETDEV_DEV(ndev, wiphy_dev(wl->wiphy)); - vif->ndev->ieee80211_ptr = wdev; - vif->ndev->ml_priv = vif; - wdev->netdev = vif->ndev; - vif->netstats.rx_packets = 0; - vif->netstats.tx_packets = 0; - vif->netstats.rx_bytes = 0; - vif->netstats.tx_bytes = 0; + vif->priv.wdev.wiphy = wl->wiphy; + vif->priv.wdev.netdev = ndev; + vif->priv.wdev.iftype = type; + vif->priv.dev = ndev; + if (rtnl_locked) + ret = register_netdevice(ndev); + else ret = register_netdev(ndev); - if (ret) - goto free_ndev; - vif->iftype = WILC_STATION_MODE; - vif->mac_opened = 0; + if (ret) { + free_netdev(ndev); + return ERR_PTR(-EFAULT); } - return 0; - -free_ndev: - for (; i >= 0; i--) { - if (wl->vif[i]) { - if (wl->vif[i]->iftype == WILC_STATION_MODE) - unregister_netdev(wl->vif[i]->ndev); - - if (wl->vif[i]->ndev) { - wilc_free_wiphy(wl->vif[i]->ndev); - free_netdev(wl->vif[i]->ndev); - } - } - } - unregister_inetaddr_notifier(&g_dev_notifier); - destroy_workqueue(wl->hif_workqueue); -free_cfg: - wilc_wlan_cfg_deinit(wl); -free_wl: - kfree(wl); - return ret; + ndev->needs_free_netdev = true; + vif->iftype = vif_type; + vif->wilc->vif[wl->vif_num] = vif; + vif->ifc_id = wl->vif_num; + vif->idx = wl->vif_num; + wl->vif_num += 1; + vif->mac_opened = 0; + return vif; } -EXPORT_SYMBOL_GPL(wilc_netdev_init); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index b789c57d7e80..4c1c81fed11f 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -8,6 +8,7 @@ #include <linux/mmc/host.h> #include "wilc_wfi_netdevice.h" +#include "wilc_wfi_cfgoperations.h" #define SDIO_MODALIAS "wilc1000_sdio" @@ -139,11 +140,9 @@ static int wilc_sdio_probe(struct sdio_func *func, } } - dev_dbg(&func->dev, "Initializing netdev\n"); - ret = wilc_netdev_init(&wilc, &func->dev, WILC_HIF_SDIO, - &wilc_hif_sdio); + ret = wilc_cfg80211_init(&wilc, &func->dev, WILC_HIF_SDIO, + &wilc_hif_sdio); if (ret) { - dev_err(&func->dev, "Couldn't initialize netdev\n"); kfree(sdio_priv); return ret; } diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index d8910bf9cb75..3c1ae9e9f9aa 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -7,6 +7,7 @@ #include <linux/spi/spi.h> #include "wilc_wfi_netdevice.h" +#include "wilc_wfi_cfgoperations.h" struct wilc_spi { int crc_off; @@ -120,7 +121,7 @@ static int wilc_bus_probe(struct spi_device *spi) dev_err(&spi->dev, "failed to get the irq gpio\n"); } - ret = wilc_netdev_init(&wilc, NULL, WILC_HIF_SPI, &wilc_hif_spi); + ret = wilc_cfg80211_init(&wilc, &spi->dev, WILC_HIF_SPI, &wilc_hif_spi); if (ret) { kfree(spi_priv); return ret; diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index b0daa1136663..012e3252cacc 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -183,48 +183,67 @@ static void cfg_connect_result(enum conn_event conn_disconn_evt, u8 mac_status, eth_zero_addr(priv->associated_bss); wilc_wlan_set_bssid(priv->dev, NULL, WILC_STATION_MODE); - if (vif->iftype != WILC_CLIENT_MODE) + if (vif->iftype != WILC_CLIENT_MODE) { wl->sta_ch = WILC_INVALID_CHANNEL; - - if (wfi_drv->ifc_up && dev == wl->vif[1]->ndev) - reason = 3; - else if (!wfi_drv->ifc_up && dev == wl->vif[1]->ndev) - reason = 1; + } else { + if (wfi_drv->ifc_up) + reason = 3; + else + reason = 1; + } cfg80211_disconnected(dev, reason, NULL, 0, false, GFP_KERNEL); } } +static struct wilc_vif *wilc_get_wl_to_vif(struct wilc *wl) +{ + int i; + + for (i = 0; i < wl->vif_num; i++) + if (wl->vif[i]) + return wl->vif[i]; + + return ERR_PTR(-EINVAL); +} + static int set_channel(struct wiphy *wiphy, struct cfg80211_chan_def *chandef) { - u32 channelnum = 0; - struct wilc_priv *priv = wiphy_priv(wiphy); - struct wilc_vif *vif = netdev_priv(priv->dev); - int result = 0; + struct wilc *wl = wiphy_priv(wiphy); + struct wilc_vif *vif; + u32 channelnum; + int result; + + mutex_lock(&wl->vif_mutex); + vif = wilc_get_wl_to_vif(wl); + if (IS_ERR(vif)) { + mutex_unlock(&wl->vif_mutex); + return PTR_ERR(vif); + } channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq); - vif->wilc->op_ch = channelnum; + wl->op_ch = channelnum; result = wilc_set_mac_chnl_num(vif, channelnum); + if (result) + netdev_err(vif->ndev, "Error in setting channel\n"); - if (result != 0) - netdev_err(priv->dev, "Error in setting channel\n"); - + mutex_unlock(&wl->vif_mutex); return result; } static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) { - struct wilc_priv *priv = wiphy_priv(wiphy); - struct wilc_vif *vif = netdev_priv(priv->dev); + struct wilc_vif *vif = netdev_priv(request->wdev->netdev); + struct wilc_priv *priv = &vif->priv; u32 i; int ret = 0; u8 scan_ch_list[WILC_MAX_NUM_SCANNED_CH]; u8 scan_type; if (request->n_channels > WILC_MAX_NUM_SCANNED_CH) { - netdev_err(priv->dev, "Requested scanned channels over\n"); + netdev_err(vif->ndev, "Requested scanned channels over\n"); return -EINVAL; } @@ -256,8 +275,8 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) static int connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme) { - struct wilc_priv *priv = wiphy_priv(wiphy); - struct wilc_vif *vif = netdev_priv(priv->dev); + struct wilc_vif *vif = netdev_priv(dev); + struct wilc_priv *priv = &vif->priv; struct host_if_drv *wfi_drv = priv->hif_drv; int ret; u32 i; @@ -410,8 +429,8 @@ out_error: static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code) { - struct wilc_priv *priv = wiphy_priv(wiphy); - struct wilc_vif *vif = netdev_priv(priv->dev); + struct wilc_vif *vif = netdev_priv(dev); + struct wilc_priv *priv = &vif->priv; struct wilc *wilc = vif->wilc; int ret; @@ -501,17 +520,17 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, { int ret = 0, keylen = params->key_len; - struct wilc_priv *priv = wiphy_priv(wiphy); const u8 *rx_mic = NULL; const u8 *tx_mic = NULL; u8 mode = WILC_FW_SEC_NO; u8 op_mode; struct wilc_vif *vif = netdev_priv(netdev); + struct wilc_priv *priv = &vif->priv; switch (params->cipher) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: - if (priv->wdev->iftype == NL80211_IFTYPE_AP) { + if (priv->wdev.iftype == NL80211_IFTYPE_AP) { wilc_wfi_cfg_copy_wep_info(priv, key_index, params); if (params->cipher == WLAN_CIPHER_SUITE_WEP40) @@ -538,8 +557,8 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, case WLAN_CIPHER_SUITE_TKIP: case WLAN_CIPHER_SUITE_CCMP: - if (priv->wdev->iftype == NL80211_IFTYPE_AP || - priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) { + if (priv->wdev.iftype == NL80211_IFTYPE_AP || + priv->wdev.iftype == NL80211_IFTYPE_P2P_GO) { struct wilc_wfi_key *key; ret = wilc_wfi_cfg_allocate_wpa_entry(priv, key_index); @@ -611,9 +630,9 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev, bool pairwise, const u8 *mac_addr) { - struct wilc_priv *priv = wiphy_priv(wiphy); + struct wilc *wl = wiphy_priv(wiphy); struct wilc_vif *vif = netdev_priv(netdev); - struct wilc *wl = vif->wilc; + struct wilc_priv *priv = &vif->priv; if (netdev == wl->vif[0]->ndev) { if (priv->wilc_gtk[key_index]) { @@ -650,7 +669,8 @@ static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, bool pairwise, const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *)) { - struct wilc_priv *priv = wiphy_priv(wiphy); + struct wilc_vif *vif = netdev_priv(netdev); + struct wilc_priv *priv = &vif->priv; struct key_params key_params; if (!pairwise) { @@ -675,8 +695,7 @@ static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, bool unicast, bool multicast) { - struct wilc_priv *priv = wiphy_priv(wiphy); - struct wilc_vif *vif = netdev_priv(priv->dev); + struct wilc_vif *vif = netdev_priv(netdev); wilc_set_wep_default_keyid(vif, key_index); @@ -686,8 +705,8 @@ static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, static int get_station(struct wiphy *wiphy, struct net_device *dev, const u8 *mac, struct station_info *sinfo) { - struct wilc_priv *priv = wiphy_priv(wiphy); struct wilc_vif *vif = netdev_priv(dev); + struct wilc_priv *priv = &vif->priv; u32 i = 0; u32 associatedsta = ~0; u32 inactive_time = 0; @@ -743,13 +762,35 @@ static int change_bss(struct wiphy *wiphy, struct net_device *dev, return 0; } +struct wilc_vif *wilc_get_interface(struct wilc *wl) +{ + int i; + struct wilc_vif *vif = NULL; + + mutex_lock(&wl->vif_mutex); + for (i = 0; i < wl->vif_num; i++) { + if (wl->vif[i]) { + vif = wl->vif[i]; + break; + } + } + mutex_unlock(&wl->vif_mutex); + return vif; +} + static int set_wiphy_params(struct wiphy *wiphy, u32 changed) { int ret; struct cfg_param_attr cfg_param_val; - struct wilc_priv *priv = wiphy_priv(wiphy); - struct wilc_vif *vif = netdev_priv(priv->dev); + struct wilc *wl = wiphy_priv(wiphy); + struct wilc_vif *vif; + struct wilc_priv *priv; + vif = wilc_get_interface(wl); + if (!vif) + return -EINVAL; + + priv = &vif->priv; cfg_param_val.flag = 0; if (changed & WIPHY_PARAM_RETRY_SHORT) { @@ -804,8 +845,8 @@ static int set_wiphy_params(struct wiphy *wiphy, u32 changed) static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev, struct cfg80211_pmksa *pmksa) { - struct wilc_priv *priv = wiphy_priv(wiphy); - struct wilc_vif *vif = netdev_priv(priv->dev); + struct wilc_vif *vif = netdev_priv(netdev); + struct wilc_priv *priv = &vif->priv; u32 i; int ret = 0; u8 flag = 0; @@ -840,7 +881,8 @@ static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev, { u32 i; int ret = 0; - struct wilc_priv *priv = wiphy_priv(wiphy); + struct wilc_vif *vif = netdev_priv(netdev); + struct wilc_priv *priv = &vif->priv; for (i = 0; i < priv->pmkid_list.numpmkid; i++) { if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid, @@ -870,9 +912,9 @@ static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev, static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) { - struct wilc_priv *priv = wiphy_priv(wiphy); + struct wilc_vif *vif = netdev_priv(netdev); - memset(&priv->pmkid_list, 0, sizeof(struct wilc_pmkid_attr)); + memset(&vif->priv.pmkid_list, 0, sizeof(struct wilc_pmkid_attr)); return 0; } @@ -987,12 +1029,11 @@ static void wilc_wfi_cfg_parse_rx_vendor_spec(struct wilc_priv *priv, u8 *buff, } } -void wilc_wfi_p2p_rx(struct net_device *dev, u8 *buff, u32 size) +void wilc_wfi_p2p_rx(struct wilc_vif *vif, u8 *buff, u32 size) { - struct wilc_priv *priv = wiphy_priv(dev->ieee80211_ptr->wiphy); - struct host_if_drv *wfi_drv = priv->hif_drv; - struct wilc_vif *vif = netdev_priv(dev); struct wilc *wl = vif->wilc; + struct wilc_priv *priv = &vif->priv; + struct host_if_drv *wfi_drv = priv->hif_drv; u32 header, pkt_offset; s32 freq; __le16 fc; @@ -1008,8 +1049,8 @@ void wilc_wfi_p2p_rx(struct net_device *dev, u8 *buff, u32 size) pkt_offset & IS_MGMT_STATUS_SUCCES) ack = true; - cfg80211_mgmt_tx_status(priv->wdev, priv->tx_cookie, buff, size, - ack, GFP_KERNEL); + cfg80211_mgmt_tx_status(&priv->wdev, priv->tx_cookie, buff, + size, ack, GFP_KERNEL); return; } @@ -1017,13 +1058,13 @@ void wilc_wfi_p2p_rx(struct net_device *dev, u8 *buff, u32 size) fc = ((struct ieee80211_hdr *)buff)->frame_control; if (!ieee80211_is_action(fc)) { - cfg80211_rx_mgmt(priv->wdev, freq, 0, buff, size, 0); + cfg80211_rx_mgmt(&priv->wdev, freq, 0, buff, size, 0); return; } if (priv->cfg_scanning && time_after_eq(jiffies, (unsigned long)wfi_drv->p2p_timeout)) { - netdev_dbg(dev, "Receiving action wrong ch\n"); + netdev_dbg(vif->ndev, "Receiving action wrong ch\n"); return; } if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) { @@ -1046,14 +1087,14 @@ void wilc_wfi_p2p_rx(struct net_device *dev, u8 *buff, u32 size) break; default: - netdev_dbg(dev, + netdev_dbg(vif->ndev, "%s: Not handled action frame type:%x\n", __func__, buff[ACTION_SUBTYPE_ID]); break; } } - cfg80211_rx_mgmt(priv->wdev, freq, 0, buff, size, 0); + cfg80211_rx_mgmt(&priv->wdev, freq, 0, buff, size, 0); } static void wilc_wfi_mgmt_tx_complete(void *priv, int status) @@ -1066,7 +1107,8 @@ static void wilc_wfi_mgmt_tx_complete(void *priv, int status) static void wilc_wfi_remain_on_channel_expired(void *data, u64 cookie) { - struct wilc_priv *priv = data; + struct wilc_vif *vif = data; + struct wilc_priv *priv = &vif->priv; struct wilc_wfi_p2p_listen_params *params = &priv->remain_on_ch_params; if (cookie != params->listen_cookie) @@ -1074,7 +1116,7 @@ static void wilc_wfi_remain_on_channel_expired(void *data, u64 cookie) priv->p2p_listen_state = false; - cfg80211_remain_on_channel_expired(priv->wdev, params->listen_cookie, + cfg80211_remain_on_channel_expired(&priv->wdev, params->listen_cookie, params->listen_ch, GFP_KERNEL); } @@ -1084,8 +1126,8 @@ static int remain_on_channel(struct wiphy *wiphy, unsigned int duration, u64 *cookie) { int ret = 0; - struct wilc_priv *priv = wiphy_priv(wiphy); - struct wilc_vif *vif = netdev_priv(priv->dev); + struct wilc_vif *vif = netdev_priv(wdev->netdev); + struct wilc_priv *priv = &vif->priv; u64 id; if (wdev->iftype == NL80211_IFTYPE_AP) { @@ -1099,7 +1141,7 @@ static int remain_on_channel(struct wiphy *wiphy, ret = wilc_remain_on_channel(vif, id, duration, chan->hw_value, wilc_wfi_remain_on_channel_expired, - (void *)priv); + (void *)vif); if (ret) return ret; @@ -1122,8 +1164,8 @@ static int cancel_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie) { - struct wilc_priv *priv = wiphy_priv(wiphy); - struct wilc_vif *vif = netdev_priv(priv->dev); + struct wilc_vif *vif = netdev_priv(wdev->netdev); + struct wilc_priv *priv = &vif->priv; if (cookie != priv->remain_on_ch_params.listen_cookie) return -ENOENT; @@ -1193,9 +1235,9 @@ static int mgmt_tx(struct wiphy *wiphy, size_t len = params->len; const struct ieee80211_mgmt *mgmt; struct wilc_p2p_mgmt_data *mgmt_tx; - struct wilc_priv *priv = wiphy_priv(wiphy); - struct host_if_drv *wfi_drv = priv->hif_drv; struct wilc_vif *vif = netdev_priv(wdev->netdev); + struct wilc_priv *priv = &vif->priv; + struct host_if_drv *wfi_drv = priv->hif_drv; u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(priv->p2p.local_random); int ret = 0; @@ -1279,7 +1321,8 @@ static int mgmt_tx_cancel_wait(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie) { - struct wilc_priv *priv = wiphy_priv(wiphy); + struct wilc_vif *vif = netdev_priv(wdev->netdev); + struct wilc_priv *priv = &vif->priv; struct host_if_drv *wfi_drv = priv->hif_drv; wfi_drv->p2p_timeout = jiffies; @@ -1289,7 +1332,7 @@ static int mgmt_tx_cancel_wait(struct wiphy *wiphy, params = &priv->remain_on_ch_params; - cfg80211_remain_on_channel_expired(priv->wdev, + cfg80211_remain_on_channel_expired(wdev, params->listen_cookie, params->listen_ch, GFP_KERNEL); @@ -1301,9 +1344,8 @@ static int mgmt_tx_cancel_wait(struct wiphy *wiphy, void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, u16 frame_type, bool reg) { - struct wilc_priv *priv = wiphy_priv(wiphy); - struct wilc_vif *vif = netdev_priv(priv->wdev->netdev); - struct wilc *wl = vif->wilc; + struct wilc *wl = wiphy_priv(wiphy); + struct wilc_vif *vif = netdev_priv(wdev->netdev); if (!frame_type) return; @@ -1337,8 +1379,7 @@ static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev, static int dump_station(struct wiphy *wiphy, struct net_device *dev, int idx, u8 *mac, struct station_info *sinfo) { - struct wilc_priv *priv = wiphy_priv(wiphy); - struct wilc_vif *vif = netdev_priv(priv->dev); + struct wilc_vif *vif = netdev_priv(dev); int ret; if (idx != 0) @@ -1350,15 +1391,15 @@ static int dump_station(struct wiphy *wiphy, struct net_device *dev, if (ret) return ret; - memcpy(mac, priv->associated_bss, ETH_ALEN); + memcpy(mac, vif->priv.associated_bss, ETH_ALEN); return 0; } static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool enabled, int timeout) { - struct wilc_priv *priv = wiphy_priv(wiphy); - struct wilc_vif *vif = netdev_priv(priv->dev); + struct wilc_vif *vif = netdev_priv(dev); + struct wilc_priv *priv = &vif->priv; if (!priv->hif_drv) return -EIO; @@ -1373,9 +1414,9 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, enum nl80211_iftype type, struct vif_params *params) { - struct wilc_priv *priv = wiphy_priv(wiphy); + struct wilc *wl = wiphy_priv(wiphy); struct wilc_vif *vif = netdev_priv(dev); - struct wilc *wl = vif->wilc; + struct wilc_priv *priv = &vif->priv; priv->p2p.local_random = 0x01; priv->p2p.recv_random = 0x00; @@ -1387,8 +1428,10 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, case NL80211_IFTYPE_STATION: vif->connecting = false; dev->ieee80211_ptr->iftype = type; - priv->wdev->iftype = type; + priv->wdev.iftype = type; vif->monitor_flag = 0; + if (vif->iftype == WILC_AP_MODE || vif->iftype == WILC_GO_MODE) + wilc_wfi_deinit_mon_interface(wl, true); vif->iftype = WILC_STATION_MODE; wilc_set_operation_mode(vif, WILC_STATION_MODE); @@ -1402,7 +1445,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, case NL80211_IFTYPE_P2P_CLIENT: vif->connecting = false; dev->ieee80211_ptr->iftype = type; - priv->wdev->iftype = type; + priv->wdev.iftype = type; vif->monitor_flag = 0; vif->iftype = WILC_CLIENT_MODE; wilc_set_operation_mode(vif, WILC_STATION_MODE); @@ -1414,7 +1457,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, case NL80211_IFTYPE_AP: wl->enable_ps = false; dev->ieee80211_ptr->iftype = type; - priv->wdev->iftype = type; + priv->wdev.iftype = type; vif->iftype = WILC_AP_MODE; if (wl->initialized) { @@ -1431,7 +1474,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, jiffies + msecs_to_jiffies(WILC_IP_TIMEOUT_MS)); wilc_set_operation_mode(vif, WILC_AP_MODE); dev->ieee80211_ptr->iftype = type; - priv->wdev->iftype = type; + priv->wdev.iftype = type; vif->iftype = WILC_GO_MODE; wl->enable_ps = false; @@ -1450,14 +1493,13 @@ static int start_ap(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ap_settings *settings) { struct wilc_vif *vif = netdev_priv(dev); - struct wilc *wl = vif->wilc; int ret; ret = set_channel(wiphy, &settings->chandef); if (ret != 0) netdev_err(dev, "Error in setting channel\n"); - wilc_wlan_set_bssid(dev, wl->vif[vif->idx]->src_addr, WILC_AP_MODE); + wilc_wlan_set_bssid(dev, vif->src_addr, WILC_AP_MODE); wilc_set_power_mgmt(vif, 0, 0); return wilc_add_beacon(vif, sett |