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