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