@@ -37,6 +37,8 @@ static int linkstate_get_sqi(struct net_device *dev)
3737 mutex_lock (& phydev -> lock );
3838 if (!phydev -> drv || !phydev -> drv -> get_sqi )
3939 ret = - EOPNOTSUPP ;
40+ else if (!phydev -> link )
41+ ret = - ENETDOWN ;
4042 else
4143 ret = phydev -> drv -> get_sqi (phydev );
4244 mutex_unlock (& phydev -> lock );
@@ -55,13 +57,26 @@ static int linkstate_get_sqi_max(struct net_device *dev)
5557 mutex_lock (& phydev -> lock );
5658 if (!phydev -> drv || !phydev -> drv -> get_sqi_max )
5759 ret = - EOPNOTSUPP ;
60+ else if (!phydev -> link )
61+ ret = - ENETDOWN ;
5862 else
5963 ret = phydev -> drv -> get_sqi_max (phydev );
6064 mutex_unlock (& phydev -> lock );
6165
6266 return ret ;
6367};
6468
69+ static bool linkstate_sqi_critical_error (int sqi )
70+ {
71+ return sqi < 0 && sqi != - EOPNOTSUPP && sqi != - ENETDOWN ;
72+ }
73+
74+ static bool linkstate_sqi_valid (struct linkstate_reply_data * data )
75+ {
76+ return data -> sqi >= 0 && data -> sqi_max >= 0 &&
77+ data -> sqi <= data -> sqi_max ;
78+ }
79+
6580static int linkstate_get_link_ext_state (struct net_device * dev ,
6681 struct linkstate_reply_data * data )
6782{
@@ -93,12 +108,12 @@ static int linkstate_prepare_data(const struct ethnl_req_info *req_base,
93108 data -> link = __ethtool_get_link (dev );
94109
95110 ret = linkstate_get_sqi (dev );
96- if (ret < 0 && ret != - EOPNOTSUPP )
111+ if (linkstate_sqi_critical_error ( ret ) )
97112 goto out ;
98113 data -> sqi = ret ;
99114
100115 ret = linkstate_get_sqi_max (dev );
101- if (ret < 0 && ret != - EOPNOTSUPP )
116+ if (linkstate_sqi_critical_error ( ret ) )
102117 goto out ;
103118 data -> sqi_max = ret ;
104119
@@ -136,11 +151,10 @@ static int linkstate_reply_size(const struct ethnl_req_info *req_base,
136151 len = nla_total_size (sizeof (u8 )) /* LINKSTATE_LINK */
137152 + 0 ;
138153
139- if (data -> sqi != - EOPNOTSUPP )
140- len += nla_total_size (sizeof (u32 ));
141-
142- if (data -> sqi_max != - EOPNOTSUPP )
143- len += nla_total_size (sizeof (u32 ));
154+ if (linkstate_sqi_valid (data )) {
155+ len += nla_total_size (sizeof (u32 )); /* LINKSTATE_SQI */
156+ len += nla_total_size (sizeof (u32 )); /* LINKSTATE_SQI_MAX */
157+ }
144158
145159 if (data -> link_ext_state_provided )
146160 len += nla_total_size (sizeof (u8 )); /* LINKSTATE_EXT_STATE */
@@ -164,13 +178,14 @@ static int linkstate_fill_reply(struct sk_buff *skb,
164178 nla_put_u8 (skb , ETHTOOL_A_LINKSTATE_LINK , !!data -> link ))
165179 return - EMSGSIZE ;
166180
167- if (data -> sqi != - EOPNOTSUPP &&
168- nla_put_u32 (skb , ETHTOOL_A_LINKSTATE_SQI , data -> sqi ))
169- return - EMSGSIZE ;
181+ if (linkstate_sqi_valid ( data )) {
182+ if ( nla_put_u32 (skb , ETHTOOL_A_LINKSTATE_SQI , data -> sqi ))
183+ return - EMSGSIZE ;
170184
171- if (data -> sqi_max != - EOPNOTSUPP &&
172- nla_put_u32 (skb , ETHTOOL_A_LINKSTATE_SQI_MAX , data -> sqi_max ))
173- return - EMSGSIZE ;
185+ if (nla_put_u32 (skb , ETHTOOL_A_LINKSTATE_SQI_MAX ,
186+ data -> sqi_max ))
187+ return - EMSGSIZE ;
188+ }
174189
175190 if (data -> link_ext_state_provided ) {
176191 if (nla_put_u8 (skb , ETHTOOL_A_LINKSTATE_EXT_STATE ,
0 commit comments