| /**************************************************************************** |
| * |
| * Copyright (c) 2014 - 2020 Samsung Electronics Co., Ltd. All rights reserved |
| * |
| ****************************************************************************/ |
| |
| #ifndef __HIP4_H__ |
| #define __HIP4_H__ |
| |
| /** |
| * This header file is the public HIP4 interface, which will be accessible by |
| * Wi-Fi service driver components. |
| * |
| * All struct and internal HIP functions shall be moved to a private header |
| * file. |
| */ |
| |
| #include <linux/interrupt.h> |
| #include <linux/types.h> |
| #include <linux/device.h> |
| #include <linux/skbuff.h> |
| #include <scsc/scsc_mifram.h> |
| #include <scsc/scsc_mx.h> |
| #ifdef CONFIG_SCSC_WLAN_RX_NAPI |
| #include <linux/netdevice.h> |
| #endif |
| #ifdef CONFIG_SCSC_WLAN_ANDROID |
| #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) |
| #include <scsc/scsc_wakelock.h> |
| #else |
| #include <linux/wakelock.h> |
| #endif |
| #endif |
| #include "mbulk.h" |
| #ifdef CONFIG_SCSC_SMAPPER |
| #include "hip4_smapper.h" |
| #endif |
| |
| /* Shared memory Layout |
| * |
| * |-------------------------| CONFIG |
| * | CONFIG + Queues | |
| * | --------- | |
| * | MIB | |
| * |-------------------------| TX Pool |
| * | TX DAT | |
| * | --------- | |
| * | TX CTL | |
| * |-------------------------| RX Pool |
| * | RX | |
| * |-------------------------| |
| */ |
| |
| /**** OFFSET SHOULD BE 4096 BYTES ALIGNED ***/ |
| /*** CONFIG POOL ***/ |
| #define HIP4_WLAN_CONFIG_OFFSET 0x00000 |
| #define HIP4_WLAN_CONFIG_SIZE 0x02000 /* 8 kB */ |
| /*** MIB POOL ***/ |
| #define HIP4_WLAN_MIB_OFFSET (HIP4_WLAN_CONFIG_OFFSET + HIP4_WLAN_CONFIG_SIZE) |
| #define HIP4_WLAN_MIB_SIZE 0x08000 /* 32 kB */ |
| /*** TX POOL ***/ |
| #define HIP4_WLAN_TX_OFFSET (HIP4_WLAN_MIB_OFFSET + HIP4_WLAN_MIB_SIZE) |
| /*** TX POOL - DAT POOL ***/ |
| #define HIP4_WLAN_TX_DAT_OFFSET HIP4_WLAN_TX_OFFSET |
| #define HIP4_WLAN_TX_DAT_SIZE 0x100000 /* 1 MB */ |
| /*** TX POOL - CTL POOL ***/ |
| #define HIP4_WLAN_TX_CTL_OFFSET (HIP4_WLAN_TX_DAT_OFFSET + HIP4_WLAN_TX_DAT_SIZE) |
| #define HIP4_WLAN_TX_CTL_SIZE 0x10000 /* 64 kB */ |
| #define HIP4_WLAN_TX_SIZE (HIP4_WLAN_TX_DAT_SIZE + HIP4_WLAN_TX_CTL_SIZE) |
| /*** RX POOL ***/ |
| #define HIP4_WLAN_RX_OFFSET (HIP4_WLAN_TX_CTL_OFFSET + HIP4_WLAN_TX_CTL_SIZE) |
| #ifdef CONFIG_SCSC_PCIE |
| #define HIP4_WLAN_RX_SIZE 0x80000 /* 512 kB */ |
| #else |
| #define HIP4_WLAN_RX_SIZE 0x100000 /* 1 MB */ |
| #endif |
| /*** TOTAL : CONFIG POOL + TX POOL + RX POOL ***/ |
| #define HIP4_WLAN_TOTAL_MEM (HIP4_WLAN_CONFIG_SIZE + HIP4_WLAN_MIB_SIZE + \ |
| HIP4_WLAN_TX_SIZE + HIP4_WLAN_RX_SIZE) /* 2 MB + 104 KB*/ |
| |
| #define HIP4_POLLING_MAX_PACKETS 512 |
| |
| #define HIP4_DAT_MBULK_SIZE (2 * 1024) |
| #define HIP4_DAT_SLOTS (HIP4_WLAN_TX_DAT_SIZE / HIP4_DAT_MBULK_SIZE) |
| #define HIP4_CTL_MBULK_SIZE (2 * 1024) |
| #define HIP4_CTL_SLOTS (HIP4_WLAN_TX_CTL_SIZE / HIP4_CTL_MBULK_SIZE) |
| |
| #define MIF_HIP_CFG_Q_NUM 6 |
| |
| #define MIF_NO_IRQ 0xff |
| |
| /* Current versions supported by this HIP */ |
| #define HIP4_SUPPORTED_V1 3 |
| #define HIP4_SUPPORTED_V2 4 |
| |
| enum hip4_hip_q_conf { |
| HIP4_MIF_Q_FH_CTRL, |
| HIP4_MIF_Q_FH_DAT, |
| HIP4_MIF_Q_FH_RFB, |
| HIP4_MIF_Q_TH_CTRL, |
| HIP4_MIF_Q_TH_DAT, |
| HIP4_MIF_Q_TH_RFB |
| }; |
| |
| struct hip4_hip_config_version_4 { |
| /* Host owned */ |
| u32 magic_number; /* 0xcaba0401 */ |
| u16 hip_config_ver; /* Version of this configuration structure = 2*/ |
| u16 config_len; /* Size of this configuration structure */ |
| |
| /* FW owned */ |
| u32 compat_flag; /* flag of the expected driver's behaviours */ |
| |
| u16 sap_mlme_ver; /* Fapi SAP_MLME version*/ |
| u16 sap_ma_ver; /* Fapi SAP_MA version */ |
| u16 sap_debug_ver; /* Fapi SAP_DEBUG version */ |
| u16 sap_test_ver; /* Fapi SAP_TEST version */ |
| |
| u32 fw_build_id; /* Firmware Build Id */ |
| u32 fw_patch_id; /* Firmware Patch Id */ |
| |
| u8 unidat_req_headroom; /* Headroom the host shall reserve in mbulk for MA-UNITDATA.REQ signal */ |
| u8 unidat_req_tailroom; /* Tailroom the host shall reserve in mbulk for MA-UNITDATA.REQ signal */ |
| u8 bulk_buffer_align; /* 4 */ |
| |
| /* Host owned */ |
| u8 host_cache_line; /* 64 */ |
| |
| u32 host_buf_loc; /* location of the host buffer in MIF_ADDR */ |
| u32 host_buf_sz; /* in byte, size of the host buffer */ |
| u32 fw_buf_loc; /* location of the firmware buffer in MIF_ADDR */ |
| u32 fw_buf_sz; /* in byte, size of the firmware buffer */ |
| u32 mib_loc; /* MIB location in MIF_ADDR */ |
| u32 mib_sz; /* MIB size */ |
| u32 log_config_loc; /* Logging Configuration Location in MIF_ADDR */ |
| u32 log_config_sz; /* Logging Configuration Size in MIF_ADDR */ |
| |
| u8 mif_fh_int_n; /* MIF from-host interrupt bit position for all HIP queue */ |
| u8 reserved1[3]; |
| |
| u8 mif_th_int_n[6]; /* MIF to-host interrupt bit positions for each HIP queue */ |
| u8 reserved2[2]; |
| |
| u32 scbrd_loc; /* Scoreboard locatin in MIF_ADDR */ |
| |
| u16 q_num; /* 6 */ |
| u16 q_len; /* 256 */ |
| u16 q_idx_sz; /* 1 */ |
| u8 reserved3[2]; |
| |
| u32 q_loc[MIF_HIP_CFG_Q_NUM]; |
| |
| #ifdef CONFIG_SCSC_SMAPPER |
| u8 smapper_th_req; /* TH smapper request interrupt bit position */ |
| u8 smapper_fh_ind; /* FH smapper ind interrupt bit position */ |
| u8 smapper_mbox_scb; /* SMAPPER MBOX scoreboard location */ |
| u8 smapper_entries_banks[16]; /* num entries banks */ |
| u8 smapper_pow_sz[16]; /* Power of size of entry i.e. 12 = 4096B */ |
| u32 smapper_bank_addr[16]; /* Bank start addr */ |
| #else |
| u8 reserved_nosmapper[99]; |
| #endif |
| u8 reserved4[16]; |
| } __packed; |
| |
| struct hip4_hip_config_version_5 { |
| /* Host owned */ |
| u32 magic_number; /* 0xcaba0401 */ |
| u16 hip_config_ver; /* Version of this configuration structure = 2*/ |
| u16 config_len; /* Size of this configuration structure */ |
| |
| /* FW owned */ |
| u32 compat_flag; /* flag of the expected driver's behaviours */ |
| |
| u16 sap_mlme_ver; /* Fapi SAP_MLME version*/ |
| u16 sap_ma_ver; /* Fapi SAP_MA version */ |
| u16 sap_debug_ver; /* Fapi SAP_DEBUG version */ |
| u16 sap_test_ver; /* Fapi SAP_TEST version */ |
| |
| u32 fw_build_id; /* Firmware Build Id */ |
| u32 fw_patch_id; /* Firmware Patch Id */ |
| |
| u8 unidat_req_headroom; /* Headroom the host shall reserve in mbulk for MA-UNITDATA.REQ signal */ |
| u8 unidat_req_tailroom; /* Tailroom the host shall reserve in mbulk for MA-UNITDATA.REQ signal */ |
| u8 bulk_buffer_align; /* 4 */ |
| |
| /* Host owned */ |
| u8 host_cache_line; /* 64 */ |
| |
| u32 host_buf_loc; /* location of the host buffer in MIF_ADDR */ |
| u32 host_buf_sz; /* in byte, size of the host buffer */ |
| u32 fw_buf_loc; /* location of the firmware buffer in MIF_ADDR */ |
| u32 fw_buf_sz; /* in byte, size of the firmware buffer */ |
| u32 mib_loc; /* MIB location in MIF_ADDR */ |
| u32 mib_sz; /* MIB size */ |
| u32 log_config_loc; /* Logging Configuration Location in MIF_ADDR */ |
| u32 log_config_sz; /* Logging Configuration Size in MIF_ADDR */ |
| |
| u8 mif_fh_int_n; /* MIF from-host interrupt bit position */ |
| u8 mif_th_int_n; /* MIF to-host interrpt bit position */ |
| u8 reserved[2]; |
| |
| u32 scbrd_loc; /* Scoreboard locatin in MIF_ADDR */ |
| |
| u16 q_num; /* 6 */ |
| u16 q_len; /* 256 */ |
| u16 q_idx_sz; /* 1 */ |
| u8 reserved2[2]; |
| |
| u32 q_loc[MIF_HIP_CFG_Q_NUM]; |
| |
| u8 reserved3[16]; |
| } __packed; |
| |
| struct hip4_hip_init { |
| /* Host owned */ |
| u32 magic_number; /* 0xcaaa0400 */ |
| /* FW owned */ |
| u32 conf_hip4_ver; |
| /* Host owned */ |
| u32 version_a_ref; /* Location of Config structure A (old) */ |
| u32 version_b_ref; /* Location of Config structure B (new) */ |
| } __packed; |
| |
| #define MAX_NUM 256 |
| struct hip4_hip_q { |
| u32 array[MAX_NUM]; |
| u8 idx_read; /* To keep track */ |
| u8 idx_write; /* To keep track */ |
| u8 total; |
| } __aligned(64); |
| |
| struct hip4_hip_control { |
| struct hip4_hip_init init; |
| struct hip4_hip_config_version_5 config_v5 __aligned(32); |
| struct hip4_hip_config_version_4 config_v4 __aligned(32); |
| u32 scoreboard[256] __aligned(64); |
| struct hip4_hip_q q[MIF_HIP_CFG_Q_NUM] __aligned(64); |
| } __aligned(4096); |
| |
| struct slsi_hip4; |
| |
| /* This struct is private to the HIP implementation */ |
| struct hip4_priv { |
| #ifdef CONFIG_SCSC_WLAN_RX_NAPI |
| /* NAPI CPU switch lock */ |
| spinlock_t napi_cpu_lock; |
| struct work_struct intr_wq_napi_cpu_switch; |
| struct work_struct intr_wq_ctrl; |
| struct tasklet_struct intr_tl_fb; |
| struct napi_struct napi; |
| unsigned long napi_state; |
| bool napi_perf_mode; |
| u8 napi_rx_full_cnt; |
| u8 napi_rx_saturated; |
| #else |
| struct work_struct intr_wq; |
| #endif |
| /* Interrupts cache < v4 */ |
| /* TOHOST */ |
| u32 intr_tohost; |
| |
| /* Interrupts cache v4 */ |
| u32 intr_tohost_mul[MIF_HIP_CFG_Q_NUM]; |
| /* FROMHOST */ |
| u32 intr_fromhost; |
| |
| /* For workqueue */ |
| struct slsi_hip4 *hip; |
| |
| /* Pool for data frames*/ |
| u8 host_pool_id_dat; |
| /* Pool for ctl frames*/ |
| u8 host_pool_id_ctl; |
| |
| /* rx cycle lock */ |
| spinlock_t rx_lock; |
| /* tx cycle lock */ |
| spinlock_t tx_lock; |
| |
| /* Scoreboard update spinlock */ |
| rwlock_t rw_scoreboard; |
| |
| /* Watchdog timer */ |
| struct timer_list watchdog; |
| /* wd spinlock */ |
| spinlock_t watchdog_lock; |
| /* wd timer control */ |
| atomic_t watchdog_timer_active; |
| #ifdef CONFIG_SCSC_WLAN_RX_NAPI |
| DECLARE_BITMAP(irq_bitmap, MIF_HIP_CFG_Q_NUM); |
| #endif |
| |
| #ifdef CONFIG_SCSC_WLAN_ANDROID |
| #ifdef CONFIG_SCSC_WLAN_RX_NAPI |
| #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) |
| struct scsc_wake_lock hip4_wake_lock_tx; |
| struct scsc_wake_lock hip4_wake_lock_ctrl; |
| struct scsc_wake_lock hip4_wake_lock_data; |
| #else |
| |
| struct wake_lock hip4_wake_lock_tx; |
| struct wake_lock hip4_wake_lock_ctrl; |
| struct wake_lock hip4_wake_lock_data; |
| #endif |
| #endif |
| /* Wakelock for modem_ctl */ |
| #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) |
| struct scsc_wake_lock hip4_wake_lock; |
| #else |
| struct wake_lock hip4_wake_lock; |
| #endif |
| #endif |
| |
| /* Control the hip4 deinit */ |
| atomic_t closing; |
| atomic_t in_tx; |
| atomic_t in_rx; |
| atomic_t in_suspend; |
| u32 storm_count; |
| |
| struct { |
| atomic_t irqs; |
| atomic_t spurious_irqs; |
| u32 q_num_frames[MIF_HIP_CFG_Q_NUM]; |
| ktime_t start; |
| struct proc_dir_entry *procfs_dir; |
| } stats; |
| |
| #ifdef CONFIG_SCSC_WLAN_HIP4_PROFILING |
| /*minor*/ |
| u32 minor; |
| #endif |
| u8 unidat_req_headroom; /* Headroom the host shall reserve in mbulk for MA-UNITDATA.REQ signal */ |
| u8 unidat_req_tailroom; /* Tailroom the host shall reserve in mbulk for MA-UNITDATA.REQ signal */ |
| u32 version; /* Version of the running FW */ |
| void *scbrd_base; /* Scbrd_base pointer */ |
| |
| /* Global domain Q control*/ |
| atomic_t gactive; |
| atomic_t gmod; |
| atomic_t gcod; |
| int saturated; |
| int guard; |
| /* Global domain Q spinlock */ |
| spinlock_t gbot_lock; |
| |
| #ifdef CONFIG_SCSC_SMAPPER |
| /* SMAPPER */ |
| /* Leman has 4 Banks of 160 entries each and 4 Banks of 64 entries each. Each Tx stream is |
| * expected to use 2 Bank . In RSDB, 5GHz streams require higher throughput |
| * so the bigger banks are allocated for 5GHz streams and the |
| * smaller banks are for 2.4GHz streams |
| */ |
| struct hip4_smapper_bank smapper_banks[HIP4_SMAPPER_TOTAL_BANKS]; |
| struct hip4_smapper_control smapper_control; |
| #endif |
| #ifdef CONFIG_SCSC_QOS |
| /* PM QoS control */ |
| struct work_struct pm_qos_work; |
| /* PM QoS control spinlock */ |
| spinlock_t pm_qos_lock; |
| u8 pm_qos_state; |
| #endif |
| /* Collection artificats */ |
| void *mib_collect; |
| u16 mib_sz; |
| /* Mutex to protect hcf file collection if a tear down is triggered */ |
| struct mutex in_collection; |
| |
| struct workqueue_struct *hip4_workq; |
| }; |
| |
| struct scsc_service; |
| |
| struct slsi_hip4 { |
| struct hip4_priv *hip_priv; |
| struct hip4_hip_control *hip_control; |
| scsc_mifram_ref hip_ref; |
| }; |
| |
| /* Public functions */ |
| int hip4_init(struct slsi_hip4 *hip); |
| int hip4_setup(struct slsi_hip4 *hip); |
| void hip4_suspend(struct slsi_hip4 *hip); |
| void hip4_resume(struct slsi_hip4 *hip); |
| void hip4_freeze(struct slsi_hip4 *hip); |
| void hip4_deinit(struct slsi_hip4 *hip); |
| int hip4_free_ctrl_slots_count(struct slsi_hip4 *hip); |
| void hip4_set_napi_cpu(struct slsi_hip4 *hip, u8 napi_cpu, bool perf_mode); |
| int scsc_wifi_transmit_frame(struct slsi_hip4 *hip, struct sk_buff *skb, bool ctrl_packet, u8 vif_index, u8 peer_index, u8 priority); |
| #ifdef CONFIG_SCSC_WLAN_RX_NAPI |
| void hip4_sched_wq_ctrl(struct slsi_hip4 *hip); |
| #else |
| void hip4_sched_wq(struct slsi_hip4 *hip); |
| #endif |
| |
| /* Macros for accessing information stored in the hip_config struct */ |
| #define scsc_wifi_get_hip_config_version_4_u8(buff_ptr, member) le16_to_cpu((((struct hip4_hip_config_version_4 *)(buff_ptr))->member)) |
| #define scsc_wifi_get_hip_config_version_4_u16(buff_ptr, member) le16_to_cpu((((struct hip4_hip_config_version_4 *)(buff_ptr))->member)) |
| #define scsc_wifi_get_hip_config_version_4_u32(buff_ptr, member) le32_to_cpu((((struct hip4_hip_config_version_4 *)(buff_ptr))->member)) |
| #define scsc_wifi_get_hip_config_version_5_u8(buff_ptr, member) le16_to_cpu((((struct hip4_hip_config_version_5 *)(buff_ptr))->member)) |
| #define scsc_wifi_get_hip_config_version_5_u16(buff_ptr, member) le16_to_cpu((((struct hip4_hip_config_version_5 *)(buff_ptr))->member)) |
| #define scsc_wifi_get_hip_config_version_5_u32(buff_ptr, member) le32_to_cpu((((struct hip4_hip_config_version_5 *)(buff_ptr))->member)) |
| #define scsc_wifi_get_hip_config_u8(buff_ptr, member, ver) le16_to_cpu((((struct hip4_hip_config_version_##ver *)(buff_ptr->config_v##ver))->member)) |
| #define scsc_wifi_get_hip_config_u16(buff_ptr, member, ver) le16_to_cpu((((struct hip4_hip_config_version_##ver *)(buff_ptr->config_v##ver))->member)) |
| #define scsc_wifi_get_hip_config_u32(buff_ptr, member, ver) le32_to_cpu((((struct hip4_hip_config_version_##ver *)(buff_ptr->config_v##ver))->member)) |
| #define scsc_wifi_get_hip_config_version(buff_ptr) le32_to_cpu((((struct hip4_hip_init *)(buff_ptr))->conf_hip4_ver)) |
| |
| #endif |