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