diff options
Diffstat (limited to 'drivers/staging/wilc1000')
-rw-r--r-- | drivers/staging/wilc1000/Kconfig | 8 | ||||
-rw-r--r-- | drivers/staging/wilc1000/Makefile | 5 | ||||
-rw-r--r-- | drivers/staging/wilc1000/coreconfigurator.c | 4 | ||||
-rw-r--r-- | drivers/staging/wilc1000/host_interface.c | 277 | ||||
-rw-r--r-- | drivers/staging/wilc1000/host_interface.h | 19 | ||||
-rw-r--r-- | drivers/staging/wilc1000/linux_mon.c | 3 | ||||
-rw-r--r-- | drivers/staging/wilc1000/linux_wlan.c | 129 | ||||
-rw-r--r-- | drivers/staging/wilc1000/wilc_debugfs.c | 115 | ||||
-rw-r--r-- | drivers/staging/wilc1000/wilc_sdio.c | 56 | ||||
-rw-r--r-- | drivers/staging/wilc1000/wilc_spi.c | 57 | ||||
-rw-r--r-- | drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 281 | ||||
-rw-r--r-- | drivers/staging/wilc1000/wilc_wfi_cfgoperations.h | 4 | ||||
-rw-r--r-- | drivers/staging/wilc1000/wilc_wfi_netdevice.h | 55 | ||||
-rw-r--r-- | drivers/staging/wilc1000/wilc_wlan.c | 208 | ||||
-rw-r--r-- | drivers/staging/wilc1000/wilc_wlan.h | 8 | ||||
-rw-r--r-- | drivers/staging/wilc1000/wilc_wlan_cfg.c | 294 | ||||
-rw-r--r-- | drivers/staging/wilc1000/wilc_wlan_cfg.h | 26 | ||||
-rw-r--r-- | drivers/staging/wilc1000/wilc_wlan_if.h | 4 |
18 files changed, 635 insertions, 918 deletions
diff --git a/drivers/staging/wilc1000/Kconfig b/drivers/staging/wilc1000/Kconfig index 73f7fefd3bc3..f9d3ad41c862 100644 --- a/drivers/staging/wilc1000/Kconfig +++ b/drivers/staging/wilc1000/Kconfig @@ -1,13 +1,13 @@ config WILC1000 tristate - ---help--- + help This module only support IEEE 802.11n WiFi. config WILC1000_SDIO tristate "Atmel WILC1000 SDIO (WiFi only)" depends on CFG80211 && INET && MMC select WILC1000 - ---help--- + help This module adds support for the SDIO interface of adapters using WILC1000 chipset. The Atmel WILC1000 SDIO is a full speed interface. It meets SDIO card specification version 2.0. The interface supports @@ -21,7 +21,7 @@ config WILC1000_SPI tristate "Atmel WILC1000 SPI (WiFi only)" depends on CFG80211 && INET && SPI select WILC1000 - ---help--- + help This module adds support for the SPI interface of adapters using WILC1000 chipset. The Atmel WILC1000 has a Serial Peripheral Interface (SPI) that operates as a SPI slave. This SPI interface can @@ -34,7 +34,7 @@ config WILC1000_HW_OOB_INTR bool "WILC1000 out of band interrupt" depends on WILC1000_SDIO default n - ---help--- + help This option enables out-of-band interrupt support for the WILC1000 chipset. This OOB interrupt is intended to provide a faster interrupt mechanism for SDIO host controllers that don't support SDIO interrupt. diff --git a/drivers/staging/wilc1000/Makefile b/drivers/staging/wilc1000/Makefile index ee7e26b886a5..37e8560e501e 100644 --- a/drivers/staging/wilc1000/Makefile +++ b/drivers/staging/wilc1000/Makefile @@ -4,12 +4,9 @@ obj-$(CONFIG_WILC1000) += wilc1000.o ccflags-y += -DFIRMWARE_1002=\"atmel/wilc1002_firmware.bin\" \ -DFIRMWARE_1003=\"atmel/wilc1003_firmware.bin\" -ccflags-y += -I$(src)/ -DWILC_ASIC_A0 -DWILC_DEBUGFS - wilc1000-objs := wilc_wfi_cfgoperations.o linux_wlan.o linux_mon.o \ coreconfigurator.o host_interface.o \ - wilc_wlan_cfg.o wilc_debugfs.o \ - wilc_wlan.o + wilc_wlan_cfg.o wilc_wlan.o obj-$(CONFIG_WILC1000_SDIO) += wilc1000-sdio.o wilc1000-sdio-objs += wilc_sdio.o diff --git a/drivers/staging/wilc1000/coreconfigurator.c b/drivers/staging/wilc1000/coreconfigurator.c index e5420676afb3..d6d3a971be43 100644 --- a/drivers/staging/wilc1000/coreconfigurator.c +++ b/drivers/staging/wilc1000/coreconfigurator.c @@ -116,7 +116,7 @@ static inline void get_address3(u8 *msa, u8 *addr) memcpy(addr, msa + 16, 6); } -static inline void get_BSSID(u8 *data, u8 *bssid) +static inline void get_bssid(u8 *data, u8 *bssid) { if (get_from_ds(data) == 1) get_address2(data, bssid); @@ -233,7 +233,7 @@ s32 wilc_parse_network_info(u8 *msg_buffer, network_info->tsf_hi = tsf_lo | ((u64)tsf_hi << 32); get_ssid(msa, network_info->ssid, &network_info->ssid_len); - get_BSSID(msa, network_info->bssid); + get_bssid(msa, network_info->bssid); network_info->ch = get_current_channel_802_11n(msa, rx_len + FCS_LEN); diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index 42d8accb1f60..01db8999335e 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -90,6 +90,7 @@ struct beacon_attr { struct set_multicast { bool enabled; u32 cnt; + u8 *mc_list; }; struct del_all_sta { @@ -186,23 +187,7 @@ struct join_bss_param { }; static struct host_if_drv *terminated_handle; -bool wilc_optaining_ip; -static u8 p2p_listen_state; -static struct workqueue_struct *hif_workqueue; -static struct completion hif_driver_comp; static struct mutex hif_deinit_lock; -static struct timer_list periodic_rssi; -static struct wilc_vif *periodic_rssi_vif; - -u8 wilc_multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN]; - -static u8 rcv_assoc_resp[MAX_ASSOC_RESP_FRAME_SIZE]; - -static u8 set_ip[2][4]; -static u8 get_ip[2][4]; -static u32 clients_count; - -static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx); /* 'msg' should be free by the caller for syc */ static struct host_if_msg* @@ -229,7 +214,11 @@ wilc_alloc_work(struct wilc_vif *vif, void (*work_fun)(struct work_struct *), static int wilc_enqueue_work(struct host_if_msg *msg) { INIT_WORK(&msg->work, msg->fn); - if (!hif_workqueue || !queue_work(hif_workqueue, &msg->work)) + + if (!msg->vif || !msg->vif->wilc || !msg->vif->wilc->hif_workqueue) + return -EINVAL; + + if (!queue_work(msg->vif->wilc->hif_workqueue, &msg->work)) return -EINVAL; return 0; @@ -320,10 +309,12 @@ static void handle_set_wfi_drv_handler(struct work_struct *work) if (ret) netdev_err(vif->ndev, "Failed to set driver handler\n"); - complete(&hif_driver_comp); kfree(buffer); free_msg: + if (msg->is_sync) + complete(&msg->work_comp); + kfree(msg); } @@ -343,73 +334,12 @@ static void handle_set_operation_mode(struct work_struct *work) ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); - if (hif_op_mode->mode == IDLE_MODE) - complete(&hif_driver_comp); - if (ret) netdev_err(vif->ndev, "Failed to set operation mode\n"); kfree(msg); } -static void handle_set_ip_address(struct work_struct *work) -{ - struct host_if_msg *msg = container_of(work, struct host_if_msg, work); - struct wilc_vif *vif = msg->vif; - u8 *ip_addr = msg->body.ip_info.ip_addr; - u8 idx = msg->body.ip_info.idx; - int ret; - struct wid wid; - char firmware_ip_addr[4] = {0}; - - if (ip_addr[0] < 192) - ip_addr[0] = 0; - - memcpy(set_ip[idx], ip_addr, IP_ALEN); - - wid.id = WID_IP_ADDRESS; - wid.type = WID_STR; - wid.val = ip_addr; - wid.size = IP_ALEN; - - ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1, - wilc_get_vif_idx(vif)); - - host_int_get_ipaddress(vif, firmware_ip_addr, idx); - - if (ret) - netdev_err(vif->ndev, "Failed to set IP address\n"); - kfree(msg); -} - -static void handle_get_ip_address(struct work_struct *work) -{ - struct host_if_msg *msg = container_of(work, struct host_if_msg, work); - struct wilc_vif *vif = msg->vif; - u8 idx = msg->body.ip_info.idx; - int ret; - struct wid wid; - - wid.id = WID_IP_ADDRESS; - wid.type = WID_STR; - wid.val = kmalloc(IP_ALEN, GFP_KERNEL); - wid.size = IP_ALEN; - - ret = wilc_send_config_pkt(vif, GET_CFG, &wid, 1, - wilc_get_vif_idx(vif)); - - memcpy(get_ip[idx], wid.val, IP_ALEN); - - kfree(wid.val); - - if (memcmp(get_ip[idx], set_ip[idx], IP_ALEN) != 0) - wilc_setup_ipaddress(vif, set_ip[idx], idx); - - if (ret) - netdev_err(vif->ndev, "Failed to get IP address\n"); - kfree(msg); -} - static void handle_get_mac_address(struct work_struct *work) { struct host_if_msg *msg = container_of(work, struct host_if_msg, work); @@ -791,7 +721,7 @@ static void handle_scan(struct work_struct *work) goto error; } - if (wilc_optaining_ip || wilc_connecting) { + if (vif->obtaining_ip || vif->connecting) { netdev_err(vif->ndev, "Don't do obss scan\n"); result = -EBUSY; goto error; @@ -883,7 +813,6 @@ error: kfree(msg); } -u8 wilc_connected_ssid[6] = {0}; static void handle_connect(struct work_struct *work) { struct host_if_msg *msg = container_of(work, struct host_if_msg, work); @@ -905,11 +834,6 @@ static void handle_connect(struct work_struct *work) return; } - if (memcmp(conn_attr->bssid, wilc_connected_ssid, ETH_ALEN) == 0) { - netdev_err(vif->ndev, "Discard connect request\n"); - goto error; - } - bss_param = conn_attr->params; if (!bss_param) { netdev_err(vif->ndev, "Required BSSID not found\n"); @@ -1089,10 +1013,6 @@ static void handle_connect(struct work_struct *work) cur_byte = wid_list[wid_cnt].val; wid_cnt++; - if (conn_attr->bssid) - memcpy(wilc_connected_ssid, - conn_attr->bssid, ETH_ALEN); - result = wilc_send_config_pkt(vif, SET_CFG, wid_list, wid_cnt, wilc_get_vif_idx(vif)); @@ -1215,8 +1135,6 @@ static void handle_connect_timeout(struct work_struct *work) kfree(hif_drv->usr_conn_req.ies); hif_drv->usr_conn_req.ies = NULL; - eth_zero_addr(wilc_connected_ssid); - out: kfree(msg); } @@ -1456,10 +1374,10 @@ done: kfree(msg); } -static s32 host_int_get_assoc_res_info(struct wilc_vif *vif, - u8 *assoc_resp_info, - u32 max_assoc_resp_info_len, - u32 *rcvd_assoc_resp_info_len) +static void host_int_get_assoc_res_info(struct wilc_vif *vif, + u8 *assoc_resp_info, + u32 max_assoc_resp_info_len, + u32 *rcvd_assoc_resp_info_len) { int result; struct wid wid; @@ -1474,11 +1392,10 @@ static s32 host_int_get_assoc_res_info(struct wilc_vif *vif, if (result) { *rcvd_assoc_resp_info_len = 0; netdev_err(vif->ndev, "Failed to send association response\n"); - return -EINVAL; + return; } *rcvd_assoc_resp_info_len = wid.size; - return result; } static inline void host_int_free_user_conn_req(struct host_if_drv *hif_drv) @@ -1504,16 +1421,16 @@ static inline void host_int_parse_assoc_resp_info(struct wilc_vif *vif, if (mac_status == MAC_STATUS_CONNECTED) { u32 assoc_resp_info_len; - memset(rcv_assoc_resp, 0, MAX_ASSOC_RESP_FRAME_SIZE); + memset(hif_drv->assoc_resp, 0, MAX_ASSOC_RESP_FRAME_SIZE); - host_int_get_assoc_res_info(vif, rcv_assoc_resp, + host_int_get_assoc_res_info(vif, hif_drv->assoc_resp, MAX_ASSOC_RESP_FRAME_SIZE, &assoc_resp_info_len); if (assoc_resp_info_len != 0) { s32 err = 0; - err = wilc_parse_assoc_resp_info(rcv_assoc_resp, + err = wilc_parse_assoc_resp_info(hif_drv->assoc_resp, assoc_resp_info_len, &conn_info); if (err) @@ -1523,16 +1440,6 @@ static inline void host_int_parse_assoc_resp_info(struct wilc_vif *vif, } } - if (mac_status == MAC_STATUS_CONNECTED && - conn_info.status != WLAN_STATUS_SUCCESS) { - netdev_err(vif->ndev, - "Received MAC status is MAC_STATUS_CONNECTED, Assoc Resp is not SUCCESS\n"); - eth_zero_addr(wilc_connected_ssid); - } else if (mac_status == MAC_STATUS_DISCONNECTED) { - netdev_err(vif->ndev, "Received MAC status is MAC_STATUS_DISCONNECTED\n"); - eth_zero_addr(wilc_connected_ssid); - } - if (hif_drv->usr_conn_req.bssid) { memcpy(conn_info.bssid, hif_drv->usr_conn_req.bssid, 6); @@ -1562,8 +1469,8 @@ static inline void host_int_parse_assoc_resp_info(struct wilc_vif *vif, hif_drv->hif_state = HOST_IF_CONNECTED; - wilc_optaining_ip = true; - mod_timer(&wilc_during_ip_timer, + vif->obtaining_ip = true; + mod_timer(&vif->during_ip_timer, jiffies + msecs_to_jiffies(10000)); } else { hif_drv->hif_state = HOST_IF_IDLE; @@ -1595,7 +1502,7 @@ static inline void host_int_handle_disconnect(struct wilc_vif *vif) disconn_info.ie_len = 0; if (conn_result) { - wilc_optaining_ip = false; + vif->obtaining_ip = false; wilc_set_power_mgmt(vif, 0, 0); conn_result(CONN_DISCONN_EVENT_DISCONN_NOTIF, NULL, 0, @@ -1942,11 +1849,9 @@ static void handle_disconnect(struct work_struct *work) wid.val = (s8 *)&dummy_reason_code; wid.size = sizeof(char); - wilc_optaining_ip = false; + vif->obtaining_ip = false; wilc_set_power_mgmt(vif, 0, 0); - eth_zero_addr(wilc_connected_ssid); - result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); @@ -2076,9 +1981,9 @@ static void handle_get_statistics(struct work_struct *work) if (stats->link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH && stats->link_speed != DEFAULT_LINK_SPEED) - wilc_enable_tcp_ack_filter(true); + wilc_enable_tcp_ack_filter(vif, true); else if (stats->link_speed != DEFAULT_LINK_SPEED) - wilc_enable_tcp_ack_filter(false); + wilc_enable_tcp_ack_filter(vif, false); /* free 'msg' for async command, for sync caller will free it */ if (msg->is_sync) @@ -2397,7 +2302,7 @@ static int handle_remain_on_chan(struct wilc_vif *vif, goto error; } - if (wilc_optaining_ip || wilc_connecting) { + if (vif->obtaining_ip || vif->connecting) { result = -EBUSY; goto error; } @@ -2422,7 +2327,6 @@ static int handle_remain_on_chan(struct wilc_vif *vif, netdev_err(vif->ndev, "Failed to set remain on channel\n"); error: - p2p_listen_state = 1; hif_drv->remain_on_ch_timer_vif = vif; mod_timer(&hif_drv->remain_on_ch_timer, jiffies + msecs_to_jiffies(hif_remain_ch->duration)); @@ -2478,8 +2382,9 @@ static void handle_listen_state_expired(struct work_struct *work) struct wid wid; int result; struct host_if_drv *hif_drv = vif->hif_drv; + struct wilc_priv *priv = wdev_priv(vif->ndev->ieee80211_ptr); - if (p2p_listen_state) { + if (priv->p2p_listen_state) { remain_on_chan_flag = false; wid.id = WID_REMAIN_ON_CHAN; wid.type = WID_STR; @@ -2504,7 +2409,6 @@ static void handle_listen_state_expired(struct work_struct *work) hif_drv->remain_on_ch.expired(hif_drv->remain_on_ch.arg, hif_remain_ch->id); } - p2p_listen_state = 0; } else { netdev_dbg(vif->ndev, "Not in listen state\n"); } @@ -2589,8 +2493,8 @@ static void handle_set_mcast_filter(struct work_struct *work) *cur_byte++ = ((hif_set_mc->cnt >> 16) & 0xFF); *cur_byte++ = ((hif_set_mc->cnt >> 24) & 0xFF); - if (hif_set_mc->cnt > 0) - memcpy(cur_byte, wilc_multicast_mac_addr_list, + if (hif_set_mc->cnt > 0 && hif_set_mc->mc_list) + memcpy(cur_byte, hif_set_mc->mc_list, ((hif_set_mc->cnt) * ETH_ALEN)); result = wilc_send_config_pkt(vif, SET_CFG, &wid, 1, @@ -2599,6 +2503,7 @@ static void handle_set_mcast_filter(struct work_struct *work) netdev_err(vif->ndev, "Failed to send setup multicast\n"); error: + kfree(hif_set_mc->mc_list); kfree(wid.val); kfree(msg); } @@ -2661,14 +2566,6 @@ static void handle_remain_on_chan_work(struct work_struct *work) kfree(msg); } -static void handle_hif_exit_work(struct work_struct *work) -{ - struct host_if_msg *msg = container_of(work, struct host_if_msg, work); - - /* free 'msg' data in caller */ - complete(&msg->work_comp); -} - static void handle_scan_complete(struct work_struct *work) { struct host_if_msg *msg = container_of(work, struct host_if_msg, work); @@ -3195,12 +3092,12 @@ int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 channel) } int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode, - u8 ifc_id) + u8 ifc_id, bool is_sync) { int result; struct host_if_msg *msg; - msg = wilc_alloc_work(vif, handle_set_wfi_drv_handler, false); + msg = wilc_alloc_work(vif, handle_set_wfi_drv_handler, is_sync); if (IS_ERR(msg)) return PTR_ERR(msg); @@ -3212,8 +3109,12 @@ int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode, if (result) { netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__); kfree(msg); + return result; } + if (is_sync) + wait_for_completion(&msg->work_comp); + return result; } @@ -3421,9 +3322,9 @@ int wilc_hif_set_cfg(struct wilc_vif *vif, return result; } -static void get_periodic_rssi(struct timer_list *unused) +static void get_periodic_rssi(struct timer_list *t) { - struct wilc_vif *vif = periodic_rssi_vif; + struct wilc_vif *vif = from_timer(vif, t, periodic_rssi); if (!vif->hif_drv) { netdev_err(vif->ndev, "%s: hif driver is NULL", __func__); @@ -3431,9 +3332,9 @@ static void get_periodic_rssi(struct timer_list *unused) } if (vif->hif_drv->hif_state == HOST_IF_CONNECTED) - wilc_get_statistics(vif, &vif->wilc->dummy_statistics, false); + wilc_get_statistics(vif, &vif->periodic_stat, false); - mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000)); + mod_timer(&vif->periodic_rssi, jiffies + msecs_to_jiffies(5000)); } int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) @@ -3455,25 +3356,13 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) break; } - wilc_optaining_ip = false; + vif->obtaining_ip = false; - if (clients_count == 0) { - init_completion(&hif_driver_comp); + if (wilc->clients_count == 0) mutex_init(&hif_deinit_lock); - } - if (clients_count == 0) { - hif_workqueue = create_singlethread_workqueue("WILC_wq"); - if (!hif_workqueue) { - netdev_err(vif->ndev, "Failed to create workqueue\n"); - kfree(hif_drv); - return -ENOMEM; - } - - periodic_rssi_vif = vif; - timer_setup(&periodic_rssi, get_periodic_rssi, 0); - mod_timer(&periodic_rssi, jiffies + msecs_to_jiffies(5000)); - } + timer_setup(&vif->periodic_rssi, get_periodic_rssi, 0); + mod_timer(&vif->periodic_rssi, jiffies + msecs_to_jiffies(5000)); timer_setup(&hif_drv->scan_timer, timer_scan_cb, 0); timer_setup(&hif_drv->connect_timer, timer_connect_cb, 0); @@ -3493,7 +3382,7 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) mutex_unlock(&hif_drv->cfg_values_lock); - clients_count++; + wilc->clients_count++; return 0; } @@ -3514,11 +3403,10 @@ int wilc_deinit(struct wilc_vif *vif) del_timer_sync(&hif_drv->scan_timer); del_timer_sync(&hif_drv->connect_timer); - del_timer_sync(&periodic_rssi); + del_timer_sync(&vif->periodic_rssi); del_timer_sync(&hif_drv->remain_on_ch_timer); - wilc_set_wfi_drv_handler(vif, 0, 0, 0); - wait_for_completion(&hif_driver_comp); + wilc_set_wfi_drv_handler(vif, 0, 0, 0, true); if (hif_drv->usr_scan_req.scan_result) { hif_drv->usr_scan_req.scan_result(SCAN_EVENT_ABORTED, NULL, @@ -3529,25 +3417,9 @@ int wilc_deinit(struct wilc_vif *vif) hif_drv->hif_state = HOST_IF_IDLE; - if (clients_count == 1) { - struct host_if_msg *msg; - - msg = wilc_alloc_work(vif, handle_hif_exit_work, true); - if (!IS_ERR(msg)) { - result = wilc_enqueue_work(msg); - if (result) - netdev_err(vif->ndev, "deinit : Error(%d)\n", - result); - else - wait_for_completion(&msg->work_comp); - kfree(msg); - } - destroy_workqueue(hif_workqueue); - } - kfree(hif_drv); - clients_count--; + vif->wilc->clients_count--; terminated_handle = NULL; mutex_unlock(&hif_deinit_lock); return result; @@ -3743,14 +3615,14 @@ int wilc_listen_state_expired(struct wilc_vif *vif, u32 session_id) return result; } -int wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg) +void wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg) { int result; struct host_if_msg *msg; msg = wilc_alloc_work(vif, handle_register_frame, false); if (IS_ERR(msg)) - return PTR_ERR(msg); + return; switch (frame_type) { case ACTION: @@ -3772,8 +3644,6 @@ int wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg) netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__); kfree(msg); } - - return result; } int wilc_add_beacon(struct wilc_vif *vif, u32 interval, u32 dtim_period, @@ -3992,8 +3862,8 @@ int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout) return result; } -int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled, - u32 count) +int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled, u32 count, + u8 *mc_list) { int result; struct host_if_msg *msg; @@ -4004,6 +3874,7 @@ int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled, msg->body.multicast_info.enabled = enabled; msg->body.multicast_info.cnt = count; + msg->body.multicast_info.mc_list = mc_list; result = wilc_enqueue_work(msg); if (result) { @@ -4013,48 +3884,6 @@ int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled, return result; } -int wilc_setup_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx) -{ - int result; - struct host_if_msg *msg; - - msg = wilc_alloc_work(vif, handle_set_ip_address, false); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - msg->body.ip_info.ip_addr = ip_addr; - msg->body.ip_info.idx = idx; - - result = wilc_enqueue_work(msg); - if (result) { - netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__); - kfree(msg); - } - - return result; -} - -static int host_int_get_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx) -{ - int result; - struct host_if_msg *msg; - - msg = wilc_alloc_work(vif, handle_get_ip_address, false); - if (IS_ERR(msg)) - return PTR_ERR(msg); - - msg->body.ip_info.ip_addr = ip_addr; - msg->body.ip_info.idx = idx; - - result = wilc_enqueue_work(msg); - if (result) { - netdev_err(vif->ndev, "%s: enqueue work failed\n", __func__); - kfree(msg); - } - - return result; -} - int wilc_set_tx_power(struct wilc_vif *vif, u8 tx_power) { int ret; diff --git a/drivers/staging/wilc1000/host_interface.h b/drivers/staging/wilc1000/host_interface.h index 84866a62a4d4..33fb7318734b 100644 --- a/drivers/staging/wilc1000/host_interface.h +++ b/drivers/staging/wilc1000/host_interface.h @@ -9,8 +9,6 @@ #include <linux/ieee80211.h> #include "coreconfigurator.h" -#define IP_ALEN 4 - #define IDLE_MODE 0x00 #define AP_MODE 0x01 #define STATION_MODE 0x02 @@ -284,6 +282,7 @@ struct host_if_drv { bool ifc_up; int driver_handler_id; + u8 assoc_resp[MAX_ASSOC_RESP_FRAME_SIZE]; }; struct add_sta_param { @@ -341,18 +340,17 @@ int wilc_del_station(struct wilc_vif *vif, const u8 *mac_addr); int wilc_edit_station(struct wilc_vif *vif, struct add_sta_param *sta_param); int wilc_set_power_mgmt(struct wilc_vif *vif, bool enabled, u32 timeout); -int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled, - u32 count); -int wilc_setup_ipaddress(struct wilc_vif *vif, u8 *ip_addr, u8 idx); +int wilc_setup_multicast_filter(struct wilc_vif *vif, bool enabled, u32 count, + u8 *mc_list); int wilc_remain_on_channel(struct wilc_vif *vif, u32 session_id, u32 duration, u16 chan, wilc_remain_on_chan_expired expired, wilc_remain_on_chan_ready ready, void *user_arg); int wilc_listen_state_expired(struct wilc_vif *vif, u32 session_id); -int wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg); +void wilc_frame_register(struct wilc_vif *vif, u16 frame_type, bool reg); int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode, - u8 ifc_id); + u8 ifc_id, bool is_sync); int wilc_set_operation_mode(struct wilc_vif *vif, u32 mode); int wilc_get_statistics(struct wilc_vif *vif, struct rf_info *stats, bool is_sync); @@ -361,11 +359,4 @@ int wilc_get_vif_idx(struct wilc_vif *vif); int wilc_set_tx_power(struct wilc_vif *vif, u8 tx_power); int wilc_get_tx_power(struct wilc_vif *vif, u8 *tx_power); -extern bool wilc_optaining_ip; -extern u8 wilc_connected_ssid[6]; -extern u8 wilc_multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN]; - -extern int wilc_connecting; -extern struct timer_list wilc_during_ip_timer; - #endif diff --git a/drivers/staging/wilc1000/linux_mon.c b/drivers/staging/wilc1000/linux_mon.c index 1afdb9e86bc1..a63446818eac 100644 --- a/drivers/staging/wilc1000/linux_mon.c +++ b/drivers/staging/wilc1000/linux_mon.c @@ -253,7 +253,7 @@ struct net_device *wilc_wfi_init_mon_interface(const char *name, return wilc_wfi_mon; } -int wilc_wfi_deinit_mon_interface(void) +void wilc_wfi_deinit_mon_interface(void) { bool rollback_lock = false; @@ -270,5 +270,4 @@ int wilc_wfi_deinit_mon_interface(void) } wilc_wfi_mon = NULL; } - return 0; } diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 3b8d237decbf..76c901235e93 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -12,8 +12,6 @@ #include "wilc_wfi_cfgoperations.h" -bool wilc_enable_ps = true; - static int dev_state_ev_handler(struct notifier_block *this, unsigned long event, void *ptr) { @@ -50,11 +48,11 @@ static int dev_state_ev_handler(struct notifier_block *this, case NETDEV_UP: if (vif->iftype == STATION_MODE || vif->iftype == CLIENT_MODE) { hif_drv->ifc_up = 1; - wilc_optaining_ip = false; - del_timer(&wilc_during_ip_timer); + vif->obtaining_ip = false; + del_timer(&vif->during_ip_timer); } - if (wilc_enable_ps) + if (vif->wilc->enable_ps) wilc_set_power_mgmt(vif, 1, 0); netdev_dbg(dev, "[%s] Up IP\n", dev_iface->ifa_label); @@ -63,14 +61,13 @@ static int dev_state_ev_handler(struct notifier_block *this, netdev_dbg(dev, "IP add=%d:%d:%d:%d\n", ip_addr_buf[0], ip_addr_buf[1], ip_addr_buf[2], ip_addr_buf[3]); - wilc_setup_ipaddress(vif, ip_addr_buf, vif->idx); break; case NETDEV_DOWN: if (vif->iftype == STATION_MODE || vif->iftype == CLIENT_MODE) { hif_drv->ifc_up = 0; - wilc_optaining_ip = false; + vif->obtaining_ip = false; } if (memcmp(dev_iface->ifa_label, wlan_dev_name, 5) == 0) @@ -85,8 +82,6 @@ static int dev_state_ev_handler(struct notifier_block *this, ip_addr_buf[0], ip_addr_buf[1], ip_addr_buf[2], ip_addr_buf[3]); - wilc_setup_ipaddress(vif, ip_addr_buf, vif->idx); - break; default: @@ -164,9 +159,9 @@ static void deinit_irq(struct net_device *dev) void wilc_mac_indicate(struct wilc *wilc) { - int status; + s8 status; - wilc_wlan_cfg_get_val(WID_STATUS, (unsigned char *)&status, 4); + wilc_wlan_cfg_get_val(wilc, WID_STATUS, &status, 1); if (wilc->mac_status == MAC_STATUS_INIT) { wilc->mac_status = status; complete(&wilc->sync_event); @@ -197,14 +192,12 @@ static struct net_device *get_if_handler(struct wilc *wilc, u8 *mac_header) return NULL; } -int 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 *vif = netdev_priv(wilc_netdev); memcpy(vif->bssid, bssid, 6); vif->mode = mode; - - return 0; } int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc) @@ -269,9 +262,6 @@ static int wilc_wlan_get_firmware(struct net_device *dev) netdev_info(dev, "loading firmware %s\n", firmware); - if (!(&vif->ndev->dev)) - goto fail; - if (request_firmware(&wilc_firmware, firmware, wilc->dev) != 0) { netdev_err(dev, "%s - firmware not available\n", firmware); ret = -1; @@ -532,7 +522,7 @@ fail: return -1; } -static int wlan_deinit_locks(struct net_device *dev) +static void wlan_deinit_locks(struct net_device *dev) { struct wilc_vif *vif = netdev_priv(dev); struct wilc *wilc = vif->wilc; @@ -540,8 +530,6 @@ static int wlan_deinit_locks(struct net_device *dev) mutex_destroy(&wilc->hif_cs); mutex_destroy(&wilc->rxq_cs); mutex_destroy(&wilc->txq_add_to_head_cs); - - return 0; } static void wlan_deinitialize_threads(struct net_device *dev) @@ -595,7 +583,7 @@ static void wilc_wlan_deinitialize(struct net_device *dev) } } -static int wlan_init_locks(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; @@ -611,8 +599,6 @@ static int wlan_init_locks(struct net_device *dev) init_completion(&wl->cfg_event); init_completion(&wl->sync_event); init_completion(&wl->txq_thread_started); - - return 0; } static int wlan_initialize_threads(struct net_device *dev) @@ -688,7 +674,7 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif) int size; char firmware_ver[20]; - size = wilc_wlan_cfg_get_val(WID_FIRMWARE_VERSION, + size = wilc_wlan_cfg_get_val(wl, WID_FIRMWARE_VERSION, firmware_ver, sizeof(firmware_ver)); firmware_ver[size] = '\0'; @@ -740,6 +726,7 @@ static int wilc_mac_open(struct net_device *ndev) { struct wilc_vif *vif = netdev_priv(ndev); struct wilc *wl = vif->wilc; + struct wilc_priv *priv = wdev_priv(vif->ndev->ieee80211_ptr); unsigned char mac_add[ETH_ALEN] = {0}; int ret = 0; int i = 0; @@ -764,7 +751,8 @@ static int wilc_mac_open(struct net_device *ndev) for (i = 0; i < wl->vif_num; i++) { if (ndev == wl->vif[i]->ndev) { wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif), - vif->iftype, vif->ifc_id); + vif->iftype, vif->ifc_id, + false); wilc_set_operation_mode(vif, vif->iftype); break; } @@ -792,6 +780,7 @@ static int wilc_mac_open(struct net_device *ndev) vif->frame_reg[1].reg); netif_wake_queue(ndev); wl->open_ifcs++; + priv->p2p.local_random = 0x01; vif->mac_opened = 1; return 0; } @@ -807,35 +796,39 @@ static void wilc_set_multicast_list(struct net_device *dev) { struct netdev_hw_addr *ha; struct wilc_vif *vif = netdev_priv(dev); - int i = 0; + int i; + u8 *mc_list; + u8 *cur_mc; if (dev->flags & IFF_PROMISC) return; if (dev->flags & IFF_ALLMULTI || dev->mc.count > WILC_MULTICAST_TABLE_SIZE) { - wilc_setup_multicast_filter(vif, false, 0); + wilc_setup_multicast_filter(vif, false, 0, NULL); return; } if (dev->mc.count == 0) { - wilc_setup_multicast_filter(vif, true, 0); + wilc_setup_multicast_filter(vif, true, 0, NULL); return; } + mc_list = kmalloc_array(dev->mc.count, ETH_ALEN, GFP_KERNEL); + if (!mc_list) + return; + + cur_mc = mc_list; + i = 0; netdev_for_each_mc_addr(ha, dev) { - memcpy(wilc_multicast_mac_addr_list[i], ha->addr, ETH_ALEN); - netdev_dbg(dev, "Entry[%d]: %x:%x:%x:%x:%x:%x\n", i, - wilc_multicast_mac_addr_list[i][0], - wilc_multicast_mac_addr_list[i][1], - wilc_multicast_mac_addr_list[i][2], - wilc_multicast_mac_addr_list[i][3], - wilc_multicast_mac_addr_list[i][4], - wilc_multicast_mac_addr_list[i][5]); + memcpy(cur_mc, ha->addr, ETH_ALEN); + netdev_dbg(dev, "Entry[%d]: %pM\n", i, cur_mc); i++; + cur_mc += ETH_ALEN; } - wilc_setup_multicast_filter(vif, true, (dev->mc.count)); + if (wilc_setup_multicast_filter(vif, true, dev->mc.count, mc_list)) + kfree(mc_list); } static void linux_wlan_tx_complete(void *priv, int status) @@ -1016,15 +1009,18 @@ void wilc_netdev_cleanup(struct wilc *wilc) { int i; - if (wilc && (wilc->vif[0]->ndev || wilc->vif[1]->ndev)) + if (!wilc) + return; + + if (wilc->vif[0]->ndev || wilc->vif[1]->ndev) unregister_inetaddr_notifier(&g_dev_notifier); - if (wilc && wilc->firmware) { + if (wilc->firmware) { release_firmware(wilc->firmware); wilc->firmware = NULL; } - if (wilc && (wilc->vif[0]->ndev || wilc->vif[1]->ndev)) { + if (wilc->vif[0]->ndev || wilc->vif[1]->ndev) { for (i = 0; i < NUM_CONCURRENT_IFC; i++) if (wilc->vif[i]->ndev) if (wilc->vif[i]->mac_opened) @@ -1037,6 +1033,10 @@ void wilc_netdev_cleanup(struct wilc *wilc) } } + flush_workqueue(wilc->hif_workqueue); + destroy_workqueue(wilc->hif_workqueue); + wilc_wlan_cfg_deinit(wilc); + kfree(wilc->bus_data); kfree(wilc); } EXPORT_SYMBOL_GPL(wilc_netdev_cleanup); @@ -1062,20 +1062,34 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, 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 = 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 < NUM_CONCURRENT_IFC; i++) { struct wireless_dev *wdev; ndev = alloc_etherdev(sizeof(struct wilc_vif)); - if (!ndev) - return -ENOMEM; + if (!ndev) { + ret = -ENOMEM; + goto free_ndev; + } vif = netdev_priv(ndev); memset(vif, 0, sizeof(struct wilc_vif)); @@ -1096,15 +1110,14 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, ndev->netdev_ops = &wilc_netdev_ops; wdev = wilc_create_wiphy(ndev, dev); - - if (dev) - SET_NETDEV_DEV(ndev, dev); - if (!wdev) { netdev_err(ndev, "Can't register WILC Wiphy\n"); - return -1; + ret = -ENOMEM; + goto free_ndev; } + SET_NETDEV_DEV(ndev, dev); + vif->ndev->ieee80211_ptr = wdev; vif->ndev->ml_priv = vif; wdev->netdev = vif->ndev; @@ -1115,13 +1128,33 @@ int wilc_netdev_init(struct wilc **wilc, struct device *dev, int io_type, ret = register_netdev(ndev); if (ret) - return ret; + goto free_ndev; vif->iftype = STATION_MODE; vif->mac_opened = 0; } return 0; + +free_ndev: + for (; i >= 0; i--) { + if (wl->vif[i]) { + if (wl->vif[i]->iftype == 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; } EXPORT_SYMBOL_GPL(wilc_netdev_init); diff --git a/drivers/staging/wilc1000/wilc_debugfs.c b/drivers/staging/wilc1000/wilc_debugfs.c deleted file mode 100644 index 8001df66b8c2..000000000000 --- a/drivers/staging/wilc1000/wilc_debugfs.c +++ /dev/null @@ -1,115 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries. - * All rights reserved. - */ - -#if defined(WILC_DEBUGFS) -#include <linux/module.h> -#include <linux/debugfs.h> - -#include "wilc_wlan_if.h" - -static struct dentry *wilc_dir; - -#define DEBUG BIT(0) -#define INFO BIT(1) -#define WRN BIT(2) -#define ERR BIT(3) - -#define DBG_LEVEL_ALL (DEBUG | INFO | WRN | ERR) -static atomic_t WILC_DEBUG_LEVEL = ATOMIC_INIT(ERR); -EXPORT_SYMBOL_GPL(WILC_DEBUG_LEVEL); - -static ssize_t wilc_debug_level_read(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) -{ - char buf[128]; - int res = 0; - - /* only allow read from start */ - if (*ppos > 0) - return 0; - - res = scnprintf(buf, sizeof(buf), "Debug Level: %x\n", - atomic_read(&WILC_DEBUG_LEVEL)); - - return simple_read_from_buffer(userbuf, count, ppos, buf, res); -} - -static ssize_t wilc_debug_level_write(struct file *filp, - const char __user *buf, size_t count, - loff_t *ppos) -{ - int flag = 0; - int ret; - - ret = kstrtouint_from_user(buf, count, 16, &flag); - if (ret) - return ret; - - if (flag > DBG_LEVEL_ALL) { - pr_info("%s, value (0x%08x) is out of range, stay previous flag (0x%08x)\n", - __func__, flag, atomic_read(&WILC_DEBUG_LEVEL)); - return -EINVAL; - } - - atomic_set(&WILC_DEBUG_LEVEL, (int)flag); - - if (flag == 0) - pr_info("Debug-level disabled\n"); - else - pr_info("Debug-level enabled\n"); - - return count; -} - -#define FOPS(_open, _read, _write, _poll) { \ - .owner = THIS_MODULE, \ - .open = (_open), \ - .read = (_read), \ - .write = (_write), \ - .poll = (_poll), \ -} - -struct wilc_debugfs_info_t { - const char *name; - int perm; - unsigned int data; - const struct file_operations fops; -}; - -static struct wilc_debugfs_info_t debugfs_info[] = { - { - "wilc_debug_level", - 0666, - (DEBUG | ERR), - FOPS(NULL, wilc_debug_level_read, wilc_debug_level_write, NULL), - }, -}; - -static int __init wilc_debugfs_init(void) -{ - int i; - struct wilc_debugfs_info_t *info; - - wilc_dir = debugfs_create_dir("wilc_wifi", NULL); - for (i = 0; i < ARRAY_SIZE(debugfs_info); i++) { - info = &debugfs_info[i]; - debugfs_create_file(info->name, - info->perm, - wilc_dir, - &info->data, - &info->fops); - } - return 0; -} -module_init(wilc_debugfs_init); - -static void __exit wilc_debugfs_remove(void) -{ - debugfs_remove_recursive(wilc_dir); -} -module_exit(wilc_debugfs_remove); - -#endif diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index b2080d8b801f..ca351c950344 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -30,7 +30,6 @@ struct wilc_sdio { int has_thrpt_enh3; }; -static struct wilc_sdio g_sdio; static const struct wilc_hif_func wilc_hif_sdio; static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data); @@ -109,6 +108,11 @@ static int linux_sdio_probe(struct sdio_func *func, struct wilc *wilc; int ret; struct gpio_desc *gpio = NULL; + struct wilc_sdio *sdio_priv; + + sdio_priv = kzalloc(sizeof(*sdio_priv), GFP_KERNEL); + if (!sdio_priv) + return -ENOMEM; if (IS_ENABLED(CONFIG_WILC1000_HW_OOB_INTR)) { gpio = gpiod_get(&func->dev, "irq", GPIOD_IN); @@ -124,9 +128,11 @@ static int linux_sdio_probe(struct sdio_func *func, ret = wilc_netdev_init(&wilc, &func->dev, HIF_SDIO, &wilc_hif_sdio); if (ret) { dev_err(&func->dev, "Couldn't initialize netdev\n"); + kfree(sdio_priv); return ret; } sdio_set_drvdata(func, wilc); + wilc->bus_data = sdio_priv; wilc->dev = &func->dev; wilc->gpio_irq = gpio; @@ -381,6 +387,7 @@ fail: static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); + struct wilc_sdio *sdio_priv = wilc->bus_data; int ret; cpu_to_le32s(&data); @@ -415,7 +422,7 @@ static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data) cmd.increment = 1; cmd.count = 4; cmd.buffer = (u8 *)&data; - cmd.block_size = g_sdio.block_size; + cmd.block_size = sdio_priv->block_size; ret = wilc_sdio_cmd53(wilc, &cmd); if (ret) { dev_err(&func->dev, @@ -434,7 +441,8 @@ fail: static int sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); - u32 block_size = g_sdio.block_size; + struct wilc_sdio *sdio_priv = wilc->bus_data; + u32 block_size = sdio_priv->block_size; struct sdio_cmd53 cmd; int nblk, nleft, ret; @@ -523,6 +531,7 @@ fail: static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); + struct wilc_sdio *sdio_priv = wilc->bus_data; int ret; if (addr >= 0xf0 && addr <= 0xff) { @@ -553,7 +562,7 @@ static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data) cmd.count = 4; cmd.buffer = (u8 *)data; - cmd.block_size = g_sdio.block_size; + cmd.block_size = sdio_priv->block_size; ret = wilc_sdio_cmd53(wilc, &cmd); if (ret) { dev_err(&func->dev, @@ -574,7 +583,8 @@ fail: static int sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); - u32 block_size = g_sdio.block_size; + struct wilc_sdio *sdio_priv = wilc->bus_data; + u32 block_size = sdio_priv->block_size; struct sdio_cmd53 cmd; int nblk, nleft, ret; @@ -674,14 +684,13 @@ static int sdio_deinit(struct wilc *wilc) static int sdio_init(struct wilc *wilc, bool resume) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); + struct wilc_sdio *sdio_priv = wilc->bus_data; struct sdio_cmd52 cmd; int loop, ret; u32 chipid; - if (!resume) { - memset(&g_sdio, 0, sizeof(struct wilc_sdio)); - g_sdio.irq_gpio = wilc->dev_irq_num; - } + if (!resume) + sdio_priv->irq_gpio = wilc->dev_irq_num; /** * function 0 csa enable @@ -704,7 +713,7 @@ static int sdio_init(struct wilc *wilc, bool resume) dev_err(&func->dev, "Fail cmd 52, set func 0 block size...\n"); goto fail; } - g_sdio.block_size = WILC_SDIO_BLOCK_SIZE; + sdio_priv->block_size = WILC_SDIO_BLOCK_SIZE; /** * enable func1 IO @@ -778,11 +787,11 @@ static int sdio_init(struct wilc *wilc, bool resume) } dev_err(&func->dev, "chipid (%08x)\n", chipid); if ((chipid & 0xfff) > 0x2a0) - g_sdio.has_thrpt_enh3 = 1; + sdio_priv->has_thrpt_enh3 = 1; else - g_sdio.has_thrpt_enh3 = 0; + sdio_priv->has_thrpt_enh3 = 0; dev_info(&func->dev, "has_thrpt_enh3 = %d...\n", - g_sdio.has_thrpt_enh3); + sdio_priv->has_thrpt_enh3); } return 1; @@ -820,6 +829,7 @@ static int sdio_read_size(struct wilc *wilc, u32 *size) static int sdio_read_int(struct wilc *wilc, u32 *int_status) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); + struct wilc_sdio *sdio_priv = wilc->bus_data; u32 tmp; struct sdio_cmd52 cmd; @@ -828,7 +838,7 @@ static int sdio_read_int(struct wilc *wilc, u32 *int_status) /** * Read IRQ flags **/ - if (!g_sdio.irq_gpio) { + if (!sdio_priv->irq_gpio) { int i; cmd.function = 1; @@ -848,7 +858,7 @@ static int sdio_read_int(struct wilc *wilc, u32 *int_status) tmp |= INT_4; if (cmd.data & BIT(6)) tmp |= INT_5; - for (i = g_sdio.nint; i < MAX_NUM_INT; i++) { + for (i = sdio_priv->nint; i < MAX_NUM_INT; i++) { if ((tmp >> (IRG_FLAGS_OFFSET + i)) & 0x1) { dev_err(&func->dev, "Unexpected interrupt (1) : tmp=%x, data=%x\n", @@ -877,13 +887,14 @@ static int sdio_read_int(struct wilc *wilc, u32 *int_status) static int sdio_clear_int_ext(struct wilc *wilc, u32 val) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); + struct wilc_sdio *sdio_priv = wilc->bus_data; int ret; int vmm_ctl; - if (g_sdio.has_thrpt_enh3) { + if (sdio_priv->has_thrpt_enh3) { u32 reg; - if (g_sdio.irq_gpio) { + if (sdio_priv->irq_gpio) { u32 flags; flags = val & (BIT(MAX_NUN_INT_THRPT_ENH2) - 1); @@ -919,7 +930,7 @@ static int sdio_clear_int_ext(struct wilc *wilc, u32 val) } return 1; } - if (g_sdio.irq_gpio) { + if (sdio_priv->irq_gpio) { /* has_thrpt_enh2 uses register 0xf8 to clear interrupts. */ /* * Cannot clear multiple interrupts. @@ -932,7 +943,7 @@ static int sdio_clear_int_ext(struct wilc *wilc, u32 val) int i; ret = 1; - for (i = 0; i < g_sdio.nint; i++) { + for (i = 0; i < sdio_priv->nint; i++) { if (flags & 1) { struct sdio_cmd52 cmd; @@ -956,7 +967,7 @@ static int sdio_clear_int_ext(struct wilc *wilc, u32 val) } if (!ret) goto fail; - for (i = g_sdio.nint; i < MAX_NUM_INT; i++) { + for (i = sdio_priv->nint; i < MAX_NUM_INT; i++) { if (flags & 1) dev_err(&func->dev, "Unexpected interrupt cleared %d...\n", @@ -1001,6 +1012,7 @@ fail: static int sdio_sync_ext(struct wilc *wilc, int nint) { struct sdio_func *func = dev_to_sdio_func(wilc->dev); + struct wilc_sdio *sdio_priv = wilc->bus_data; u32 reg; if (nint > MAX_NUM_INT) { @@ -1013,7 +1025,7 @@ static int sdio_sync_ext(struct wilc *wilc, int nint) return 0; } - g_sdio.nint = nint; + sdio_priv->nint = nint; /** * Disable power sequencer @@ -1029,7 +1041,7 @@ static int sdio_sync_ext(struct wilc *wilc, int nint) return 0; } - if (g_sdio.irq_gpio) { + if (sdio_priv->irq_gpio) { u32 reg; int ret, i; diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index 5517477d875a..cef127b249fb 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -14,7 +14,6 @@ struct wilc_spi { int has_thrpt_enh; }; -static struct wilc_spi g_spi; static const struct wilc_hif_func wilc_hif_spi; /******************************************** @@ -107,6 +106,11 @@ static int wilc_bus_probe(struct spi_device *spi) int ret; struct wilc *wilc; struct gpio_desc *gpio; + struct wilc_spi *spi_priv; + + spi_priv = kzalloc(sizeof(*spi_priv), GFP_KERNEL); + if (!spi_priv) + return -ENOMEM; gpio = gpiod_get(&spi->dev, "irq", GPIOD_IN); if (IS_ERR(gpio)) { @@ -117,11 +121,14 @@ static int wilc_bus_probe(struct spi_device *spi) } ret = wilc_netdev_init(&wilc, NULL, HIF_SPI, &wilc_hif_spi); - if (ret) + if (ret) { + kfree(spi_priv); return ret; + } spi_set_drvdata(spi, wilc); wilc->dev = &spi->dev; + wilc->bus_data = spi_priv; wilc->gpio_irq = gpio; return 0; @@ -275,6 +282,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, u8 clockless) { struct spi_device *spi = to_spi_device(wilc->dev); + struct wilc_spi *spi_priv = wilc->bus_data; u8 wb[32], rb[32]; u8 wix, rix; u32 len2; @@ -375,7 +383,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, if (result != N_OK) return result; - if (!g_spi.crc_off) + if (!spi_priv->crc_off) wb[len - 1] = (crc7(0x7f, (const u8 *)&wb[0], len - 1)) << 1; else len -= 1; @@ -393,7 +401,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, } else if (cmd == CMD_INTERNAL_READ || cmd == CMD_SINGLE_READ) { int tmp = NUM_RSP_BYTES + NUM_DATA_HDR_BYTES + NUM_DATA_BYTES + NUM_DUMMY_BYTES; - if (!g_spi.crc_off) + if (!spi_priv->crc_off) len2 = len + tmp + NUM_CRC_BYTES; else len2 = len + tmp; @@ -485,7 +493,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, return N_FAIL; } - if (!g_spi.crc_off) { + if (!spi_priv->crc_off) { /* * Read Crc */ @@ -527,7 +535,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, /* * Read Crc */ - if (!g_spi.crc_off && wilc_spi_rx(wilc, crc, 2)) { + if (!spi_priv->crc_off && wilc_spi_rx(wilc, crc, 2)) { dev_err(&spi->dev, "Failed block crc read, bus err\n"); return N_FAIL; @@ -585,7 +593,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, /* * Read Crc */ - if (!g_spi.crc_off && wilc_spi_rx(wilc, crc, 2)) { + if (!spi_priv->crc_off && wilc_spi_rx(wilc, crc, 2)) { dev_err(&spi->dev, "Failed block crc read, bus err\n"); result = N_FAIL; @@ -602,6 +610,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz) { struct spi_device *spi = to_spi_device(wilc->dev); + struct wilc_spi *spi_priv = wilc->bus_data; int ix, nbytes; int result = 1; u8 cmd, order, crc[2] = {0}; @@ -648,7 +657,7 @@ static int spi_data_write(struct wilc *wilc, u8 *b, u32 sz) /* * Write Crc */ - if (!g_spi.crc_off) { + if (!spi_priv->crc_off) { if (wilc_spi_tx(wilc, crc, 2)) { dev_err(&spi->dev, "Failed data block crc write, bus error...\n"); result = N_FAIL; @@ -816,6 +825,7 @@ static int _wilc_spi_deinit(struct wilc *wilc) static int wilc_spi_init(struct wilc *wilc, bool resume) { struct spi_device *spi = to_spi_device(wilc->dev); + struct wilc_spi *spi_priv = wilc->bus_data; u32 reg; u32 chipid; static int isinit; @@ -828,12 +838,9 @@ static int wilc_spi_init(struct wilc *wilc, bool resume) return 1; } - memset(&g_spi, 0, sizeof(struct wilc_spi)); - /* * configure protocol */ - g_spi.crc_off = 0; /* * TODO: We can remove the CRC trials if there is a definite @@ -845,7 +852,7 @@ static int wilc_spi_init(struct wilc *wilc, bool resume) * Read failed. Try with CRC off. This might happen when module * is removed but chip isn't reset */ - g_spi.crc_off = 1; + spi_priv->crc_off = 1; dev_err(&spi->dev, "Failed read with CRC on, retrying with CRC off\n"); if (!spi_internal_read(wilc, WILC_SPI_PROTOCOL_OFFSET, ®)) { @@ -857,7 +864,7 @@ static int wilc_spi_init(struct wilc *wilc, bool resume) return 0; } } - if (g_spi.crc_off == 0) { + if (spi_priv->crc_off == 0) { reg &= ~0xc; /* disable crc checking */ reg &= ~0x70; reg |= (0x5 << 4); @@ -867,7 +874,7 @@ static int wilc_spi_init(struct wilc *wilc, bool resume) __LINE__); return 0; } - g_spi.crc_off = 1; + spi_priv->crc_off = 1; } /* @@ -878,7 +885,7 @@ static int wilc_spi_init(struct wilc *wilc, bool resume) return 0; } - g_spi.has_thrpt_enh = 1; + spi_priv->has_thrpt_enh = 1; isinit = 1; @@ -888,9 +895,10 @@ static int wilc_spi_init(struct wilc *wilc, bool resume) static int wilc_spi_read_size(struct wilc *wilc, u32 *size) { struct spi_device *spi = to_spi_device(wilc->dev); + struct wilc_spi *spi_priv = wilc->bus_data; int ret; - if (g_spi.has_thrpt_enh) { + if (spi_priv->has_thrpt_enh) { ret = spi_internal_read(wilc, 0xe840 - WILC_SPI_REG_BASE, size); *size = *size & IRQ_DMA_WD_CNT_MASK; @@ -915,6 +923,7 @@ static int wilc_spi_read_size(struct wilc *wilc, u32 *size) static int wilc_spi_read_int(struct wilc *wilc, u32 *int_status) { struct spi_device *spi = to_spi_device(wilc->dev); + struct wilc_spi *spi_priv = wilc->bus_data; int ret; u32 tmp; u32 byte_cnt; @@ -923,7 +932,7 @@ static int wilc_spi_read_int(struct wilc *wilc, u32 *int_status) u32 irq_flags; int k = IRG_FLAGS_OFFSET + 5; - if (g_spi.has_thrpt_enh) { + if (spi_priv->has_thrpt_enh) { ret = spi_internal_read(wilc, 0xe840 - WILC_SPI_REG_BASE, int_status); return ret; @@ -943,12 +952,12 @@ static int wilc_spi_read_int(struct wilc *wilc, u32 *int_status) wilc_spi_read_reg(wilc, 0x1a90, &irq_flags); tmp |= ((irq_flags >> 27) << IRG_FLAGS_OFFSET); - if (g_spi.nint > 5) { + if (spi_priv->nint > 5) { wilc_spi_read_reg(wilc, 0x1a94, &irq_flags); tmp |= (((irq_flags >> 0) & 0x7) << k); } - unknown_mask = ~((1ul << g_spi.nint) - 1); + unknown_mask = ~((1ul << spi_priv->nint) - 1); if ((tmp >> IRG_FLAGS_OFFSET) & unknown_mask) { dev_err(&spi->dev, @@ -968,11 +977,12 @@ static int wilc_spi_read_int(struct wilc *wilc, u32 *int_status) static int wilc_spi_clear_int_ext(struct wilc *wilc, u32 val) { struct spi_device *spi = to_spi_device(wilc->dev); + struct wilc_spi *spi_priv = wilc->bus_data; int ret; u32 flags; u32 tbl_ctl; - if (g_spi.has_thrpt_enh) { + if (spi_priv->has_thrpt_enh) { ret = spi_internal_write(wilc, 0xe844 - WILC_SPI_REG_BASE, val); return ret; @@ -983,7 +993,7 @@ static int wilc_spi_clear_int_ext(struct wilc *wilc, u32 val) int i; ret = 1; - for (i = 0; i < g_spi.nint; i++) { + for (i = 0; i < spi_priv->nint; i++) { /* * No matter what you write 1 or 0, * it will clear interrupt. @@ -1001,7 +1011,7 @@ static int wilc_spi_clear_int_ext(struct wilc *wilc, u32 val) 0x10c8 + i * 4); return ret; } - for (i = g_spi.nint; i < MAX_NUM_INT; i++) { + for (i = spi_priv->nint; i < MAX_NUM_INT; i++) { if (flags & 1) dev_err(&spi->dev, "Unexpected interrupt cleared %d...\n", @@ -1041,6 +1051,7 @@ static int wilc_spi_clear_int_ext(struct wilc *wilc, u32 val) static int wilc_spi_sync_ext(struct wilc *wilc, int nint) { struct spi_device *spi = to_spi_device(wilc->dev); + struct wilc_spi *spi_priv = wilc->bus_data; u32 reg; int ret, i; @@ -1049,7 +1060,7 @@ static int wilc_spi_sync_ext(struct wilc *wilc, int nint) return 0; } - g_spi.nint = nint; + spi_priv->nint = nint; /* * interrupt pin mux select diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 7cd033004651..4fbbbbd5a64b 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -82,12 +82,6 @@ static const struct wiphy_wowlan_support wowlan_support = { .flags = WIPHY_WOWLAN_ANY }; -static struct network_info last_scanned_shadow[MAX_NUM_SCANNED_NETWORKS_SHADOW]; -static u32 last_scanned_cnt; -struct timer_list wilc_during_ip_timer; -static struct timer_list aging_timer; -static u8 op_ifcs; - #define CHAN2G(_channel, _freq, _flags) { \ .band = NL80211_BAND_2GHZ, \ .center_freq = (_freq), \ @@ -143,10 +137,7 @@ struct p2p_mgmt_data { static u8 wlan_channel = INVALID_CHANNEL; static u8 curr_channel; static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09}; -static u8 p2p_local_random = 0x01; -static u8 p2p_recv_random; static u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03}; -static bool wilc_ie; static struct ieee80211_supported_band wilc_band_2ghz = { .channels = ieee80211_2ghz_channels, @@ -158,25 +149,18 @@ static struct ieee80211_supported_band wilc_band_2ghz = { #define AGING_TIME (9 * 1000) #define DURING_IP_TIME_OUT 15000 -static void clear_shadow_scan(void) +static void clear_shadow_scan(struct wilc_priv *priv) { int i; - if (op_ifcs != 0) - return; - - del_timer_sync(&aging_timer); + for (i = 0; i < priv->scanned_cnt; i++) { + kfree(priv->scanned_shadow[i].ies); + priv->scanned_shadow[i].ies = NULL; - for (i = 0; i < last_scanned_cnt; i++) { - if (last_scanned_shadow[last_scanned_cnt].ies) { - kfree(last_scanned_shadow[i].ies); - last_scanned_shadow[last_scanned_cnt].ies = NULL; - } - - kfree(last_scanned_shadow[i].join_params); - last_scanned_shadow[i].join_params = NULL; + kfree(priv->scanned_shadow[i].join_params); + priv->scanned_shadow[i].join_params = NULL; } - last_scanned_cnt = 0; + priv->scanned_cnt = 0; } static u32 get_rssi_avg(struct network_info *network_info) @@ -198,14 +182,14 @@ static void refresh_scan(struct wilc_priv *priv, bool direct_scan) struct wiphy *wiphy = priv->dev->ieee80211_ptr->wiphy; int i; - for (i = 0; i < last_scanned_cnt; i++) { + for (i = 0; i < priv->scanned_cnt; i++) { struct network_info *network_info; s32 freq; struct ieee80211_channel *channel; int rssi; struct cfg80211_bss *bss; - network_info = &last_scanned_shadow[i]; + network_info = &priv->scanned_shadow[i]; if (!memcmp("DIRECT-", network_info->ssid, 7) && !direct_scan) continue; @@ -229,62 +213,68 @@ static void refresh_scan(struct wilc_priv *priv, bool direct_scan) } } -static void reset_shadow_found(void) +static void reset_shadow_found(struct wilc_priv *priv) { int i; - for (i = 0; i < last_scanned_cnt; i++) - last_scanned_shadow[i].found = 0; + for (i = 0; i < priv->scanned_cnt; i++) + priv->scanned_shadow[i].found = 0; } -static void update_scan_time(void) +static void update_scan_time(struct wilc_priv *priv) { int i; - for (i = 0; i < last_scanned_cnt; i++) - last_scanned_shadow[i].time_scan = jiffies; + for (i = 0; i < priv->scanned_cnt; i++) + priv->scanned_shadow[i].time_scan = jiffies; } -static void remove_network_from_shadow(struct timer_list *unused) +static void remove_network_from_shadow(struct timer_list *t) { + struct wilc_priv *priv = from_timer(priv, t, aging_timer); unsigned long now = jiffies; int i, j; - for (i = 0; i < last_scanned_cnt; i++) { - if (!time_after(now, last_scanned_shadow[i].time_scan + + for (i = 0; i < priv->scanned_cnt; i++) { + if (!time_after(now, priv->scanned_shadow[i].time_scan + (unsigned long)(SCAN_RESULT_EXPIRE))) continue; - kfree(last_scanned_shadow[i].ies); - last_scanned_shadow[i].ies = NULL; + kfree(priv->scanned_shadow[i].ies); + priv->scanned_shadow[i].ies = NULL; - kfree(last_scanned_shadow[i].join_params); + kfree(priv->scanned_shadow[i].join_params); - for (j = i; (j < last_scanned_cnt - 1); j++) - last_scanned_shadow[j] = last_scanned_shadow[j + 1]; + for (j = i; (j < priv->scanned_cnt - 1); j++) + priv->scanned_shadow[j] = priv->scanned_shadow[j + 1]; - last_scanned_cnt--; + priv->scanned_cnt--; } - if (last_scanned_cnt != 0) - mod_timer(&aging_timer, jiffies + msecs_to_jiffies(AGING_TIME)); + if (priv->scanned_cnt != 0) + mod_timer(&priv->aging_timer, + jiffies + msecs_to_jiffies(AGING_TIME)); } -static void clear_during_ip(struct timer_list *unused) +static void clear_during_ip(struct timer_list *t) { - wilc_optaining_ip = false; + struct wilc_vif *vif = from_timer(vif, t, during_ip_timer); + + vif->obtaining_ip = false; } -static int is_network_in_shadow(struct network_info *nw_info, void *user_void) +static int is_network_in_shadow(struct network_info *nw_info, + struct wilc_priv *priv) { int state = -1; int i; - if (last_scanned_cnt == 0) { - mod_timer(&aging_timer, jiffies + msecs_to_jiffies(AGING_TIME)); + if (priv->scanned_cnt == 0) { + mod_timer(&priv->aging_timer, + jiffies + msecs_to_jiffies(AGING_TIME)); state = -1; } else { - for (i = 0; i < last_scanned_cnt; i++) { - if (memcmp(last_scanned_shadow[i].bssid, + for (i = 0; i < priv->scanned_cnt; i++) { + if (memcmp(priv->scanned_shadow[i].bssid, nw_info->bssid, 6) == 0) { state = i; break; @@ -295,23 +285,23 @@ static int is_network_in_shadow(struct network_info *nw_info, void *user_void) } static void add_network_to_shadow(struct network_info *nw_info, - void *user_void, void *join_params) + struct wilc_priv *priv, void *join_params) { - int ap_found = is_network_in_shadow(nw_info, user_void); + int ap_found = is_network_in_shadow(nw_info, priv); u32 ap_index = 0; u8 rssi_index = 0; struct network_info *shadow_nw_info; - if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW) + if (priv->scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW) return; if (ap_found == -1) { - ap_index = last_scanned_cnt; - last_scanned_cnt++; + ap_index = priv->scanned_cnt; + priv->scanned_cnt++; } else { ap_index = ap_found; } - shadow_nw_info = &last_scanned_shadow[ap_index]; + shadow_nw_info = &priv->scanned_shadow[ap_index]; rssi_index = shadow_nw_info->rssi_history.index; shadow_nw_info->rssi_history.samples[rssi_index++] = nw_info->rssi; if (rssi_index == NUM_RSSI) { @@ -403,7 +393,7 @@ static void cfg_scan_result(enum scan_event scan_event, u32 i; for (i = 0; i < priv->rcvd_ch_cnt; i++) { - if (memcmp(last_scanned_shadow[i].bssid, + if (memcmp(priv->scanned_shadow[i].bssid, network_info->bssid, 6) == 0) break; } @@ -411,8 +401,8 @@ static void cfg_scan_result(enum scan_event scan_event, if (i >= priv->rcvd_ch_cnt) return; - last_scanned_shadow[i].rssi = network_info->rssi; - last_scanned_shadow[i].time_scan = jiffies; + priv->scanned_shadow[i].rssi = network_info->rssi; + priv->scanned_shadow[i].time_scan = jiffies; } } else if (scan_event == SCAN_EVENT_DONE) { refresh_scan(priv, false); @@ -438,7 +428,7 @@ static void cfg_scan_result(enum scan_event scan_event, .aborted = false, }; - update_scan_time(); + update_scan_time(priv); refresh_scan(priv, false); cfg80211_scan_done(priv->scan_req, &info); @@ -449,19 +439,17 @@ static void cfg_scan_result(enum scan_event scan_event, } } -static inline bool wilc_wfi_cfg_scan_time_expired(int i) +static inline bool wilc_cfg_scan_time_expired(struct wilc_priv *priv, int i) { unsigned long now = jiffies; - if (time_after(now, last_scanned_shadow[i].time_scan_cached + + if (time_after(now, priv->scanned_shadow[i].time_scan_cached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) return true; else return false; } -int wilc_connecting; - static void cfg_connect_result(enum conn_event conn_disconn_evt, struct connect_info *conn_info, u8 mac_status, @@ -475,7 +463,7 @@ static void cfg_connect_result(enum conn_event conn_disconn_evt, struct host_if_drv *wfi_drv = priv->hif_drv; u8 null_bssid[ETH_ALEN] = {0}; - wilc_connecting = 0; + vif->connecting = false; if (conn_disconn_evt == CONN_DISCONN_EVENT_CONN_RESP) { u16 connect_status; @@ -487,7 +475,6 @@ static void cfg_connect_result(enum conn_event conn_disconn_evt, connect_status = WLAN_STATUS_UNSPECIFIED_FAILURE; wilc_wlan_set_bssid(priv->dev, null_bssid, STATION_MODE); - eth_zero_addr(wilc_connected_ssid); if (!wfi_drv->p2p_connect) wlan_channel = INVALID_CHANNEL; @@ -502,11 +489,11 @@ static void cfg_connect_result(enum conn_event conn_disconn_evt, memcpy(priv->associated_bss, conn_info->bssid, ETH_ALEN); - for (i = 0; i < last_scanned_cnt; i++) { - if (memcmp(last_scanned_shadow[i].bssid, + for (i = 0; i < priv->scanned_cnt; i++) { + if (memcmp(priv->scanned_shadow[i].bssid, conn_info->bssid, ETH_ALEN) == 0) { - if (wilc_wfi_cfg_scan_time_expired(i)) + if (wilc_cfg_scan_time_expired(priv, i)) scan_refresh = true; break; @@ -524,13 +511,12 @@ static void cfg_connect_result(enum conn_event conn_disconn_evt, conn_info->resp_ies_len, connect_status, GFP_KERNEL); } else if (conn_disconn_evt == CONN_DISCONN_EVENT_DISCONN_NOTIF) { - wilc_optaining_ip = false; - p2p_local_random = 0x01; - p2p_recv_random = 0x00; - wilc_ie = false; + vif->obtaining_ip = false; + priv->p2p.local_random = 0x01; + priv->p2p.recv_random = 0x00; + priv->p2p.is_wilc_ie = false; eth_zero_addr(priv->associated_bss); wilc_wlan_set_bssid(priv->dev, null_bssid, STATION_MODE); - eth_zero_addr(wilc_connected_ssid); if (!wfi_drv->p2p_connect) wlan_channel = INVALID_CHANNEL; @@ -620,7 +606,7 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) priv->rcvd_ch_cnt = 0; - reset_shadow_found(); + reset_shadow_found(priv); priv->cfg_scanning = true; if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { @@ -673,25 +659,25 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, enum authtype auth_type = ANY; u32 cipher_group; - wilc_connecting = 1; + vif->connecting = true; if (!(strncmp(sme->ssid, "DIRECT-", 7))) wfi_drv->p2p_connect = 1; else wfi_drv->p2p_connect = 0; - for (i = 0; i < last_scanned_cnt; i++) { - if (sme->ssid_len == last_scanned_shadow[i].ssid_len && - memcmp(last_scanned_shadow[i].ssid, + for (i = 0; i < priv->scanned_cnt; i++) { + if (sme->ssid_len == priv->scanned_shadow[i].ssid_len && + memcmp(priv->scanned_shadow[i].ssid, sme->ssid, sme->ssid_len) == 0) { if (!sme->bssid) { if (sel_bssi_idx == UINT_MAX || - last_scanned_shadow[i].rssi > - last_scanned_shadow[sel_bssi_idx].rssi) + priv->scanned_shadow[i].rssi > + priv->scanned_shadow[sel_bssi_idx].rssi) sel_bssi_idx = i; } else { - if (memcmp(last_scanned_shadow[i].bssid, + if (memcmp(priv->scanned_shadow[i].bssid, sme->bssid, ETH_ALEN) == 0) { sel_bssi_idx = i; @@ -701,12 +687,16 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, } } - if (sel_bssi_idx < last_scanned_cnt) { - nw_info = &last_scanned_shadow[sel_bssi_idx]; + if (sel_bssi_idx < priv->scanned_cnt) { + nw_info = &priv->scanned_shadow[sel_bssi_idx]; } else { ret = -ENOENT; - wilc_connecting = 0; - return ret; + goto out_error; + } + + if (ether_addr_equal_unaligned(vif->bssid, nw_info->bssid)) { + ret = -EALREADY; + goto out_error; } memset(priv->wep_key, 0, sizeof(priv->wep_key)); @@ -748,8 +738,7 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, ret = -ENOTSUPP; netdev_err(dev, "%s: Unsupported cipher\n", __func__); - wilc_connecting = 0; - return ret; + goto out_error; } } @@ -796,13 +785,18 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, security, auth_type, nw_info->ch, nw_info->join_params); - if (ret != 0) { + if (ret) { + u8 null_bssid[ETH_ALEN] = {0}; + netdev_err(dev, "wilc_set_join_req(): Error\n"); ret = -ENOENT; - wilc_connecting = 0; - return ret; + wilc_wlan_set_bssid(dev, null_bssid, STATION_MODE); + goto out_error; } + return 0; +out_error: + vif->connecting = false; return ret; } @@ -816,7 +810,7 @@ static int disconnect(struct wiphy *wiphy, struct net_device *dev, int ret; u8 null_bssid[ETH_ALEN] = {0}; - wilc_connecting = 0; + vif->connecting = false; if (!wilc) return -EIO; @@ -832,9 +826,9 @@ static int disconnect(struct wiphy *wiphy, struct net_device *dev, wlan_channel = INVALID_CHANNEL; wilc_wlan_set_bssid(priv->dev, null_bssid, STATION_MODE); - p2p_local_random = 0x01; - p2p_recv_random = 0x00; - wilc_ie = false; + priv->p2p.local_random = 0x01; + priv->p2p.recv_random = 0x00; + priv->p2p.is_wilc_ie = false; wfi_drv->p2p_timeout = 0; ret = wilc_disconnect(vif, reason_code); @@ -1132,9 +1126,9 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev, if (stats.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH && stats.link_speed != DEFAULT_LINK_SPEED) - wilc_enable_tcp_ack_filter(true); + wilc_enable_tcp_ack_filter(vif, true); else if (stats.link_speed != DEFAULT_LINK_SPEED) - wilc_enable_tcp_ack_filter(false); + wilc_enable_tcp_ack_filter(vif, false); } return 0; } @@ -1333,20 +1327,21 @@ static void wilc_wfi_cfg_parse_rx_vendor_spec(struct wilc_priv *priv, u8 *buff, struct wilc_vif *vif = netdev_priv(priv->dev); subtype = buff[P2P_PUB_ACTION_SUBTYPE]; - if ((subtype == GO_NEG_REQ || subtype == GO_NEG_RSP) && !wilc_ie) { + if ((subtype == GO_NEG_REQ || subtype == GO_NEG_RSP) && + !priv->p2p.is_wilc_ie) { for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) { if (!memcmp(p2p_vendor_spec, &buff[i], 6)) { - p2p_recv_random = buff[i + 6]; - wilc_ie = true; + priv->p2p.recv_random = buff[i + 6]; + priv->p2p.is_wilc_ie = true; break; } } } - if (p2p_local_random <= p2p_recv_random) { + if (priv->p2p.local_random <= priv->p2p.recv_random) { netdev_dbg(vif->ndev, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", - p2p_local_random, p2p_recv_random); + priv->p2p.local_random, priv->p2p.recv_random); return; } @@ -1414,7 +1409,7 @@ void wilc_wfi_p2p_rx(struct net_device *dev, u8 *buff, u32 size) size); if ((subtype == GO_NEG_REQ || subtype == GO_NEG_RSP) && - wilc_ie) + priv->p2p.is_wilc_ie) size -= 7; break; @@ -1506,7 +1501,8 @@ static int cancel_remain_on_channel(struct wiphy *wiphy, priv->remain_on_ch_params.listen_session_id); } -static void wilc_wfi_cfg_tx_vendor_spec(struct p2p_mgmt_data *mgmt_tx, +static void wilc_wfi_cfg_tx_vendor_spec(struct wilc_priv *priv, + struct p2p_mgmt_data *mgmt_tx, struct cfg80211_mgmt_tx_params *params, u8 iftype, u32 buf_len) { @@ -1516,17 +1512,16 @@ static void wilc_wfi_cfg_tx_vendor_spec(struct p2p_mgmt_data *mgmt_tx, u8 subtype = buf[P2P_PUB_ACTION_SUBTYPE]; if (subtype == GO_NEG_REQ || subtype == GO_NEG_RSP) { - if (p2p_local_random == 1 && - p2p_recv_random < p2p_local_random) { - get_random_bytes(&p2p_local_random, 1); - p2p_local_random++; + if (priv->p2p.local_random == 1 && + priv->p2p.recv_random < priv->p2p.local_random) { + get_random_bytes(&priv->p2p.local_random, 1); + priv->p2p.local_random++; } } - if (p2p_local_random <= p2p_recv_random || !(subtype == GO_NEG_REQ || - subtype == GO_NEG_RSP || - subtype == P2P_INV_REQ || - subtype == P2P_INV_RSP)) + if (priv->p2p.local_random <= priv->p2p.recv_random || + !(subtype == GO_NEG_REQ || subtype == GO_NEG_RSP || + subtype == P2P_INV_REQ || subtype == P2P_INV_RSP)) return; for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) { @@ -1550,7 +1545,7 @@ static void wilc_wfi_cfg_tx_vendor_spec(struct p2p_mgmt_data *mgmt_tx, memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, vendor_spec_len); - mgmt_tx->buff[len + vendor_spec_len] = p2p_local_random; + mgmt_tx->buff[len + vendor_spec_len] = priv->p2p.local_random; mgmt_tx->size = buf_len; } } @@ -1569,7 +1564,7 @@ static int mgmt_tx(struct wiphy *wiphy, struct wilc_priv *priv = wiphy_priv(wiphy); struct host_if_drv *wfi_drv = priv->hif_drv; struct wilc_vif *vif = netdev_priv(wdev->netdev); - u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random); + u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(priv->p2p.local_random); int ret = 0; *cookie = (unsigned long)buf; @@ -1617,8 +1612,8 @@ static int mgmt_tx(struct wiphy *wiphy, case PUBLIC_ACT_VENDORSPEC: if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) - wilc_wfi_cfg_tx_vendor_spec(mgmt_tx, params, - vif->iftype, + wilc_wfi_cfg_tx_vendor_spec(priv, mgmt_tx, + params, vif->iftype, buf_len); else netdev_dbg(vif->ndev, @@ -1732,7 +1727,7 @@ static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, if (!priv->hif_drv) return -EIO; - if (wilc_enable_ps) + if (vif->wilc->enable_ps) wilc_set_power_mgmt(vif, enabled, timeout); return 0; @@ -1746,15 +1741,15 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, struct wilc_vif *vif = netdev_priv(dev); struct wilc *wl = vif->wilc; - p2p_local_random = 0x01; - p2p_recv_random = 0x00; - wilc_ie = false; - wilc_optaining_ip = false; - del_timer(&wilc_during_ip_timer); + priv->p2p.local_random = 0x01; + priv->p2p.recv_random = 0x00; + priv->p2p.is_wilc_ie = false; + vif->obtaining_ip = false; + del_timer(&vif->during_ip_timer); switch (type) { case NL80211_IFTYPE_STATION: - wilc_connecting = 0; + vif->connecting = false; dev->ieee80211_ptr->iftype = type; priv->wdev->iftype = type; vif->monitor_flag = 0; @@ -1764,46 +1759,46 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, memset(priv->assoc_stainfo.sta_associated_bss, 0, MAX_NUM_STA * ETH_ALEN); - wilc_enable_ps = true; + wl->enable_ps = true; wilc_set_power_mgmt(vif, 1, 0); break; case NL80211_IFTYPE_P2P_CLIENT: - wilc_connecting = 0; + vif->connecting = false; dev->ieee80211_ptr->iftype = type; priv->wdev->iftype = type; vif->monitor_flag = 0; vif->iftype = CLIENT_MODE; wilc_set_operation_mode(vif, STATION_MODE); - wilc_enable_ps = false; + wl->enable_ps = false; wilc_set_power_mgmt(vif, 0, 0); break; case NL80211_IFTYPE_AP: - wilc_enable_ps = false; + wl->enable_ps = false; dev->ieee80211_ptr->iftype = type; priv->wdev->iftype = type; vif->iftype = AP_MODE; if (wl->initialized) { wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif), - 0, vif->ifc_id); + 0, vif->ifc_id, false); wilc_set_operation_mode(vif, AP_MODE); wilc_set_power_mgmt(vif, 0, 0); } break; case NL80211_IFTYPE_P2P_GO: - wilc_optaining_ip = true; - mod_timer(&wilc_during_ip_timer, + vif->obtaining_ip = true; + mod_timer(&vif->during_ip_timer, jiffies + msecs_to_jiffies(DURING_IP_TIME_OUT)); wilc_set_operation_mode(vif, AP_MODE); dev->ieee80211_ptr->iftype = type; priv->wdev->iftype = type; vif->iftype = GO_MODE; - wilc_enable_ps = false; + wl->enable_ps = false; wilc_set_power_mgmt(vif, 0, 0); break; @@ -2154,8 +2149,12 @@ struct wireless_dev *wilc_create_wiphy(struct net_device *net, set_wiphy_dev(wdev->wiphy, dev); ret = wiphy_register(wdev->wiphy); - if (ret) + if (ret) { netdev_err(net, "Cannot register wiphy device\n"); + wiphy_free(wdev->wiphy); + kfree(wdev); + return NULL; + } priv->dev = net; return wdev; @@ -2165,12 +2164,10 @@ int wilc_init_host_int(struct net_device *net) { int ret; struct wilc_priv *priv = wdev_priv(net->ieee80211_ptr); + struct wilc_vif *vif = netdev_priv(priv->dev); - if (op_ifcs == 0) { - timer_setup(&aging_timer, remove_network_from_shadow, 0); - timer_setup(&wilc_during_ip_timer, clear_during_ip, 0); - } - op_ifcs++; + timer_setup(&priv->aging_timer, remove_network_from_shadow, 0); + timer_setup(&vif->during_ip_timer, clear_during_ip, 0); priv->p2p_listen_state = false; @@ -2182,7 +2179,7 @@ int wilc_init_host_int(struct net_device *net) return ret; } -int wilc_deinit_host_int(struct net_device *net) +void wilc_deinit_host_int(struct net_device *net) { int ret; struct wilc_priv *priv = wdev_priv(net->ieee80211_ptr); @@ -2190,19 +2187,15 @@ int wilc_deinit_host_int(struct net_device *net) priv->p2p_listen_state = false; - op_ifcs--; - mutex_destroy(&priv->scan_req_lock); ret = wilc_deinit(vif); - clear_shadow_scan(); - if (op_ifcs == 0) - del_timer_sync(&wilc_during_ip_timer); + del_timer_sync(&priv->aging_timer); + clear_shadow_scan(priv); + del_timer_sync(&vif->during_ip_timer); if (ret) netdev_err(net, "Error while deinitializing host interface\n"); - - return ret; } void wilc_free_wiphy(struct net_device *net) diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h index be412b65926c..4812c8e2c79b 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.h @@ -11,10 +11,10 @@ struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev); void wilc_free_wiphy(struct net_device *net); -int 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); void wilc_wfi_monitor_rx(u8 *buff, u32 size); -int wilc_wfi_deinit_mon_interface(void); +void wilc_wfi_deinit_mon_interface(void); struct net_device *wilc_wfi_init_mon_interface(const char *name, struct net_device *real_dev); void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index b7eee772f3fe..4f05a16c778e 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -16,6 +16,7 @@ #include "host_interface.h" #include "wilc_wlan.h" +#include "wilc_wlan_cfg.h" #define FLOW_CONTROL_LOWER_THRESHOLD 128 #define FLOW_CONTROL_UPPER_THRESHOLD 256 @@ -68,6 +69,12 @@ struct wilc_wfi_p2p_listen_params { u32 listen_session_id; }; +struct wilc_p2p_var { + u8 local_random; + u8 recv_random; + bool is_wilc_ie; +}; + struct wilc_priv { struct wireless_dev *wdev; struct cfg80211_scan_request *scan_req; @@ -94,7 +101,10 @@ struct wilc_priv { /* mutexes */ struct mutex scan_req_lock; bool p2p_listen_state; - + struct timer_list aging_timer; + struct network_info scanned_shadow[MAX_NUM_SCANNED_NETWORKS_SHADOW]; + int scanned_cnt; + struct wilc_p2p_var p2p; }; struct frame_reg { @@ -102,6 +112,32 @@ struct frame_reg { bool reg; }; +#define MAX_TCP_SESSION 25 +#define MAX_PENDING_ACKS 256 + +struct ack_session_info { + u32 seq_num; + u32 bigger_ack_num; + u16 src_port; + u16 dst_port; + u16 status; +}; + +struct pending_acks { + u32 ack_num; + u32 session_index; + struct txq_entry_t *txqe; +}; + +struct tcp_ack_filter { + struct ack_session_info ack_session_info[2 * MAX_TCP_SESSION]; + struct pending_acks pending_acks[MAX_PENDING_ACKS]; + u32 pending_base; + u32 tcp_session; + u32 pending_acks_idx; + bool enabled; +}; + struct wilc_vif { u8 idx; u8 iftype; @@ -116,12 +152,18 @@ struct wilc_vif { struct net_device *ndev; u8 mode; u8 ifc_id; + struct timer_list during_ip_timer; + bool obtaining_ip; + struct timer_list periodic_rssi; + struct rf_info periodic_stat; + struct tcp_ack_filter ack_filter; + bool connecting; }; struct wilc { const struct wilc_hif_func *hif_func; int io_type; - int mac_status; + s8 mac_status; struct gpio_desc *gpio_irq; bool initialized; int dev_irq_num; @@ -165,7 +207,12 @@ struct wilc { struct device *dev; bool suspend_event; - struct rf_info dummy_statistics; + bool enable_ps; + int clients_count; + struct workqueue_struct *hif_workqueue; + enum chip_ps_states chip_ps_state; + struct wilc_cfg cfg; + void *bus_data; }; struct wilc_wfi_mon_priv { @@ -178,6 +225,6 @@ 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); -int 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); #endif diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index 8b184aa30d25..a48c906b2443 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -9,8 +9,6 @@ #include "wilc_wfi_netdevice.h" #include "wilc_wlan_cfg.h" -static enum chip_ps_states chip_ps_state = CHIP_WAKEDUP; - static inline bool is_wilc1000(u32 id) { return ((id & 0xfffff000) == 0x100000 ? true : false); @@ -73,8 +71,8 @@ static void wilc_wlan_txq_add_to_tail(struct net_device *dev, complete(&wilc->txq_event); } -static int wilc_wlan_txq_add_to_head(struct wilc_vif *vif, - struct txq_entry_t *tqe) +static void wilc_wlan_txq_add_to_head(struct wilc_vif *vif, + struct txq_entry_t *tqe) { unsigned long flags; struct wilc *wilc = vif->wilc; @@ -89,69 +87,47 @@ static int wilc_wlan_txq_add_to_head(struct wilc_vif *vif, spin_unlock_irqrestore(&wilc->txq_spinlock, flags); mutex_unlock(&wilc->txq_add_to_head_cs); complete(&wilc->txq_event); - - return 0; } -struct ack_session_info; -struct ack_session_info { - u32 seq_num; - u32 bigger_ack_num; - u16 src_port; - u16 dst_port; - u16 status; -}; - -struct pending_acks_info { - u32 ack_num; - u32 session_index; - struct txq_entry_t *txqe; -}; - #define NOT_TCP_ACK (-1) -#define MAX_TCP_SESSION 25 -#define MAX_PENDING_ACKS 256 -static struct ack_session_info ack_session_info[2 * MAX_TCP_SESSION]; -static struct pending_acks_info pending_acks_info[MAX_PENDING_ACKS]; - -static u32 pending_base; -static u32 tcp_session; -static u32 pending_acks; - -static inline int add_tcp_session(u32 src_prt, u32 dst_prt, u32 seq) +static inline void add_tcp_session(struct wilc_vif *vif, u32 src_prt, + u32 dst_prt, u32 seq) { - if (tcp_session < 2 * MAX_TCP_SESSION) { - ack_session_info[tcp_session].seq_num = seq; - ack_session_info[tcp_session].bigger_ack_num = 0; - ack_session_info[tcp_session].src_port = src_prt; - ack_session_info[tcp_session].dst_port = dst_prt; - tcp_session++; + struct tcp_ack_filter *f = &vif->ack_filter; + + if (f->tcp_session < 2 * MAX_TCP_SESSION) { + f->ack_session_info[f->tcp_session].seq_num = seq; + f->ack_session_info[f->tcp_session].bigger_ack_num = 0; + f->ack_session_info[f->tcp_session].src_port = src_prt; + f->ack_session_info[f->tcp_session].dst_port = dst_prt; + f->tcp_session++; } - return 0; } -static inline int update_tcp_session(u32 index, u32 ack) +static inline void update_tcp_session(struct wilc_vif *vif, u32 index, u32 ack) { + struct tcp_ack_filter *f = &vif->ack_filter; + if (index < 2 * MAX_TCP_SESSION && - ack > ack_session_info[index].bigger_ack_num) - ack_session_info[index].bigger_ack_num = ack; - return 0; + ack > f->ack_session_info[index].bigger_ack_num) + f->ack_session_info[index].bigger_ack_num = ack; } -static inline int add_tcp_pending_ack(u32 ack, u32 session_index, - struct txq_entry_t *txqe) +static inline void add_tcp_pending_ack(struct wilc_vif *vif, u32 ack, + u32 session_index, + struct txq_entry_t *txqe) { - u32 i = pending_base + pending_acks; + struct tcp_ack_filter *f = &vif->ack_filter; + u32 i = f->pending_base + f->pending_acks_idx; if (i < MAX_PENDING_ACKS) { - pending_acks_info[i].ack_num = ack; - pending_acks_info[i].txqe = txqe; - pending_acks_info[i].session_index = session_index; - txqe->tcp_pending_ack_idx = i; - pending_acks++; + f->pending_acks[i].ack_num = ack; + f->pending_acks[i].txqe = txqe; + f->pending_acks[i].session_index = session_index; + txqe->ack_idx = i; + f->pending_acks_idx++; } - return 0; } static inline void tcp_process(struct net_device *dev, struct txq_entry_t *tqe) @@ -162,72 +138,79 @@ static inline void tcp_process(struct net_device *dev, struct txq_entry_t *tqe) unsigned long flags; struct wilc_vif *vif = netdev_priv(dev); struct wilc *wilc = vif->wilc; + struct tcp_ack_filter *f = &vif->ack_filter; + const struct iphdr *ip_hdr_ptr; + const struct tcphdr *tcp_hdr_ptr; + u32 ihl, total_length, data_offset; spin_lock_irqsave(&wilc->txq_spinlock, flags); - if (eth_hdr_ptr->h_proto == htons(ETH_P_IP)) { - const struct iphdr *ip_hdr_ptr = buffer + ETH_HLEN; + if (eth_hdr_ptr->h_proto != htons(ETH_P_IP)) + goto out; - if (ip_hdr_ptr->protocol == IPPROTO_TCP) { - const struct tcphdr *tcp_hdr_ptr; - u32 IHL, total_length, data_offset; + ip_hdr_ptr = buffer + ETH_HLEN; - IHL = ip_hdr_ptr->ihl << 2; - tcp_hdr_ptr = buffer + ETH_HLEN + IHL; - total_length = ntohs(ip_hdr_ptr->tot_len); + if (ip_hdr_ptr->protocol != IPPROTO_TCP) + goto out; - data_offset = tcp_hdr_ptr->doff << 2; - if (total_length == (IHL + data_offset)) { - u32 seq_no, ack_no; + ihl = ip_hdr_ptr->ihl << 2; + tcp_hdr_ptr = buffer + ETH_HLEN + ihl; + total_length = ntohs(ip_hdr_ptr->tot_len); - seq_no = ntohl(tcp_hdr_ptr->seq); - ack_no = ntohl(tcp_hdr_ptr->ack_seq); - for (i = 0; i < tcp_session; i++) { - u32 j = ack_session_info[i].seq_num; + data_offset = tcp_hdr_ptr->doff << 2; + if (total_length == (ihl + data_offset)) { + u32 seq_no, ack_no; - if (i < 2 * MAX_TCP_SESSION && - j == seq_no) { - update_tcp_session(i, ack_no); - break; - } - } - if (i == tcp_session) - add_tcp_session(0, 0, seq_no); + seq_no = ntohl(tcp_hdr_ptr->seq); + ack_no = ntohl(tcp_hdr_ptr->ack_seq); + for (i = 0; i < f->tcp_session; i++) { + u32 j = f->ack_session_info[i].seq_num; - add_tcp_pending_ack(ack_no, i, tqe); + if (i < 2 * MAX_TCP_SESSION && + j == seq_no) { + update_tcp_session(vif, i, ack_no); + break; } } + if (i == f->tcp_session) + add_tcp_session(vif, 0, 0, seq_no); + + add_tcp_pending_ack(vif, ack_no, i, tqe); } + +out: spin_unlock_irqrestore(&wilc->txq_spinlock, flags); } -static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) +static void wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) { struct wilc_vif *vif = netdev_priv(dev); struct wilc *wilc = vif->wilc; + struct tcp_ack_filter *f = &vif->ack_filter; u32 i = 0; u32 dropped = 0; unsigned long flags; spin_lock_irqsave(&wilc->txq_spinlock, flags); - for (i = pending_base; i < (pending_base + pending_acks); i++) { - u32 session_index; + for (i = f->pending_base; + i < (f->pending_base + f->pending_acks_idx); i++) { + u32 index; u32 bigger_ack_num; if (i >= MAX_PENDING_ACKS) break; - session_index = pending_acks_info[i].session_index; + index = f->pending_acks[i].session_index; - if (session_index >= 2 * MAX_TCP_SESSION) + if (index >= 2 * MAX_TCP_SESSION) break; - bigger_ack_num = ack_session_info[session_index].bigger_ack_num; + bigger_ack_num = f->ack_session_info[index].bigger_ack_num; - if (pending_acks_info[i].ack_num < bigger_ack_num) { + if (f->pending_acks[i].ack_num < bigger_ack_num) { struct txq_entry_t *tqe; - tqe = pending_acks_info[i].txqe; + tqe = f->pending_acks[i].txqe; if (tqe) { wilc_wlan_txq_remove(wilc, tqe); tqe->status = 1; @@ -239,13 +222,13 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) } } } - pending_acks = 0; - tcp_session = 0; + f->pending_acks_idx = 0; + f->tcp_session = 0; - if (pending_base == 0) - pending_base = MAX_TCP_SESSION; + if (f->pending_base == 0) + f->pending_base = MAX_TCP_SESSION; else - pending_base = 0; + f->pending_base = 0; spin_unlock_irqrestore(&wilc->txq_spinlock, flags); @@ -254,15 +237,11 @@ static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev) msecs_to_jiffies(1)); dropped--; } - - return 1; } -static bool enabled; - -void wilc_enable_tcp_ack_filter(bool value) +void wilc_enable_tcp_ack_filter(struct wilc_vif *vif, bool value) { - enabled = value; + vif->ack_filter.enabled = value; } static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, u8 *buffer, @@ -287,12 +266,9 @@ static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, u8 *buffer, tqe->buffer_size = buffer_size; tqe->tx_complete_func = NULL; tqe->priv = NULL; - tqe->tcp_pending_ack_idx = NOT_TCP_ACK; + tqe->ack_idx = NOT_TCP_ACK; - if (wilc_wlan_txq_add_to_head(vif, tqe)) { - kfree(tqe); - return 0; - } + wilc_wlan_txq_add_to_head(vif, tqe); return 1; } @@ -319,8 +295,8 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer, tqe->tx_complete_func = func; tqe->priv = priv; - tqe->tcp_pending_ack_idx = NOT_TCP_ACK; - if (enabled) + tqe->ack_idx = NOT_TCP_ACK; + if (vif->ack_filter.enabled) tcp_process(dev, tqe); wilc_wlan_txq_add_to_tail(dev, tqe); return wilc->txq_entries; @@ -347,7 +323,7 @@ int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, tqe->buffer_size = buffer_size; tqe->tx_complete_func = func; tqe->priv = priv; - tqe->tcp_pending_ack_idx = NOT_TCP_ACK; + tqe->ack_idx = NOT_TCP_ACK; wilc_wlan_txq_add_to_tail(dev, tqe); return 1; } @@ -436,7 +412,7 @@ void chip_wakeup(struct wilc *wilc) } while (wilc_get_chipid(wilc, true) == 0); } else if ((wilc->io_type & 0x1) == HIF_SDIO) { wilc->hif_func->hif_write_reg(wilc, 0xfa, 1); - udelay(200); + usleep_range(200, 400); wilc->hif_func->hif_read_reg(wilc, 0xf0, ®); do { wilc->hif_func->hif_write_reg(wilc, 0xf0, @@ -457,7 +433,7 @@ void chip_wakeup(struct wilc *wilc) } while ((clk_status_reg & 0x1) == 0); } - if (chip_ps_state == CHIP_SLEEPING_MANUAL) { + if (wilc->chip_ps_state == CHIP_SLEEPING_MANUAL) { if (wilc_get_chipid(wilc, false) < 0x1002b0) { u32 val32; @@ -470,20 +446,20 @@ void chip_wakeup(struct wilc *wilc) wilc->hif_func->hif_write_reg(wilc, 0x1e9c, val32); } } - chip_ps_state = CHIP_WAKEDUP; + wilc->chip_ps_state = CHIP_WAKEDUP; } EXPORT_SYMBOL_GPL(chip_wakeup); void wilc_chip_sleep_manually(struct wilc *wilc) { - if (chip_ps_state != CHIP_WAKEDUP) + if (wilc->chip_ps_state != CHIP_WAKEDUP) return; acquire_bus(wilc, ACQUIRE_ONLY); chip_allow_sleep(wilc); wilc->hif_func->hif_write_reg(wilc, 0x10a8, 1); - chip_ps_state = CHIP_SLEEPING_MANUAL; + wilc->chip_ps_state = CHIP_SLEEPING_MANUAL; release_bus(wilc, RELEASE_ONLY); } EXPORT_SYMBOL_GPL(wilc_chip_sleep_manually); @@ -685,9 +661,9 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) tqe->status = 1; if (tqe->tx_complete_func) tqe->tx_complete_func(tqe->priv, tqe->status); - if (tqe->tcp_pending_ack_idx != NOT_TCP_ACK && - tqe->tcp_pending_ack_idx < MAX_PENDING_ACKS) - pending_acks_info[tqe->tcp_pending_ack_idx].txqe = NULL; + if (tqe->ack_idx != NOT_TCP_ACK && + tqe->ack_idx < MAX_PENDING_ACKS) + vif->ack_filter.pending_acks[tqe->ack_idx].txqe = NULL; kfree(tqe); } while (--entries); @@ -1218,9 +1194,9 @@ int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit, return ret_size; } -int wilc_wlan_cfg_get_val(u16 wid, u8 *buffer, u32 buffer_size) +int wilc_wlan_cfg_get_val(struct wilc *wl, u16 wid, u8 *buffer, u32 buffer_size) { - return wilc_wlan_cfg_get_wid_value(wid, buffer, buffer_size); + return wilc_wlan_cfg_get_wid_value(wl, wid, buffer, buffer_size); } int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids, @@ -1240,7 +1216,8 @@ int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids, } } for (i = 0; i < count; i++) { - wids[i].size = wilc_wlan_cfg_get_val(wids[i].id, + wids[i].size = wilc_wlan_cfg_get_val(vif->wilc, + wids[i].id, wids[i].val, wids[i].size); } @@ -1339,11 +1316,6 @@ int wilc_wlan_init(struct net_device *dev) goto fail; } - if (!wilc_wlan_cfg_init()) { - ret = -ENOBUFS; - goto fail; - } - if (!wilc->tx_buffer) wilc->tx_buffer = kmalloc(LINUX_TX_SIZE, GFP_KERNEL); diff --git a/drivers/staging/wilc1000/wilc_wlan.h b/drivers/staging/wilc1000/wilc_wlan.h index 7467188dbf2f..27667131de1a 100644 --- a/drivers/staging/wilc1000/wilc_wlan.h +++ b/drivers/staging/wilc1000/wilc_wlan.h @@ -212,7 +212,7 @@ struct txq_entry_t { struct list_head list; int type; - int tcp_pending_ack_idx; + int ack_idx; u8 *buffer; int buffer_size; void *priv; @@ -277,19 +277,19 @@ int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer, u32 buffer_size, int commit, u32 drv_handler); int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit, u32 drv_handler); -int wilc_wlan_cfg_get_val(u16 wid, u8 *buffer, u32 buffer_size); +int wilc_wlan_cfg_get_val(struct wilc *wl, u16 wid, u8 *buffer, + u32 buffer_size); int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, u32 buffer_size, wilc_tx_complete_func_t func); void wilc_chip_sleep_manually(struct wilc *wilc); -void wilc_enable_tcp_ack_filter(bool value); +void wilc_enable_tcp_ack_filter(struct wilc_vif *vif, bool value); int wilc_wlan_get_num_conn_ifcs(struct wilc *wilc); 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 host_wakeup_notify(struct wilc *wilc); void host_sleep_notify(struct wilc *wilc); -extern bool wilc_enable_ps; void chip_allow_sleep(struct wilc *wilc); void chip_wakeup(struct wilc *wilc); int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids, diff --git a/drivers/staging/wilc1000/wilc_wlan_cfg.c b/drivers/staging/wilc1000/wilc_wlan_cfg.c index 421576386ab4..faa001c75681 100644 --- a/drivers/staging/wilc1000/wilc_wlan_cfg.c +++ b/drivers/staging/wilc1000/wilc_wlan_cfg.c @@ -8,6 +8,7 @@ #include "wilc_wlan.h" #include "wilc_wlan_cfg.h" #include "coreconfigurator.h" +#include "wilc_wfi_netdevice.h" enum cfg_cmd_type { CFG_BYTE_CMD = 0, @@ -17,134 +18,30 @@ enum cfg_cmd_type { CFG_BIN_CMD = 4 }; -struct wilc_mac_cfg { - int mac_status; - u8 mac_address[7]; - u8 ip_address[5]; - u8 bssid[7]; - u8 ssid[34]; - u8 firmware_version[129]; - u8 supp_rate[24]; - u8 wep_key[28]; - u8 i_psk[66]; - u8 hw_product_version[33]; - u8 phyversion[17]; - u8 supp_username[21]; - u8 supp_password[64]; - u8 assoc_req[256]; - u8 assoc_rsp[256]; - u8 firmware_info[8]; - u8 scan_result[256]; - u8 scan_result1[256]; -}; - -static struct wilc_mac_cfg g_mac; - -static struct wilc_cfg_byte g_cfg_byte[] = { - {WID_BSS_TYPE, 0}, - {WID_CURRENT_TX_RATE, 0}, - {WID_CURRENT_CHANNEL, 0}, - {WID_PREAMBLE, 0}, - {WID_11G_OPERATING_MODE, 0}, +static const struct wilc_cfg_byte g_cfg_byte[] = { {WID_STATUS, 0}, - {WID_SCAN_TYPE, 0}, - {WID_KEY_ID, 0}, - {WID_QOS_ENABLE, 0}, - {WID_POWER_MANAGEMENT, 0}, - {WID_11I_MODE, 0}, - {WID_AUTH_TYPE, 0}, - {WID_SITE_SURVEY, 0}, - {WID_LISTEN_INTERVAL, 0}, - {WID_DTIM_PERIOD, 0}, - {WID_ACK_POLICY, 0}, - {WID_BCAST_SSID, 0}, - {WID_REKEY_POLICY, 0}, - {WID_SHORT_SLOT_ALLOWED, 0}, - {WID_START_SCAN_REQ, 0}, {WID_RSSI, 0}, {WID_LINKSPEED, 0}, - {WID_AUTO_RX_SENSITIVITY, 0}, - {WID_DATAFLOW_CONTROL, 0}, - {WID_SCAN_FILTER, 0}, - {WID_11N_PROT_MECH, 0}, - {WID_11N_ERP_PROT_TYPE, 0}, - {WID_11N_ENABLE, 0}, - {WID_11N_OPERATING_MODE, 0}, - {WID_11N_OBSS_NONHT_DETECTION, 0}, - {WID_11N_HT_PROT_TYPE, 0}, - {WID_11N_RIFS_PROT_ENABLE, 0}, - {WID_11N_SMPS_MODE, 0}, - {WID_11N_CURRENT_TX_MCS, 0}, - {WID_11N_SHORT_GI_ENABLE, 0}, - {WID_RIFS_MODE, 0}, - {WID_TX_ABORT_CONFIG, 0}, - {WID_11N_IMMEDIATE_BA_ENABLED, 0}, - {WID_11N_TXOP_PROT_DISABLE, 0}, {WID_NIL, 0} }; -static struct wilc_cfg_hword g_cfg_hword[] = { - {WID_LINK_LOSS_THRESHOLD, 0}, - {WID_RTS_THRESHOLD, 0}, - {WID_FRAG_THRESHOLD, 0}, - {WID_SHORT_RETRY_LIMIT, 0}, - {WID_LONG_RETRY_LIMIT, 0}, - {WID_BEACON_INTERVAL, 0}, - {WID_RX_SENSE, 0}, - {WID_ACTIVE_SCAN_TIME, 0}, - {WID_PASSIVE_SCAN_TIME, 0}, - {WID_SITE_SURVEY_SCAN_TIME, 0}, - {WID_JOIN_START_TIMEOUT, 0}, - {WID_AUTH_TIMEOUT, 0}, - {WID_ASOC_TIMEOUT, 0}, - {WID_11I_PROTOCOL_TIMEOUT, 0}, - {WID_EAPOL_RESPONSE_TIMEOUT, 0}, - {WID_11N_SIG_QUAL_VAL, 0}, - {WID_CCA_THRESHOLD, 0}, +static const struct wilc_cfg_hword g_cfg_hword[] = { {WID_NIL, 0} }; -static struct wilc_cfg_word g_cfg_word[] = { +static const struct wilc_cfg_word g_cfg_word[] = { {WID_FAILED_COUNT, 0}, - {WID_RETRY_COUNT, 0}, - {WID_MULTIPLE_RETRY_COUNT, 0}, - {WID_FRAME_DUPLICATE_COUNT, 0}, - {WID_ACK_FAILURE_COUNT, 0}, {WID_RECEIVED_FRAGMENT_COUNT, 0}, - {WID_MCAST_RECEIVED_FRAME_COUNT, 0}, - {WID_FCS_ERROR_COUNT, 0}, {WID_SUCCESS_FRAME_COUNT, 0}, - {WID_TX_FRAGMENT_COUNT, 0}, - {WID_TX_MULTICAST_FRAME_COUNT, 0}, - {WID_RTS_SUCCESS_COUNT, 0}, - {WID_RTS_FAILURE_COUNT, 0}, - {WID_WEP_UNDECRYPTABLE_COUNT, 0}, - {WID_REKEY_PERIOD, 0}, - {WID_REKEY_PACKET_COUNT, 0}, - {WID_HW_RX_COUNT, 0}, {WID_GET_INACTIVE_TIME, 0}, {WID_NIL, 0} }; -static struct wilc_cfg_str g_cfg_str[] = { - {WID_SSID, g_mac.ssid}, /* 33 + 1 bytes */ - {WID_FIRMWARE_VERSION, g_mac.firmware_version}, - {WID_OPERATIONAL_RATE_SET, g_mac.supp_rate}, - {WID_BSSID, g_mac.bssid}, /* 6 bytes */ - {WID_WEP_KEY_VALUE, g_mac.wep_key}, /* 27 bytes */ - {WID_11I_PSK, g_mac.i_psk}, /* 65 bytes */ - {WID_HARDWARE_VERSION, g_mac.hw_product_version}, - {WID_MAC_ADDR, g_mac.mac_address}, - {WID_PHY_VERSION, g_mac.phyversion}, - {WID_SUPP_USERNAME, g_mac.supp_username}, - {WID_SUPP_PASSWORD, g_mac.supp_password}, - {WID_SITE_SURVEY_RESULTS, g_mac.scan_result}, - {WID_SITE_SURVEY_RESULTS, g_mac.scan_result1}, - {WID_ASSOC_REQ_INFO, g_mac.assoc_req}, - {WID_ASSOC_RES_INFO, g_mac.assoc_rsp}, - {WID_FIRMWARE_INFO, g_mac.firmware_version}, - {WID_IP_ADDRESS, g_mac.ip_address}, +static const struct wilc_cfg_str g_cfg_str[] = { + {WID_FIRMWARE_VERSION, NULL}, + {WID_MAC_ADDR, NULL}, + {WID_ASSOC_RES_INFO, NULL}, {WID_NIL, NULL} }; @@ -265,7 +162,7 @@ static int wilc_wlan_cfg_set_bin(u8 *frame, u32 offset, u16 id, u8 *b, u32 size) ********************************************/ #define GET_WID_TYPE(wid) (((wid) >> 12) & 0x7) -static void wilc_wlan_parse_response_frame(u8 *info, int size) +static void wilc_wlan_parse_response_frame(struct wilc *wl, u8 *info, int size) { u16 wid; u32 len = 0, i = 0; @@ -277,11 +174,11 @@ static void wilc_wlan_parse_response_frame(u8 *info, int size) switch (GET_WID_TYPE(wid)) { case WID_CHAR: do { - if (g_cfg_byte[i].id == WID_NIL) + if (wl->cfg.b[i].id == WID_NIL) break; - if (g_cfg_byte[i].id == wid) { - g_cfg_byte[i].val = info[4]; + if (wl->cfg.b[i].id == wid) { + wl->cfg.b[i].val = info[4]; break; } i++; @@ -291,12 +188,12 @@ static void wilc_wlan_parse_response_frame(u8 *info, int size) case WID_SHORT: do { - if (g_cfg_hword[i].id == WID_NIL) + if (wl->cfg.hw[i].id == WID_NIL) break; - if (g_cfg_hword[i].id == wid) { - g_cfg_hword[i].val = (info[4] | - (info[5] << 8)); + if (wl->cfg.hw[i].id == wid) { + wl->cfg.hw[i].val = (info[4] | + (info[5] << 8)); break; } i++; @@ -306,14 +203,14 @@ static void wilc_wlan_parse_response_frame(u8 *info, int size) case WID_INT: do { - if (g_cfg_word[i].id == WID_NIL) + if (wl->cfg.w[i].id == WID_NIL) break; - if (g_cfg_word[i].id == wid) { - g_cfg_word[i].val = (info[4] | - (info[5] << 8) | - (info[6] << 16) | - (info[7] << 24)); + if (wl->cfg.w[i].id == wid) { + wl->cfg.w[i].val = (info[4] | + (info[5] << 8) | + (info[6] << 16) | + (info[7] << 24)); break; } i++; @@ -323,17 +220,11 @@ static void wilc_wlan_parse_response_frame(u8 *info, int size) case WID_STR: do { - if (g_cfg_str[i].id == WID_NIL) + if (wl->cfg.s[i].id == WID_NIL) break; - if (g_cfg_str[i].id == wid) { - if (wid == WID_SITE_SURVEY_RESULTS) { - static int toggle; - - i += toggle; - toggle ^= 1; - } - memcpy(g_cfg_str[i].str, &info[2], + if (wl->cfg.s[i].id == wid) { + memcpy(wl->cfg.s[i].str, &info[2], (info[2] + 2)); break; } @@ -350,22 +241,28 @@ static void wilc_wlan_parse_response_frame(u8 *info, int size) } } -static int wilc_wlan_parse_info_frame(u8 *info, int size) +static void wilc_wlan_parse_info_frame(struct wilc *wl, u8 *info) { - struct wilc_mac_cfg *pd = &g_mac; u32 wid, len; - int type = WILC_CFG_RSP_STATUS; wid = info[0] | (info[1] << 8); len = info[2]; if (len == 1 && wid == WID_STATUS) { - pd->mac_status = info[3]; - type = WILC_CFG_RSP_STATUS; - } + int i = 0; - return type; + do { + if (wl->cfg.b[i].id == WID_NIL) + break; + + if (wl->cfg.b[i].id == wid) { + wl->cfg.b[i].val = info[3]; + break; + } + i++; + } while (1); + } } /******************************************** @@ -424,24 +321,20 @@ int wilc_wlan_cfg_get_wid(u8 *frame, u32 offset, u16 id) return 2; } -int wilc_wlan_cfg_get_wid_value(u16 wid, u8 *buffer, u32 buffer_size) +int wilc_wlan_cfg_get_wid_value(struct wilc *wl, u16 wid, u8 *buffer, + u32 buffer_size) { u32 type = (wid >> 12) & 0xf; int i, ret = 0; - if (wid == WID_STATUS) { - *((u32 *)buffer) = g_mac.mac_status; - return 4; - } - i = 0; if (type == CFG_BYTE_CMD) { do { - if (g_cfg_byte[i].id == WID_NIL) + if (wl->cfg.b[i].id == WID_NIL) break; - if (g_cfg_byte[i].id == wid) { - memcpy(buffer, &g_cfg_byte[i].val, 1); + if (wl->cfg.b[i].id == wid) { + memcpy(buffer, &wl->cfg.b[i].val, 1); ret = 1; break; } @@ -449,11 +342,11 @@ int wilc_wlan_cfg_get_wid_value(u16 wid, u8 *buffer, u32 buffer_size) } while (1); } else if (type == CFG_HWORD_CMD) { do { - if (g_cfg_hword[i].id == WID_NIL) + if (wl->cfg.hw[i].id == WID_NIL) break; - if (g_cfg_hword[i].id == wid) { - memcpy(buffer, &g_cfg_hword[i].val, 2); + if (wl->cfg.hw[i].id == wid) { + memcpy(buffer, &wl->cfg.hw[i].val, 2); ret = 2; break; } @@ -461,11 +354,11 @@ int wilc_wlan_cfg_get_wid_value(u16 wid, u8 *buffer, u32 buffer_size) } while (1); } else if (type == CFG_WORD_CMD) { do { - if (g_cfg_word[i].id == WID_NIL) + if (wl->cfg.w[i].id == WID_NIL) break; - if (g_cfg_word[i].id == wid) { - memcpy(buffer, &g_cfg_word[i].val, 4); + if (wl->cfg.w[i].id == wid) { + memcpy(buffer, &wl->cfg.w[i].val, 4); ret = 4; break; } @@ -473,23 +366,17 @@ int wilc_wlan_cfg_get_wid_value(u16 wid, u8 *buffer, u32 buffer_size) } while (1); } else if (type == CFG_STR_CMD) { do { - u32 id = g_cfg_str[i].id; + u32 id = wl->cfg.s[i].id; if (id == WID_NIL) break; if (id == wid) { - u32 size = g_cfg_str[i].str[0] | - (g_cfg_str[i].str[1] << 8); + u32 size = (wl->cfg.s[i].str[0] | + (wl->cfg.s[i].str[1] << 8)); if (buffer_size >= size) { - if (id == WID_SITE_SURVEY_RESULTS) { - static int toggle; - - i += toggle; - toggle ^= 1; - } - memcpy(buffer, &g_cfg_str[i].str[2], + memcpy(buffer, &wl->cfg.s[i].str[2], size); ret = size; } @@ -498,14 +385,12 @@ int wilc_wlan_cfg_get_wid_value(u16 wid, u8 *buffer, u32 buffer_size) i++; } while (1); } - return ret; } -int wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size, - struct wilc_cfg_rsp *rsp) +void wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size, + struct wilc_cfg_rsp *rsp) { - int ret = 1; u8 msg_type; u8 msg_id; @@ -513,6 +398,7 @@ int wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size, msg_id = frame[1]; /* seq no */ frame += 4; size -= 4; + rsp->type = 0; /* * The valid types of response messages are @@ -523,13 +409,14 @@ int wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size, switch (msg_type) { case 'R': - wilc_wlan_parse_response_frame(frame, size); + wilc_wlan_parse_response_frame(wilc, frame, size); rsp->type = WILC_CFG_RSP; rsp->seq_no = msg_id; break; case 'I': - rsp->type = wilc_wlan_parse_info_frame(frame, size); + wilc_wlan_parse_info_frame(wilc, frame); + rsp->type = WILC_CFG_RSP_STATUS; rsp->seq_no = msg_id; /*call host interface info parse as well*/ wilc_gnrl_async_info_received(wilc, frame - 4, size + 4); @@ -537,7 +424,6 @@ int wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size, case 'N': wilc_network_info_received(wilc, frame - 4, size + 4); - rsp->type = 0; break; case 'S': @@ -545,17 +431,67 @@ int wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size, break; default: - rsp->type = 0; rsp->seq_no = msg_id; - ret = 0; break; } +} - return ret; +int wilc_wlan_cfg_init(struct wilc *wl) +{ + struct wilc_cfg_str_vals *str_vals; + int i = 0; + + wl->cfg.b = kmemdup(g_cfg_byte, sizeof(g_cfg_byte), GFP_KERNEL); + if (!wl->cfg.b) + return -ENOMEM; + + wl->cfg.hw = kmemdup(g_cfg_hword, sizeof(g_cfg_hword), GFP_KERNEL); + if (!wl->cfg.hw) + goto out_b; + + wl->cfg.w = kmemdup(g_cfg_word, sizeof(g_cfg_word), GFP_KERNEL); + if (!wl->cfg.w) + goto out_hw; + + wl->cfg.s = kmemdup(g_cfg_str, sizeof(g_cfg_str), GFP_KERNEL); + if (!wl->cfg.s) + goto out_w; + + str_vals = kzalloc(sizeof(*str_vals), GFP_KERNEL); + if (!str_vals) + goto out_s; + + wl->cfg.str_vals = str_vals; + /* store the string cfg parameters */ + wl->cfg.s[i].id = WID_FIRMWARE_VERSION; + wl->cfg.s[i].str = str_vals->firmware_version; + i++; + wl->cfg.s[i].id = WID_MAC_ADDR; + wl->cfg.s[i].str = str_vals->mac_address; + i++; + wl->cfg.s[i].id = WID_ASSOC_RES_INFO; + wl->cfg.s[i].str = str_vals->assoc_rsp; + i++; + wl->cfg.s[i].id = WID_NIL; + wl->cfg.s[i].str = NULL; + return 0; + +out_s: + kfree(wl->cfg.s); +out_w: + kfree(wl->cfg.w); +out_hw: + kfree(wl->cfg.hw); +out_b: + kfree(wl->cfg.b); + return -ENOMEM; } -int wilc_wlan_cfg_init(void) +void wilc_wlan_cfg_deinit(struct wilc *wl) { - memset((void *)&g_mac, 0, sizeof(struct wilc_mac_cfg)); - return 1; + kfree(wl->cfg.b); + kfree(wl->cfg.hw); + kfree(wl->cfg.w); + kfree(wl->cfg.s); + kfree(wl->cfg.str_vals); } diff --git a/drivers/staging/wilc1000/wilc_wlan_cfg.h b/drivers/staging/wilc1000/wilc_wlan_cfg.h index 0c649d1f6f11..e5ca6cea0682 100644 --- a/drivers/staging/wilc1000/wilc_wlan_cfg.h +++ b/drivers/staging/wilc1000/wilc_wlan_cfg.h @@ -9,7 +9,7 @@ struct wilc_cfg_byte { u16 id; - u16 val; + u8 val; }; struct wilc_cfg_hword { @@ -27,12 +27,28 @@ struct wilc_cfg_str { u8 *str; }; +struct wilc_cfg_str_vals { + u8 mac_address[7]; + u8 firmware_version[129]; + u8 assoc_rsp[256]; +}; + +struct wilc_cfg { + struct wilc_cfg_byte *b; + struct wilc_cfg_hword *hw; + struct wilc_cfg_word *w; + struct wilc_cfg_str *s; + struct wilc_cfg_str_vals *str_vals; +}; + struct wilc; int wilc_wlan_cfg_set_wid(u8 *frame, u32 offset, u16 id, u8 *buf, int size); int wilc_wlan_cfg_get_wid(u8 *frame, u32 offset, u16 id); -int wilc_wlan_cfg_get_wid_value(u16 wid, u8 *buffer, u32 buffer_size); -int wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size, - struct wilc_cfg_rsp *rsp); -int wilc_wlan_cfg_init(void); +int wilc_wlan_cfg_get_wid_value(struct wilc *wl, u16 wid, u8 *buffer, + u32 buffer_size); +void wilc_wlan_cfg_indicate_rx(struct wilc *wilc, u8 *frame, int size, + struct wilc_cfg_rsp *rsp); +int wilc_wlan_cfg_init(struct wilc *wl); +void wilc_wlan_cfg_deinit(struct wilc *wl); #endif diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h index b81a73b9bd67..ce2066b74287 100644 --- a/drivers/staging/wilc1000/wilc_wlan_if.h +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -204,10 +204,6 @@ enum wid_type { WID_STR = 3, WID_BIN_DATA = 4, WID_BIN = 5, - WID_IP = 6, - WID_ADR = 7, - WID_UNDEF = 8, - WID_TYPE_FORCE_32BIT = 0xFFFFFFFF }; struct wid { |