1 /*
2 * Copyright (c) 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_time.h"
13 #include "pcie_if.h"
14 #include "pcie_test.h"
15
16 #define HDF_LOG_TAG pcie_test_c
17
18 #define PCIE_TEST_DISABLE_ADDR 0xB7
19 #define PCIE_TEST_UPPER_ADDR 0x28
20 #define PCIE_TEST_CMD_ADDR 0x04
21
22 struct PcieTestFunc {
23 enum PcieTestCmd type;
24 int32_t (*Func)(struct PcieTester *tester);
25 };
26
PcieTestGetHandle(struct PcieTester * tester)27 static DevHandle PcieTestGetHandle(struct PcieTester *tester)
28 {
29 if (tester == NULL) {
30 HDF_LOGE("%s: tester is null", __func__);
31 return NULL;
32 }
33 return PcieOpen(tester->busNum);
34 }
35
PcieTestReleaseHandle(DevHandle handle)36 static void PcieTestReleaseHandle(DevHandle handle)
37 {
38 if (handle == NULL) {
39 HDF_LOGE("%s: pcie handle is null", __func__);
40 return;
41 }
42 PcieClose(handle);
43 }
44
TestPcieReadAndWrite(struct PcieTester * tester)45 static int32_t TestPcieReadAndWrite(struct PcieTester *tester)
46 {
47 int32_t ret;
48 uint8_t disable;
49 uint32_t upper;
50 uint16_t cmd;
51
52 ret = PcieRead(tester->handle, PCIE_TEST_DISABLE_ADDR, &disable, sizeof(disable));
53 if (ret != HDF_SUCCESS) {
54 HDF_LOGE("%s: PcieRead failed ret = %d.", __func__, ret);
55 return ret;
56 }
57 HDF_LOGD("%s: disable is %d", __func__, disable);
58 ret = PcieWrite(tester->handle, PCIE_TEST_DISABLE_ADDR, &disable, sizeof(disable));
59 if (ret != HDF_SUCCESS) {
60 HDF_LOGE("%s: PcieWrite failed ret = %d.", __func__, ret);
61 return ret;
62 }
63
64 ret = PcieRead(tester->handle, PCIE_TEST_UPPER_ADDR, (uint8_t *)&upper, sizeof(upper));
65 if (ret != HDF_SUCCESS) {
66 HDF_LOGE("%s: PcieRead failed ret = %d.", __func__, ret);
67 return ret;
68 }
69 HDF_LOGD("%s: upper is 0x%x", __func__, upper);
70 ret = PcieWrite(tester->handle, PCIE_TEST_UPPER_ADDR, (uint8_t *)&upper, sizeof(upper));
71 if (ret != HDF_SUCCESS) {
72 HDF_LOGE("%s: PcieWrite failed ret = %d.", __func__, ret);
73 return ret;
74 }
75
76 ret = PcieRead(tester->handle, PCIE_TEST_CMD_ADDR, (uint8_t *)&cmd, sizeof(cmd));
77 if (ret != HDF_SUCCESS) {
78 HDF_LOGE("%s: PcieRead failed ret = %d.", __func__, ret);
79 return ret;
80 }
81 HDF_LOGD("%s: cmd is 0x%x", __func__, cmd);
82 ret = PcieWrite(tester->handle, PCIE_TEST_CMD_ADDR, (uint8_t *)&cmd, sizeof(cmd));
83 if (ret != HDF_SUCCESS) {
84 HDF_LOGE("%s: PcieWrite failed ret = %d.", __func__, ret);
85 }
86 return ret;
87 }
88
89 struct PcieTestFunc g_pcieTestFunc[] = {
90 { PCIE_READ_AND_WRITE_01, TestPcieReadAndWrite },
91 };
92
PcieTestEntry(struct PcieTester * tester,int32_t cmd)93 static int32_t PcieTestEntry(struct PcieTester *tester, int32_t cmd)
94 {
95 int32_t i;
96 int32_t ret = HDF_SUCCESS;
97 bool isFind = false;
98
99 if (tester == NULL) {
100 HDF_LOGE("%s: tester is NULL", __func__);
101 return HDF_ERR_INVALID_OBJECT;
102 }
103 tester->handle = PcieTestGetHandle(tester);
104 if (tester->handle == NULL) {
105 HDF_LOGE("%s: pcie test get handle failed", __func__);
106 return HDF_FAILURE;
107 }
108 for (i = 0; i < sizeof(g_pcieTestFunc) / sizeof(g_pcieTestFunc[0]); i++) {
109 if (cmd == g_pcieTestFunc[i].type && g_pcieTestFunc[i].Func != NULL) {
110 ret = g_pcieTestFunc[i].Func(tester);
111 isFind = true;
112 break;
113 }
114 }
115 if (!isFind) {
116 ret = HDF_ERR_NOT_SUPPORT;
117 HDF_LOGE("%s: cmd %d not supported", __func__, cmd);
118 }
119 PcieTestReleaseHandle(tester->handle);
120 return ret;
121 }
122
PcieTestFillConfig(struct PcieTester * tester,const struct DeviceResourceNode * node)123 static int32_t PcieTestFillConfig(struct PcieTester *tester, const struct DeviceResourceNode *node)
124 {
125 int32_t ret;
126 struct DeviceResourceIface *drsOps = NULL;
127
128 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
129 if (drsOps == NULL || drsOps->GetUint32 == NULL) {
130 HDF_LOGE("%s: invalid drs ops", __func__);
131 return HDF_FAILURE;
132 }
133
134 ret = drsOps->GetUint32(node, "busNum", &(tester->busNum), 0);
135 if (ret != HDF_SUCCESS) {
136 HDF_LOGE("%s: fill bus num failed", __func__);
137 return ret;
138 }
139
140 HDF_LOGE("%s: busNum:%d.", __func__, tester->busNum);
141 return HDF_SUCCESS;
142 }
143
PcieTestBind(struct HdfDeviceObject * device)144 static int32_t PcieTestBind(struct HdfDeviceObject *device)
145 {
146 static struct PcieTester tester;
147
148 if (device == NULL) {
149 HDF_LOGE("%s: device or config is null!", __func__);
150 return HDF_ERR_IO;
151 }
152
153 device->service = &tester.service;
154 HDF_LOGE("%s: PCIE_TEST service init success!", __func__);
155 return HDF_SUCCESS;
156 }
157
PcieTestInit(struct HdfDeviceObject * device)158 static int32_t PcieTestInit(struct HdfDeviceObject *device)
159 {
160 struct PcieTester *tester = NULL;
161 int32_t ret;
162
163 if (device == NULL || device->service == NULL || device->property == NULL) {
164 HDF_LOGE("%s: invalid parameter", __func__);
165 return HDF_ERR_INVALID_PARAM;
166 }
167
168 tester = (struct PcieTester *)device->service;
169 if (tester == NULL) {
170 HDF_LOGE("%s: tester is NULL", __func__);
171 return HDF_ERR_INVALID_PARAM;
172 }
173 ret = PcieTestFillConfig(tester, device->property);
174 if (ret != HDF_SUCCESS) {
175 HDF_LOGE("%s: read config failed", __func__);
176 return ret;
177 }
178 tester->TestEntry = PcieTestEntry;
179 HDF_LOGE("%s: success", __func__);
180 return HDF_SUCCESS;
181 }
182
PcieTestRelease(struct HdfDeviceObject * device)183 static void PcieTestRelease(struct HdfDeviceObject *device)
184 {
185 if (device != NULL) {
186 device->service = NULL;
187 }
188 }
189
190 struct HdfDriverEntry g_pcieTestEntry = {
191 .moduleVersion = 1,
192 .Bind = PcieTestBind,
193 .Init = PcieTestInit,
194 .Release = PcieTestRelease,
195 .moduleName = "PLATFORM_PCIE_TEST",
196 };
197 HDF_INIT(g_pcieTestEntry);
198