22/* Copyright (c) 2024, Intel Corporation. */
33#include "ice.h"
44#include "ice_lib.h"
5+ #include "ice_txrx.h"
56#include "ice_fltr.h"
67#include "ice_sf_eth.h"
78#include "devlink/devlink_port.h"
89#include "devlink/devlink.h"
910
11+ static const struct net_device_ops ice_sf_netdev_ops = {
12+ .ndo_open = ice_open ,
13+ .ndo_stop = ice_stop ,
14+ .ndo_start_xmit = ice_start_xmit ,
15+ .ndo_vlan_rx_add_vid = ice_vlan_rx_add_vid ,
16+ .ndo_vlan_rx_kill_vid = ice_vlan_rx_kill_vid ,
17+ .ndo_change_mtu = ice_change_mtu ,
18+ .ndo_get_stats64 = ice_get_stats64 ,
19+ .ndo_tx_timeout = ice_tx_timeout ,
20+ .ndo_bpf = ice_xdp ,
21+ .ndo_xdp_xmit = ice_xdp_xmit ,
22+ .ndo_xsk_wakeup = ice_xsk_wakeup ,
23+ };
24+
25+ /**
26+ * ice_sf_cfg_netdev - Allocate, configure and register a netdev
27+ * @dyn_port: subfunction associated with configured netdev
28+ * @devlink_port: subfunction devlink port to be linked with netdev
29+ *
30+ * Return: 0 on success, negative value on failure
31+ */
32+ static int ice_sf_cfg_netdev (struct ice_dynamic_port * dyn_port ,
33+ struct devlink_port * devlink_port )
34+ {
35+ struct ice_vsi * vsi = dyn_port -> vsi ;
36+ struct ice_netdev_priv * np ;
37+ struct net_device * netdev ;
38+ int err ;
39+
40+ netdev = alloc_etherdev_mqs (sizeof (* np ), vsi -> alloc_txq ,
41+ vsi -> alloc_rxq );
42+ if (!netdev )
43+ return - ENOMEM ;
44+
45+ SET_NETDEV_DEV (netdev , & vsi -> back -> pdev -> dev );
46+ set_bit (ICE_VSI_NETDEV_ALLOCD , vsi -> state );
47+ vsi -> netdev = netdev ;
48+ np = netdev_priv (netdev );
49+ np -> vsi = vsi ;
50+
51+ ice_set_netdev_features (netdev );
52+
53+ netdev -> xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |
54+ NETDEV_XDP_ACT_XSK_ZEROCOPY |
55+ NETDEV_XDP_ACT_RX_SG ;
56+ netdev -> xdp_zc_max_segs = ICE_MAX_BUF_TXD ;
57+
58+ eth_hw_addr_set (netdev , dyn_port -> hw_addr );
59+ ether_addr_copy (netdev -> perm_addr , dyn_port -> hw_addr );
60+ netdev -> netdev_ops = & ice_sf_netdev_ops ;
61+ SET_NETDEV_DEVLINK_PORT (netdev , devlink_port );
62+
63+ err = register_netdev (netdev );
64+ if (err ) {
65+ free_netdev (netdev );
66+ vsi -> netdev = NULL ;
67+ return - ENOMEM ;
68+ }
69+ set_bit (ICE_VSI_NETDEV_REGISTERED , vsi -> state );
70+ netif_carrier_off (netdev );
71+ netif_tx_stop_all_queues (netdev );
72+
73+ return 0 ;
74+ }
75+
76+ static void ice_sf_decfg_netdev (struct ice_vsi * vsi )
77+ {
78+ unregister_netdev (vsi -> netdev );
79+ clear_bit (ICE_VSI_NETDEV_REGISTERED , vsi -> state );
80+ free_netdev (vsi -> netdev );
81+ vsi -> netdev = NULL ;
82+ clear_bit (ICE_VSI_NETDEV_ALLOCD , vsi -> state );
83+ }
84+
1085/**
1186 * ice_sf_dev_probe - subfunction driver probe function
1287 * @adev: pointer to the auxiliary device
@@ -57,10 +132,16 @@ static int ice_sf_dev_probe(struct auxiliary_device *adev,
57132 goto err_vsi_decfg ;
58133 }
59134
135+ err = ice_sf_cfg_netdev (dyn_port , & sf_dev -> priv -> devlink_port );
136+ if (err ) {
137+ dev_err (dev , "Subfunction netdev config failed" );
138+ goto err_devlink_destroy ;
139+ }
140+
60141 err = devl_port_fn_devlink_set (& dyn_port -> devlink_port , devlink );
61142 if (err ) {
62143 dev_err (dev , "Can't link devlink instance to SF devlink port" );
63- goto err_devlink_destroy ;
144+ goto err_netdev_decfg ;
64145 }
65146
66147 ice_napi_add (vsi );
@@ -70,6 +151,8 @@ static int ice_sf_dev_probe(struct auxiliary_device *adev,
70151
71152 return 0 ;
72153
154+ err_netdev_decfg :
155+ ice_sf_decfg_netdev (vsi );
73156err_devlink_destroy :
74157 ice_devlink_destroy_sf_dev_port (sf_dev );
75158err_vsi_decfg :
@@ -98,6 +181,7 @@ static void ice_sf_dev_remove(struct auxiliary_device *adev)
98181
99182 ice_vsi_close (vsi );
100183
184+ ice_sf_decfg_netdev (vsi );
101185 ice_devlink_destroy_sf_dev_port (sf_dev );
102186 devl_unregister (devlink );
103187 devl_unlock (devlink );
0 commit comments