1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 * Description: implementation of ethtool APIs
15 * Author: none
16 * Create: 2020
17 */
18 #include "lwip/opt.h"
19
20 #if LWIP_NETIF_ETHTOOL && LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
21 #include "lwip/ethtool.h"
ethtool_get_link(struct netif * netif,struct ethtool_value * edata)22 static s32_t ethtool_get_link(struct netif *netif, struct ethtool_value *edata)
23 {
24 struct ethtool_ops *ops = (struct ethtool_ops *)(netif->ethtool_ops);
25
26 LWIP_ASSERT("netif != NULL", netif != NULL);
27 LWIP_ASSERT("edata != NULL", edata != NULL);
28
29 edata->cmd = ETHTOOL_GLINK;
30
31 if ((ops == NULL) || (ops->get_link == NULL)) {
32 edata->data = netif_is_up(netif) && netif_is_link_up(netif);
33 return 0;
34 }
35
36 edata->data = netif_is_up(netif) && ops->get_link(netif);
37 return 0;
38 }
39
ethtool_get_settings(struct netif * netif,struct ethtool_cmd * edata)40 static s32_t ethtool_get_settings(struct netif *netif, struct ethtool_cmd *edata)
41 {
42 struct ethtool_ops *ops = (struct ethtool_ops *)(netif->ethtool_ops);
43 LWIP_ASSERT("netif != NULL", netif != NULL);
44 LWIP_ASSERT("edata != NULL", edata != NULL);
45
46 edata->cmd = ETHTOOL_GSET;
47
48 if ((ops == NULL) || (ops->get_settings == NULL)) {
49 return EOPNOTSUPP;
50 }
51
52 return ops->get_settings(netif, edata);
53 }
54
ethtool_set_settings(struct netif * netif,struct ethtool_cmd * edata)55 static s32_t ethtool_set_settings(struct netif *netif, struct ethtool_cmd *edata)
56 {
57 struct ethtool_ops *ops = (struct ethtool_ops *)(netif->ethtool_ops);
58
59 LWIP_ASSERT("netif != NULL", netif != NULL);
60 LWIP_ASSERT("edata != NULL", edata != NULL);
61
62 edata->cmd = ETHTOOL_SSET;
63
64 if ((ops == NULL) || (ops->set_settings == NULL)) {
65 return EOPNOTSUPP;
66 }
67
68 return ops->set_settings(netif, edata);
69 }
70
dev_ethtool(struct netif * netif,struct ifreq * ifr)71 s32_t dev_ethtool(struct netif *netif, struct ifreq *ifr)
72 {
73 u32_t ethcmd;
74 s32_t retval;
75 struct ethtool_ops *ops = (struct ethtool_ops *)(netif->ethtool_ops);
76
77 LWIP_ASSERT("netif != NULL", netif != NULL);
78 LWIP_ASSERT("ifr != NULL", ifr != NULL);
79
80 if (ops && ops->begin) {
81 if (ops->begin(netif) < 0) {
82 return EINVAL;
83 }
84 }
85 if (ifr->ifr_data == NULL) {
86 return EINVAL;
87 }
88
89 ethcmd = *(u32_t *)ifr->ifr_data;
90
91 switch (ethcmd) {
92 case ETHTOOL_GLINK:
93 retval = ethtool_get_link(netif, (struct ethtool_value *)ifr->ifr_data);
94 break;
95 case ETHTOOL_GSET:
96 retval = ethtool_get_settings(netif, (struct ethtool_cmd *)ifr->ifr_data);
97 break;
98 case ETHTOOL_SSET:
99 retval = ethtool_set_settings(netif, (struct ethtool_cmd *)ifr->ifr_data);
100 break;
101 default:
102 retval = EOPNOTSUPP;
103 break;
104 }
105
106 if (ops && ops->complete) {
107 ops->complete(netif);
108 }
109 return retval;
110 }
111 #endif /* LWIP_NETIF_ETHTOOL && LWIP_SOCKET */
112
113