1 /*
2 * net_device_adapter.c
3 *
4 * net device adapter of linux
5 *
6 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19 #include "net_device_adapter.h"
20 #include <linux/etherdevice.h>
21 #include <linux/rtnetlink.h>
22 #include <linux/version.h>
23 #include "net_device.h"
24 #include "net_device_impl.h"
25 #include "osal_mem.h"
26 #include "securec.h"
27
28 #define HDF_LOG_TAG NetDeviceFull
29
NetDevXmitCheck(struct sk_buff * skb,struct net_device * dev)30 static int32_t NetDevXmitCheck(struct sk_buff *skb, struct net_device *dev)
31 {
32 struct FullNetDevicePriv *priv = NULL;
33
34 if (dev == NULL || skb == NULL) {
35 HDF_LOGE("%s : dev = NUll or skb = NULL!", __func__);
36 return HDF_ERR_INVALID_PARAM;
37 }
38 priv = (struct FullNetDevicePriv *)netdev_priv(dev);
39 if (priv == NULL || priv->dev == NULL || priv->impl == NULL) {
40 HDF_LOGE("%s fail : priv NULL!", __func__);
41 return HDF_ERR_INVALID_PARAM;
42 }
43 return HDF_SUCCESS;
44 }
45
NetDevXmit(struct sk_buff * skb,struct net_device * dev)46 static netdev_tx_t NetDevXmit(struct sk_buff *skb, struct net_device *dev)
47 {
48 struct FullNetDevicePriv *priv = NULL;
49 struct NetDevice *netDev = NULL;
50 struct NetDeviceInterFace *netDevIf = NULL;
51
52 if (NetDevXmitCheck(skb, dev) != HDF_SUCCESS) {
53 NetBufFree(skb);
54 return NETDEV_TX_OK;
55 }
56 priv = (struct FullNetDevicePriv *)netdev_priv(dev);
57 netDev = priv->impl->netDevice;
58
59 skb->dev = (struct net_device *)netDev;
60 netDevIf = netDev->netDeviceIf;
61 if (netDevIf != NULL && netDevIf->xmit != NULL) {
62 netDevIf->xmit(netDev, skb);
63 } else {
64 HDF_LOGE("%s fail : netdevIf = null or xmit = null!", __func__);
65 NetBufFree(skb);
66 }
67 return NETDEV_TX_OK;
68 }
69
NetDevChangeMtu(struct net_device * dev,int mtu)70 static int NetDevChangeMtu(struct net_device *dev, int mtu)
71 {
72 if (mtu > WLAN_MAX_MTU || mtu < WLAN_MIN_MTU || dev == NULL) {
73 return -EINVAL;
74 }
75
76 dev->mtu = (uint32_t)mtu;
77 return HDF_SUCCESS;
78 }
79
NetDevOpen(struct net_device * dev)80 static int NetDevOpen(struct net_device *dev)
81 {
82 if (dev == NULL) {
83 return -EINVAL;
84 }
85
86 netif_start_queue(dev);
87 return HDF_SUCCESS;
88 }
89
NetDevStop(struct net_device * dev)90 static int NetDevStop(struct net_device *dev)
91 {
92 if (dev == NULL) {
93 return -EINVAL;
94 }
95
96 netif_stop_queue(dev);
97 return HDF_SUCCESS;
98 }
99
100 static struct net_device_ops g_netDeviceOps = {
101 .ndo_start_xmit = NetDevXmit,
102 .ndo_change_mtu = NetDevChangeMtu,
103 .ndo_open = NetDevOpen,
104 .ndo_stop = NetDevStop
105 };
106
CreateNetDevice(struct NetDevice * hdfDev)107 static struct net_device *CreateNetDevice(struct NetDevice *hdfDev)
108 {
109 struct net_device *dev = NULL;
110
111 dev = alloc_etherdev(sizeof(struct FullNetDevicePriv));
112 if (dev == NULL) {
113 return NULL;
114 }
115
116 if (memcpy_s(dev->name, IFNAMSIZ, hdfDev->name, IFNAMSIZ) != EOK) {
117 free_netdev(dev);
118 return NULL;
119 }
120 dev->mtu = DEFAULT_MTU;
121 dev->netdev_ops = &g_netDeviceOps;
122
123 return dev;
124 }
125
DestroyNetDevice(struct net_device * dev)126 static void DestroyNetDevice(struct net_device *dev)
127 {
128 free_netdev(dev);
129 }
130
GetDevFromDevImpl(const struct NetDeviceImpl * impl)131 static struct net_device *GetDevFromDevImpl(const struct NetDeviceImpl *impl)
132 {
133 struct FullNetDevicePriv *priv = NULL;
134
135 if (impl == NULL || impl->osPrivate == NULL) {
136 return NULL;
137 }
138 priv = (struct FullNetDevicePriv *)impl->osPrivate;
139 return priv->dev;
140 }
141
NetDevInit(struct NetDeviceImpl * impl)142 static int32_t NetDevInit(struct NetDeviceImpl *impl)
143 {
144 struct FullNetDevicePriv *priv = NULL;
145 struct net_device *dev = NULL;
146
147 if (impl == NULL || impl->netDevice == NULL) {
148 HDF_LOGE("%s fail: impl null , netDevice null", __func__);
149 return HDF_ERR_INVALID_PARAM;
150 }
151
152 dev = CreateNetDevice(impl->netDevice);
153 if (dev == NULL) {
154 HDF_LOGE("%s fail : CreateNetDevice fail!", __func__);
155 return HDF_FAILURE;
156 }
157
158 priv = (struct FullNetDevicePriv *)netdev_priv(dev);
159 priv->dev = dev;
160 priv->impl = impl;
161 impl->osPrivate = (void *)priv;
162 HDF_LOGI("%s Success!", __func__);
163
164 return HDF_SUCCESS;
165 }
166
NetDevDeInit(struct NetDeviceImpl * impl)167 static int32_t NetDevDeInit(struct NetDeviceImpl *impl)
168 {
169 struct FullNetDevicePriv *priv = NULL;
170
171 if (impl == NULL) {
172 HDF_LOGE("netdevice linux deinit already free.");
173 return HDF_SUCCESS;
174 }
175 if (impl->osPrivate != NULL) {
176 priv = (struct FullNetDevicePriv *)impl->osPrivate;
177 DestroyNetDevice(priv->dev);
178 impl->osPrivate = NULL;
179 }
180 HDF_LOGI("net device linux deinit success!");
181
182 return HDF_SUCCESS;
183 }
184
NetDevAdd(struct NetDeviceImpl * impl)185 static int32_t NetDevAdd(struct NetDeviceImpl *impl)
186 {
187 struct net_device *dev = NULL;
188 int ret;
189
190 if ((dev = GetDevFromDevImpl(impl)) == NULL) {
191 return HDF_ERR_INVALID_PARAM;
192 }
193 if (impl->netDevice == NULL) {
194 return HDF_ERR_INVALID_PARAM;
195 }
196
197 if (memcpy_s(dev->dev_addr, ETH_ALEN, impl->netDevice->macAddr,
198 MAC_ADDR_SIZE) != EOK) {
199 HDF_LOGE("%s : memcpy fail!", __func__);
200 return HDF_ERR_INVALID_PARAM;
201 }
202 dev->needed_headroom = impl->netDevice->neededHeadRoom;
203 dev->needed_tailroom = impl->netDevice->neededTailRoom;
204
205 if ((ret = register_netdev(dev)) < 0) {
206 HDF_LOGE("%s : register_netdev fail!,ret=%d", __func__, ret);
207 return HDF_FAILURE;
208 }
209
210 HDF_LOGI("%s success!!", __func__);
211 return HDF_SUCCESS;
212 }
213
NetDevDelete(struct NetDeviceImpl * impl)214 static int32_t NetDevDelete(struct NetDeviceImpl *impl)
215 {
216 struct FullNetDevicePriv *priv = NULL;
217 struct net_device *dev = NULL;
218
219 if (impl == NULL || impl->osPrivate == NULL) {
220 HDF_LOGE("%s fail : impl = null or osPrivate = null!", __func__);
221 return HDF_ERR_INVALID_PARAM;
222 }
223 priv = (struct FullNetDevicePriv *)impl->osPrivate;
224
225 dev = priv->dev;
226 if (dev != NULL) {
227 unregister_netdev(dev);
228 }
229 HDF_LOGI("%s success!", __func__);
230 return HDF_SUCCESS;
231 }
232
NetDevSetStatus(struct NetDeviceImpl * impl,NetIfStatus status)233 static int32_t NetDevSetStatus(struct NetDeviceImpl *impl,
234 NetIfStatus status)
235 {
236 struct net_device *dev = GetDevFromDevImpl(impl);
237 int32_t ret;
238
239 if (dev == NULL) {
240 HDF_LOGE("%s fail : net dev null!", __func__);
241 return HDF_ERR_INVALID_PARAM;
242 }
243
244 rtnl_lock();
245 if (status == NETIF_DOWN) {
246 dev_close(dev);
247 ret = HDF_SUCCESS;
248 } else if (status == NETIF_UP) {
249 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5,0,0)
250 ret = dev_open(dev, NULL);
251 #else
252 ret = dev_open(dev);
253 #endif
254 } else {
255 HDF_LOGE("%s fail : status error!", __func__);
256 rtnl_unlock();
257 return HDF_ERR_INVALID_PARAM;
258 }
259 rtnl_unlock();
260
261 if (!ret) {
262 return HDF_SUCCESS;
263 }
264 HDF_LOGE("%s fail ret = %d!", __func__, ret);
265 return HDF_FAILURE;
266 }
267
NetDevReceive(struct NetDeviceImpl * impl,NetBuf * buff,ReceiveFlag flag)268 static int32_t NetDevReceive(struct NetDeviceImpl *impl,
269 NetBuf *buff, ReceiveFlag flag)
270 {
271 struct net_device *dev = GetDevFromDevImpl(impl);
272
273 if (dev == NULL) {
274 HDF_LOGE("%s fail : dev = null!", __func__);
275 return HDF_ERR_INVALID_PARAM;
276 }
277
278 if (flag >= MAX_RECEIVE_FLAG || buff == NULL) {
279 HDF_LOGE("%s fail : flag = %d or buff = null!", __func__, flag);
280 return HDF_ERR_INVALID_PARAM;
281 }
282
283 buff->dev = dev;
284 buff->protocol = eth_type_trans(buff, dev);
285 if (flag & IN_INTERRUPT) {
286 netif_rx(buff);
287 } else {
288 netif_rx_ni(buff);
289 }
290 return HDF_SUCCESS;
291 }
292
NetDevChangeMacAddr(struct NetDeviceImpl * impl)293 int32_t NetDevChangeMacAddr(struct NetDeviceImpl *impl)
294 {
295 struct net_device *dev = NULL;
296
297 if ((dev = GetDevFromDevImpl(impl)) == NULL) {
298 return HDF_ERR_INVALID_PARAM;
299 }
300 if (impl->netDevice == NULL) {
301 return HDF_ERR_INVALID_PARAM;
302 }
303
304 if (memcpy_s(dev->dev_addr, ETH_ALEN, impl->netDevice->macAddr, MAC_ADDR_SIZE) != EOK) {
305 HDF_LOGE("%s : memcpy fail!", __func__);
306 return HDF_ERR_INVALID_PARAM;
307 }
308 return HDF_SUCCESS;
309 }
310
311 static struct NetDeviceImplOp g_ndImplOps = {
312 .init = NetDevInit,
313 .deInit = NetDevDeInit,
314 .add = NetDevAdd,
315 .delete = NetDevDelete,
316 .setStatus = NetDevSetStatus,
317 .receive = NetDevReceive,
318 .changeMacAddr = NetDevChangeMacAddr,
319 };
320
RegisterNetDeviceImpl(struct NetDeviceImpl * ndImpl)321 int32_t RegisterNetDeviceImpl(struct NetDeviceImpl *ndImpl)
322 {
323 if (ndImpl == NULL) {
324 HDF_LOGE("%s fail : impl = null!", __func__);
325 return HDF_ERR_INVALID_PARAM;
326 }
327 ndImpl->interFace = &g_ndImplOps;
328 HDF_LOGI("register full netdevice impl success.");
329 return HDF_SUCCESS;
330 }
331
UnRegisterNetDeviceImpl(struct NetDeviceImpl * ndImpl)332 int32_t UnRegisterNetDeviceImpl(struct NetDeviceImpl *ndImpl)
333 {
334 if (ndImpl == NULL) {
335 HDF_LOGI("%s already unregister!", __func__);
336 return HDF_SUCCESS;
337 }
338 ndImpl->interFace = NULL;
339 HDF_LOGI("%s success.", __func__);
340 return HDF_SUCCESS;
341 }
342