2
2
3
3
#include "netlink.h"
4
4
#include "common.h"
5
+ #include <linux/phy.h>
5
6
6
7
struct linkstate_req_info {
7
8
struct ethnl_req_info base ;
@@ -10,6 +11,8 @@ struct linkstate_req_info {
10
11
struct linkstate_reply_data {
11
12
struct ethnl_reply_data base ;
12
13
int link ;
14
+ int sqi ;
15
+ int sqi_max ;
13
16
};
14
17
15
18
#define LINKSTATE_REPDATA (__reply_base ) \
@@ -20,8 +23,46 @@ linkstate_get_policy[ETHTOOL_A_LINKSTATE_MAX + 1] = {
20
23
[ETHTOOL_A_LINKSTATE_UNSPEC ] = { .type = NLA_REJECT },
21
24
[ETHTOOL_A_LINKSTATE_HEADER ] = { .type = NLA_NESTED },
22
25
[ETHTOOL_A_LINKSTATE_LINK ] = { .type = NLA_REJECT },
26
+ [ETHTOOL_A_LINKSTATE_SQI ] = { .type = NLA_REJECT },
27
+ [ETHTOOL_A_LINKSTATE_SQI_MAX ] = { .type = NLA_REJECT },
23
28
};
24
29
30
+ static int linkstate_get_sqi (struct net_device * dev )
31
+ {
32
+ struct phy_device * phydev = dev -> phydev ;
33
+ int ret ;
34
+
35
+ if (!phydev )
36
+ return - EOPNOTSUPP ;
37
+
38
+ mutex_lock (& phydev -> lock );
39
+ if (!phydev -> drv || !phydev -> drv -> get_sqi )
40
+ ret = - EOPNOTSUPP ;
41
+ else
42
+ ret = phydev -> drv -> get_sqi (phydev );
43
+ mutex_unlock (& phydev -> lock );
44
+
45
+ return ret ;
46
+ }
47
+
48
+ static int linkstate_get_sqi_max (struct net_device * dev )
49
+ {
50
+ struct phy_device * phydev = dev -> phydev ;
51
+ int ret ;
52
+
53
+ if (!phydev )
54
+ return - EOPNOTSUPP ;
55
+
56
+ mutex_lock (& phydev -> lock );
57
+ if (!phydev -> drv || !phydev -> drv -> get_sqi_max )
58
+ ret = - EOPNOTSUPP ;
59
+ else
60
+ ret = phydev -> drv -> get_sqi_max (phydev );
61
+ mutex_unlock (& phydev -> lock );
62
+
63
+ return ret ;
64
+ }
65
+
25
66
static int linkstate_prepare_data (const struct ethnl_req_info * req_base ,
26
67
struct ethnl_reply_data * reply_base ,
27
68
struct genl_info * info )
@@ -34,6 +75,19 @@ static int linkstate_prepare_data(const struct ethnl_req_info *req_base,
34
75
if (ret < 0 )
35
76
return ret ;
36
77
data -> link = __ethtool_get_link (dev );
78
+
79
+ ret = linkstate_get_sqi (dev );
80
+ if (ret < 0 && ret != - EOPNOTSUPP )
81
+ return ret ;
82
+
83
+ data -> sqi = ret ;
84
+
85
+ ret = linkstate_get_sqi_max (dev );
86
+ if (ret < 0 && ret != - EOPNOTSUPP )
87
+ return ret ;
88
+
89
+ data -> sqi_max = ret ;
90
+
37
91
ethnl_ops_complete (dev );
38
92
39
93
return 0 ;
@@ -42,8 +96,19 @@ static int linkstate_prepare_data(const struct ethnl_req_info *req_base,
42
96
static int linkstate_reply_size (const struct ethnl_req_info * req_base ,
43
97
const struct ethnl_reply_data * reply_base )
44
98
{
45
- return nla_total_size (sizeof (u8 )) /* LINKSTATE_LINK */
99
+ struct linkstate_reply_data * data = LINKSTATE_REPDATA (reply_base );
100
+ int len ;
101
+
102
+ len = nla_total_size (sizeof (u8 )) /* LINKSTATE_LINK */
46
103
+ 0 ;
104
+
105
+ if (data -> sqi != - EOPNOTSUPP )
106
+ len += nla_total_size (sizeof (u32 ));
107
+
108
+ if (data -> sqi_max != - EOPNOTSUPP )
109
+ len += nla_total_size (sizeof (u32 ));
110
+
111
+ return len ;
47
112
}
48
113
49
114
static int linkstate_fill_reply (struct sk_buff * skb ,
@@ -56,6 +121,14 @@ static int linkstate_fill_reply(struct sk_buff *skb,
56
121
nla_put_u8 (skb , ETHTOOL_A_LINKSTATE_LINK , !!data -> link ))
57
122
return - EMSGSIZE ;
58
123
124
+ if (data -> sqi != - EOPNOTSUPP &&
125
+ nla_put_u32 (skb , ETHTOOL_A_LINKSTATE_SQI , data -> sqi ))
126
+ return - EMSGSIZE ;
127
+
128
+ if (data -> sqi_max != - EOPNOTSUPP &&
129
+ nla_put_u32 (skb , ETHTOOL_A_LINKSTATE_SQI_MAX , data -> sqi_max ))
130
+ return - EMSGSIZE ;
131
+
59
132
return 0 ;
60
133
}
61
134
0 commit comments