1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "osal_mem.h"
10 #include "sdio_if.h"
11 #include "wifi_inc.h"
12 #include "hdf_wlan_sdio.h"
13 #include "hdf_base.h"
14 #include "hdf_ibus_intf.h"
15 #include "hdf_log.h"
16 #include "securec.h"
17
18 #ifdef __cplusplus
19 #if __cplusplus
20 extern "C" {
21 #endif
22 #endif
23
HdfGetSdioInfo(struct BusDev * dev,struct BusConfig * busCfg)24 static int32_t HdfGetSdioInfo(struct BusDev *dev, struct BusConfig *busCfg)
25 {
26 int32_t ret;
27 struct DevHandle *handle = NULL;
28 SdioCommonInfo palSdioCommonInfo;
29 if (dev == NULL || busCfg == NULL || busCfg->busType != BUS_SDIO) {
30 HDF_LOGE("%s:input parameter error!", __func__);
31 return HDF_FAILURE;
32 }
33 handle = (struct DevHandle *)dev->devBase;
34 (void)memset_s(&palSdioCommonInfo, sizeof(SdioCommonInfo), 0, sizeof(SdioCommonInfo));
35
36 ret = SdioGetCommonInfo(handle, &palSdioCommonInfo, SDIO_FUNC_INFO);
37 if (ret != HDF_SUCCESS) {
38 HDF_LOGE("%s:get sdio info error!", __func__);
39 return ret;
40 }
41 busCfg->busInfo.sdioInfo.maxBlockNum = palSdioCommonInfo.funcInfo.maxBlockNum;
42 busCfg->busInfo.sdioInfo.maxBlockSize = palSdioCommonInfo.funcInfo.maxBlockSize;
43 busCfg->busInfo.sdioInfo.maxRequestSize = palSdioCommonInfo.funcInfo.maxRequestSize;
44 busCfg->busInfo.sdioInfo.funcNumSize = palSdioCommonInfo.funcInfo.funcNum;
45 busCfg->busInfo.sdioInfo.irqCap = palSdioCommonInfo.funcInfo.irqCap;
46 busCfg->busInfo.sdioInfo.data = palSdioCommonInfo.funcInfo.data;
47
48 return ret;
49 }
50
HdfSdioReleaseDev(struct BusDev * dev)51 static void HdfSdioReleaseDev(struct BusDev *dev)
52 {
53 if (dev == NULL) {
54 HDF_LOGE("%s:input parameter error!", __func__);
55 return;
56 }
57 if (dev->priData.data != NULL) {
58 dev->priData.release(dev->priData.data);
59 dev->priData.data = NULL;
60 }
61 OsalMemFree(dev);
62 dev = NULL;
63 }
64
HdfSdioEnableFunc(struct BusDev * dev)65 static int32_t HdfSdioEnableFunc(struct BusDev *dev)
66 {
67 int32_t ret;
68 struct DevHandle *handle = NULL;
69 if (dev == NULL) {
70 HDF_LOGE("%s:input parameter error!", __func__);
71 return HDF_FAILURE;
72 }
73 handle = (struct DevHandle *)dev->devBase;
74 ret = SdioEnableFunc(handle);
75 if (ret != HDF_SUCCESS) {
76 HDF_LOGE("%s:enable sdio func failed!", __func__);
77 }
78 return ret;
79 }
80
HdfSdioDisableFunc(struct BusDev * dev)81 static int32_t HdfSdioDisableFunc(struct BusDev *dev)
82 {
83 int32_t ret;
84 struct DevHandle *handle = NULL;
85 if (dev == NULL) {
86 HDF_LOGE("%s:input parameter error!", __func__);
87 return HDF_FAILURE;
88 }
89 handle = (struct DevHandle *)dev->devBase;
90 ret = SdioDisableFunc(handle);
91 if (ret != HDF_SUCCESS) {
92 HDF_LOGE("%s:disable sdio func failed!", __func__);
93 }
94 return ret;
95 }
96
HdfSdioCliamIrq(struct BusDev * dev,IrqHandler * handler,void * data)97 static int32_t HdfSdioCliamIrq(struct BusDev *dev, IrqHandler *handler, void *data)
98 {
99 (void)data;
100 int32_t ret;
101 struct DevHandle *handle = NULL;
102 if (dev == NULL) {
103 HDF_LOGE("%s:input parameter error!", __func__);
104 return HDF_FAILURE;
105 }
106 handle = (struct DevHandle *)dev->devBase;
107 ret = SdioClaimIrq(handle, (SdioIrqHandler *)handler);
108 if (ret != HDF_SUCCESS) {
109 HDF_LOGE("%s:claim sdio irq failed!", __func__);
110 }
111 return ret;
112 }
113
HdfSdioClaimHost(struct BusDev * dev)114 static void HdfSdioClaimHost(struct BusDev *dev)
115 {
116 struct DevHandle *handle = NULL;
117 if (dev == NULL) {
118 HDF_LOGE("%s:input parameter error!", __func__);
119 return;
120 }
121 handle = (struct DevHandle *)dev->devBase;
122 SdioClaimHost(handle);
123 }
124
HdfSdioReleaseHost(struct BusDev * dev)125 static void HdfSdioReleaseHost(struct BusDev *dev)
126 {
127 struct DevHandle *handle = NULL;
128 if (dev == NULL) {
129 HDF_LOGE("%s:input parameter error!", __func__);
130 return;
131 }
132 handle = (struct DevHandle *)dev->devBase;
133 SdioReleaseHost(handle);
134 }
135
136
HdfSdioReleaseIrq(struct BusDev * dev)137 static int32_t HdfSdioReleaseIrq(struct BusDev *dev)
138 {
139 int32_t ret;
140 struct DevHandle *handle = NULL;
141 if (dev == NULL) {
142 HDF_LOGE("%s:input parameter error!", __func__);
143 return HDF_FAILURE;
144 }
145 handle = (struct DevHandle *)dev->devBase;
146 ret = SdioReleaseIrq(handle);
147 if (ret != HDF_SUCCESS) {
148 HDF_LOGE("%s:release sdio irq failed!", __func__);
149 }
150 return ret;
151 }
152
HdfSdioReset(struct BusDev * dev)153 static int32_t HdfSdioReset(struct BusDev *dev)
154 {
155 int32_t ret;
156 struct DevHandle *handle = NULL;
157 if (dev == NULL) {
158 HDF_LOGE("%s:input parameter error!", __func__);
159 return HDF_FAILURE;
160 }
161 handle = (struct DevHandle *)dev->devBase;
162 ret = SdioFlushData(handle);
163 if (ret != HDF_SUCCESS) {
164 HDF_LOGE("%s:reset sdio failed!", __func__);
165 }
166 return ret;
167 }
168
HdfSdioReadN(struct BusDev * dev,uint32_t addr,uint32_t cnt,uint8_t * buf)169 static int32_t HdfSdioReadN(struct BusDev *dev, uint32_t addr, uint32_t cnt, uint8_t *buf)
170 {
171 int32_t ret;
172 struct DevHandle *handle = NULL;
173 if (dev == NULL) {
174 HDF_LOGE("%s:input parameter error!", __func__);
175 return HDF_FAILURE;
176 }
177 handle = (struct DevHandle *)dev->devBase;
178 ret = SdioReadBytes(handle, buf, addr, cnt);
179 if (ret != HDF_SUCCESS) {
180 HDF_LOGE("%s:read sdio data failed!", __func__);
181 }
182 return ret;
183 }
184
HdfSdioReadFunc0(struct BusDev * dev,uint32_t addr,uint32_t cnt,uint8_t * buf)185 static int32_t HdfSdioReadFunc0(struct BusDev *dev, uint32_t addr, uint32_t cnt, uint8_t *buf)
186 {
187 int32_t ret;
188 struct DevHandle *handle = NULL;
189 if (dev == NULL) {
190 HDF_LOGE("%s:input parameter error!", __func__);
191 return HDF_FAILURE;
192 }
193 handle = (struct DevHandle *)dev->devBase;
194 ret = SdioReadBytesFromFunc0(handle, buf, addr, cnt);
195 if (ret != HDF_SUCCESS) {
196 HDF_LOGE("%s:read sdio func0 data failed!", __func__);
197 }
198 return ret;
199 }
200
HdfSdioReadSpcReg(struct BusDev * dev,uint32_t addr,uint32_t cnt,uint8_t * buf,uint32_t sg_len)201 static int32_t HdfSdioReadSpcReg(struct BusDev *dev, uint32_t addr, uint32_t cnt, uint8_t *buf, uint32_t sg_len)
202 {
203 int32_t ret;
204 struct DevHandle *handle = NULL;
205 if (dev == NULL) {
206 HDF_LOGE("%s:input parameter error!", __func__);
207 return HDF_FAILURE;
208 }
209 handle = (struct DevHandle *)dev->devBase;
210 ret = SdioReadBytesFromFixedAddr(handle, buf, addr, cnt, sg_len);
211 if (ret != HDF_SUCCESS) {
212 HDF_LOGE("%s:read sdio special reg data failed!", __func__);
213 }
214 return ret;
215 }
216
HdfSdioWriteN(struct BusDev * dev,uint32_t addr,uint32_t cnt,uint8_t * buf)217 static int32_t HdfSdioWriteN(struct BusDev *dev, uint32_t addr, uint32_t cnt, uint8_t *buf)
218 {
219 int32_t ret;
220 struct DevHandle *handle = NULL;
221 if (dev == NULL || buf == NULL) {
222 HDF_LOGE("%s:input parameter error!", __func__);
223 return HDF_FAILURE;
224 }
225 handle = (struct DevHandle *)dev->devBase;
226 ret = SdioWriteBytes(handle, buf, addr, cnt);
227 if (ret != HDF_SUCCESS) {
228 HDF_LOGE("%s:write sdio data failed!", __func__);
229 }
230 return ret;
231 }
232
HdfSdioWriteFunc0(struct BusDev * dev,uint32_t addr,uint32_t cnt,uint8_t * buf)233 static int32_t HdfSdioWriteFunc0(struct BusDev *dev, uint32_t addr, uint32_t cnt, uint8_t *buf)
234 {
235 int32_t ret;
236 struct DevHandle *handle = NULL;
237 if (dev == NULL || buf == NULL) {
238 HDF_LOGE("%s:input parameter error!", __func__);
239 return HDF_FAILURE;
240 }
241 handle = (struct DevHandle *)dev->devBase;
242 ret = SdioWriteBytesToFunc0(handle, buf, addr, cnt);
243 if (ret != HDF_SUCCESS) {
244 HDF_LOGE("%s:write sdio func0 data failed!", __func__);
245 }
246 return ret;
247 }
248
HdfSdioWriteSpcReg(struct BusDev * dev,uint32_t addr,uint32_t cnt,uint8_t * buf,uint32_t sg_len)249 static int32_t HdfSdioWriteSpcReg(struct BusDev *dev, uint32_t addr, uint32_t cnt, uint8_t *buf, uint32_t sg_len)
250 {
251 int32_t ret;
252 struct DevHandle *handle = NULL;
253 if (dev == NULL || buf == NULL) {
254 HDF_LOGE("%s:input parameter error!", __func__);
255 return HDF_FAILURE;
256 }
257 handle = (struct DevHandle *)dev->devBase;
258 ret = SdioWriteBytesToFixedAddr(handle, buf, addr, cnt, sg_len);
259 if (ret != HDF_SUCCESS) {
260 HDF_LOGI("%s:write sdio special reg data failed!", __func__);
261 }
262 return ret;
263 }
264
HdfSdioSetBlk(struct BusDev * dev,uint32_t blkSize)265 static int32_t HdfSdioSetBlk(struct BusDev *dev, uint32_t blkSize)
266 {
267 int32_t ret;
268 struct DevHandle *handle = NULL;
269 if (dev == NULL) {
270 HDF_LOGE("%s:input parameter error!", __func__);
271 return HDF_FAILURE;
272 }
273 handle = (struct DevHandle *)dev->devBase;
274 ret = SdioSetBlockSize(handle, blkSize);
275 if (ret != HDF_SUCCESS) {
276 HDF_LOGE("%s:sdio set block size failed!", __func__);
277 }
278 return ret;
279 }
280
HdfGetDevHandle(struct BusDev * dev,const struct HdfConfigWlanBus * busCfg)281 static struct DevHandle *HdfGetDevHandle(struct BusDev *dev, const struct HdfConfigWlanBus *busCfg)
282 {
283 struct DevHandle *handle = NULL;
284 int32_t cnt;
285 struct SdioFunctionConfig palSdioConfig[WLAN_MAX_CHIP_NUM] = {0};
286 struct HdfConfigWlanChipList *tmpChipList = NULL;
287
288 struct HdfConfigWlanRoot *rootConfig = HdfWlanGetModuleConfigRoot();
289 if (rootConfig == NULL) {
290 HDF_LOGE("%s: NULL ptr!", __func__);
291 return NULL;
292 }
293 tmpChipList = &rootConfig->wlanConfig.chipList;
294 for (cnt = 0; (cnt < tmpChipList->chipInstSize) && (cnt < WLAN_MAX_CHIP_NUM); cnt++) {
295 // once detected card break
296 palSdioConfig[cnt].deviceId = tmpChipList->chipInst[cnt].chipBus.deviceId[0];
297 palSdioConfig[cnt].vendorId = tmpChipList->chipInst[cnt].chipBus.vendorId;
298 palSdioConfig[cnt].funcNr = busCfg->funcNum[0];
299 handle = SdioOpen(busCfg->busIdx, &palSdioConfig[cnt]);
300 if (handle != NULL) {
301 HDF_LOGI("%s: sdio card detected!", __func__);
302 break;
303 }
304 }
305 if (cnt == tmpChipList->chipInstSize || cnt == WLAN_MAX_CHIP_NUM) {
306 HDF_LOGE("%s: NO sdio card detected!", __func__);
307 SdioClose(handle);
308 return NULL;
309 }
310 dev->devBase = handle;
311 dev->priData.driverName = tmpChipList->chipInst[cnt].driverName;
312 return handle;
313 }
314
HdfSdioInit(struct BusDev * dev,const struct HdfConfigWlanBus * busCfg)315 static int32_t HdfSdioInit(struct BusDev *dev, const struct HdfConfigWlanBus *busCfg)
316 {
317 int32_t ret;
318 struct DevHandle *handle = NULL;
319 SdioCommonInfo palSdioCommonInfo;
320
321 if (dev == NULL || busCfg == NULL) {
322 HDF_LOGE("%s: input parameter error!", __func__);
323 goto sdioInitFail;
324 }
325 handle = HdfGetDevHandle(dev, busCfg);
326 if (handle == NULL) {
327 HDF_LOGE("%s: sdio card detected fail!", __func__);
328 return HDF_FAILURE;
329 }
330 SdioClaimHost(handle);
331 (void)memset_s(&palSdioCommonInfo, sizeof(SdioCommonInfo), 0, sizeof(SdioCommonInfo));
332 SdioGetCommonInfo(handle, &palSdioCommonInfo, SDIO_FUNC_INFO);
333 palSdioCommonInfo.funcInfo.enTimeout = busCfg->timeout;
334 SdioSetCommonInfo(handle, &palSdioCommonInfo, SDIO_FUNC_INFO);
335 ret = HdfSdioEnableFunc(dev);
336 if (ret != HDF_SUCCESS) {
337 HDF_LOGE("%s: enable sdio failed!", __func__);
338 goto sdioInitFail;
339 }
340 ret = HdfSdioSetBlk(dev, busCfg->blockSize);
341 if (ret != HDF_SUCCESS) {
342 HDF_LOGE("%s: set sdio block size failed!", __func__);
343 goto sdioInitFail;
344 }
345 SdioReleaseHost(handle);
346 HDF_LOGI("%s: sdio bus init success!", __func__);
347 return ret;
348
349 sdioInitFail:
350 SdioClose(handle);
351 return HDF_FAILURE;
352 }
353
HdfSetBusOps(struct BusDev * dev)354 static void HdfSetBusOps(struct BusDev *dev)
355 {
356 dev->ops.getBusInfo = HdfGetSdioInfo;
357 dev->ops.deInit = HdfSdioReleaseDev;
358 dev->ops.init = HdfSdioInit;
359
360 dev->ops.readData = HdfSdioReadN;
361 dev->ops.writeData = HdfSdioWriteN;
362 dev->ops.bulkRead = HdfSdioReadSpcReg;
363 dev->ops.bulkWrite = HdfSdioWriteSpcReg;
364 dev->ops.readFunc0 = HdfSdioReadFunc0;
365 dev->ops.writeFunc0 = HdfSdioWriteFunc0;
366
367 dev->ops.claimIrq = HdfSdioCliamIrq;
368 dev->ops.releaseIrq = HdfSdioReleaseIrq;
369 dev->ops.disableBus = HdfSdioDisableFunc;
370 dev->ops.reset = HdfSdioReset;
371
372 dev->ops.claimHost = HdfSdioClaimHost;
373 dev->ops.releaseHost = HdfSdioReleaseHost;
374 }
HdfWlanBusAbsInit(struct BusDev * dev,const struct HdfConfigWlanBus * busConfig)375 int32_t HdfWlanBusAbsInit(struct BusDev *dev, const struct HdfConfigWlanBus *busConfig)
376 {
377 if (dev == NULL) {
378 HDF_LOGE("%s:set sdio device ops failed!", __func__);
379 return HDF_FAILURE;
380 }
381 HdfSetBusOps(dev);
382 return HdfSdioInit(dev, busConfig);
383 }
384
HdfWlanConfigBusAbs(uint8_t busId)385 int32_t HdfWlanConfigBusAbs(uint8_t busId)
386 {
387 return HdfWlanConfigSDIO(busId);
388 }
389
390 #ifdef __cplusplus
391 #if __cplusplus
392 }
393 #endif
394 #endif
395