@@ -63,6 +63,29 @@ static const struct i40evf_stats i40evf_gstrings_stats[] = {
6363#define I40EVF_STATS_LEN (_dev ) \
6464 (I40EVF_GLOBAL_STATS_LEN + I40EVF_QUEUE_STATS_LEN(_dev))
6565
66+ /* For now we have one and only one private flag and it is only defined
67+ * when we have support for the SKIP_CPU_SYNC DMA attribute. Instead
68+ * of leaving all this code sitting around empty we will strip it unless
69+ * our one private flag is actually available.
70+ */
71+ struct i40evf_priv_flags {
72+ char flag_string [ETH_GSTRING_LEN ];
73+ u32 flag ;
74+ bool read_only ;
75+ };
76+
77+ #define I40EVF_PRIV_FLAG (_name , _flag , _read_only ) { \
78+ .flag_string = _name, \
79+ .flag = _flag, \
80+ .read_only = _read_only, \
81+ }
82+
83+ static const struct i40evf_priv_flags i40evf_gstrings_priv_flags [] = {
84+ I40EVF_PRIV_FLAG ("legacy-rx" , I40EVF_FLAG_LEGACY_RX , 0 ),
85+ };
86+
87+ #define I40EVF_PRIV_FLAGS_STR_LEN ARRAY_SIZE(i40evf_gstrings_priv_flags)
88+
6689/**
6790 * i40evf_get_link_ksettings - Get Link Speed and Duplex settings
6891 * @netdev: network interface device structure
@@ -124,6 +147,8 @@ static int i40evf_get_sset_count(struct net_device *netdev, int sset)
124147{
125148 if (sset == ETH_SS_STATS )
126149 return I40EVF_STATS_LEN (netdev );
150+ else if (sset == ETH_SS_PRIV_FLAGS )
151+ return I40EVF_PRIV_FLAGS_STR_LEN ;
127152 else
128153 return - EINVAL ;
129154}
@@ -189,7 +214,83 @@ static void i40evf_get_strings(struct net_device *netdev, u32 sset, u8 *data)
189214 snprintf (p , ETH_GSTRING_LEN , "rx-%u.bytes" , i );
190215 p += ETH_GSTRING_LEN ;
191216 }
217+ } else if (sset == ETH_SS_PRIV_FLAGS ) {
218+ for (i = 0 ; i < I40EVF_PRIV_FLAGS_STR_LEN ; i ++ ) {
219+ snprintf (p , ETH_GSTRING_LEN , "%s" ,
220+ i40evf_gstrings_priv_flags [i ].flag_string );
221+ p += ETH_GSTRING_LEN ;
222+ }
223+ }
224+ }
225+
226+ /**
227+ * i40evf_get_priv_flags - report device private flags
228+ * @dev: network interface device structure
229+ *
230+ * The get string set count and the string set should be matched for each
231+ * flag returned. Add new strings for each flag to the i40e_gstrings_priv_flags
232+ * array.
233+ *
234+ * Returns a u32 bitmap of flags.
235+ **/
236+ static u32 i40evf_get_priv_flags (struct net_device * netdev )
237+ {
238+ struct i40evf_adapter * adapter = netdev_priv (netdev );
239+ u32 i , ret_flags = 0 ;
240+
241+ for (i = 0 ; i < I40EVF_PRIV_FLAGS_STR_LEN ; i ++ ) {
242+ const struct i40evf_priv_flags * priv_flags ;
243+
244+ priv_flags = & i40evf_gstrings_priv_flags [i ];
245+
246+ if (priv_flags -> flag & adapter -> flags )
247+ ret_flags |= BIT (i );
248+ }
249+
250+ return ret_flags ;
251+ }
252+
253+ /**
254+ * i40evf_set_priv_flags - set private flags
255+ * @dev: network interface device structure
256+ * @flags: bit flags to be set
257+ **/
258+ static int i40evf_set_priv_flags (struct net_device * netdev , u32 flags )
259+ {
260+ struct i40evf_adapter * adapter = netdev_priv (netdev );
261+ u64 changed_flags ;
262+ u32 i ;
263+
264+ changed_flags = adapter -> flags ;
265+
266+ for (i = 0 ; i < I40EVF_PRIV_FLAGS_STR_LEN ; i ++ ) {
267+ const struct i40evf_priv_flags * priv_flags ;
268+
269+ priv_flags = & i40evf_gstrings_priv_flags [i ];
270+
271+ if (priv_flags -> read_only )
272+ continue ;
273+
274+ if (flags & BIT (i ))
275+ adapter -> flags |= priv_flags -> flag ;
276+ else
277+ adapter -> flags &= ~(priv_flags -> flag );
278+ }
279+
280+ /* check for flags that changed */
281+ changed_flags ^= adapter -> flags ;
282+
283+ /* Process any additional changes needed as a result of flag changes. */
284+
285+ /* issue a reset to force legacy-rx change to take effect */
286+ if (changed_flags & I40EVF_FLAG_LEGACY_RX ) {
287+ if (netif_running (netdev )) {
288+ adapter -> flags |= I40EVF_FLAG_RESET_NEEDED ;
289+ schedule_work (& adapter -> reset_task );
290+ }
192291 }
292+
293+ return 0 ;
193294}
194295
195296/**
@@ -238,6 +339,7 @@ static void i40evf_get_drvinfo(struct net_device *netdev,
238339 strlcpy (drvinfo -> version , i40evf_driver_version , 32 );
239340 strlcpy (drvinfo -> fw_version , "N/A" , 4 );
240341 strlcpy (drvinfo -> bus_info , pci_name (adapter -> pdev ), 32 );
342+ drvinfo -> n_priv_flags = I40EVF_PRIV_FLAGS_STR_LEN ;
241343}
242344
243345/**
@@ -649,6 +751,8 @@ static const struct ethtool_ops i40evf_ethtool_ops = {
649751 .get_strings = i40evf_get_strings ,
650752 .get_ethtool_stats = i40evf_get_ethtool_stats ,
651753 .get_sset_count = i40evf_get_sset_count ,
754+ .get_priv_flags = i40evf_get_priv_flags ,
755+ .set_priv_flags = i40evf_set_priv_flags ,
652756 .get_msglevel = i40evf_get_msglevel ,
653757 .set_msglevel = i40evf_set_msglevel ,
654758 .get_coalesce = i40evf_get_coalesce ,
0 commit comments