• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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