• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-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 "device_resource_if.h"
10 #include "hdf_base.h"
11 #include "hdf_log.h"
12 #include "osal_mem.h"
13 #include "osal_time.h"
14 #include "sdio_if.h"
15 #include "sdio_test.h"
16 
17 #define HDF_LOG_TAG sdio_test_c
18 
19 #define TEST_DATA_LEN 3
20 #define TEST_BLOCKSIZE 512
21 #define TEST_SDIO_BASE_ADDR 0x100
22 #define TEST_FUNC_NUM 1
23 #define TEST_ADDR_OFFSET 0x10
24 #define TEST_FIXED_OFFSET 0x09
25 #define TEST_TIME_OUT 1000
26 #define TEST_ADDR_ADD 1
27 #define TEST_FUNC0_ADDR 0xFE
28 
29 struct SdioTestFunc {
30     enum SdioTestCmd type;
31     int32_t (*Func)(struct SdioTester *tester);
32 };
33 
SdioTestGetHandle(struct SdioTester * tester)34 static DevHandle SdioTestGetHandle(struct SdioTester *tester)
35 {
36     if (tester == NULL) {
37         HDF_LOGE("%s: tester is null", __func__);
38         return NULL;
39     }
40     return SdioOpen((int16_t)(tester->busNum), &(tester->config));
41 }
42 
SdioTestReleaseHandle(DevHandle handle)43 static void SdioTestReleaseHandle(DevHandle handle)
44 {
45     if (handle == NULL) {
46         HDF_LOGE("%s: sdio handle is null", __func__);
47         return;
48     }
49     SdioClose(handle);
50 }
51 
TestSdioIncrAddrReadAndWriteOtherBytes(struct SdioTester * tester)52 static int32_t TestSdioIncrAddrReadAndWriteOtherBytes(struct SdioTester *tester)
53 {
54     int32_t ret;
55     uint8_t data[TEST_DATA_LEN] = {0};
56     const uint32_t addr = TEST_SDIO_BASE_ADDR * TEST_FUNC_NUM + TEST_ADDR_OFFSET + TEST_ADDR_ADD;
57 
58     ret = SdioReadBytes(tester->handle, &data[0], addr, 1);
59     if (ret != HDF_SUCCESS) {
60         HDF_LOGE("%s: SdioReadBytes fail! ret=%d.", __func__, ret);
61         return HDF_FAILURE;
62     }
63     HDF_LOGE("%s: read, data[0]:%d\n", __func__, data[0]);
64     ret = SdioWriteBytes(tester->handle, &data[0], addr, 1);
65     if (ret != HDF_SUCCESS) {
66         HDF_LOGE("%s: SdioWriteBytes fail! ret=%d.", __func__, ret);
67         return HDF_FAILURE;
68     }
69     HDF_LOGE("%s: write, data[0]:%u\n", __func__, data[0]);
70     return HDF_SUCCESS;
71 }
72 
TestSdioIncrAddrReadAndWriteOneByte(struct SdioTester * tester)73 static int32_t TestSdioIncrAddrReadAndWriteOneByte(struct SdioTester *tester)
74 {
75     int32_t ret;
76     uint8_t val;
77     uint32_t addr;
78 
79     addr = TEST_SDIO_BASE_ADDR * TEST_FUNC_NUM + TEST_ADDR_OFFSET;
80     /* read 1 bits */
81     ret = SdioReadBytes(tester->handle, &val, addr, 1);
82     if (ret != HDF_SUCCESS) {
83         HDF_LOGE("%s: SdioReadBytes fail! ret=%d.", __func__, ret);
84         return HDF_FAILURE;
85     }
86     HDF_LOGE("%s: read, val:%d\n", __func__, val);
87     /* write 1 bits */
88     ret = SdioWriteBytes(tester->handle, &val, addr, 1);
89     if (ret != HDF_SUCCESS) {
90         HDF_LOGE("%s: SdioWriteBytes fail! ret=%d.", __func__, ret);
91         return HDF_FAILURE;
92     }
93     HDF_LOGE("%s: write, val:%d\n", __func__, val);
94     /* read 1 bits */
95     addr++;
96     ret = SdioReadBytes(tester->handle, &val, addr, 1);
97     if (ret != HDF_SUCCESS) {
98         HDF_LOGE("%s: SdioReadBytes fail! ret=%d.", __func__, ret);
99         return HDF_FAILURE;
100     }
101     HDF_LOGE("%s: read, val:%u.", __func__, val);
102     /* read 1 bits */
103     addr++;
104     ret = SdioReadBytes(tester->handle, &val, addr, 1);
105     if (ret != HDF_SUCCESS) {
106         HDF_LOGE("%s: SdioReadBytes fail! ret=%d.", __func__, ret);
107         return HDF_FAILURE;
108     }
109     HDF_LOGE("%s: read, val:%u.", __func__, val);
110     return HDF_SUCCESS;
111 }
112 
TestSdioIncrAddrReadAndWriteBytes(struct SdioTester * tester)113 static int32_t TestSdioIncrAddrReadAndWriteBytes(struct SdioTester *tester)
114 {
115     int32_t ret;
116 
117     SdioClaimHost(tester->handle);
118     ret = TestSdioIncrAddrReadAndWriteOneByte(tester);
119     if (ret != HDF_SUCCESS) {
120         HDF_LOGE("%s: TestSdioIncrAddrReadAndWriteOneByte fail! ret=%d.", __func__, ret);
121         SdioReleaseHost(tester->handle);
122         return HDF_FAILURE;
123     }
124     ret = TestSdioIncrAddrReadAndWriteOtherBytes(tester);
125     if (ret != HDF_SUCCESS) {
126         HDF_LOGE("%s: TestSdioIncrAddrReadAndWriteOtherBytes fail! ret=%d.", __func__, ret);
127         SdioReleaseHost(tester->handle);
128         return HDF_FAILURE;
129     }
130     SdioReleaseHost(tester->handle);
131 
132     return ret;
133 }
134 
TestSdioFixedAddrReadAndWriteOtherBytes(struct SdioTester * tester)135 static int32_t TestSdioFixedAddrReadAndWriteOtherBytes(struct SdioTester *tester)
136 {
137     int32_t ret;
138     uint8_t data[TEST_DATA_LEN] = {0};
139     const uint32_t addr = TEST_SDIO_BASE_ADDR * TEST_FUNC_NUM + TEST_FIXED_OFFSET + TEST_ADDR_ADD;
140 
141     /* read bits */
142     ret = SdioReadBytes(tester->handle, &data[0], addr, 1);
143     if (ret != HDF_SUCCESS) {
144         HDF_LOGE("%s: SdioReadBytesFromFixedAddr fail! ret=%d.", __func__, ret);
145         return HDF_FAILURE;
146     }
147     HDF_LOGE("%s: read, data[0]:%u, data[1]:%u\n", __func__, data[0], data[1]);
148     /* write bits */
149     ret = SdioWriteBytes(tester->handle, &data[0], addr, 1);
150     if (ret != HDF_SUCCESS) {
151         HDF_LOGE("%s: SdioWriteBytesToFixedAddr fail! ret=%d.", __func__, ret);
152         return HDF_FAILURE;
153     }
154     HDF_LOGE("%s: write, data[0]:%u, data[1]:%u.", __func__, data[0], data[1]);
155     return ret;
156 }
157 
TestSdioFixedAddrReadAndWriteOneByte(struct SdioTester * tester)158 static int32_t TestSdioFixedAddrReadAndWriteOneByte(struct SdioTester *tester)
159 {
160     int32_t ret;
161     uint32_t addr;
162     uint8_t val;
163 
164     addr = TEST_SDIO_BASE_ADDR * TEST_FUNC_NUM + TEST_FIXED_OFFSET;
165     /* read 1 bits */
166     ret = SdioReadBytes(tester->handle, &val, addr, 1);
167     if (ret != HDF_SUCCESS) {
168         HDF_LOGE("%s: SdioReadBytesFromFixedAddr fail! ret=%d.", __func__, ret);
169         return HDF_FAILURE;
170     }
171     HDF_LOGE("%s: read, val:%d\n", __func__, val);
172     /* write 1 bits */
173     ret = SdioWriteBytes(tester->handle, &val, addr, 1);
174     if (ret != HDF_SUCCESS) {
175         HDF_LOGE("%s: SdioWriteBytesToFixedAddr fail! ret=%d.", __func__, ret);
176         return HDF_FAILURE;
177     }
178     HDF_LOGE("%s: write, val:%d.", __func__, val);
179     /* read 1 bits */
180     addr++;
181     ret = SdioReadBytes(tester->handle, &val, addr, 1);
182     if (ret != HDF_SUCCESS) {
183         HDF_LOGE("%s: SdioReadBytesFromFixedAddr fail! ret=%d.", __func__, ret);
184         return HDF_FAILURE;
185     }
186     HDF_LOGE("%s: read, val:%d.", __func__, val);
187     /* read 1 bits */
188     addr++;
189     ret = SdioWriteBytes(tester->handle, &val, addr, 1);
190     if (ret != HDF_SUCCESS) {
191         HDF_LOGE("%s: SdioReadBytesFromFixedAddr fail! ret=%d.", __func__, ret);
192         return HDF_FAILURE;
193     }
194     HDF_LOGE("%s: read, val:%d.", __func__, val);
195 
196     return ret;
197 }
198 
TestSdioFixedAddrReadAndWriteBytes(struct SdioTester * tester)199 static int32_t TestSdioFixedAddrReadAndWriteBytes(struct SdioTester *tester)
200 {
201     int32_t ret;
202 
203     SdioClaimHost(tester->handle);
204     ret = TestSdioFixedAddrReadAndWriteOtherBytes(tester);
205     if (ret != HDF_SUCCESS) {
206         HDF_LOGE("%s: TestSdioFixedAddrReadAndWriteOtherBytes fail! ret=%d.", __func__, ret);
207         SdioReleaseHost(tester->handle);
208         return HDF_FAILURE;
209     }
210     ret = TestSdioFixedAddrReadAndWriteOneByte(tester);
211     if (ret != HDF_SUCCESS) {
212         HDF_LOGE("%s: TestSdioFixedAddrReadAndWriteOneByte fail! ret=%d.", __func__, ret);
213         SdioReleaseHost(tester->handle);
214         return HDF_FAILURE;
215     }
216     SdioReleaseHost(tester->handle);
217 
218     return ret;
219 }
220 
TestSdioFunc0ReadAndWriteBytes(struct SdioTester * tester)221 static int32_t TestSdioFunc0ReadAndWriteBytes(struct SdioTester *tester)
222 {
223     int32_t ret;
224     uint8_t val;
225 
226     SdioClaimHost(tester->handle);
227     /* read sdio rev */
228     ret = SdioReadBytesFromFunc0(tester->handle, &val, TEST_FUNC0_ADDR, 1);
229     if (ret != HDF_SUCCESS) {
230         HDF_LOGE("%s: SdioReadBytesFromFunc0 fail! ret=%d.", __func__, ret);
231         SdioReleaseHost(tester->handle);
232         return HDF_FAILURE;
233     }
234     HDF_LOGE("%s: Func0 Read, val :%d.", __func__, val);
235 
236     /* write sdio rev */
237     ret = SdioWriteBytesToFunc0(tester->handle, &val, TEST_FUNC0_ADDR, 1);
238     if (ret != HDF_SUCCESS) {
239         HDF_LOGE("%s: SdioWriteBytesToFunc0 fail! ret=%d.", __func__, ret);
240         SdioReleaseHost(tester->handle);
241         return HDF_FAILURE;
242     }
243 
244     /* read sdio rev again */
245     ret = SdioReadBytesFromFunc0(tester->handle, &val, TEST_FUNC0_ADDR, 1);
246     if (ret != HDF_SUCCESS) {
247         HDF_LOGE("%s: SdioReadBytesFromFunc0 fail! ret=%d.", __func__, ret);
248         SdioReleaseHost(tester->handle);
249         return HDF_FAILURE;
250     }
251     SdioReleaseHost(tester->handle);
252 
253     HDF_LOGE("%s: Func0 Read, val:%u.", __func__, val);
254     return ret;
255 }
256 
TestSdioSetAndGetFuncInfo(struct SdioTester * tester)257 static int32_t TestSdioSetAndGetFuncInfo(struct SdioTester *tester)
258 {
259     int32_t ret;
260     SdioCommonInfo info = {0};
261 
262     ret = SdioGetCommonInfo(tester->handle, &info, SDIO_FUNC_INFO);
263     if (ret != HDF_SUCCESS) {
264         HDF_LOGE("%s: SdioGetCommonInfo fail! ret=%d.", __func__, ret);
265         return ret;
266     }
267     HDF_LOGE("%s: succ! Timeout=%u.", __func__, info.funcInfo.enTimeout);
268 
269     info.funcInfo.enTimeout = TEST_TIME_OUT;
270     ret = SdioSetCommonInfo(tester->handle, &info, SDIO_FUNC_INFO);
271     if (ret != HDF_SUCCESS) {
272         HDF_LOGE("%s: SdioSetCommonInfo fail! ret=%d.", __func__, ret);
273         return ret;
274     }
275 
276     ret = SdioGetCommonInfo(tester->handle, &info, SDIO_FUNC_INFO);
277     if (ret != HDF_SUCCESS) {
278         HDF_LOGE("%s: SdioGetCommonInfo fail! ret=%d.", __func__, ret);
279         return ret;
280     }
281     HDF_LOGE("%s: again succ! Timeout=%u.", __func__, info.funcInfo.enTimeout);
282 
283     return HDF_SUCCESS;
284 }
285 
TestSdioSetAndGetCommonInfo(struct SdioTester * tester)286 static int32_t TestSdioSetAndGetCommonInfo(struct SdioTester *tester)
287 {
288     int32_t ret;
289 
290     SdioClaimHost(tester->handle);
291     ret = TestSdioSetAndGetFuncInfo(tester);
292     if (ret != HDF_SUCCESS) {
293         HDF_LOGE("%s: TestSdioSetAndGetFuncInfo fail! ret=%d.", __func__, ret);
294         SdioReleaseHost(tester->handle);
295         return HDF_FAILURE;
296     }
297     SdioReleaseHost(tester->handle);
298     return ret;
299 }
300 
TestSdioSetBlockSize(struct SdioTester * tester)301 static int32_t TestSdioSetBlockSize(struct SdioTester *tester)
302 {
303     int32_t ret;
304     SdioClaimHost(tester->handle);
305     ret = SdioSetBlockSize(tester->handle, TEST_BLOCKSIZE);
306     if (ret != HDF_SUCCESS) {
307         HDF_LOGE("%s: SdioSetBlockSize fail! ret=%d.", __func__, ret);
308         SdioReleaseHost(tester->handle);
309         return HDF_FAILURE;
310     }
311     SdioReleaseHost(tester->handle);
312     return ret;
313 }
314 
TestSdioEnableFunc(struct SdioTester * tester)315 static int32_t TestSdioEnableFunc(struct SdioTester *tester)
316 {
317     int32_t ret;
318 
319     SdioClaimHost(tester->handle);
320     ret = SdioEnableFunc(tester->handle);
321     if (ret != HDF_SUCCESS) {
322         HDF_LOGE("%s: SdioEnableFunc fail! ret=%d.", __func__, ret);
323         SdioReleaseHost(tester->handle);
324         return HDF_FAILURE;
325     }
326     SdioReleaseHost(tester->handle);
327     return ret;
328 }
329 
TestSdioDisableFunc(struct SdioTester * tester)330 static int32_t TestSdioDisableFunc(struct SdioTester *tester)
331 {
332     int32_t ret;
333 
334     SdioClaimHost(tester->handle);
335     ret = SdioDisableFunc(tester->handle);
336     if (ret != HDF_SUCCESS) {
337         HDF_LOGE("%s: SdioDisableFunc fail! ret=%d.", __func__, ret);
338         SdioReleaseHost(tester->handle);
339         return HDF_FAILURE;
340     }
341     SdioReleaseHost(tester->handle);
342     return ret;
343 }
344 
345 struct SdioTestFunc g_sdioTestFunc[] = {
346     { SDIO_DISABLE_FUNC_01, TestSdioDisableFunc },
347     { SDIO_ENABLE_FUNC_01, TestSdioEnableFunc },
348     { SDIO_SET_BLOCK_SIZE_01, TestSdioSetBlockSize },
349     { SDIO_INCR_ADDR_READ_AND_WRITE_BYTES_01, TestSdioIncrAddrReadAndWriteBytes },
350     { SDIO_FIXED_ADDR_READ_AND_WRITE_BYTES_01, TestSdioFixedAddrReadAndWriteBytes },
351     { SDIO_FUNC0_READ_AND_WRITE_BYTES_01, TestSdioFunc0ReadAndWriteBytes },
352     { SDIO_SET_AND_GET_COMMON_INFO_01, TestSdioSetAndGetCommonInfo },
353 };
354 
SdioTestEntry(struct SdioTester * tester,int32_t cmd)355 static int32_t SdioTestEntry(struct SdioTester *tester, int32_t cmd)
356 {
357     int32_t i;
358     int32_t ret = HDF_SUCCESS;
359     bool isFind = false;
360 
361     if (tester == NULL) {
362         HDF_LOGE("%s: tester is NULL", __func__);
363         return HDF_ERR_INVALID_OBJECT;
364     }
365     tester->handle = SdioTestGetHandle(tester);
366     if (tester->handle == NULL) {
367         HDF_LOGE("%s: sdio test get handle fail", __func__);
368         return HDF_FAILURE;
369     }
370     for (i = 0; i < sizeof(g_sdioTestFunc) / sizeof(g_sdioTestFunc[0]); i++) {
371         if (cmd == g_sdioTestFunc[i].type && g_sdioTestFunc[i].Func != NULL) {
372             ret = g_sdioTestFunc[i].Func(tester);
373             isFind = true;
374             break;
375         }
376     }
377     if (!isFind) {
378         ret = HDF_ERR_NOT_SUPPORT;
379         HDF_LOGE("%s: cmd %d not support", __func__, cmd);
380     }
381     SdioTestReleaseHandle(tester->handle);
382     return ret;
383 }
384 
SdioTestFillConfig(struct SdioTester * tester,const struct DeviceResourceNode * node)385 static int32_t SdioTestFillConfig(struct SdioTester *tester, const struct DeviceResourceNode *node)
386 {
387     int32_t ret;
388     struct DeviceResourceIface *drsOps = NULL;
389 
390     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
391     if (drsOps == NULL || drsOps->GetUint32 == NULL) {
392         HDF_LOGE("%s: invalid drs ops fail!", __func__);
393         return HDF_FAILURE;
394     }
395 
396     ret = drsOps->GetUint32(node, "busNum", &(tester->busNum), 0);
397     if (ret != HDF_SUCCESS) {
398         HDF_LOGE("%s: fill bus num fail!", __func__);
399         return ret;
400     }
401 
402     ret = drsOps->GetUint32(node, "funcNum", &(tester->config.funcNr), 0);
403     if (ret != HDF_SUCCESS) {
404         HDF_LOGE("%s: fill funcNum fail!", __func__);
405         return ret;
406     }
407     ret = drsOps->GetUint16(node, "vendorId", &(tester->config.vendorId), 0);
408     if (ret != HDF_SUCCESS) {
409         HDF_LOGE("%s: fill vendorId fail!", __func__);
410         return ret;
411     }
412     ret = drsOps->GetUint16(node, "deviceId", &(tester->config.deviceId), 0);
413     if (ret != HDF_SUCCESS) {
414         HDF_LOGE("%s: fill deviceId fail!", __func__);
415         return ret;
416     }
417 
418     HDF_LOGE("%s: busNum:%u, funcNum:%u, vendorId:0x%x, deviceId:0x%x.", __func__,
419         tester->busNum, tester->config.funcNr, tester->config.vendorId, tester->config.deviceId);
420     return HDF_SUCCESS;
421 }
422 
SdioTestBind(struct HdfDeviceObject * device)423 static int32_t SdioTestBind(struct HdfDeviceObject *device)
424 {
425     static struct SdioTester tester;
426 
427     if (device == NULL) {
428         HDF_LOGE("%s: device or config is null!", __func__);
429         return HDF_ERR_IO;
430     }
431 
432     device->service = &tester.service;
433     HDF_LOGE("%s: Sdio_TEST service init success!", __func__);
434     return HDF_SUCCESS;
435 }
436 
SdioTestInit(struct HdfDeviceObject * device)437 static int32_t SdioTestInit(struct HdfDeviceObject *device)
438 {
439     struct SdioTester *tester = NULL;
440     int32_t ret;
441 
442     if (device == NULL || device->service == NULL || device->property == NULL) {
443         HDF_LOGE("%s: invalid parameter", __func__);
444         return HDF_ERR_INVALID_PARAM;
445     }
446 
447     tester = (struct SdioTester *)device->service;
448     if (tester == NULL) {
449         HDF_LOGE("%s: tester is NULL", __func__);
450         return HDF_ERR_INVALID_PARAM;
451     }
452     ret = SdioTestFillConfig(tester, device->property);
453     if (ret != HDF_SUCCESS) {
454         HDF_LOGE("%s: read config fail!", __func__);
455         return ret;
456     }
457     tester->TestEntry = SdioTestEntry;
458     HDF_LOGE("%s: success", __func__);
459     return HDF_SUCCESS;
460 }
461 
SdioTestRelease(struct HdfDeviceObject * device)462 static void SdioTestRelease(struct HdfDeviceObject *device)
463 {
464     if (device != NULL) {
465         device->service = NULL;
466     }
467 }
468 
469 struct HdfDriverEntry g_sdioTestEntry = {
470     .moduleVersion = 1,
471     .Bind = SdioTestBind,
472     .Init = SdioTestInit,
473     .Release = SdioTestRelease,
474     .moduleName = "PLATFORM_SDIO_TEST",
475 };
476 HDF_INIT(g_sdioTestEntry);
477