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