xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/ssv6xxx/hci/hctrl.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright (c) 2015 South Silicon Valley Microelectronics Inc.
3  * Copyright (c) 2015 iComm Corporation
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12  * See the GNU General Public License for more details.
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 #ifndef _HCTRL_H_
18 #define _HCTRL_H_
19 #define MAX_FRAME_SIZE 4096
20 #define SSV6XXX_INT_RX 0x00000001
21 #define SSV6XXX_INT_TX 0x00000002
22 #define SSV6XXX_INT_SOC 0x00000004
23 #define SSV6XXX_INT_LOW_EDCA_0 0x00000008
24 #define SSV6XXX_INT_LOW_EDCA_1 0x00000010
25 #define SSV6XXX_INT_LOW_EDCA_2 0x00000020
26 #define SSV6XXX_INT_LOW_EDCA_3 0x00000040
27 #define SSV6XXX_INT_RESOURCE_LOW 0x00000080
28 #define IFDEV(_ct) ((_ct)->shi->dev)
29 #define IFOPS(_ct) ((_ct)->shi->if_ops)
30 #define HCI_REG_READ(_ct,_adr,_val) IFOPS(_ct)->readreg(IFDEV(_ct), _adr, _val)
31 #define HCI_REG_WRITE(_ct,_adr,_val) IFOPS(_ct)->writereg(IFDEV(_ct), _adr, _val)
32 #define HCI_REG_SET_BITS(_ct,_reg,_set,_clr) \
33 { \
34     u32 _regval; \
35     if(HCI_REG_READ(_ct, _reg, &_regval)); \
36     _regval &= ~(_clr); \
37     _regval |= (_set); \
38     if(HCI_REG_WRITE(_ct, _reg, _regval)); \
39 }
40 #define IF_SEND(_ct,_bf,_len,_qid) IFOPS(_ct)->write(IFDEV(_ct), _bf, _len, _qid)
41 #define IF_RECV(ct,bf,len) IFOPS(ct)->read(IFDEV(ct), bf, len)
42 #define HCI_LOAD_FW(ct,_bf,open) IFOPS(ct)->load_fw(IFDEV(ct), _bf, open)
43 #define HCI_IFC_RESET(ct) IFOPS(ct)->interface_reset(IFDEV(ct))
44 struct ssv6xxx_hci_ctrl {
45     struct ssv6xxx_hci_info *shi;
46     spinlock_t int_lock;
47     u32 int_status;
48     u32 int_mask;
49     struct mutex txq_mask_lock;
50     u32 txq_mask;
51     struct ssv_hw_txq hw_txq[SSV_HW_TXQ_NUM];
52     struct mutex hci_mutex;
53     bool hci_start;
54     struct sk_buff *rx_buf;
55     u32 rx_pkt;
56     struct workqueue_struct *hci_work_queue;
57     struct work_struct hci_rx_work;
58 #ifdef CONFIG_SSV_TX_LOWTHRESHOLD
59     struct work_struct hci_tx_work;
60 #else
61     struct work_struct hci_tx_work[SSV_HW_TXQ_NUM];
62 #endif
63     u32 read_rs0_info_fail;
64     u32 read_rs1_info_fail;
65     u32 rx_work_running;
66     u32 isr_running;
67     u32 xmit_running;
68     u32 isr_summary_eable;
69     u32 isr_routine_time;
70     u32 isr_tx_time;
71     u32 isr_rx_time;
72     u32 isr_idle_time;
73     u32 isr_rx_idle_time;
74     u32 isr_miss_cnt;
75     unsigned long prev_isr_jiffes;
76     unsigned long prev_rx_isr_jiffes;
77 #ifdef CONFIG_SSV6XXX_DEBUGFS
78  struct dentry *debugfs_dir;
79  u32 isr_mib_enable;
80  u32 isr_mib_reset;
81  long long isr_total_time;
82  long long isr_tx_io_time;
83  long long isr_rx_io_time;
84  u32 isr_rx_io_count;
85  u32 isr_tx_io_count;
86  long long isr_rx_proc_time;
87 #ifdef CONFIG_IRQ_DEBUG_COUNT
88     bool irq_enable;
89     u32 irq_count;
90     u32 invalid_irq_count;
91     u32 tx_irq_count;
92     u32 real_tx_irq_count;
93     u32 rx_irq_count;
94     u32 irq_rx_pkt_count;
95     u32 irq_tx_pkt_count;
96 #endif
97 #endif
98 };
99 struct ssv6xxx_hci_txq_info {
100  u32 tx_use_page:8;
101     u32 tx_use_id:6;
102     u32 txq0_size:4;
103  u32 txq1_size:4;
104  u32 txq2_size:5;
105  u32 txq3_size:5;
106 };
107 struct ssv6xxx_hci_txq_info2 {
108  u32 tx_use_page:9;
109     u32 tx_use_id:8;
110  u32 txq4_size:4;
111     u32 rsvd:11;
112 };
113 struct ssv6xxx_hw_resource
114 {
115  u32 free_tx_page;
116  u32 free_tx_id;
117  int max_tx_frame[SSV_HW_TXQ_NUM];
118 };
ssv6xxx_hwif_irq_request(struct ssv6xxx_hci_ctrl * hctrl,irq_handler_t irq_handler)119 static inline void ssv6xxx_hwif_irq_request(struct ssv6xxx_hci_ctrl *hctrl, irq_handler_t irq_handler)
120 {
121  if(hctrl->shi->if_ops->irq_request)
122   hctrl->shi->if_ops->irq_request(IFDEV(hctrl), irq_handler, hctrl);
123 }
ssv6xxx_hwif_irq_enable(struct ssv6xxx_hci_ctrl * hctrl)124 static inline void ssv6xxx_hwif_irq_enable(struct ssv6xxx_hci_ctrl *hctrl)
125 {
126  if(hctrl->shi->if_ops->irq_enable)
127   hctrl->shi->if_ops->irq_enable(IFDEV(hctrl));
128 }
ssv6xxx_hwif_irq_disable(struct ssv6xxx_hci_ctrl * hctrl)129 static inline void ssv6xxx_hwif_irq_disable(struct ssv6xxx_hci_ctrl *hctrl)
130 {
131  if(hctrl->shi->if_ops->irq_disable)
132   hctrl->shi->if_ops->irq_disable(IFDEV(hctrl), false);
133 }
ssv6xxx_hwif_irq_getstatus(struct ssv6xxx_hci_ctrl * hctrl,int * status)134 static inline int ssv6xxx_hwif_irq_getstatus(struct ssv6xxx_hci_ctrl *hctrl, int *status)
135 {
136  if(hctrl->shi->if_ops->irq_getstatus)
137   return hctrl->shi->if_ops->irq_getstatus(IFDEV(hctrl), status);
138  return 0;
139 }
ssv6xxx_hwif_irq_setmask(struct ssv6xxx_hci_ctrl * hctrl,int mask)140 static inline void ssv6xxx_hwif_irq_setmask(struct ssv6xxx_hci_ctrl *hctrl, int mask)
141 {
142  if(hctrl->shi->if_ops->irq_setmask)
143   hctrl->shi->if_ops->irq_setmask(IFDEV(hctrl), mask);
144 }
ssv6xxx_hwif_irq_trigger(struct ssv6xxx_hci_ctrl * hctrl)145 static inline void ssv6xxx_hwif_irq_trigger(struct ssv6xxx_hci_ctrl *hctrl)
146 {
147  if(hctrl->shi->if_ops->irq_trigger)
148   hctrl->shi->if_ops->irq_trigger(IFDEV(hctrl));
149 }
ssv6xxx_hwif_pmu_wakeup(struct ssv6xxx_hci_ctrl * hctrl)150 static inline void ssv6xxx_hwif_pmu_wakeup(struct ssv6xxx_hci_ctrl *hctrl)
151 {
152  if(hctrl->shi->if_ops->pmu_wakeup)
153   hctrl->shi->if_ops->pmu_wakeup(IFDEV(hctrl));
154 }
ssv6xxx_hwif_write_sram(struct ssv6xxx_hci_ctrl * hctrl,u32 addr,u8 * data,u32 size)155 static inline int ssv6xxx_hwif_write_sram(struct ssv6xxx_hci_ctrl *hctrl, u32 addr, u8 *data, u32 size)
156 {
157  if(hctrl->shi->if_ops->write_sram)
158   return hctrl->shi->if_ops->write_sram(IFDEV(hctrl), addr, data, size);
159  return 0;
160 }
161 #define HCI_IRQ_REQUEST(ct,hdle) ssv6xxx_hwif_irq_request(ct, hdle)
162 #define HCI_IRQ_ENABLE(ct) ssv6xxx_hwif_irq_enable(ct)
163 #define HCI_IRQ_DISABLE(ct) ssv6xxx_hwif_irq_disable(ct)
164 #define HCI_IRQ_STATUS(ct,sts) ssv6xxx_hwif_irq_getstatus(ct, sts)
165 #define HCI_IRQ_SET_MASK(ct,mk) ssv6xxx_hwif_irq_setmask(ct, mk)
166 #define HCI_IRQ_TRIGGER(ct) ssv6xxx_hwif_irq_trigger(ct)
167 #define HCI_PMU_WAKEUP(ct) ssv6xxx_hwif_pmu_wakeup(ct)
168 #define HCI_SRAM_WRITE(_ct,_adr,_dat,_size) ssv6xxx_hwif_write_sram(_ct, _adr, _dat, _size);
169 #endif
170