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