| /***************************************************************************** |
| * |
| * Copyright (c) 2012 - 2021 Samsung Electronics Co., Ltd. All rights reserved |
| * |
| ****************************************************************************/ |
| |
| #ifndef __SLSI_DEVICE_H__ |
| #define __SLSI_DEVICE_H__ |
| |
| #include <linux/init.h> |
| #include <linux/device.h> |
| #include <linux/inetdevice.h> |
| #include <net/addrconf.h> |
| |
| #include <linux/version.h> |
| #include <linux/module.h> |
| #include <linux/string.h> |
| #include <linux/kernel.h> |
| #include <linux/netdevice.h> |
| #include <linux/etherdevice.h> |
| #include <linux/ratelimit.h> |
| #include <linux/ip.h> |
| |
| #include <linux/completion.h> |
| #include <linux/workqueue.h> |
| #include <linux/time.h> |
| #include <linux/sched.h> |
| |
| #include <linux/nl80211.h> |
| #include <linux/wireless.h> |
| #include <linux/proc_fs.h> |
| #include <linux/ieee80211.h> |
| #include <net/cfg80211.h> |
| #include <linux/nl80211.h> |
| |
| #include <scsc/scsc_mx.h> |
| |
| #include "fapi.h" |
| #include "const.h" |
| #include "utils.h" |
| #include "hip.h" |
| #include "log_clients.h" |
| #include "src_sink.h" |
| |
| #include "scsc_wifi_fcq.h" |
| |
| #include "scsc_wifi_cm_if.h" |
| #include "hip4.h" |
| |
| #include "nl80211_vendor.h" |
| #define FAPI_MAJOR_VERSION(v) (((v) >> 8) & 0xFF) |
| #define FAPI_MINOR_VERSION(v) ((v) & 0xFF) |
| |
| |
| /* Modes for CMDGETBSSINFO and CMDGETSTAINFO */ |
| #define SLSI_80211_MODE_11B 0 |
| #define SLSI_80211_MODE_11G 1 |
| #define SLSI_80211_MODE_11N 2 |
| #define SLSI_80211_MODE_11A 3 |
| #define SLSI_80211_MODE_11AC 4 |
| |
| #define SLSI_FW_API_RATE_HT_SELECTOR_FIELD 0xc000 |
| #define SLSI_FW_API_RATE_NON_HT_SELECTED 0x4000 |
| #define SLSI_FW_API_RATE_HT_SELECTED 0x8000 |
| #define SLSI_FW_API_RATE_VHT_SELECTED 0xc000 |
| |
| #define SLSI_FW_API_RATE_VHT_MCS_FIELD 0x000F |
| #define SLSI_FW_API_RATE_HT_MCS_FIELD 0x003F |
| #define SLSI_FW_API_RATE_INDEX_FIELD 0x1fff |
| #define SLSI_FW_API_RATE_VHT_NSS_FIELD 0x0070 |
| #define SLSI_FW_API_RATE_HT_NSS_FIELD 0x0040 |
| |
| #define SLSI_FW_API_RATE_BW_FIELD 0x0600 |
| #define SLSI_FW_API_RATE_BW_40MHZ 0x0200 |
| #define SLSI_FW_API_RATE_BW_20MHZ 0x0000 |
| |
| #define SLSI_FW_API_RATE_SGI 0x0100 |
| #define SLSI_FW_API_RATE_GF 0x0080 |
| |
| #define SLSI_HOSTSTATE_LCD_ACTIVE 0x0001 |
| #define SLSI_HOSTSTATE_CELLULAR_ACTIVE 0x0002 |
| #define SLSI_HOSTSTATE_SAR_ACTIVE 0x0004 |
| #define SLSI_HOSTSTATE_GRIP_ACTIVE 0x0040 |
| #define SLSI_HOSTSTATE_LOW_LATENCY_ACTIVE 0x0080 |
| |
| #ifdef CONFIG_SCSC_WLAN_STA_ENHANCED_ARP_DETECT |
| #define SLSI_MAX_ARP_SEND_FRAME 8 |
| #endif |
| |
| /* indices: 3= BW20->idx_0, BW40->idx_1, BW80->idx_2. |
| * 2= noSGI->idx_0, SGI->idx_1 |
| * 10= mcs index |
| * rate units 100kbps |
| * This table for single stream Nss=1and does not include 160MHz BW and 80+80MHz BW. |
| */ |
| static const u16 slsi_rates_table[3][2][10] = { |
| { /* BW20 */ |
| { /* no SGI */ |
| 65, 130, 195, 260, 390, 520, 585, 650, 780, 0 |
| }, |
| { /* SGI */ |
| 72, 144, 217, 289, 433, 578, 650, 722, 867, 0 |
| } |
| }, |
| { /* BW40 */ |
| { /* no SGI */ |
| 135, 270, 405, 540, 810, 1080, 1215, 1350, 1620, 1800 |
| }, |
| { /* SGI */ |
| 150, 300, 450, 600, 900, 1200, 1350, 1500, 1800, 2000 |
| } |
| }, |
| { /* BW80 */ |
| { /* no SGI */ |
| 293, 585, 878, 1170, 1755, 2340, 2633, 2925, 3510, 3900 |
| }, |
| { /* SGI */ |
| 325, 650, 975, 1300, 1950, 2600, 2925, 3250, 3900, 4333 |
| } |
| } |
| }; |
| |
| #define SLSI_TX_PROCESS_ID_MIN (0xC001) |
| #define SLSI_TX_PROCESS_ID_MAX (0xCF00) |
| #define SLSI_TX_PROCESS_ID_UDI_MIN (0xCF01) |
| #define SLSI_TX_PROCESS_ID_UDI_MAX (0xCFFE) |
| |
| /* There are no wakelocks in kernel/supplicant/hostapd. |
| * So keep the platform active for some time after receiving any data packet. |
| * This timeout value can be fine-tuned based on the test results. |
| */ |
| #define SLSI_RX_WAKELOCK_TIME (1000) |
| #define MAX_BA_BUFFER_SIZE 64 |
| #define NUM_BA_SESSIONS_PER_PEER 8 |
| #define SLSI_NCHO_MAX_CHANNEL_LIST 20 |
| #define SLSI_MAX_RX_BA_SESSIONS (8) |
| #define SLSI_STA_ACTION_FRAME_BITMAP (SLSI_ACTION_FRAME_PUBLIC | SLSI_ACTION_FRAME_WMM | SLSI_ACTION_FRAME_WNM |\ |
| SLSI_ACTION_FRAME_QOS | SLSI_ACTION_FRAME_PROTECTED_DUAL |\ |
| SLSI_ACTION_FRAME_RADIO_MEASUREMENT) |
| #define SLSI_STA_ACTION_FRAME_SUSPEND_BITMAP (SLSI_ACTION_FRAME_PUBLIC | SLSI_ACTION_FRAME_WMM | SLSI_ACTION_FRAME_WNM |\ |
| SLSI_ACTION_FRAME_QOS | SLSI_ACTION_FRAME_PROTECTED_DUAL) |
| |
| /* Default value for MIB SLSI_PSID_UNIFI_DISCONNECT_TIMEOUT + 1 sec*/ |
| #define SLSI_DEFAULT_AP_DISCONNECT_IND_TIMEOUT 3000 |
| |
| #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)) |
| #define WLAN_EID_VHT_CAPABILITY 191 |
| #define WLAN_EID_VHT_OPERATION 192 |
| #endif |
| |
| #define NUM_COUNTRY (300) |
| |
| #ifdef CONFIG_SCSC_WLAN_MUTEX_DEBUG |
| #define SLSI_MUTEX_INIT(slsi_mutex__) \ |
| { \ |
| (slsi_mutex__).owner = NULL; \ |
| mutex_init(&(slsi_mutex__).mutex); \ |
| (slsi_mutex__).valid = true; \ |
| } |
| |
| #define SLSI_MUTEX_LOCK(slsi_mutex_to_lock) \ |
| { \ |
| (slsi_mutex_to_lock).line_no_before = __LINE__; \ |
| (slsi_mutex_to_lock).file_name_before = __FILE__; \ |
| mutex_lock(&(slsi_mutex_to_lock).mutex); \ |
| (slsi_mutex_to_lock).owner = current; \ |
| (slsi_mutex_to_lock).line_no_after = __LINE__; \ |
| (slsi_mutex_to_lock).file_name_after = __FILE__; \ |
| (slsi_mutex_to_lock).function = __func__; \ |
| } |
| |
| #define SLSI_MUTEX_UNLOCK(slsi_mutex_to_unlock) \ |
| { \ |
| (slsi_mutex_to_unlock).owner = NULL; \ |
| mutex_unlock(&(slsi_mutex_to_unlock).mutex); \ |
| } |
| #define SLSI_MUTEX_IS_LOCKED(slsi_mutex__) mutex_is_locked(&(slsi_mutex__).mutex) |
| |
| struct slsi_mutex { |
| bool valid; |
| u32 line_no_before; |
| const u8 *file_name_before; |
| /* a std mutex */ |
| struct mutex mutex; |
| u32 line_no_after; |
| const u8 *file_name_after; |
| const u8 *function; |
| struct task_struct *owner; |
| }; |
| |
| #else |
| #define SLSI_MUTEX_INIT(mutex__) mutex_init(&(mutex__)) |
| #define SLSI_MUTEX_LOCK(mutex_to_lock) mutex_lock(&(mutex_to_lock)) |
| #define SLSI_MUTEX_UNLOCK(mutex_to_unlock) mutex_unlock(&(mutex_to_unlock)) |
| #define SLSI_MUTEX_IS_LOCKED(mutex__) mutex_is_locked(&(mutex__)) |
| #endif |
| |
| #define OS_UNUSED_PARAMETER(x) ((void)(x)) |
| |
| #define SLSI_HOST_TAG_TRAFFIC_QUEUE(htag) (htag & 0x00000003) |
| |
| /* For each mlme-req a mlme-cfm is expected to be received from the |
| * firmware. The host is not allowed to send another mlme-req until |
| * the mlme-cfm is received. |
| * |
| * However there are also instances where we need to wait for an mlme-ind |
| * following a mlme-req/cfm exchange. One example of this is the disconnect |
| * sequence: |
| * mlme-disconnect-req - host requests disconnection |
| * mlme-disconnect-cfm - firmware accepts disconnection request but hasn't |
| * disconnected yet. |
| * mlme-disconnect-ind - firmware reports final result of disconnection |
| * |
| * Assuming that waiting for the mlme-ind following on from the mlme-req/cfm |
| * is ok. |
| */ |
| struct slsi_sig_send { |
| /* a std spinlock */ |
| spinlock_t send_signal_lock; |
| #ifdef CONFIG_SCSC_WLAN_MUTEX_DEBUG |
| struct slsi_mutex mutex; |
| #else |
| /* a std mutex */ |
| struct mutex mutex; |
| #endif |
| struct completion completion; |
| |
| u16 process_id; |
| u16 req_id; |
| u16 cfm_id; |
| u16 ind_id; |
| struct sk_buff *cfm; |
| struct sk_buff *ind; |
| struct sk_buff *mib_error; |
| }; |
| |
| static inline void slsi_sig_send_init(struct slsi_sig_send *sig_send) |
| { |
| spin_lock_init(&sig_send->send_signal_lock); |
| sig_send->req_id = 0; |
| sig_send->cfm_id = 0; |
| sig_send->process_id = SLSI_TX_PROCESS_ID_MIN; |
| SLSI_MUTEX_INIT(sig_send->mutex); |
| init_completion(&sig_send->completion); |
| } |
| |
| struct slsi_ba_frame_desc { |
| bool active; |
| struct sk_buff *signal; |
| u16 sn; |
| }; |
| |
| struct slsi_ba_session_rx { |
| bool active; |
| bool used; |
| void *vif; |
| struct slsi_ba_frame_desc buffer[MAX_BA_BUFFER_SIZE]; |
| u16 buffer_size; |
| u16 occupied_slots; |
| u16 expected_sn; |
| u16 start_sn; |
| u16 highest_received_sn; |
| bool trigger_ba_after_ssn; |
| u8 tid; |
| |
| /* Aging timer parameters */ |
| bool timer_on; |
| struct timer_list ba_age_timer; |
| struct slsi_spinlock ba_lock; |
| struct net_device *dev; |
| }; |
| |
| #define SLSI_TID_MAX (16) |
| #define SLSI_AMPDU_F_INITIATED (0x0001) |
| #define SLSI_AMPDU_F_CREATED (0x0002) |
| #define SLSI_AMPDU_F_OPERATIONAL (0x0004) |
| |
| #ifdef CONFIG_SCSC_WLAN_RX_NAPI |
| struct slsi_napi { |
| struct napi_struct napi; |
| struct sk_buff_head rx_data; |
| struct slsi_spinlock lock; |
| bool interrupt_enabled; |
| }; |
| #endif |
| |
| #define SLSI_SCAN_HW_ID 0 |
| #define SLSI_SCAN_SCHED_ID 1 |
| #define SLSI_SCAN_MAX 3 |
| |
| #define SLSI_SCAN_SSID_MAP_MAX 10 /* Arbitrary value */ |
| #define SLSI_SCAN_SSID_MAP_EXPIRY_AGE 2 /* If hidden bss not found these many scan cycles, remove map. Arbitrary value*/ |
| #define SLSI_FW_SCAN_DONE_TIMEOUT_MSEC (20 * 1000) |
| |
| #ifdef CONFIG_SCSC_WLAN_BSS_SELECTION |
| enum slsi_bss_security { |
| SLSI_BSS_SECURED_NO = BIT(0), |
| SLSI_BSS_SECURED_PSK = BIT(1), |
| SLSI_BSS_SECURED_1x = BIT(2), |
| SLSI_BSS_SECURED_SAE = BIT(3) |
| }; |
| |
| struct slsi_ssid_info { |
| struct list_head list; |
| struct cfg80211_ssid ssid; |
| struct list_head bssid_list; |
| u8 akm_type; |
| }; |
| |
| struct slsi_bssid_info { |
| struct list_head list; |
| u8 bssid[ETH_ALEN]; |
| u16 freq; |
| int rssi; |
| bool connect_attempted; |
| }; |
| |
| struct slsi_bssid_blacklist_info { |
| struct list_head list; |
| u8 bssid[ETH_ALEN]; |
| int end_time; |
| }; |
| #endif |
| |
| struct slsi_scan_result { |
| u8 bssid[ETH_ALEN]; |
| u8 hidden; |
| int rssi; |
| struct sk_buff *probe_resp; |
| struct sk_buff *beacon; |
| struct slsi_scan_result *next; |
| int band; |
| u8 ssid[32]; |
| u8 ssid_length; |
| #ifdef CONFIG_SCSC_WLAN_BSS_SELECTION |
| u8 akm_type; |
| #endif |
| }; |
| |
| /* Per Interface Scan Data |
| * Access protected by: cfg80211_lock |
| */ |
| struct slsi_scan { |
| /* When a Scan is running this not NULL. */ |
| struct cfg80211_scan_request *scan_req; |
| struct slsi_acs_request *acs_request; |
| struct cfg80211_sched_scan_request *sched_req; |
| bool requeue_timeout_work; |
| |
| /* Indicates if the scan req is blocking. i.e, waiting until scan_done_ind received */ |
| bool is_blocking_scan; |
| |
| struct slsi_scan_result *scan_results; /* head for scan_results list*/ |
| }; |
| |
| struct slsi_ssid_map { |
| u8 bssid[ETH_ALEN]; |
| u8 ssid[32]; |
| u8 ssid_len; |
| u8 age; |
| int band; |
| }; |
| |
| struct slsi_ioctl_args { |
| int arg_count; |
| u8 *args[]; |
| }; |
| |
| #ifdef CONFIG_SCSC_WLAN_STA_ENHANCED_ARP_DETECT |
| struct slsi_enhanced_arp_counters { |
| u16 arp_req_count_from_netdev; |
| u16 arp_req_count_to_lower_mac; |
| u16 arp_req_rx_count_by_lower_mac; |
| u16 arp_req_count_tx_success; |
| u16 arp_rsp_rx_count_by_lower_mac; |
| u16 arp_rsp_rx_count_by_upper_mac; |
| u16 arp_rsp_count_to_netdev; |
| u16 arp_rsp_count_out_of_order_drop; |
| u16 ap_link_active; |
| bool is_duplicate_addr_detected; |
| }; |
| #endif |
| |
| struct slsi_peer { |
| /* Flag MUST be set last when creating a record and immediately when removing. |
| * Otherwise another process could test the flag and start using the data. |
| */ |
| bool valid; |
| u8 address[ETH_ALEN]; |
| |
| /* Presently connected_state is used only for AP/GO mode*/ |
| u8 connected_state; |
| u16 aid; |
| /* Presently is_wps is used only in P2P GO mode */ |
| bool is_wps; |
| u16 capabilities; |
| bool qos_enabled; |
| u8 queueset; |
| struct scsc_wifi_fcq_data_qset data_qs; |
| struct scsc_wifi_fcq_ctrl_q ctrl_q; |
| |
| bool authorized; |
| bool pairwise_key_set; |
| |
| /* Needed for STA/AP VIF */ |
| struct sk_buff *assoc_ie; |
| struct sk_buff_head buffered_frames; |
| /* Needed for STA VIF */ |
| struct sk_buff *assoc_resp_ie; |
| |
| /* bitmask that keeps the status of acm bit for each AC |
| * bit 7 6 5 4 3 2 1 0 |
| * | | | | | | | | |
| * vo vo vi vi be bk bk be |
| */ |
| u8 wmm_acm; |
| /* bitmask that keeps the status of tspec establishment for each priority |
| * bit 7 6 5 4 3 2 1 0 |
| * | | | | | | | | |
| * p7 p6 p5 p4 p3 p2 p1 p0 |
| */ |
| u8 tspec_established; |
| u8 uapsd; |
| |
| /* TODO_HARDMAC: |
| * Q: Can we obtain stats from the firmware? |
| * Yes - then this is NOT needed and we can just get from the firmware when requested. |
| * No - How much can we get from the PSCHED? |
| */ |
| struct station_info sinfo; |
| /* rate limit for peer sinfo mib reads */ |
| struct ratelimit_state sinfo_mib_get_rs; |
| struct slsi_ba_session_rx *ba_session_rx[NUM_BA_SESSIONS_PER_PEER]; |
| |
| #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) |
| /* qos map configured at peer end*/ |
| bool qos_map_set; |
| struct cfg80211_qos_map qos_map; |
| #endif |
| u16 ndl_vif; |
| |
| }; |
| |
| /* Used to update vif type on vif deactivation indicating vif is no longer available */ |
| #define SLSI_VIFTYPE_UNSPECIFIED 0xFFFF |
| |
| struct slsi_vif_mgmt_tx { |
| u64 cookie; /* Cookie assigned by Host for the tx mgmt frame */ |
| u16 host_tag; /* Host tag for the tx mgmt frame */ |
| const u8 *buf; /* Buffer - Mgmt frame requested for tx */ |
| size_t buf_len; /* Buffer length */ |
| u8 exp_frame; /* Next expected Public action frame subtype from peer */ |
| }; |
| |
| struct slsi_wmm_ac { |
| u8 aci_aifsn; |
| u8 ecw; |
| u16 txop_limit; |
| } __packed; |
| |
| /* struct slsi_wmm_parameter_element |
| * |
| * eid - Vendor Specific |
| * len - Remaining Length of IE |
| * oui - Microsoft OUI |
| * oui_type - WMM |
| * oui_subtype - Param IE |
| * version - 1 |
| * qos_info - Qos |
| * reserved - |
| * ac - BE,BK,VI,VO |
| */ |
| struct slsi_wmm_parameter_element { |
| u8 eid; |
| u8 len; |
| u8 oui[3]; |
| u8 oui_type; |
| u8 oui_subtype; |
| u8 version; |
| u8 qos_info; |
| u8 reserved; |
| struct slsi_wmm_ac ac[4]; |
| } __packed; |
| |
| #define SLSI_MIN_FILTER_ID 0x80 /* Start of filter range reserved for host */ |
| |
| /* for AP */ |
| #define SLSI_AP_ALL_IPV6_PKTS_FILTER_ID 0x80 |
| |
| /* filter IDs for filters installed by driver */ |
| #ifdef CONFIG_SCSC_WLAN_BLOCK_IPV6 |
| |
| enum slsi_filter_id { |
| SLSI_LOCAL_ARP_FILTER_ID = SLSI_MIN_FILTER_ID, /* 0x80 */ |
| SLSI_ALL_BC_MC_FILTER_ID, /* 0x81 */ |
| SLSI_PROXY_ARP_FILTER_ID, /* 0x82 */ |
| SLSI_ALL_IPV6_PKTS_FILTER_ID, /* 0x83 */ |
| #ifndef CONFIG_SCSC_WLAN_DISABLE_NAT_KA |
| SLSI_NAT_IPSEC_FILTER_ID, /* 0x84 */ |
| #endif |
| #ifdef CONFIG_SCSC_WLAN_ENHANCED_PKT_FILTER |
| SLSI_OPT_OUT_ALL_FILTER_ID, /* 0x85 */ |
| SLSI_OPT_IN_TCP4_FILTER_ID, /* 0x86 */ |
| SLSI_OPT_IN_TCP6_FILTER_ID, /* 0x87 */ |
| #endif |
| SLSI_ABNORMAL_MULTICAST_ID, /* 0x85 / 0x88*/ |
| SLSI_ALL_ARP_FILTER_ID, /* 0x86 / 0x89 */ |
| SLSI_REGD_MC_FILTER_ID, /* 0x87 / 0x8a */ |
| }; |
| #else |
| |
| /* for STA */ |
| enum slsi_filter_id { |
| SLSI_LOCAL_ARP_FILTER_ID = SLSI_MIN_FILTER_ID, /* 0x80 */ |
| SLSI_ALL_BC_MC_FILTER_ID, /* 0x81 */ |
| SLSI_PROXY_ARP_FILTER_ID, /* 0x82 */ |
| SLSI_LOCAL_NS_FILTER_ID, /* 0x83 */ |
| SLSI_PROXY_ARP_NA_FILTER_ID, /* 0x84 */ |
| #ifndef CONFIG_SCSC_WLAN_DISABLE_NAT_KA |
| SLSI_NAT_IPSEC_FILTER_ID, /* 0x85 */ |
| #endif |
| #ifdef CONFIG_SCSC_WLAN_ENHANCED_PKT_FILTER |
| SLSI_OPT_OUT_ALL_FILTER_ID, /* 0x86 */ |
| SLSI_OPT_IN_TCP4_FILTER_ID, /* 0x87 */ |
| SLSI_OPT_IN_TCP6_FILTER_ID, /* 0x88 */ |
| #endif |
| SLSI_ABNORMAL_MULTICAST_ID, /* 0x86 / 0x89 */ |
| SLSI_ALL_ARP_FILTER_ID, /* 0x87 / 0x8a */ |
| SLSI_REGD_MC_FILTER_ID, /* 0x88 / 0x8b */ |
| }; |
| |
| #endif |
| |
| #define SLSI_MAX_PKT_FILTERS 16 |
| |
| #ifndef CONFIG_SCSC_WLAN_DISABLE_NAT_KA |
| /* default config */ |
| #define SLSI_MC_ADDR_ENTRY_MAX (SLSI_MIN_FILTER_ID + SLSI_MAX_PKT_FILTERS - SLSI_REGD_MC_FILTER_ID) |
| #else |
| #define SLSI_MC_ADDR_ENTRY_MAX (SLSI_MIN_FILTER_ID + SLSI_MAX_PKT_FILTERS - SLSI_REGD_MC_FILTER_ID + 1) |
| #endif |
| |
| /* Values for vif_status field |
| * |
| * Used to indicate the status of an activated VIF, to help resolve |
| * conflicting activities with indications from the firmware eg. |
| * cfg80211 triggers a disconnection before a STA completes its |
| * connection to an AP. |
| */ |
| #define SLSI_VIF_STATUS_UNSPECIFIED 0 |
| #define SLSI_VIF_STATUS_CONNECTING 1 |
| #define SLSI_VIF_STATUS_CONNECTED 2 |
| #define SLSI_VIF_STATUS_DISCONNECTING 3 |
| |
| /*From wifi_offload.h (N_AVAIL_ID=3)*/ |
| #define SLSI_MAX_KEEPALIVE_ID 3 |
| |
| struct slsi_last_connected_bss { |
| u8 address[ETH_ALEN]; |
| int antenna_mode; |
| int rssi; |
| int mode; |
| int passpoint_version; |
| int snr; |
| int noise_level; |
| u16 bandwidth; |
| u16 roaming_count; |
| u16 channel_freq; |
| u16 tx_data_rate; |
| u8 roaming_akm; |
| u8 kv; |
| u32 kvie; |
| bool mimo_used; |
| }; |
| |
| enum slsi_wpa3_auth_state { |
| SLSI_WPA3_PREAUTH, |
| SLSI_WPA3_AUTHENTICATING, |
| SLSI_WPA3_AUTHENTICATED |
| }; |
| |
| struct slsi_vif_sta { |
| /* Only valid when the VIF is activated */ |
| u8 vif_status; |
| bool is_wps; |
| u16 eap_hosttag; |
| u16 m4_host_tag; |
| u16 keepalive_host_tag[SLSI_MAX_KEEPALIVE_ID]; |
| |
| struct sk_buff *roam_mlme_procedure_started_ind; |
| |
| /* This id is used to find out which response (connect resp/roamed resp/reassoc resp) |
| * is to be sent once M4 is transmitted successfully |
| */ |
| u16 resp_id; |
| bool gratuitous_arp_needed; |
| |
| /* regd multicast address*/ |
| u8 regd_mc_addr_count; |
| u8 regd_mc_addr[SLSI_MC_ADDR_ENTRY_MAX][ETH_ALEN]; |
| bool group_key_set; |
| bool wep_key_set; |
| struct sk_buff *mlme_scan_ind_skb; |
| bool roam_in_progress; |
| int tdls_peer_sta_records; |
| bool tdls_enabled; |
| struct cfg80211_bss *sta_bss; |
| u8 *assoc_req_add_info_elem; |
| int assoc_req_add_info_elem_len; |
| |
| /* List of seen ESS and Freq associated with them */ |
| struct list_head network_map; |
| #ifdef CONFIG_SCSC_WLAN_BSS_SELECTION |
| struct list_head ssid_info; |
| struct list_head blacklist_head; |
| #endif |
| |
| struct slsi_wmm_ac wmm_ac[4]; |
| bool nd_offload_enabled; |
| unsigned long data_rate_mbps; |
| unsigned long max_rate_mbps; |
| |
| struct cfg80211_crypto_settings crypto; |
| /*This structure is used to store last disconnected bss info and valid even when vif is deactivated. */ |
| struct slsi_last_connected_bss last_connected_bss; |
| |
| /* Variable to indicate if roamed_ind needs to be dropped in driver, to maintain roam synchronization. */ |
| atomic_t drop_roamed_ind; |
| u8 *vendor_disconnect_ies; |
| int vendor_disconnect_ies_len; |
| u8 bssid[ETH_ALEN]; |
| u8 ssid[IEEE80211_MAX_SSID_LEN]; |
| u8 ssid_len; |
| #ifdef CONFIG_SCSC_WLAN_SAE_CONFIG |
| u8 *rsn_ie; |
| int rsn_ie_len; |
| #endif |
| |
| /* Storing channel bitmap to use it for setting cached channels */ |
| u16 channels_24_ghz; |
| u32 channels_5_ghz; |
| #ifdef CONFIG_SCSC_WLAN_BSS_SELECTION |
| bool drv_bss_selection; |
| |
| /* save connection parameters in order to retry connection */ |
| struct cfg80211_connect_params sme; |
| const u8 *connected_bssid; |
| const u8 *connected_ssid; |
| int connected_ssid_len; |
| u8 akm_type; |
| int beacon_int; |
| enum slsi_wpa3_auth_state wpa3_auth_state; |
| u32 action_frame_bmap; |
| u32 action_frame_suspend_bmap; |
| #endif |
| }; |
| |
| struct slsi_vif_unsync { |
| struct delayed_work roc_expiry_work; /* Work on ROC duration expiry */ |
| struct delayed_work del_vif_work; /* Work on unsync vif retention timeout */ |
| struct delayed_work hs2_del_vif_work; /* Work on HS2 unsync vif retention timeout */ |
| u64 roc_cookie; /* Cookie id for ROC */ |
| u8 *probe_rsp_ies; /* Probe response IEs to be configured in firmware */ |
| size_t probe_rsp_ies_len; /* Probe response IE length */ |
| bool ies_changed; /* To indicate if Probe Response IEs have changed from that previously stored */ |
| bool listen_offload; /* To indicate if Listen Offload is started */ |
| }; |
| |
| struct slsi_last_disconnected_sta { |
| u8 address[ETH_ALEN]; |
| u32 rx_retry_packets; |
| u32 rx_bc_mc_packets; |
| u16 capabilities; |
| int bandwidth; |
| int antenna_mode; |
| int rssi; |
| int mode; |
| u16 tx_data_rate; |
| bool mimo_used; |
| u16 reason; |
| int support_mode; |
| }; |
| |
| struct slsi_vif_ap { |
| struct slsi_wmm_parameter_element wmm_ie; |
| struct slsi_last_disconnected_sta last_disconnected_sta; |
| u8 *cache_wmm_ie; |
| u8 *cache_wpa_ie; |
| u8 *add_info_ies; |
| size_t wmm_ie_len; |
| size_t wpa_ie_len; |
| size_t add_info_ies_len; |
| bool p2p_gc_keys_set; /* Used in GO mode to identify that a CLI has connected after WPA2 handshake */ |
| bool privacy; /* Used for port enabling based on the open/secured AP configuration */ |
| bool qos_enabled; |
| int beacon_interval; /* Beacon interval in AP/GO mode */ |
| int mode; |
| bool non_ht_bss_present; /* Non HT BSS observed in HT20 OBSS scan */ |
| struct scsc_wifi_fcq_data_qset group_data_qs; |
| u32 cipher; |
| u16 channel_freq; |
| u8 ssid[IEEE80211_MAX_SSID_LEN]; |
| u8 ssid_len; |
| }; |
| |
| struct slsi_nan_ndl_info { |
| u8 peer_nmi[ETH_ALEN]; |
| s8 ndp_count; |
| }; |
| |
| enum ndp_slot_status { |
| ndp_slot_status_free, |
| ndp_slot_status_in_use, |
| ndp_slot_status_terminating, |
| }; |
| |
| struct slsi_vif_nan { |
| struct slsi_hal_nan_config_req config; |
| u32 service_id_map; |
| u32 followup_id_map; |
| u32 ndp_id_map; |
| struct slsi_nan_ndl_info ndl_list[SLSI_NAN_MAX_NDP_INSTANCES]; |
| u8 ndp_ndi[SLSI_NAN_MAX_NDP_INSTANCES][ETH_ALEN]; |
| u16 ndp_id2ndl_vif[SLSI_NAN_MAX_NDP_INSTANCES]; |
| u16 ndp_local_ndp_id[SLSI_NAN_MAX_NDP_INSTANCES]; |
| enum ndp_slot_status ndp_state[SLSI_NAN_MAX_NDP_INSTANCES]; |
| u32 followup_trans_id; |
| |
| u8 disable_cluster_merge; |
| u16 nan_sdf_flags[SLSI_NAN_MAX_SERVICE_ID+1]; |
| /* fields used for nan stats/status*/ |
| u8 local_nmi[ETH_ALEN]; |
| u8 cluster_id[ETH_ALEN]; |
| u32 operating_channel[2]; |
| u8 role; |
| u8 state; /* 1 -> nan on; 0 -> nan off */ |
| u8 master_pref_value; |
| u8 amt; |
| u8 hopcount; |
| u32 random_mac_interval_sec; |
| }; |
| |
| #define TCP_ACK_SUPPRESSION_RECORDS_MAX 16 |
| #define TCP_ACK_SUPPRESSION_RECORD_UNUSED_TIMEOUT 10 /* in seconds */ |
| |
| #define TCP_ACK_SUPPRESSION_OPTIONS_OFFSET 20 |
| #define TCP_ACK_SUPPRESSION_OPTION_EOL 0 |
| #define TCP_ACK_SUPPRESSION_OPTION_NOP 1 |
| #define TCP_ACK_SUPPRESSION_OPTION_MSS 2 |
| #define TCP_ACK_SUPPRESSION_OPTION_WINDOW 3 |
| #define TCP_ACK_SUPPRESSION_OPTION_SACK 5 |
| |
| #define SLSI_IS_VIF_CHANNEL_5G(ndev_vif) (((ndev_vif)->chan) ? ((ndev_vif)->chan->hw_value > 14) : 0) |
| |
| struct slsi_tcp_ack_s { |
| u32 daddr; |
| u32 dport; |
| u32 saddr; |
| u32 sport; |
| struct sk_buff_head list; |
| u8 window_multiplier; |
| u16 mss; |
| u32 ack_seq; |
| u16 slow_start_count; |
| u8 count; |
| u8 max; |
| u8 age; |
| struct timer_list timer; |
| bool state; |
| ktime_t last_sent; |
| bool tcp_slow_start; |
| |
| /* TCP session throughput monitor */ |
| u16 hysteresis; |
| u32 last_tcp_rate; |
| ktime_t last_sample_time; |
| u32 last_ack_seq; |
| u64 num_bytes; |
| struct netdev_vif *ndev_vif; |
| }; |
| |
| struct slsi_tcp_ack_stats { |
| u32 tack_acks; |
| u32 tack_suppressed; |
| u32 tack_sent; |
| u32 tack_max; |
| u32 tack_timeout; |
| u32 tack_dacks; |
| u32 tack_sacks; |
| u32 tack_delay_acks; |
| u32 tack_low_window; |
| u32 tack_nocache; |
| u32 tack_norecord; |
| u32 tack_hasdata; |
| u32 tack_psh; |
| u32 tack_dropped; |
| u32 tack_ktime; |
| u32 tack_lastrecord; |
| u32 tack_searchrecord; |
| u32 tack_ece; |
| }; |
| |
| struct netdev_vif { |
| struct slsi_dev *sdev; |
| struct wireless_dev wdev; |
| atomic_t is_registered; /* Has the net dev been registered */ |
| bool is_available; /* Has the net dev been opened AND is usable */ |
| bool is_fw_test; /* Is the device in use as a test device via UDI */ |
| #ifdef CONFIG_SLSI_WLAN_STA_FWD_BEACON |
| bool is_wips_running; |
| #endif |
| /* Structure can be accessed by cfg80211 ops, procfs/ioctls and as a result |
| * of receiving MLME indications e.g. MLME-CONNECT-IND that can affect the |
| * status of the interface eg. STA connect failure will delete the VIF. |
| */ |
| #ifdef CONFIG_SCSC_WLAN_MUTEX_DEBUG |
| struct slsi_mutex vif_mutex; |
| #else |
| /* a std mutex */ |
| struct mutex vif_mutex; |
| #endif |
| struct slsi_sig_send sig_wait; |
| struct slsi_skb_work rx_data; |
| struct slsi_skb_work rx_mlme; |
| #ifdef CONFIG_SCSC_WLAN_RX_NAPI |
| struct slsi_napi napi; |
| #endif |
| u16 ifnum; |
| enum nl80211_iftype iftype; |
| enum nl80211_channel_type channel_type; |
| struct ieee80211_channel *chan; |
| #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9)) |
| struct cfg80211_chan_def *chandef; |
| #endif |
| |
| /* NOTE: The Address is a __be32 |
| * It needs converting to pass to the FW |
| * But not for the Arp or trace %pI4 |
| */ |
| __be32 ipaddress; |
| |
| #ifndef CONFIG_SCSC_WLAN_BLOCK_IPV6 |
| struct in6_addr ipv6address; |
| struct slsi_spinlock ipv6addr_lock; |
| #endif |
| struct net_device_stats stats; |
| u32 rx_packets[SLSI_LLS_AC_MAX]; |
| u32 tx_packets[SLSI_LLS_AC_MAX]; |
| u32 tx_no_ack[SLSI_LLS_AC_MAX]; |
| #ifdef CONFIG_SCSC_WLAN_MUTEX_DEBUG |
| struct slsi_mutex scan_mutex; |
| struct slsi_mutex scan_result_mutex; |
| #else |
| /* a std mutex */ |
| struct mutex scan_mutex; |
| struct mutex scan_result_mutex; |
| |
| #endif |
| struct slsi_scan scan[SLSI_SCAN_MAX]; |
| |
| struct slsi_src_sink_params src_sink_params; |
| u16 power_mode; |
| u16 set_power_mode; |
| |
| bool activated; /* VIF is created in firmware and ready to use */ |
| u16 vif_type; |
| struct slsi_spinlock peer_lock; |
| int peer_sta_records; |
| struct slsi_peer *peer_sta_record[SLSI_ADHOC_PEER_CONNECTIONS_MAX]; |
| |
| /* Used to populate the cfg80211 station_info structure generation variable. |
| * This number should increase every time the list of stations changes |
| * i.e. when a station is added or removed, so that userspace can tell |
| * whether it got a consistent snapshot. |
| */ |
| int cfg80211_sinfo_generation; |
| |
| /* Block Ack MPDU Re-order */ |
| struct sk_buff_head ba_complete; |
| atomic_t ba_flush; |
| |
| u64 mgmt_tx_cookie; /* Cookie id for mgmt tx */ |
| struct slsi_vif_mgmt_tx mgmt_tx_data; |
| struct delayed_work scan_timeout_work; /* Work on scan timeout */ |
| bool delete_probe_req_ies; /* Delete probe request stored at probe_req_ies, if |
| * connected for WAP2 at mlme_del_vif or in all cases |
| * if STA |
| */ |
| u8 *probe_req_ies; |
| size_t probe_req_ie_len; |
| |
| struct slsi_vif_unsync unsync; |
| struct slsi_vif_sta sta; |
| struct slsi_vif_ap ap; |
| struct slsi_vif_nan nan; |
| bool mgmt_tx_gas_frame; |
| u8 gas_frame_mac_addr[ETH_ALEN]; |
| |
| /* TCP ack suppression. */ |
| struct slsi_spinlock tcp_ack_lock; |
| struct slsi_tcp_ack_s *last_tcp_ack; |
| struct slsi_tcp_ack_s ack_suppression[TCP_ACK_SUPPRESSION_RECORDS_MAX]; |
| struct slsi_tcp_ack_stats tcp_ack_stats; |
| #ifdef CONFIG_SCSC_WLAN_STA_ENHANCED_ARP_DETECT |
| bool enhanced_arp_detect_enabled; |
| struct slsi_enhanced_arp_counters enhanced_arp_stats; |
| u8 target_ip_addr[4]; |
| int enhanced_arp_host_tag[SLSI_MAX_ARP_SEND_FRAME]; |
| #endif |
| struct work_struct sched_scan_stop_wk; |
| struct work_struct set_multicast_filter_work; |
| }; |
| |
| struct slsi_802_11d_reg_domain { |
| u8 *countrylist; |
| struct ieee80211_regdomain *regdomain; |
| int country_len; |
| }; |
| |
| struct slsi_apf_capabilities { |
| u16 version; |
| u16 max_length; |
| }; |
| |
| #ifdef CONFIG_SCSC_WLAN_WES_NCHO |
| struct slsi_wes_mode_roam_scan_channels { |
| int n; |
| u8 channels[SLSI_NCHO_MAX_CHANNEL_LIST]; |
| }; |
| #endif |
| |
| struct slsi_dev_config { |
| /* Current Channel Config */ |
| struct sk_buff *channel_config; |
| |
| /* Supported Freq Band (Dynamic) |
| * Set via the freq_band procfs |
| */ |
| #define SLSI_FREQ_BAND_AUTO 0 |
| #define SLSI_FREQ_BAND_5GHZ 1 |
| #define SLSI_FREQ_BAND_2GHZ 2 |
| int supported_band; |
| |
| struct ieee80211_supported_band *band_5G; |
| struct ieee80211_supported_band *band_2G; |
| |
| /* current user suspend mode |
| * Set via the suspend_mode procfs |
| * 0 : not suspended |
| * 1 : suspended |
| */ |
| int user_suspend_mode; |
| |
| /* Rx filtering rule |
| * Set via the rx_filter_num procfs |
| * 0: Unicast, 1: Broadcast, 2:Multicast IPv4, 3: Multicast IPv6 |
| */ |
| int rx_filter_num; |
| |
| /* Rx filter rule enabled |
| * Set via the rx_filter_start & rx_filter_stop procfs |
| */ |
| bool rx_filter_rule_started; |
| |
| /* AP Auto channel Selection */ |
| #define SLSI_NO_OF_SCAN_CHANLS_FOR_AUTO_CHAN_MAX 14 |
| int ap_auto_chan; |
| |
| /*QoS capability for a non-AP Station*/ |
| int qos_info; |
| #ifdef CONFIG_SCSC_WLAN_WES_NCHO |
| /* NCHO OKC mode */ |
| int okc_mode; |
| |
| /*NCHO WES mode */ |
| int wes_mode; |
| |
| int roam_scan_mode; |
| |
| int dfs_scan_mode; |
| |
| int ncho_mode; |
| |
| /*WES mode roam scan channels*/ |
| struct slsi_wes_mode_roam_scan_channels wes_roam_scan_list; |
| #endif |
| struct slsi_802_11d_reg_domain domain_info; |
| int ap_disconnect_ind_timeout; |
| u8 host_state; |
| int rssi_boost_5g; |
| int rssi_boost_2g; |
| bool disable_ch12_ch13; |
| bool fw_enhanced_arp_detect_supported; |
| bool fw_apf_supported; |
| struct slsi_apf_capabilities apf_cap; |
| }; |
| |
| #define SLSI_DEVICE_STATE_ATTACHING 0 |
| #define SLSI_DEVICE_STATE_STOPPED 1 |
| #define SLSI_DEVICE_STATE_STARTING 2 |
| #define SLSI_DEVICE_STATE_STARTED 3 |
| #define SLSI_DEVICE_STATE_STOPPING 4 |
| |
| #define SLSI_NET_INDEX_WLAN 1 |
| #define SLSI_NET_INDEX_P2P 2 |
| #define SLSI_NET_INDEX_P2PX_SWLAN 3 |
| #define SLSI_NET_INDEX_NAN 4 |
| |
| /* States used during P2P operations */ |
| enum slsi_p2p_states { |
| P2P_IDLE_NO_VIF, /* Initial state - Unsync vif is not present */ |
| P2P_IDLE_VIF_ACTIVE, /* Unsync vif is present but no P2P procedure in progress */ |
| P2P_SCANNING, /* P2P SOCIAL channel (1,6,11) scan in progress. Not used for P2P full scan */ |
| P2P_LISTENING, /* P2P Listen (ROC) in progress */ |
| P2P_ACTION_FRAME_TX_RX, /* P2P Action frame Tx in progress or waiting for a peer action frame Rx (i.e. in response to the Tx frame) */ |
| P2P_GROUP_FORMED_CLI, /* P2P Group Formed - CLI role */ |
| P2P_GROUP_FORMED_GO, /* P2P Group Formed - GO role */ |
| /* NOTE: In P2P_LISTENING state if frame transmission is requested to driver then a peer response is ideally NOT expected. |
| * This is an assumption based on the fact that FIND would be stopped prior to group formation/connection. |
| * If driver were to receive a peer frame in P2P_LISTENING state then it would most probably be a REQUEST frame and the supplicant would respond to it. |
| * Hence the driver should get only RESPONSE frames for transmission in P2P_LISTENING state. |
| */ |
| }; |
| |
| enum slsi_wlan_state { |
| WLAN_UNSYNC_NO_VIF = 0, /* Initial state - Unsync vif is not present */ |
| WLAN_UNSYNC_VIF_ACTIVE, /* Unsync vif is activated but no wlan procedure in progress */ |
| WLAN_UNSYNC_VIF_TX /* Unsync vif is activated and wlan procedure in progress */ |
| }; |
| |
| /* Wakelock timeouts */ |
| #define SLSI_WAKELOCK_TIME_MSEC_EAPOL (1000) |
| |
| struct slsi_chip_info_mib { |
| u16 chip_version; |
| }; |
| |
| struct slsi_plat_info_mib { |
| u16 plat_build; |
| }; |
| |
| /* P2P States in text format for debug purposes */ |
| static inline char *slsi_p2p_state_text(u8 state) |
| { |
| switch (state) { |
| case P2P_IDLE_NO_VIF: |
| return "P2P_IDLE_NO_VIF"; |
| case P2P_IDLE_VIF_ACTIVE: |
| return "P2P_IDLE_VIF_ACTIVE"; |
| case P2P_SCANNING: |
| return "P2P_SCANNING"; |
| case P2P_LISTENING: |
| return "P2P_LISTENING"; |
| case P2P_ACTION_FRAME_TX_RX: |
| return "P2P_ACTION_FRAME_TX_RX"; |
| case P2P_GROUP_FORMED_CLI: |
| return "P2P_GROUP_FORMED_CLI"; |
| case P2P_GROUP_FORMED_GO: |
| return "P2P_GROUP_FORMED_GO"; |
| default: |
| return "UNKNOWN"; |
| } |
| } |
| |
| #define SLSI_WLAN_MAX_HCF_PLATFORM_LEN (128) |
| |
| struct slsi_dev_mib_info { |
| char *mib_file_name; |
| unsigned int mib_hash; |
| |
| /* Cached File MIB Configuration values from User Space */ |
| u8 *mib_data; |
| u32 mib_len; |
| char platform[SLSI_WLAN_MAX_HCF_PLATFORM_LEN]; |
| }; |
| |
| #define SLSI_WLAN_MAX_MIB_FILE 2 /* Number of WLAN HCFs to load */ |
| |
| #ifdef CONFIG_SCSC_LOG_COLLECTION |
| struct slsi_dev_mib_collect_file { |
| char file_name[32]; |
| u16 len; |
| u8 *data; |
| } __packed; |
| |
| struct slsi_dev_mib_collect { |
| bool enabled; |
| /* Serialize writers/readers */ |
| spinlock_t in_collection; |
| char num_files; |
| /* +1 represents local_mib */ |
| struct slsi_dev_mib_collect_file file[SLSI_WLAN_MAX_MIB_FILE + 1]; |
| }; |
| |
| #endif |
| |
| struct slsi_dev { |
| /* Devices */ |
| struct device *dev; |
| struct wiphy *wiphy; |
| |
| struct slsi_hip hip; /* HIP bookkeeping block */ |
| struct slsi_hip4 hip4_inst; /* The handler to parse to HIP */ |
| |
| struct scsc_wifi_cm_if cm_if; /* cm_if bookkeeping block */ |
| struct scsc_mx *maxwell_core; |
| struct scsc_service_client mx_wlan_client; |
| struct scsc_service *service; |
| struct slsi_chip_info_mib chip_info_mib; |
| struct slsi_plat_info_mib plat_info_mib; |
| u16 reg_dom_version; |
| |
| #ifdef CONFIG_SCSC_WLAN_MUTEX_DEBUG |
| struct slsi_mutex netdev_add_remove_mutex; |
| struct slsi_mutex netdev_remove_mutex; |
| #else |
| /* a std mutex */ |
| struct mutex netdev_add_remove_mutex; |
| /* a std mutex */ |
| struct mutex netdev_remove_mutex; |
| #endif |
| int netdev_up_count; |
| struct net_device __rcu *netdev[CONFIG_SCSC_WLAN_MAX_INTERFACES + 1]; /* 0 is reserved */ |
| struct net_device __rcu *netdev_ap; |
| u8 netdev_addresses[CONFIG_SCSC_WLAN_MAX_INTERFACES + 1][ETH_ALEN]; /* 0 is reserved */ |
| bool require_vif_delete[CONFIG_SCSC_WLAN_MAX_INTERFACES + 1]; |
| int device_state; |
| |
| /* BoT */ |
| atomic_t in_pause_state; |
| struct work_struct trigger_wlan_fail_work; /* Work on mlme cfm or ind timeout*/ |
| /* Locking used to control Starting and stopping the chip */ |
| #ifdef CONFIG_SCSC_WLAN_MUTEX_DEBUG |
| struct slsi_mutex start_stop_mutex; |
| #else |
| /* a std mutex */ |
| struct mutex start_stop_mutex; |
| #endif |
| |
| #ifdef CONFIG_SCSC_WLAN_OFFLINE_TRACE |
| struct slsi_spinlock offline_dbg_lock; |
| #endif |
| |
| /* UDI Logging */ |
| struct slsi_log_clients log_clients; |
| void *uf_cdev; |
| |
| /* ProcFS */ |
| int procfs_instance; |
| struct proc_dir_entry *procfs_dir; |
| |
| /* Configuration */ |
| u8 hw_addr[ETH_ALEN]; |
| struct slsi_dev_mib_info mib[SLSI_WLAN_MAX_MIB_FILE]; |
| struct slsi_dev_mib_info local_mib; |
| #ifdef CONFIG_SCSC_LOG_COLLECTION |
| struct slsi_dev_mib_collect collect_mib; |
| #endif |
| char *maddr_file_name; |
| bool *term_udi_users; /* Try to terminate UDI users during unload */ |
| int *sig_wait_cfm_timeout; |
| |
| struct slsi_wake_lock wlan_wl; |
| struct slsi_wake_lock wlan_wl_to; |
| #ifndef SLSI_TEST_DEV |
| struct wake_lock wlan_roam_wl; |
| #endif |
| struct slsi_sig_send sig_wait; |
| struct slsi_skb_work rx_dbg_sap; |
| atomic_t tx_host_tag[SLSI_LLS_AC_MAX]; |
| #ifdef CONFIG_SCSC_WLAN_MUTEX_DEBUG |
| struct slsi_mutex device_config_mutex; |
| #else |
| /* a std mutex */ |
| struct mutex device_config_mutex; |
| #endif |
| struct slsi_dev_config device_config; |
| |
| struct notifier_block inetaddr_notifier; |
| #ifndef CONFIG_SCSC_WLAN_BLOCK_IPV6 |
| struct notifier_block inet6addr_notifier; |
| #endif |
| |
| struct workqueue_struct *device_wq; /* Driver Workqueue */ |
| enum slsi_p2p_states p2p_state; /* Store current P2P operation */ |
| |
| enum slsi_wlan_state wlan_unsync_vif_state; /* Store current sate of unsync wlan vif */ |
| |
| int current_tspec_id; |
| int tspec_error_code; |
| bool *tx_cfm_reqd; |
| u8 p2p_group_exp_frame; /* Next expected Public action frame subtype from peer */ |
| bool initial_scan; |
| |
| #ifdef CONFIG_SCSC_WLAN_GSCAN_ENABLE |
| struct slsi_gscan *gscan; |
| struct slsi_gscan_result *gscan_hash_table[SLSI_GSCAN_HASH_TABLE_SIZE]; |
| int num_gscan_results; |
| int buffer_threshold; |
| int buffer_consumed; |
| struct slsi_bucket bucket[SLSI_GSCAN_MAX_BUCKETS]; |
| struct list_head hotlist_results; |
| bool epno_active; |
| #endif |
| #ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION |
| u8 scan_mac_addr[6]; |
| bool scan_addr_set; |
| #endif |
| #ifdef CONFIG_SCSC_WLAN_HIP4_PROFILING |
| int minor_prof; |
| #endif |
| struct slsi_ba_session_rx rx_ba_buffer_pool[SLSI_MAX_RX_BA_SESSIONS]; |
| struct slsi_spinlock rx_ba_buffer_pool_lock; |
| bool fail_reported; |
| bool p2p_certif; /* Set to true to idenitfy p2p_certification testing is going on*/ |
| bool mlme_blocked; /* When true do not send mlme signals to FW */ |
| atomic_t debug_inds; |
| int recovery_next_state; |
| struct completion recovery_remove_completion; |
| struct completion recovery_stop_completion; |
| struct completion recovery_completed; |
| struct completion service_fail_started_indication; |
| int recovery_status; |
| struct slsi_ssid_map ssid_map[SLSI_SCAN_SSID_MAP_MAX]; |
| bool band_5g_supported; |
| int supported_2g_channels[14]; |
| int supported_5g_channels[25]; |
| int enabled_channel_count; |
| bool fw_ht_enabled; |
| u8 fw_ht_cap[4]; /* HT capabilities is 21 bytes but host is never intersted in last 17 bytes*/ |
| bool fw_vht_enabled; |
| u8 fw_vht_cap[4]; |
| #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING |
| u8 wifi_sharing_5ghz_channel[8]; |
| int valid_5g_freq[25]; |
| int wifi_sharing_5g_restricted_channels[25]; |
| int num_5g_restricted_channels; |
| #endif |
| bool fw_SoftAp_2g_40mhz_enabled; |
| bool nan_enabled; |
| u16 assoc_result_code; /* Status of latest association in STA mode */ |
| bool allow_switch_40_mhz; /* Used in AP cert to disable HT40 when not configured */ |
| bool allow_switch_80_mhz; /* Used in AP cert to disable VHT when not configured */ |
| #ifdef CONFIG_SCSC_WLAN_AP_INFO_FILE |
| /* Parameters in '/data/vendor/conn/.softap.info' */ |
| bool dualband_concurrency; |
| u32 softap_max_client; |
| #endif |
| u32 fw_dwell_time; |
| |
| #ifdef CONFIG_SCSC_WLAN_MUTEX_DEBUG |
| struct slsi_mutex logger_mutex; |
| #else |
| /* a std mutex */ |
| struct mutex logger_mutex; |
| #endif |
| int lls_num_radio; |
| /*Store vif index corresponding to rtt id for FTM*/ |
| u16 rtt_vif[8]; |
| bool acs_channel_switched; |
| int recovery_timeout; /* ms autorecovery completion timeout */ |
| #ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION |
| bool fw_mac_randomization_enabled; |
| #endif |
| |
| #ifdef CONFIG_SCSC_WLAN_ENHANCED_PKT_FILTER |
| bool enhanced_pkt_filter_enabled; |
| #endif |
| u8 fw_ext_cap_ie[9]; /*extended capability IE length is 9 */ |
| u32 fw_ext_cap_ie_len; |
| bool mac_changed; |
| int wlan_service_on; |
| bool igmp_offload_activated; |
| }; |
| |
| /* Compact representation of channels a ESS has been seen on |
| * This is sized correctly for the Channels we currently support, |
| * 2.4Ghz Channels 1 - 14 |
| * 5 Ghz Channels Uni1, Uni2 and Uni3 |
| */ |
| struct slsi_roaming_network_map_entry { |
| struct list_head list; |
| unsigned long last_seen_jiffies; /* Timestamp of the last time we saw this ESS */ |
| struct cfg80211_ssid ssid; /* SSID of the ESS */ |
| u8 initial_bssid[ETH_ALEN]; /* Bssid of the first ap seen in this ESS */ |
| bool only_one_ap_seen; /* Has more than one AP for this ESS been seen */ |
| u16 channels_24_ghz; /* 2.4 Ghz Channels Bit Map */ |
| /* 5 Ghz Channels Bit Map |
| * channels_5_ghz & 0x000000FF = 4 Uni1 Channels |
| * channels_5_ghz & 0x00FFFF00 = 15 Uni2 Channels |
| * channels_5_ghz & 0xFF000000 = 5 Uni3 Channels |
| */ |
| u32 channels_5_ghz; |
| }; |
| |
| #define LLC_SNAP_HDR_LEN 8 |
| struct llc_snap_hdr { |
| u8 llc_dsap; |
| u8 llc_ssap; |
| u8 llc_ctrl; |
| u8 snap_oui[3]; |
| u16 snap_type; |
| } __packed; |
| |
| #ifdef CONFIG_SCSC_WLAN_RX_NAPI |
| int slsi_rx_data_napi(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb, bool from_ba); |
| #endif |
| void slsi_rx_data_deliver_skb(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb); |
| void slsi_rx_dbg_sap_work(struct work_struct *work); |
| void slsi_rx_netdev_data_work(struct work_struct *work); |
| void slsi_rx_netdev_mlme_work(struct work_struct *work); |
| int slsi_rx_enqueue_netdev_mlme(struct slsi_dev *sdev, struct sk_buff *skb, u16 vif); |
| struct ieee80211_channel *slsi_rx_scan_pass_to_cfg80211(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb); |
| void slsi_rx_buffered_frames(struct slsi_dev *sdev, struct net_device *dev, struct slsi_peer *peer); |
| int slsi_rx_blocking_signals(struct slsi_dev *sdev, struct sk_buff *skb); |
| void slsi_scan_complete(struct slsi_dev *sdev, struct net_device *dev, u16 scan_id, bool aborted, |
| bool flush_scan_results); |
| void slsi_tx_pause_queues(struct slsi_dev *sdev); |
| void slsi_tx_unpause_queues(struct slsi_dev *sdev); |
| int slsi_tx_control(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb); |
| int slsi_tx_data(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb); |
| int slsi_tx_data_lower(struct slsi_dev *sdev, struct sk_buff *skb); |
| bool slsi_is_test_mode_enabled(void); |
| bool slsi_is_rf_test_mode_enabled(void); |
| int slsi_check_rf_test_mode(void); |
| void slsi_regd_deinit(struct slsi_dev *sdev); |
| void slsi_init_netdev_mac_addr(struct slsi_dev *sdev); |
| bool slsi_dev_lls_supported(void); |
| bool slsi_dev_gscan_supported(void); |
| bool slsi_dev_epno_supported(void); |
| bool slsi_dev_vo_vi_block_ack(void); |
| int slsi_dev_get_scan_result_count(void); |
| bool slsi_dev_llslogs_supported(void); |
| int slsi_dev_nan_supported(struct slsi_dev *sdev); |
| #ifdef CONFIG_SCSC_WIFI_NAN_ENABLE |
| bool slsi_dev_nan_is_ipv6_link_tlv_include(void); |
| int slsi_get_nan_max_ndp_instances(void); |
| int slsi_get_nan_max_ndi_ifaces(void); |
| #endif |
| void slsi_regd_init(struct slsi_dev *sdev); |
| bool slsi_dev_rtt_supported(void); |
| void slsi_sched_scan_stopped(struct work_struct *work); |
| |
| static inline u16 slsi_tx_host_tag(struct slsi_dev *sdev, enum slsi_traffic_q tq) |
| { |
| /* host_tag: |
| * bit 0,1 = trafficqueue identifier |
| * bit 2-15 = incremental number |
| * So increment by 4 to get bit 2-15 a incremental sequence |
| */ |
| return (u16)atomic_add_return(4, &sdev->tx_host_tag[tq]); |
| } |
| |
| static inline u16 slsi_tx_mgmt_host_tag(struct slsi_dev *sdev) |
| { |
| /* Doesn't matter which traffic queue host tag is selected.*/ |
| return slsi_tx_host_tag(sdev, 0); |
| } |
| |
| static inline struct net_device *slsi_get_netdev_rcu(struct slsi_dev *sdev, u16 ifnum) |
| { |
| WARN_ON(!rcu_read_lock_held()); |
| if (ifnum > CONFIG_SCSC_WLAN_MAX_INTERFACES) { |
| /* WARN(1, "ifnum:%d", ifnum); WARN() is used like this to avoid Coverity Error */ |
| return NULL; |
| } |
| return rcu_dereference(sdev->netdev[ifnum]); |
| } |
| |
| static inline struct net_device *slsi_get_netdev_locked(struct slsi_dev *sdev, u16 ifnum) |
| { |
| WARN_ON(!SLSI_MUTEX_IS_LOCKED(sdev->netdev_add_remove_mutex)); |
| if (ifnum > CONFIG_SCSC_WLAN_MAX_INTERFACES) { |
| WARN(1, "ifnum:%d", ifnum); /* WARN() is used like this to avoid Coverity Error */ |
| return NULL; |
| } |
| return sdev->netdev[ifnum]; |
| } |
| |
| static inline struct net_device *slsi_get_netdev(struct slsi_dev *sdev, u16 ifnum) |
| { |
| struct net_device *dev; |
| |
| SLSI_MUTEX_LOCK(sdev->netdev_add_remove_mutex); |
| dev = slsi_get_netdev_locked(sdev, ifnum); |
| SLSI_MUTEX_UNLOCK(sdev->netdev_add_remove_mutex); |
| |
| return dev; |
| } |
| |
| static inline struct net_device *slsi_get_netdev_by_mac_addr_locked(struct slsi_dev *sdev, u8 *mac_addr, int start_idx) |
| { |
| int i; |
| |
| if (!start_idx) |
| start_idx = 1; |
| WARN_ON(!SLSI_MUTEX_IS_LOCKED(sdev->netdev_add_remove_mutex)); |
| for (i = start_idx; i < CONFIG_SCSC_WLAN_MAX_INTERFACES + 1; i++) { |
| if (sdev->netdev[i] && ether_addr_equal(mac_addr, sdev->netdev[i]->dev_addr)) |
| return sdev->netdev[i]; |
| } |
| return NULL; |
| } |
| |
| static inline struct net_device *slsi_get_netdev_by_mac_addr(struct slsi_dev *sdev, u8 *mac_addr, int start_idx) |
| { |
| struct net_device *dev; |
| |
| SLSI_MUTEX_LOCK(sdev->netdev_add_remove_mutex); |
| dev = slsi_get_netdev_by_mac_addr_locked(sdev, mac_addr, start_idx); |
| SLSI_MUTEX_UNLOCK(sdev->netdev_add_remove_mutex); |
| |
| return dev; |
| } |
| |
| static inline struct net_device *slsi_get_netdev_by_ifname_locked(struct slsi_dev *sdev, u8 *ifname) |
| { |
| int i; |
| |
| WARN_ON(!SLSI_MUTEX_IS_LOCKED(sdev->netdev_add_remove_mutex)); |
| for (i = 1; i < CONFIG_SCSC_WLAN_MAX_INTERFACES + 1; i++) { |
| if (sdev->netdev[i] && strcmp(ifname, sdev->netdev[i]->name) == 0) |
| return sdev->netdev[i]; |
| } |
| return NULL; |
| } |
| |
| static inline struct net_device *slsi_get_netdev_by_ifname(struct slsi_dev *sdev, u8 *ifname) |
| { |
| struct net_device *dev; |
| |
| SLSI_MUTEX_LOCK(sdev->netdev_add_remove_mutex); |
| dev = slsi_get_netdev_by_ifname_locked(sdev, ifname); |
| SLSI_MUTEX_UNLOCK(sdev->netdev_add_remove_mutex); |
| |
| return dev; |
| } |
| |
| static inline int slsi_get_supported_mode(const u8 *peer_ie) |
| { |
| const u8 *peer_ie_data; |
| u8 peer_ie_len; |
| int i; |
| int supported_rate; |
| |
| peer_ie_len = peer_ie[1]; |
| peer_ie_data = &peer_ie[2]; |
| for (i = 0; i < peer_ie_len; i++) { |
| supported_rate = ((peer_ie_data[i] & 0x7F) / 2); |
| if (supported_rate > 11) |
| return SLSI_80211_MODE_11G; |
| } |
| return SLSI_80211_MODE_11B; |
| } |
| |
| /* Names of full mode HCF files */ |
| extern char *slsi_mib_file; |
| extern char *slsi_mib_file2; |
| |
| #endif |