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_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
rtw_hci_tx_write(struct rtw_dev * rtwdev,struct rtw_tx_pkt_info * pkt_info,struct sk_buff * skb)32 static 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
rtw_hci_tx_kick_off(struct rtw_dev * rtwdev)39 static inline void rtw_hci_tx_kick_off(struct rtw_dev *rtwdev)
40 {
41 return rtwdev->hci.ops->tx_kick_off(rtwdev);
42 }
43
rtw_hci_setup(struct rtw_dev * rtwdev)44 static inline int rtw_hci_setup(struct rtw_dev *rtwdev)
45 {
46 return rtwdev->hci.ops->setup(rtwdev);
47 }
48
rtw_hci_start(struct rtw_dev * rtwdev)49 static inline int rtw_hci_start(struct rtw_dev *rtwdev)
50 {
51 return rtwdev->hci.ops->start(rtwdev);
52 }
53
rtw_hci_stop(struct rtw_dev * rtwdev)54 static inline void rtw_hci_stop(struct rtw_dev *rtwdev)
55 {
56 rtwdev->hci.ops->stop(rtwdev);
57 }
58
rtw_hci_deep_ps(struct rtw_dev * rtwdev,bool enter)59 static inline void rtw_hci_deep_ps(struct rtw_dev *rtwdev, bool enter)
60 {
61 rtwdev->hci.ops->deep_ps(rtwdev, enter);
62 }
63
rtw_hci_link_ps(struct rtw_dev * rtwdev,bool enter)64 static inline void rtw_hci_link_ps(struct rtw_dev *rtwdev, bool enter)
65 {
66 rtwdev->hci.ops->link_ps(rtwdev, enter);
67 }
68
rtw_hci_interface_cfg(struct rtw_dev * rtwdev)69 static inline void rtw_hci_interface_cfg(struct rtw_dev *rtwdev)
70 {
71 rtwdev->hci.ops->interface_cfg(rtwdev);
72 }
73
74 static inline int
rtw_hci_write_data_rsvd_page(struct rtw_dev * rtwdev,u8 * buf,u32 size)75 rtw_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
80 static inline int
rtw_hci_write_data_h2c(struct rtw_dev * rtwdev,u8 * buf,u32 size)81 rtw_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
rtw_read8(struct rtw_dev * rtwdev,u32 addr)86 static inline u8 rtw_read8(struct rtw_dev *rtwdev, u32 addr)
87 {
88 return rtwdev->hci.ops->read8(rtwdev, addr);
89 }
90
rtw_read16(struct rtw_dev * rtwdev,u32 addr)91 static inline u16 rtw_read16(struct rtw_dev *rtwdev, u32 addr)
92 {
93 return rtwdev->hci.ops->read16(rtwdev, addr);
94 }
95
rtw_read32(struct rtw_dev * rtwdev,u32 addr)96 static inline u32 rtw_read32(struct rtw_dev *rtwdev, u32 addr)
97 {
98 return rtwdev->hci.ops->read32(rtwdev, addr);
99 }
100
rtw_write8(struct rtw_dev * rtwdev,u32 addr,u8 val)101 static inline void rtw_write8(struct rtw_dev *rtwdev, u32 addr, u8 val)
102 {
103 rtwdev->hci.ops->write8(rtwdev, addr, val);
104 }
105
rtw_write16(struct rtw_dev * rtwdev,u32 addr,u16 val)106 static inline void rtw_write16(struct rtw_dev *rtwdev, u32 addr, u16 val)
107 {
108 rtwdev->hci.ops->write16(rtwdev, addr, val);
109 }
110
rtw_write32(struct rtw_dev * rtwdev,u32 addr,u32 val)111 static inline void rtw_write32(struct rtw_dev *rtwdev, u32 addr, u32 val)
112 {
113 rtwdev->hci.ops->write32(rtwdev, addr, val);
114 }
115
rtw_write8_set(struct rtw_dev * rtwdev,u32 addr,u8 bit)116 static 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
rtw_write16_set(struct rtw_dev * rtwdev,u32 addr,u16 bit)124 static 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
rtw_write32_set(struct rtw_dev * rtwdev,u32 addr,u32 bit)132 static 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
rtw_write8_clr(struct rtw_dev * rtwdev,u32 addr,u8 bit)140 static 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
rtw_write16_clr(struct rtw_dev * rtwdev,u32 addr,u16 bit)148 static 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
rtw_write32_clr(struct rtw_dev * rtwdev,u32 addr,u32 bit)156 static 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
164 static inline u32
rtw_read_rf(struct rtw_dev * rtwdev,enum rtw_rf_path rf_path,u32 addr,u32 mask)165 rtw_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
178 static inline void
rtw_write_rf(struct rtw_dev * rtwdev,enum rtw_rf_path rf_path,u32 addr,u32 mask,u32 data)179 rtw_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
189 static inline u32
rtw_read32_mask(struct rtw_dev * rtwdev,u32 addr,u32 mask)190 rtw_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
202 static inline u16
rtw_read16_mask(struct rtw_dev * rtwdev,u32 addr,u32 mask)203 rtw_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
215 static inline u8
rtw_read8_mask(struct rtw_dev * rtwdev,u32 addr,u32 mask)216 rtw_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
228 static inline void
rtw_write32_mask(struct rtw_dev * rtwdev,u32 addr,u32 mask,u32 data)229 rtw_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
242 static inline void
rtw_write8_mask(struct rtw_dev * rtwdev,u32 addr,u32 mask,u8 data)243 rtw_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
rtw_hci_type(struct rtw_dev * rtwdev)256 static inline enum rtw_hci_type rtw_hci_type(struct rtw_dev *rtwdev)
257 {
258 return rtwdev->hci.type;
259 }
260
261 #endif
262