1/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
2/* Copyright(c) 2018-2019  Realtek Corporation
3 */
4
5#ifndef	__RTW_HCI_H__
6#define __RTW_HCI_H__
7
8/* ops for PCI, USB and SDIO */
9struct rtw_hci_ops {
10	int (*tx_write)(struct rtw_dev *rtwdev,
11			struct rtw_tx_pkt_info *pkt_info,
12			struct sk_buff *skb);
13	void (*tx_kick_off)(struct rtw_dev *rtwdev);
14	int (*setup)(struct rtw_dev *rtwdev);
15	int (*start)(struct rtw_dev *rtwdev);
16	void (*stop)(struct rtw_dev *rtwdev);
17	void (*deep_ps)(struct rtw_dev *rtwdev, bool enter);
18	void (*link_ps)(struct rtw_dev *rtwdev, bool enter);
19	void (*interface_cfg)(struct rtw_dev *rtwdev);
20
21	int (*write_data_rsvd_page)(struct rtw_dev *rtwdev, u8 *buf, u32 size);
22	int (*write_data_h2c)(struct rtw_dev *rtwdev, u8 *buf, u32 size);
23
24	u8 (*read8)(struct rtw_dev *rtwdev, u32 addr);
25	u16 (*read16)(struct rtw_dev *rtwdev, u32 addr);
26	u32 (*read32)(struct rtw_dev *rtwdev, u32 addr);
27	void (*write8)(struct rtw_dev *rtwdev, u32 addr, u8 val);
28	void (*write16)(struct rtw_dev *rtwdev, u32 addr, u16 val);
29	void (*write32)(struct rtw_dev *rtwdev, u32 addr, u32 val);
30};
31
32static inline int rtw_hci_tx_write(struct rtw_dev *rtwdev,
33				   struct rtw_tx_pkt_info *pkt_info,
34				   struct sk_buff *skb)
35{
36	return rtwdev->hci.ops->tx_write(rtwdev, pkt_info, skb);
37}
38
39static inline void rtw_hci_tx_kick_off(struct rtw_dev *rtwdev)
40{
41	return rtwdev->hci.ops->tx_kick_off(rtwdev);
42}
43
44static inline int rtw_hci_setup(struct rtw_dev *rtwdev)
45{
46	return rtwdev->hci.ops->setup(rtwdev);
47}
48
49static inline int rtw_hci_start(struct rtw_dev *rtwdev)
50{
51	return rtwdev->hci.ops->start(rtwdev);
52}
53
54static inline void rtw_hci_stop(struct rtw_dev *rtwdev)
55{
56	rtwdev->hci.ops->stop(rtwdev);
57}
58
59static inline void rtw_hci_deep_ps(struct rtw_dev *rtwdev, bool enter)
60{
61	rtwdev->hci.ops->deep_ps(rtwdev, enter);
62}
63
64static inline void rtw_hci_link_ps(struct rtw_dev *rtwdev, bool enter)
65{
66	rtwdev->hci.ops->link_ps(rtwdev, enter);
67}
68
69static inline void rtw_hci_interface_cfg(struct rtw_dev *rtwdev)
70{
71	rtwdev->hci.ops->interface_cfg(rtwdev);
72}
73
74static inline int
75rtw_hci_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf, u32 size)
76{
77	return rtwdev->hci.ops->write_data_rsvd_page(rtwdev, buf, size);
78}
79
80static inline int
81rtw_hci_write_data_h2c(struct rtw_dev *rtwdev, u8 *buf, u32 size)
82{
83	return rtwdev->hci.ops->write_data_h2c(rtwdev, buf, size);
84}
85
86static inline u8 rtw_read8(struct rtw_dev *rtwdev, u32 addr)
87{
88	return rtwdev->hci.ops->read8(rtwdev, addr);
89}
90
91static inline u16 rtw_read16(struct rtw_dev *rtwdev, u32 addr)
92{
93	return rtwdev->hci.ops->read16(rtwdev, addr);
94}
95
96static inline u32 rtw_read32(struct rtw_dev *rtwdev, u32 addr)
97{
98	return rtwdev->hci.ops->read32(rtwdev, addr);
99}
100
101static inline void rtw_write8(struct rtw_dev *rtwdev, u32 addr, u8 val)
102{
103	rtwdev->hci.ops->write8(rtwdev, addr, val);
104}
105
106static inline void rtw_write16(struct rtw_dev *rtwdev, u32 addr, u16 val)
107{
108	rtwdev->hci.ops->write16(rtwdev, addr, val);
109}
110
111static inline void rtw_write32(struct rtw_dev *rtwdev, u32 addr, u32 val)
112{
113	rtwdev->hci.ops->write32(rtwdev, addr, val);
114}
115
116static inline void rtw_write8_set(struct rtw_dev *rtwdev, u32 addr, u8 bit)
117{
118	u8 val;
119
120	val = rtw_read8(rtwdev, addr);
121	rtw_write8(rtwdev, addr, val | bit);
122}
123
124static inline void rtw_write16_set(struct rtw_dev *rtwdev, u32 addr, u16 bit)
125{
126	u16 val;
127
128	val = rtw_read16(rtwdev, addr);
129	rtw_write16(rtwdev, addr, val | bit);
130}
131
132static inline void rtw_write32_set(struct rtw_dev *rtwdev, u32 addr, u32 bit)
133{
134	u32 val;
135
136	val = rtw_read32(rtwdev, addr);
137	rtw_write32(rtwdev, addr, val | bit);
138}
139
140static inline void rtw_write8_clr(struct rtw_dev *rtwdev, u32 addr, u8 bit)
141{
142	u8 val;
143
144	val = rtw_read8(rtwdev, addr);
145	rtw_write8(rtwdev, addr, val & ~bit);
146}
147
148static inline void rtw_write16_clr(struct rtw_dev *rtwdev, u32 addr, u16 bit)
149{
150	u16 val;
151
152	val = rtw_read16(rtwdev, addr);
153	rtw_write16(rtwdev, addr, val & ~bit);
154}
155
156static inline void rtw_write32_clr(struct rtw_dev *rtwdev, u32 addr, u32 bit)
157{
158	u32 val;
159
160	val = rtw_read32(rtwdev, addr);
161	rtw_write32(rtwdev, addr, val & ~bit);
162}
163
164static inline u32
165rtw_read_rf(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
166	    u32 addr, u32 mask)
167{
168	unsigned long flags;
169	u32 val;
170
171	spin_lock_irqsave(&rtwdev->rf_lock, flags);
172	val = rtwdev->chip->ops->read_rf(rtwdev, rf_path, addr, mask);
173	spin_unlock_irqrestore(&rtwdev->rf_lock, flags);
174
175	return val;
176}
177
178static inline void
179rtw_write_rf(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path,
180	     u32 addr, u32 mask, u32 data)
181{
182	unsigned long flags;
183
184	spin_lock_irqsave(&rtwdev->rf_lock, flags);
185	rtwdev->chip->ops->write_rf(rtwdev, rf_path, addr, mask, data);
186	spin_unlock_irqrestore(&rtwdev->rf_lock, flags);
187}
188
189static inline u32
190rtw_read32_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask)
191{
192	u32 shift = __ffs(mask);
193	u32 orig;
194	u32 ret;
195
196	orig = rtw_read32(rtwdev, addr);
197	ret = (orig & mask) >> shift;
198
199	return ret;
200}
201
202static inline u16
203rtw_read16_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask)
204{
205	u32 shift = __ffs(mask);
206	u32 orig;
207	u32 ret;
208
209	orig = rtw_read16(rtwdev, addr);
210	ret = (orig & mask) >> shift;
211
212	return ret;
213}
214
215static inline u8
216rtw_read8_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask)
217{
218	u32 shift = __ffs(mask);
219	u32 orig;
220	u32 ret;
221
222	orig = rtw_read8(rtwdev, addr);
223	ret = (orig & mask) >> shift;
224
225	return ret;
226}
227
228static inline void
229rtw_write32_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data)
230{
231	u32 shift = __ffs(mask);
232	u32 orig;
233	u32 set;
234
235	WARN(addr & 0x3, "should be 4-byte aligned, addr = 0x%08x\n", addr);
236
237	orig = rtw_read32(rtwdev, addr);
238	set = (orig & ~mask) | ((data << shift) & mask);
239	rtw_write32(rtwdev, addr, set);
240}
241
242static inline void
243rtw_write8_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u8 data)
244{
245	u32 shift;
246	u8 orig, set;
247
248	mask &= 0xff;
249	shift = __ffs(mask);
250
251	orig = rtw_read8(rtwdev, addr);
252	set = (orig & ~mask) | ((data << shift) & mask);
253	rtw_write8(rtwdev, addr, set);
254}
255
256static inline enum rtw_hci_type rtw_hci_type(struct rtw_dev *rtwdev)
257{
258	return rtwdev->hci.type;
259}
260
261#endif
262