Commit 9bc061e8 authored by Ajay Singh's avatar Ajay Singh Committed by Greg Kroah-Hartman

staging: wilc1000: added support to dynamically add/remove interfaces

Removed the use of two hardcoded interfaces and added support to
add/remove the network interfaces dynamically.
Now the driver will have single default interface with name 'wlan0' and
later other interface can be added from user space application e.g
using 'iw add' command.
Also taken care to maintain 'wilc_vif' as part of 'net_device'
private data and 'wilc' struct as 'wiphy' private data.
Signed-off-by: default avatarAjay Singh <ajay.kathat@microchip.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 6419f818
...@@ -233,6 +233,7 @@ struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl, ...@@ -233,6 +233,7 @@ struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl,
strncpy(wl->monitor_dev->name, name, IFNAMSIZ); strncpy(wl->monitor_dev->name, name, IFNAMSIZ);
wl->monitor_dev->name[IFNAMSIZ - 1] = 0; wl->monitor_dev->name[IFNAMSIZ - 1] = 0;
wl->monitor_dev->netdev_ops = &wilc_wfi_netdev_ops; wl->monitor_dev->netdev_ops = &wilc_wfi_netdev_ops;
wl->monitor_dev->needs_free_netdev = true;
if (register_netdevice(wl->monitor_dev)) { if (register_netdevice(wl->monitor_dev)) {
netdev_err(real_dev, "register_netdevice failed\n"); netdev_err(real_dev, "register_netdevice failed\n");
...@@ -247,12 +248,14 @@ struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl, ...@@ -247,12 +248,14 @@ struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl,
return wl->monitor_dev; 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) if (!wl->monitor_dev)
return; return;
unregister_netdev(wl->monitor_dev); if (rtnl_locked)
free_netdev(wl->monitor_dev); unregister_netdevice(wl->monitor_dev);
else
unregister_netdev(wl->monitor_dev);
wl->monitor_dev = NULL; wl->monitor_dev = NULL;
} }
This diff is collapsed.
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <linux/mmc/host.h> #include <linux/mmc/host.h>
#include "wilc_wfi_netdevice.h" #include "wilc_wfi_netdevice.h"
#include "wilc_wfi_cfgoperations.h"
#define SDIO_MODALIAS "wilc1000_sdio" #define SDIO_MODALIAS "wilc1000_sdio"
...@@ -139,11 +140,9 @@ static int wilc_sdio_probe(struct sdio_func *func, ...@@ -139,11 +140,9 @@ static int wilc_sdio_probe(struct sdio_func *func,
} }
} }
dev_dbg(&func->dev, "Initializing netdev\n"); ret = wilc_cfg80211_init(&wilc, &func->dev, WILC_HIF_SDIO,
ret = wilc_netdev_init(&wilc, &func->dev, WILC_HIF_SDIO, &wilc_hif_sdio);
&wilc_hif_sdio);
if (ret) { if (ret) {
dev_err(&func->dev, "Couldn't initialize netdev\n");
kfree(sdio_priv); kfree(sdio_priv);
return ret; return ret;
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include "wilc_wfi_netdevice.h" #include "wilc_wfi_netdevice.h"
#include "wilc_wfi_cfgoperations.h"
struct wilc_spi { struct wilc_spi {
int crc_off; int crc_off;
...@@ -120,7 +121,7 @@ static int wilc_bus_probe(struct spi_device *spi) ...@@ -120,7 +121,7 @@ static int wilc_bus_probe(struct spi_device *spi)
dev_err(&spi->dev, "failed to get the irq gpio\n"); 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) { if (ret) {
kfree(spi_priv); kfree(spi_priv);
return ret; return ret;
......
...@@ -8,17 +8,20 @@ ...@@ -8,17 +8,20 @@
#define NM_WFI_CFGOPERATIONS #define NM_WFI_CFGOPERATIONS
#include "wilc_wfi_netdevice.h" #include "wilc_wfi_netdevice.h"
struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct wiphy *wilc_cfg_alloc(void);
struct device *dev); int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type,
void wilc_free_wiphy(struct net_device *net); const struct wilc_hif_func *ops);
struct wilc *wilc_create_wiphy(struct device *dev);
void wilc_deinit_host_int(struct net_device *net); void wilc_deinit_host_int(struct net_device *net);
int wilc_init_host_int(struct net_device *net); int wilc_init_host_int(struct net_device *net);
void wilc_wfi_monitor_rx(struct net_device *mon_dev, u8 *buff, u32 size); void wilc_wfi_monitor_rx(struct net_device *mon_dev, u8 *buff, u32 size);
void wilc_wfi_deinit_mon_interface(struct wilc *wl); struct wilc_vif *wilc_netdev_interface(struct wilc *wl, const char *name,
enum nl80211_iftype type);
void wilc_wfi_deinit_mon_interface(struct wilc *wl, bool rtnl_locked);
struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl, struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl,
const char *name, const char *name,
struct net_device *real_dev); struct net_device *real_dev);
void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
u16 frame_type, bool reg); u16 frame_type, bool reg);
struct wilc_vif *wilc_get_interface(struct wilc *wl);
#endif #endif
...@@ -129,7 +129,7 @@ static struct ieee80211_rate wilc_bitrates[] = { ...@@ -129,7 +129,7 @@ static struct ieee80211_rate wilc_bitrates[] = {
}; };
struct wilc_priv { struct wilc_priv {
struct wireless_dev *wdev; struct wireless_dev wdev;
struct cfg80211_scan_request *scan_req; struct cfg80211_scan_request *scan_req;
struct wilc_wfi_p2p_listen_params remain_on_ch_params; struct wilc_wfi_p2p_listen_params remain_on_ch_params;
...@@ -156,10 +156,6 @@ struct wilc_priv { ...@@ -156,10 +156,6 @@ struct wilc_priv {
int scanned_cnt; int scanned_cnt;
struct wilc_p2p_var p2p; struct wilc_p2p_var p2p;
struct ieee80211_channel channels[ARRAY_SIZE(wilc_2ghz_channels)];
struct ieee80211_rate bitrates[ARRAY_SIZE(wilc_bitrates)];
struct ieee80211_supported_band band;
u32 cipher_suites[ARRAY_SIZE(wilc_cipher_suites)];
u64 inc_roc_cookie; u64 inc_roc_cookie;
}; };
...@@ -214,9 +210,11 @@ struct wilc_vif { ...@@ -214,9 +210,11 @@ struct wilc_vif {
struct rf_info periodic_stat; struct rf_info periodic_stat;
struct tcp_ack_filter ack_filter; struct tcp_ack_filter ack_filter;
bool connecting; bool connecting;
struct wilc_priv priv;
}; };
struct wilc { struct wilc {
struct wiphy *wiphy;
const struct wilc_hif_func *hif_func; const struct wilc_hif_func *hif_func;
int io_type; int io_type;
s8 mac_status; s8 mac_status;
...@@ -226,6 +224,8 @@ struct wilc { ...@@ -226,6 +224,8 @@ struct wilc {
int close; int close;
u8 vif_num; u8 vif_num;
struct wilc_vif *vif[WILC_NUM_CONCURRENT_IFC]; struct wilc_vif *vif[WILC_NUM_CONCURRENT_IFC];
/*protect vif list*/
struct mutex vif_mutex;
u8 open_ifcs; u8 open_ifcs;
/*protect head of transmit queue*/ /*protect head of transmit queue*/
struct mutex txq_add_to_head_cs; struct mutex txq_add_to_head_cs;
...@@ -275,6 +275,10 @@ struct wilc { ...@@ -275,6 +275,10 @@ struct wilc {
struct mutex deinit_lock; struct mutex deinit_lock;
u8 sta_ch; u8 sta_ch;
u8 op_ch; u8 op_ch;
struct ieee80211_channel channels[ARRAY_SIZE(wilc_2ghz_channels)];
struct ieee80211_rate bitrates[ARRAY_SIZE(wilc_bitrates)];
struct ieee80211_supported_band band;
u32 cipher_suites[ARRAY_SIZE(wilc_cipher_suites)];
}; };
struct wilc_wfi_mon_priv { struct wilc_wfi_mon_priv {
...@@ -284,9 +288,9 @@ struct wilc_wfi_mon_priv { ...@@ -284,9 +288,9 @@ struct wilc_wfi_mon_priv {
void wilc_frmw_to_host(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset); void wilc_frmw_to_host(struct wilc *wilc, u8 *buff, u32 size, u32 pkt_offset);
void wilc_mac_indicate(struct wilc *wilc); void wilc_mac_indicate(struct wilc *wilc);
void wilc_netdev_cleanup(struct wilc *wilc); void wilc_netdev_cleanup(struct wilc *wilc);
int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type,
const struct wilc_hif_func *ops);
void wilc_wfi_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size); void wilc_wfi_mgmt_rx(struct wilc *wilc, u8 *buff, u32 size);
void wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid, u8 mode); void wilc_wlan_set_bssid(struct net_device *wilc_netdev, u8 *bssid, u8 mode);
struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name,
int vif_type, enum nl80211_iftype type,
bool rtnl_locked);
#endif #endif
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#include <linux/if_ether.h> #include <linux/if_ether.h>
#include <linux/ip.h> #include <linux/ip.h>
#include "wilc_wfi_netdevice.h" #include "wilc_wfi_cfgoperations.h"
#include "wilc_wlan_cfg.h" #include "wilc_wlan_cfg.h"
static inline bool is_wilc1000(u32 id) static inline bool is_wilc1000(u32 id)
...@@ -267,6 +267,7 @@ static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, u8 *buffer, ...@@ -267,6 +267,7 @@ static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, u8 *buffer,
tqe->tx_complete_func = NULL; tqe->tx_complete_func = NULL;
tqe->priv = NULL; tqe->priv = NULL;
tqe->ack_idx = NOT_TCP_ACK; tqe->ack_idx = NOT_TCP_ACK;
tqe->vif = vif;
wilc_wlan_txq_add_to_head(vif, tqe); wilc_wlan_txq_add_to_head(vif, tqe);
...@@ -295,6 +296,7 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, ...@@ -295,6 +296,7 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
tqe->buffer_size = buffer_size; tqe->buffer_size = buffer_size;
tqe->tx_complete_func = tx_complete_fn; tqe->tx_complete_func = tx_complete_fn;
tqe->priv = priv; tqe->priv = priv;
tqe->vif = vif;
tqe->ack_idx = NOT_TCP_ACK; tqe->ack_idx = NOT_TCP_ACK;
if (vif->ack_filter.enabled) if (vif->ack_filter.enabled)
...@@ -326,6 +328,7 @@ int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, ...@@ -326,6 +328,7 @@ int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer,
tqe->tx_complete_func = tx_complete_fn; tqe->tx_complete_func = tx_complete_fn;
tqe->priv = priv; tqe->priv = priv;
tqe->ack_idx = NOT_TCP_ACK; tqe->ack_idx = NOT_TCP_ACK;
tqe->vif = vif;
wilc_wlan_txq_add_to_tail(dev, tqe); wilc_wlan_txq_add_to_tail(dev, tqe);
return 1; return 1;
} }
...@@ -482,7 +485,7 @@ void host_sleep_notify(struct wilc *wilc) ...@@ -482,7 +485,7 @@ void host_sleep_notify(struct wilc *wilc)
} }
EXPORT_SYMBOL_GPL(host_sleep_notify); EXPORT_SYMBOL_GPL(host_sleep_notify);
int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
{ {
int i, entries = 0; int i, entries = 0;
u32 sum; u32 sum;
...@@ -494,17 +497,20 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) ...@@ -494,17 +497,20 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
int counter; int counter;
int timeout; int timeout;
u32 vmm_table[WILC_VMM_TBL_SIZE]; u32 vmm_table[WILC_VMM_TBL_SIZE];
struct wilc_vif *vif = netdev_priv(dev);
struct wilc *wilc = vif->wilc;
const struct wilc_hif_func *func; const struct wilc_hif_func *func;
u8 *txb = wilc->tx_buffer; u8 *txb = wilc->tx_buffer;
struct net_device *dev;
struct wilc_vif *vif;
if (wilc->quit) if (wilc->quit)
goto out; goto out;
mutex_lock(&wilc->txq_add_to_head_cs); mutex_lock(&wilc->txq_add_to_head_cs);
wilc_wlan_txq_filter_dup_tcp_ack(dev);
tqe = wilc_wlan_txq_get_first(wilc); tqe = wilc_wlan_txq_get_first(wilc);
if (!tqe)
goto out;
dev = tqe->vif->ndev;
wilc_wlan_txq_filter_dup_tcp_ack(dev);
i = 0; i = 0;
sum = 0; sum = 0;
do { do {
...@@ -629,6 +635,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) ...@@ -629,6 +635,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
if (!tqe) if (!tqe)
break; break;
vif = tqe->vif;
if (vmm_table[i] == 0) if (vmm_table[i] == 0)
break; break;
...@@ -648,8 +655,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) ...@@ -648,8 +655,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
if (tqe->type == WILC_CFG_PKT) { if (tqe->type == WILC_CFG_PKT) {
buffer_offset = ETH_CONFIG_PKT_HDR_OFFSET; buffer_offset = ETH_CONFIG_PKT_HDR_OFFSET;
} else if (tqe->type == WILC_NET_PKT) { } else if (tqe->type == WILC_NET_PKT) {
bssid = ((struct tx_complete_data *)(tqe->priv))->bssid; bssid = tqe->vif->bssid;
buffer_offset = ETH_ETHERNET_HDR_OFFSET; buffer_offset = ETH_ETHERNET_HDR_OFFSET;
memcpy(&txb[offset + 8], bssid, 6); memcpy(&txb[offset + 8], bssid, 6);
} else { } else {
......
...@@ -216,6 +216,7 @@ struct txq_entry_t { ...@@ -216,6 +216,7 @@ struct txq_entry_t {
int buffer_size; int buffer_size;
void *priv; void *priv;
int status; int status;
struct wilc_vif *vif;
void (*tx_complete_func)(void *priv, int status); void (*tx_complete_func)(void *priv, int status);
}; };
...@@ -253,7 +254,6 @@ struct wilc_hif_func { ...@@ -253,7 +254,6 @@ struct wilc_hif_func {
struct tx_complete_data { struct tx_complete_data {
int size; int size;
void *buff; void *buff;
u8 *bssid;
struct sk_buff *skb; struct sk_buff *skb;
}; };
...@@ -284,7 +284,7 @@ int wilc_wlan_stop(struct wilc *wilc); ...@@ -284,7 +284,7 @@ int wilc_wlan_stop(struct wilc *wilc);
int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
u32 buffer_size, u32 buffer_size,
void (*tx_complete_fn)(void *, int)); void (*tx_complete_fn)(void *, int));
int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count); int wilc_wlan_handle_txq(struct wilc *wl, u32 *txq_count);
void wilc_handle_isr(struct wilc *wilc); void wilc_handle_isr(struct wilc *wilc);
void wilc_wlan_cleanup(struct net_device *dev); void wilc_wlan_cleanup(struct net_device *dev);
int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer, int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer,
...@@ -301,7 +301,7 @@ void wilc_enable_tcp_ack_filter(struct wilc_vif *vif, bool value); ...@@ -301,7 +301,7 @@ void wilc_enable_tcp_ack_filter(struct wilc_vif *vif, bool value);
int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc); int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc);
netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *dev); netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *dev);
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);
void host_wakeup_notify(struct wilc *wilc); void host_wakeup_notify(struct wilc *wilc);
void host_sleep_notify(struct wilc *wilc); void host_sleep_notify(struct wilc *wilc);
void chip_allow_sleep(struct wilc *wilc); void chip_allow_sleep(struct wilc *wilc);
......
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