blob: 026ad5255a302c2453dfcd632b96963f1ee1e75a [file] [log] [blame]
/****************************************************************************
*
* Copyright (c) 2014 - 2017 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>
#ifndef SLSI_TEST_DEV
#include <linux/wakelock.h>
#endif
#include "mbulk.h"
#define MIF_HIP_COMPAT_FLAG_NEED_MLME_RESET BIT(0)
#define MIF_HIP_COMPAT_FLAG_MIB_DAT_BY_FAPI BIT(1)
#define HIP4_DAT_SLOTS 218
#define HIP4_CTL_SLOTS 32
#define MIF_HIP_CFG_Q_NUM 6
/* 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 */
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_config_version_3 {
/* 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_3 config_v3 __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;
/* #define TASKLET 1 */
/* This struct is private to the HIP implementation */
struct hip4_priv {
#ifdef TASKLET
struct tasklet_struct intr_tq;
#else
struct work_struct intr_wq;
#endif
/* Interrupts cache */
/* TOHOST */
u32 rx_intr_tohost;
/* FROMHOST */
u32 rx_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;
#ifndef TASKLET
/* rx cycle lock */
spinlock_t rx_lock;
#endif
/* 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;
#ifndef SLSI_TEST_DEV
/* Wakelock for modem_ctl */
struct wake_lock hip4_wake_lock;
#endif
/* Control the hip4 init */
atomic_t rx_ready;
/* 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;
/* 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);
int scsc_wifi_transmit_frame(struct slsi_hip4 *hip, bool ctrl_packet, struct sk_buff *skb);
/* 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_3_u8(buff_ptr, member) le16_to_cpu((((struct hip4_hip_config_version_4 *)(buff_ptr))->member))
#define scsc_wifi_get_hip_config_version_3_u16(buff_ptr, member) le16_to_cpu((((struct hip4_hip_config_version_4 *)(buff_ptr))->member))
#define scsc_wifi_get_hip_config_version_3_u32(buff_ptr, member) le32_to_cpu((((struct hip4_hip_config_version_4 *)(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