/* SPDX-License-Identifier: GPL-2.0-only */ #ifndef _CORE_H_ #define _CORE_H_ #include #include #include #include #include #include #include "descriptors.h" #include "rpu_iface.h" #include "hal_common.h" #include "img_mac80211_osal.h" #include "host_rpu_sys_if.h" #ifdef RPU_VHT_SUPPORT extern unsigned int vht_support; #endif extern struct cmd_send_recv_cnt cmd_info; extern int rpu_debug; #ifdef WOWLAN #ifdef CONFIG_PM extern unsigned char img_suspend_status; extern unsigned char rx_interrupt_status; #endif #endif #define RPU_DEBUG_UMACIF(fmt, ...) \ do { \ if (rpu_debug & RPU_DEBUG_UMACIF) \ pr_debug(fmt, ##__VA_ARGS__); \ } while (0) #define RPU_DEBUG_CRYPTO(fmt, ...) \ do { \ if (rpu_debug & RPU_DEBUG_CRYPTO) \ pr_debug(fmt, ##__VA_ARGS__); \ } while (0) #define RPU_DEBUG_VIF(fmt, ...) \ do { \ if (rpu_debug & RPU_DEBUG_VIF) \ pr_debug(fmt, ##__VA_ARGS__); \ } while (0) #define RPU_DEBUG_TX(fmt, ...) \ do { \ if (rpu_debug & RPU_DEBUG_TX) \ pr_debug(fmt, ##__VA_ARGS__); \ } while (0) #define RPU_DEBUG_SCAN(fmt, ...) \ do { \ if (rpu_debug & RPU_DEBUG_SCAN) \ pr_debug(fmt, ##__VA_ARGS__); \ } while (0) #define RPU_DEBUG_ROC(fmt, ...) \ do { \ if (rpu_debug & RPU_DEBUG_ROC) \ pr_debug(fmt, ##__VA_ARGS__); \ } while (0) #define RPU_DEBUG_TSMC(fmt, ...) \ do { \ if (rpu_debug & RPU_DEBUG_TSMC) \ pr_debug(fmt, ##__VA_ARGS__); \ } while (0) #define RPU_DEBUG_IF(fmt, ...) \ do { \ if (rpu_debug & RPU_DEBUG_IF) \ pr_debug(fmt, ##__VA_ARGS__); \ } while (0) #define RPU_DEBUG_HAL(fmt, ...) \ do { \ if ((rpu_debug & RPU_DEBUG_HAL) && net_ratelimit()) \ pr_debug(fmt, ##__VA_ARGS__); \ } while (0) #define RPU_DEBUG_DUMP_HAL(fmt, ...) \ do { \ if (rpu_debug & RPU_DEBUG_DUMP_HAL) \ print_hex_dump(KERN_DEBUG, fmt, ##__VA_ARGS__); \ } while (0) #define DUMP_HAL (rpu_debug & RPU_DEBUG_DUMP_HAL) #define RPU_DEBUG_DUMP_TX(fmt, ...) \ do { \ if (rpu_debug & RPU_DEBUG_DUMP_TX) \ print_hex_dump(KERN_DEBUG, "DUMP_TX", fmt, ##__VA_ARGS__); \ } while (0) #define DUMP_TX (rpu_debug & RPU_DEBUG_DUMP_TX) /* Wrapper to check return values for all * umac_if layer calls. */ #define CALL_RPU(prog_rpu, ...) \ do { \ ret = prog_rpu(__VA_ARGS__); \ if (ret != 0) { \ printk("%s:%d " #prog_rpu " failed ret %d\n", __FUNCTION__, __LINE__, ret); \ goto prog_rpu_fail; \ } \ } while (0) extern unsigned int ftm; extern unsigned char vif_macs[2][ETH_ALEN]; #define MAX_OUTSTANDING_CTRL_REQ 10 #define RESET_TIMEOUT 10000 /* In milli-seconds*/ #define RESET_TIMEOUT_TICKS msecs_to_jiffies(RESET_TIMEOUT) /*100: For ROC, 500: For initial*/ #define CH_PROG_TIMEOUT 1000 /* In milli-seconds*/ #define CH_PROG_TIMEOUT_TICKS msecs_to_jiffies(CH_PROG_TIMEOUT) #define QUEUE_FLUSH_TIMEOUT 2000 /* Specify delay in milli-seconds*/ #define QUEUE_FLUSH_TIMEOUT_TICKS msecs_to_jiffies(QUEUE_FLUSH_TIMEOUT) #define TX_DEINIT_TIMEOUT 5000 #define TX_DEINIT_TIMEOUT_TICKS msecs_to_jiffies(TX_DEINIT_TIMEOUT) #ifdef WOWLAN #ifdef CONFIG_PM #define PS_ECON_CFG_TIMEOUT 1000 #define PS_ECON_CFG_TIMEOUT_TICKS msecs_to_jiffies(PS_ECON_CFG_TIMEOUT) #endif /* CONFIG_PM */ #endif #define TX_COMPLETE_TIMEOUT 1000l /* In milli-seconds*/ #define TX_COMPLETE_TIMEOUT_TICKS msecs_to_jiffies(TX_COMPLETE_TIMEOUT) #define SCAN_ABORT_TIMEOUT 1000 #define SCAN_ABORT_TIMEOUT_TICKS msecs_to_jiffies(SCAN_ABORT_TIMEOUT) #define CANCEL_HW_ROC_TIMEOUT 1000 #define CANCEL_HW_ROC_TIMEOUT_TICKS msecs_to_jiffies(CANCEL_HW_ROC_TIMEOUT) #define DEFAULT_TX_ANT_SELECT 3 /* bitmap of antennas for tx, 3=> both first and * second antenna to be used */ #define DEFAULT_TX_POWER 15 #define DEFAULT_RTS_THRESHOLD 2347 #define SUPPORTED_FILTERS (FIF_ALLMULTI | FIF_BCN_PRBRESP_PROMISC) #define TX_DESC_BUCKET_BOUND 32 #define MAX_DATA_SIZE (0) /* Defined in HAL (or) can be configured from proc */ #define MAX_TX_QUEUE_LEN 192 /* Maximum number of Tx streams supported */ /* Maximum number of RX streams supported */ #define MAX_TX_STREAMS 1 #define MAX_RX_STREAMS 1 #define MAX_RSSI_SAMPLES 10 #define RPU_DBG_DEFAULT 0 #define CLOCK_MASK 0x3FFFFFFF #define TICK_NUMRATOR 12288 /* 12288 KHz */ #define TICK_DENOMINATOR 1000 /* 1000 KHz */ #define BTS_AP_24GHZ_ETS 195 /* Microsecs */ #define BTS_AP_5GHZ_ETS 25 /* Microsecs */ #define DEFAULT_MAC_ADDRESS "001122331416" enum ptype { UCAST = 0, MCAST }; enum noa_triggers { FROM_TX = 0, FROM_TX_DONE, FROM_EVENT_NOA }; enum rpu_hw_scan_status { HW_SCAN_STATUS_NONE, HW_SCAN_STATUS_PROGRESS }; enum rpu_debug { RPU_DEBUG_SCAN = BIT(1), RPU_DEBUG_ROC = BIT(2), RPU_DEBUG_TX = BIT(3), RPU_DEBUG_MAIN = BIT(4), RPU_DEBUG_IF = BIT(5), RPU_DEBUG_UMACIF = BIT(6), RPU_DEBUG_RX = BIT(7), RPU_DEBUG_HAL = BIT(8), RPU_DEBUG_CRYPTO = BIT(9), RPU_DEBUG_DUMP_RX = BIT(10), RPU_DEBUG_DUMP_HAL = BIT(11), RPU_DEBUG_TSMC = BIT(12), RPU_DEBUG_P2P = BIT(13), RPU_DEBUG_VIF = BIT(14), RPU_DEBUG_DUMP_TX = BIT(15), }; struct umac_rx_event_info { unsigned int rx_pkt_cnt; unsigned int ddr_ptr[HAL_INT_EVENT_MAX_RX]; unsigned int pkt_len[HAL_INT_EVENT_MAX_RX]; unsigned int host_desc_num[HAL_INT_EVENT_MAX_RX]; char align_offset[HAL_INT_EVENT_MAX_RX]; }; struct wifi_sync { unsigned int status; unsigned char ts1[8]; unsigned long long atu; unsigned char bssid[8]; unsigned char name[10]; unsigned int ts2; }; struct wifi_params { int num_vifs; int tx_fixed_rate; int tx_fixed_mcs_indx; int mgd_mode_tx_fixed_rate; int mgd_mode_tx_fixed_mcs_indx; unsigned char is_associated; unsigned char rate_protection_type; unsigned char num_spatial_streams; unsigned char uccp_num_spatial_streams; /*RF Params: Input to the RF for operation*/ unsigned char rf_params[RF_PARAMS_SIZE]; unsigned int phy_calib; unsigned char production_test; int mode; unsigned int dot11a_support; unsigned int dot11g_support; unsigned int chnl_bw; unsigned int prod_mode_chnl_bw_40_mhz; unsigned int sec_ch_offset_40_plus; unsigned int sec_ch_offset_40_minus; /*Multicast Rate config options*/ unsigned int mgd_mode_mcast_fixed_rate_flags; int mgd_mode_mcast_fixed_data_rate; unsigned int mgd_mode_mcast_fixed_bcc_or_ldpc; unsigned int mgd_mode_mcast_fixed_stbc_enabled; unsigned int mgd_mode_mcast_fixed_preamble; unsigned char mgd_mode_mcast_fixed_nss; /*End*/ unsigned int prod_mode_rate_flag; unsigned int prod_mode_rate_preamble_type; unsigned int prod_mode_stbc_enabled; unsigned int prod_mode_bcc_or_ldpc; unsigned int max_tx_streams; unsigned int max_rx_streams; unsigned int max_data_size; unsigned int disable_power_save; unsigned int disable_sm_power_save; unsigned int max_tx_cmds; unsigned int prod_mode_chnl_bw_80_mhz; unsigned int sec_40_ch_offset_80_plus; unsigned int sec_40_ch_offset_80_minus; unsigned int vht_beamform_enable; unsigned int vht_beamform_period; unsigned int vht_beamform_support; unsigned int hw_scan_status; unsigned int scan_type; unsigned int set_tx_power; unsigned int aux_adc_chain_id; unsigned int rssi_average; unsigned int antenna_sel; int pkt_gen_val; int payload_length; unsigned int cont_tx; unsigned int primary_num; int stats_type; unsigned int pdout_voltage; unsigned char prod_mode_rate_flags; char phy_threshold; }; struct cmd_send_recv_cnt { int tx_cmd_send_count; int tx_done_recv_count; int total_cmd_send_count; unsigned int outstanding_ctrl_req; unsigned long control_path_flags; spinlock_t control_path_lock; LST_T outstanding_cmd; }; struct wifi_stats { unsigned int ht_tx_mcs0_packet_count; unsigned int ht_tx_mcs1_packet_count; unsigned int ht_tx_mcs2_packet_count; unsigned int ht_tx_mcs3_packet_count; unsigned int ht_tx_mcs4_packet_count; unsigned int ht_tx_mcs5_packet_count; unsigned int ht_tx_mcs6_packet_count; unsigned int ht_tx_mcs7_packet_count; unsigned int ht_tx_mcs8_packet_count; unsigned int ht_tx_mcs9_packet_count; unsigned int ht_tx_mcs10_packet_count; unsigned int ht_tx_mcs11_packet_count; unsigned int ht_tx_mcs12_packet_count; unsigned int ht_tx_mcs13_packet_count; unsigned int ht_tx_mcs14_packet_count; unsigned int ht_tx_mcs15_packet_count; #ifdef RPU_VHT_SUPPORT unsigned int vht_tx_mcs0_packet_count; unsigned int vht_tx_mcs1_packet_count; unsigned int vht_tx_mcs2_packet_count; unsigned int vht_tx_mcs3_packet_count; unsigned int vht_tx_mcs4_packet_count; unsigned int vht_tx_mcs5_packet_count; unsigned int vht_tx_mcs6_packet_count; unsigned int vht_tx_mcs7_packet_count; unsigned int vht_tx_mcs8_packet_count; unsigned int vht_tx_mcs9_packet_count; #endif /* RPU_VHT_SUPPORT */ unsigned int tx_cmds_from_stack; unsigned int tx_dones_to_stack; unsigned int outstanding_cmd_cnt; unsigned int pending_tx_cnt; unsigned int gen_cmd_send_count; unsigned int tx_cmd_send_count_single; unsigned int tx_cmd_send_count_multi; unsigned int tx_cmd_send_count_beaconq; unsigned int tx_done_recv_count; unsigned int tx_noagg_not_qos; unsigned int tx_noagg_not_ampdu; unsigned int tx_noagg_not_addr; unsigned int ofdm_crc32_pass_cnt; unsigned int ofdm_crc32_fail_cnt; unsigned int dsss_crc32_pass_cnt; unsigned int dsss_crc32_fail_cnt; }; struct tx_pkt_info { struct sk_buff_head pkt; unsigned int hdr_len; unsigned int queue; unsigned int vif_index; unsigned int rate[4]; unsigned int retries[4]; unsigned int curr_retries; unsigned int max_retries; int roc_peer_id; int peer_id; bool adjusted_rates; #ifdef ENABLE_COALESCING_TX_PKTS unsigned int tx_buff_pkt_count; unsigned int tx_buff_pkt_ref[MAX_TX_CMDS]; struct sk_buff *deferred_skb; /* sent partial number of packets rest may sent through onther descriptor */ #endif /* ENABLE_COALESCING_TX_PKTS */ }; struct tx_config { /* Used to protect the TX pool */ spinlock_t lock; /* Used to store tx tokens(buff pool ids) */ unsigned long buf_pool_bmp[(NUM_TX_DESCS/TX_DESC_BUCKET_BOUND) + 1]; unsigned int outstanding_tokens[NUM_ACS]; unsigned int next_spare_token_ac; /* Used to store the address of pending skbs per ac */ struct sk_buff_head pending_pkt[MAX_PEND_Q_PER_AC] [NUM_ACS]; unsigned int curr_peer_opp[NUM_ACS]; /* Used to store the address of tx'ed skb and len of 802.11 hdr * it will be used in tx complete. */ struct tx_pkt_info pkt_info[NUM_TX_DESCS]; unsigned int queue_stopped_bmp; struct sk_buff_head proc_tx_list[NUM_TX_DESCS]; }; enum device_state { STOPPED = 0, STARTED }; enum tid_aggr_state { TID_STATE_INVALID = 0, TID_STATE_AGGR_START, TID_STATE_AGGR_STOP, TID_STATE_AGGR_OPERATIONAL }; #define TID_INITIATOR_STA 0x0000 #define TID_INITIATOR_AP 0x0010 struct sta_tid_info { unsigned short ssn; enum tid_aggr_state tid_state; }; #ifdef WOWLAN #ifdef CONFIG_PM struct econ_ps_cfg_status { unsigned char completed; unsigned char result; int wake_trig; }; #endif /* CONFIG_PM */ #endif struct current_channel { unsigned int pri_chnl_num; unsigned int center_freq1; unsigned int center_freq2; unsigned int freq_band; unsigned int ch_width; }; struct roc_params { unsigned char roc_in_progress; unsigned int roc_type; bool need_offchan; atomic_t roc_mgmt_tx_count; }; struct rpu_if_data { char *name; void *context; }; struct img_priv { struct device *dev; struct mac_address if_mac_addresses[MAX_VIFS]; unsigned int current_vif_count; unsigned int active_vifs; DEFINE_MUTEX(mutex); int state; int txpower; unsigned char mc_filters[MCST_ADDR_LIMIT][6]; int mc_filter_count; /*ROC Work*/ struct delayed_work roc_complete_work; struct roc_params roc_params; struct current_channel cur_chan; struct tx_config tx; struct sk_buff_head pending_pkt[NUM_ACS]; #ifdef WOWLAN #ifdef CONFIG_PM struct econ_ps_cfg_status econ_ps_cfg_stats; #endif /* CONFIG_PM */ #endif struct wifi_params *params; struct wifi_stats *stats; union rpu_stats *rpu_stats; SEMAPHORE_T scan_abort_done_sem; SEMAPHORE_T cancel_hw_roc_done_sem; SEMAPHORE_T chan_prog_done_sem; SEMAPHORE_T reset_complete_sem; int power_save; /* Will be set only when a single VIF in * STA mode is active */ struct ieee80211_vif *vifs[MAX_VIFS]; struct ieee80211_sta *peers[MAX_PEERS]; struct ieee80211_hw *hw; struct sta_tid_info tid_info[32]; spinlock_t bcast_lock; /* Used to ensure more_frames bit is set properly * when transmitting bcast frames in AP in IBSS * modes */ spinlock_t roc_lock; spinlock_t pkt_gen_lock; char name[12]; /* Regulatory stuff */ char alpha2[2]; /* alpha2 country code */ char scan_abort_done; char cancel_hw_roc_done; char cancel_roc; char chan_prog_done; char reset_complete; char tx_deinit_complete; unsigned char tx_antenna; unsigned char tx_last_beacon; unsigned char ru_tx; unsigned char block_tx_done; unsigned int rts_threshold; unsigned int unexpected_code_path; unsigned long rx_trigger_jiffie_value; unsigned int trig_recv_cnt; }; RETENTION_MEM_SECTION_UNINITIALIZED extern struct wifi_dev *wifi; struct wifi_dev { struct wifi_params params; struct wifi_stats stats; struct ieee80211_hw *hw; int unexpected_code_path; unsigned char *patch_ptr; }; struct edca_params { unsigned short txop; /* units of 32us */ unsigned short cwmin;/* units of 2^n-1 */ unsigned short cwmax;/* units of 2^n-1 */ unsigned char aifs; unsigned char uapsd; }; struct umac_vif { struct timer_list bcn_timer; struct uvif_config { unsigned int atim_window; unsigned int aid; unsigned int bcn_lost_cnt; struct edca_params edca_params[NUM_ACS]; } config; unsigned int noa_active; struct sk_buff_head noa_que; spinlock_t noa_que_lock; unsigned int noa_tx_allowed; int vif_index; struct ieee80211_vif *vif; struct img_priv *priv; unsigned char bssid[ETH_ALEN]; /*Global Sequence no for non-qos and mgmt frames/vif*/ __u16 seq_no; #ifdef RPU_WAPI_SUPPORT #define WAPI_PN_LEN 16 unsigned char pn128[WAPI_PN_LEN]; #endif /* RPU_WAPI_SUPPORT */ }; struct umac_sta { int index; int vif_index; }; struct curr_peer_info { int id; int op_chan_idx; }; extern int rpu_prog_srg(struct umac_vif *uvif, struct ieee80211_he_obss_pd obss_pd, struct ieee80211_he_operation he_op); extern int rpu_core_init(struct img_priv *priv, unsigned int ftm); extern void rpu_core_deinit(struct img_priv *priv, unsigned int ftm); extern void rpu_vif_add(struct umac_vif *uvif); extern void rpu_vif_remove(struct umac_vif *uvif); extern void rpu_vif_set_edca_params(unsigned short queue, struct umac_vif *uvif, struct edca_params *params, unsigned int vif_active); extern void rpu_vif_bss_info_changed(struct umac_vif *uvif, struct ieee80211_bss_conf *bss_conf, unsigned int changed); extern int rpu_tx_frame(struct sk_buff *skb, struct ieee80211_sta *sta, struct img_priv *priv, bool bcast); extern int __rpu_tx_frame(struct img_priv *priv, unsigned int queue, unsigned int token_id, unsigned int more_frames, bool retry); extern void rpu_tx_init(struct img_priv *priv); extern void rpu_tx_deinit(struct img_priv *priv); void rpu_tx_proc_send_pend_frms_all(struct img_priv *priv, int chan_id); extern void proc_bss_info_changed(unsigned char *mac_addr, int value); extern void packet_generation(unsigned long data); extern int wait_for_reset_complete(struct img_priv *priv); extern int rpu_tx_proc_pend_frms(struct img_priv *priv, int queue, int token_id); void free_token(struct img_priv *priv, int token_id, int queue); struct curr_peer_info get_curr_peer_opp(struct img_priv *priv, int queue); int rpu_flush_vif_queues(struct img_priv *priv, struct umac_vif *uvif, int chanctx_idx, unsigned int hw_queue_map, enum LMAC_VIF_CHANCTX_TYPE vif_chanctx_type, bool drop); int rpu_discard_sta_pend_q(struct img_priv *priv, struct umac_vif *uvif, int peer_id, unsigned int hw_queue_map); int rpu_discard_sta_tx_q(struct img_priv *priv, struct umac_vif *uvif, int peer_id, unsigned int hw_queue_map, int chanctx_idx); /* Beacon TimeStamp */ __s32 __attribute__((weak)) frc_to_atu(__u32 frccnt, __u64 *patu, s32 dir); int __attribute__((weak)) get_evt_timer_freq(unsigned int *mask, unsigned int *num, unsigned int *denom); int tx_queue_map(int queue); int tx_queue_unmap(int queue); extern int num_streams_vpd; static inline int vif_addr_to_index(unsigned char *addr, struct img_priv *priv) { int i; struct ieee80211_vif *vif = NULL; for (i = 0; i < MAX_VIFS; i++) { if (!((i < MAX_VIFS) && (priv->active_vifs & (1 << i)))) continue; rcu_read_lock(); vif = rcu_dereference(priv->vifs[i]); rcu_read_unlock(); if (ether_addr_equal(addr, vif->addr)) break; } if (i < priv->params->num_vifs) return i; else return -1; } static inline int ieee80211_is_unicast_robust_mgmt_frame(struct sk_buff *skb) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; if (skb->len < 24 || is_multicast_ether_addr(hdr->addr1)) return 0; return ieee80211_is_robust_mgmt_frame(skb); } static inline bool is_bufferable_mgmt_frame(struct ieee80211_hdr *hdr) { __u16 fc = hdr->frame_control; /*TODO: Handle Individual Probe Response frame in IBSS*/ if (ieee80211_is_action(fc) || ieee80211_is_disassoc(fc) || ieee80211_is_deauth(fc)) return true; return false; } static inline void img_ether_addr_copy(unsigned char *dst, const unsigned char *src) { ether_addr_copy(dst, src); } int proc_init(struct proc_dir_entry ***main_dir_entry); int rpu_init(void); void rpu_exit(void); void proc_exit(void); void update_mcs_packet_stat(int mcs_rate_num, int rate_flags, struct img_priv *priv); int rpu_proc_tx(struct img_priv *priv); #ifdef RPU_SERIES_4 int load_fw(struct ieee80211_hw *hw); #else /* RPU_SERIES_4 */ int load_rompatch (struct ieee80211_hw *hw); #endif /* RPU_SERIES_4 */ void stop(struct ieee80211_hw *hw); int start_prod_mode(struct img_priv *priv, unsigned int val); int stop_prod_mode(struct img_priv *priv, unsigned int val); int start_packet_gen(struct img_priv *priv, int sval); int stop_packet_gen(struct img_priv *priv, int sval); int img_get_rate_prod(struct lmac_cmd_tx *txcmd, struct img_priv *priv); int img_resume(struct ieee80211_hw *hw); int img_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan); void init_beacon (struct umac_vif *uvif); void deinit_beacon (struct umac_vif *uvif); void modify_beacon_params (struct umac_vif *uvif, struct ieee80211_bss_conf *bss_conf); extern void read_mem_region(unsigned int,int); #define RPU_READY_TIMEOUT 200 #define RPU_READY_TIMEOUT_TICKS msecs_to_jiffies(RPU_READY_TIMEOUT) #define RPU_EVENT_RPU_READY 0xDEAD #endif /* _CORE_H_ */