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 "eth_device.h"
10 #include "eth_chip_driver.h"
11 #include <string.h>
12 #include "device_resource_if.h"
13 #include "hdf_log.h"
14 #include "los_vm_zone.h"
15 #include "osal_mem.h"
16 #include "securec.h"
17
18 #define HDF_LOG_TAG eth_device
19
GetEthIfName(const struct ConfigEthDevList * configEthDevList,char * ifName,uint32_t ifNameSize)20 int32_t GetEthIfName(const struct ConfigEthDevList *configEthDevList, char *ifName, uint32_t ifNameSize)
21 {
22 if (configEthDevList == NULL || ifName == NULL || ifNameSize == 0) {
23 HDF_LOGE("%s:para is null!", __func__);
24 return HDF_FAILURE;
25 }
26 if (snprintf_s(ifName, ifNameSize, ifNameSize - 1, "eth%d", configEthDevList->deviceInstId) < 0) {
27 HDF_LOGE("%s:format ifName failed!deviceInstId = %d.", __func__, configEthDevList->deviceInstId);
28 return HDF_FAILURE;
29 }
30 return HDF_SUCCESS;
31 }
32
CreateEthDevice(const struct ConfigEthDevList * configEthDevList)33 struct EthDevice *CreateEthDevice(const struct ConfigEthDevList *configEthDevList)
34 {
35 int32_t ret;
36 struct HdfEthNetDeviceData *data = NULL;
37 struct NetDevice *netDevice = NULL;
38 struct EthDevice *ethDevice = NULL;
39 char ethIfName[IFNAMSIZ] = {0};
40
41 if (configEthDevList == NULL) {
42 HDF_LOGE("%s input is NULL!", __func__);
43 return NULL;
44 }
45 data = (struct HdfEthNetDeviceData *)OsalMemCalloc(sizeof(struct HdfEthNetDeviceData));
46 if (data == NULL) {
47 HDF_LOGE("%s failed to OsalMemCalloc HdfEthNetDeviceData", __func__);
48 return NULL;
49 }
50 ret = GetEthIfName(configEthDevList, ethIfName, IFNAMSIZ);
51 if (ret != HDF_SUCCESS) {
52 OsalMemFree(data);
53 return NULL;
54 }
55 netDevice = NetDeviceInit(ethIfName, strlen(ethIfName), ETHERNET_LINK, LITE_OS);
56 if (netDevice == NULL) {
57 HDF_LOGE("%s failed to init netDevice", __func__);
58 OsalMemFree(data);
59 return NULL;
60 }
61 ethDevice = (struct EthDevice *)OsalMemCalloc(sizeof(struct EthDevice));
62 if (ethDevice == NULL) {
63 HDF_LOGE("%s failed to OsalMemCalloc ethDevice", __func__);
64 NetDeviceDeInit(netDevice);
65 OsalMemFree(data);
66 return NULL;
67 }
68 netDevice->mlPriv = ethDevice;
69 ethDevice->netdev = netDevice;
70 ethDevice->netdev->classDriverPriv = data;
71 ethDevice->name = configEthDevList->driverName;
72 return ethDevice;
73 }
74
ParseEthMacConfig(const struct DeviceResourceNode * node,struct HdfConfigEthMac * ethMacConfig)75 static int32_t ParseEthMacConfig(const struct DeviceResourceNode *node, struct HdfConfigEthMac *ethMacConfig)
76 {
77 struct DeviceResourceIface *drsOps = NULL;
78
79 if (node == NULL || ethMacConfig == NULL) {
80 HDF_LOGE("%s: invalid node or ethMacConfig!", __func__);
81 return HDF_FAILURE;
82 }
83
84 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
85 if (drsOps == NULL || drsOps->GetUint8 == NULL || drsOps->GetUint32 == NULL) {
86 HDF_LOGE("%s: at least one of the paras is NULL!", __func__);
87 return HDF_FAILURE;
88 }
89 if (drsOps->GetUint32(node, "regBase", ðMacConfig->regBase, 0) != HDF_SUCCESS) {
90 HDF_LOGE("%s: read regBase fail", __func__);
91 return HDF_FAILURE;
92 }
93 if (drsOps->GetUint32(node, "irqVector", ðMacConfig->irqVector, 0) != HDF_SUCCESS) {
94 HDF_LOGE("%s: read irqVector fail", __func__);
95 return HDF_FAILURE;
96 }
97 if (drsOps->GetUint8(node, "mdioFrqDiv", ðMacConfig->mdioFrqDiv, 0) != HDF_SUCCESS) {
98 HDF_LOGE("%s: read mdioFrqDiv fail", __func__);
99 return HDF_FAILURE;
100 }
101 if (drsOps->GetUint8(node, "txBusy", ðMacConfig->txBusy, 0) != HDF_SUCCESS) {
102 HDF_LOGE("%s: read txBusy fail", __func__);
103 return HDF_FAILURE;
104 }
105 if (drsOps->GetUint32(node, "iobase", ðMacConfig->iobase, 0) != HDF_SUCCESS) {
106 HDF_LOGE("%s: read iobase fail", __func__);
107 return HDF_FAILURE;
108 }
109 if (drsOps->GetUint32(node, "regOffSize", ðMacConfig->regOffSize, 0) != HDF_SUCCESS) {
110 HDF_LOGE("%s: read regOffSize fail", __func__);
111 return HDF_FAILURE;
112 }
113 return HDF_SUCCESS;
114 }
115
ParseEthPhyConfig(const struct DeviceResourceNode * node,struct HdfConfigEthPhy * ethPhyConfig)116 static int32_t ParseEthPhyConfig(const struct DeviceResourceNode *node, struct HdfConfigEthPhy *ethPhyConfig)
117 {
118 struct DeviceResourceIface *drsOps = NULL;
119
120 if (node == NULL || ethPhyConfig == NULL) {
121 HDF_LOGE("%s: invalid node or ethPhyConfig!", __func__);
122 return HDF_FAILURE;
123 }
124
125 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
126 if (drsOps == NULL || drsOps->GetUint8 == NULL) {
127 HDF_LOGE("%s: at least one of the paras is NULL!", __func__);
128 return HDF_FAILURE;
129 }
130
131 if (drsOps->GetUint8(node, "phyMode", ðPhyConfig->phyMode, 0) != HDF_SUCCESS) {
132 HDF_LOGE("%s: read phyMode fail", __func__);
133 return HDF_FAILURE;
134 }
135 return HDF_SUCCESS;
136 }
137
ParseEthDevInstConfig(const struct DeviceResourceNode * node,struct ConfigEthDevList * devLstConfig)138 static int32_t ParseEthDevInstConfig(const struct DeviceResourceNode *node, struct ConfigEthDevList *devLstConfig)
139 {
140 struct DeviceResourceIface *drsOps = NULL;
141 const struct DeviceResourceNode *ethMacNode = NULL;
142 const struct DeviceResourceNode *ethPhyNode = NULL;
143 if (node == NULL || devLstConfig == NULL) {
144 return HDF_FAILURE;
145 }
146 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
147 if (drsOps == NULL || drsOps->GetUint8 == NULL || drsOps->GetChildNode == NULL) {
148 HDF_LOGE("%s: at least one of the paras is NULL!", __func__);
149 return HDF_FAILURE;
150 }
151 if (drsOps->GetUint8(node, "deviceInstId", &devLstConfig->deviceInstId, 0) != HDF_SUCCESS) {
152 HDF_LOGE("%s: deviceInstId fail!", __func__);
153 return HDF_FAILURE;
154 }
155 if (drsOps->GetUint8(node, "isSetDefault", &devLstConfig->isSetDefault, 0) != HDF_SUCCESS) {
156 HDF_LOGE("%s: isSetDefault fail!", __func__);
157 return HDF_FAILURE;
158 }
159 if (drsOps->GetString(node, "driverName", &devLstConfig->driverName, NULL) != HDF_SUCCESS) {
160 HDF_LOGE("%s: driverName fail!", __func__);
161 return HDF_FAILURE;
162 }
163 if (drsOps->GetUint8(node, "hwXmitq", &devLstConfig->hwXmitq, 0) != HDF_SUCCESS) {
164 HDF_LOGE("%s: read hwXmitq fail", __func__);
165 return HDF_FAILURE;
166 }
167 if (drsOps->GetUint8(node, "qSize", &devLstConfig->qSize, 0) != HDF_SUCCESS) {
168 HDF_LOGE("%s: read qSize fail", __func__);
169 return HDF_FAILURE;
170 }
171 if (drsOps->GetUint8(node, "port", &devLstConfig->port, 0) != HDF_SUCCESS) {
172 HDF_LOGE("%s: read port fail", __func__);
173 return HDF_FAILURE;
174 }
175
176 ethMacNode = drsOps->GetChildNode(node, "MAC");
177 if (ethMacNode == NULL) {
178 HDF_LOGE("%s: GetChildNode fail!", __func__);
179 return HDF_FAILURE;
180 }
181 if (ParseEthMacConfig(ethMacNode, &devLstConfig->ethMac) != HDF_SUCCESS) {
182 return HDF_FAILURE;
183 }
184 ethPhyNode = drsOps->GetChildNode(node, "PHY");
185 if (ethPhyNode == NULL) {
186 HDF_LOGE("%s: GetChildNode fail!", __func__);
187 return HDF_FAILURE;
188 }
189 if (ParseEthPhyConfig(ethPhyNode, &devLstConfig->ethPhy) != HDF_SUCCESS) {
190 return HDF_FAILURE;
191 }
192 return HDF_SUCCESS;
193 }
194
ParseEthDevListNode(const struct DeviceResourceNode * node,struct EthConfig * ethConfig)195 static int32_t ParseEthDevListNode(const struct DeviceResourceNode *node, struct EthConfig *ethConfig)
196 {
197 struct DeviceResourceNode *childNode = NULL;
198 uint32_t index = 0;
199
200 if (node == NULL || ethConfig == NULL) {
201 HDF_LOGE("%s: invalid node or ethConfig!", __func__);
202 return HDF_FAILURE;
203 }
204 DEV_RES_NODE_FOR_EACH_CHILD_NODE(node, childNode)
205 {
206 if (ParseEthDevInstConfig(childNode, ðConfig->deviceInst[index]) != HDF_SUCCESS) {
207 return HDF_FAILURE;
208 }
209 index++;
210 ethConfig->deviceListSize++;
211 }
212 HDF_LOGD("%s: deviceListSize=%d", __func__, ethConfig->deviceListSize);
213 return HDF_SUCCESS;
214 }
215
ParseConfigFromProperty(const struct DeviceResourceNode * node,struct EthConfig * config)216 static int32_t ParseConfigFromProperty(const struct DeviceResourceNode *node, struct EthConfig *config)
217 {
218 struct DeviceResourceIface *drsOps = NULL;
219 const struct DeviceResourceNode *devListNode = NULL;
220
221 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
222 if (drsOps == NULL || drsOps->GetChildNode == NULL) {
223 HDF_LOGE("%s: invalid drs ops fail!", __func__);
224 return HDF_FAILURE;
225 }
226 devListNode = drsOps->GetChildNode(node, "ethList");
227 if (devListNode == NULL) {
228 HDF_LOGE("%s: get child node fail!", __func__);
229 return HDF_FAILURE;
230 }
231 return ParseEthDevListNode(devListNode, config);
232 }
233
GetEthConfig(const struct DeviceResourceNode * node)234 struct EthConfig *GetEthConfig(const struct DeviceResourceNode *node)
235 {
236 if (node == NULL) {
237 HDF_LOGE("%s input is NULL", __func__);
238 return NULL;
239 }
240
241 struct EthConfig *config = NULL;
242
243 config = (struct EthConfig *)OsalMemCalloc(sizeof(*config));
244 if (config == NULL) {
245 HDF_LOGE("%s failed to OsalMemCalloc config", __func__);
246 return NULL;
247 }
248
249 if (ParseConfigFromProperty(node, config) != HDF_SUCCESS) {
250 HDF_LOGE("%s failed to parse config from property", __func__);
251 return NULL;
252 }
253 return config;
254 }
255
GetEthNetDeviceData(const struct NetDevice * netDev)256 struct HdfEthNetDeviceData *GetEthNetDeviceData(const struct NetDevice *netDev)
257 {
258 if (netDev == NULL) {
259 return NULL;
260 }
261 return (struct HdfEthNetDeviceData *)(netDev->classDriverPriv);
262 }
263
ReleaseEthDevice(struct EthDevice * ethDevice)264 int32_t ReleaseEthDevice(struct EthDevice *ethDevice)
265 {
266 int32_t ret;
267 struct HdfEthNetDeviceData *data = NULL;
268
269 if (ethDevice == NULL) {
270 HDF_LOGE("%s:NULL ptr!", __func__);
271 return HDF_FAILURE;
272 }
273
274 data = GetEthNetDeviceData(ethDevice->netdev);
275 if (data == NULL) {
276 HDF_LOGE("%s: GetEthNetDeviceData failed!", __func__);
277 return HDF_FAILURE;
278 }
279 struct HdfEthMacChipDriver *macChipDriver = data->macChipDriver;
280 if (macChipDriver != NULL) {
281 OsalMemFree(macChipDriver);
282 macChipDriver = NULL;
283 }
284 ret = NetDeviceDeInit(ethDevice->netdev);
285 if (ret != HDF_SUCCESS) {
286 return ret;
287 }
288
289 OsalMemFree(ethDevice);
290 OsalMemFree(data);
291 return HDF_SUCCESS;
292 }