1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2019-2021, Intel Corporation. */
3 
4 #include "ice.h"
5 #include "ice_eswitch.h"
6 #include "ice_devlink.h"
7 #include "ice_virtchnl_pf.h"
8 
9 /**
10  * ice_repr_get_sw_port_id - get port ID associated with representor
11  * @repr: pointer to port representor
12  */
13 static int ice_repr_get_sw_port_id(struct ice_repr *repr)
14 {
15 	return repr->vf->pf->hw.port_info->lport;
16 }
17 
18 /**
19  * ice_repr_get_phys_port_name - get phys port name
20  * @netdev: pointer to port representor netdev
21  * @buf: write here port name
22  * @len: max length of buf
23  */
24 static int
25 ice_repr_get_phys_port_name(struct net_device *netdev, char *buf, size_t len)
26 {
27 	struct ice_netdev_priv *np = netdev_priv(netdev);
28 	struct ice_repr *repr = np->repr;
29 	int res;
30 
31 	/* Devlink port is registered and devlink core is taking care of name formatting. */
32 	if (repr->vf->devlink_port.devlink)
33 		return -EOPNOTSUPP;
34 
35 	res = snprintf(buf, len, "pf%dvfr%d", ice_repr_get_sw_port_id(repr),
36 		       repr->vf->vf_id);
37 	if (res <= 0)
38 		return -EOPNOTSUPP;
39 	return 0;
40 }
41 
42 /**
43  * ice_netdev_to_repr - Get port representor for given netdevice
44  * @netdev: pointer to port representor netdev
45  */
46 struct ice_repr *ice_netdev_to_repr(struct net_device *netdev)
47 {
48 	struct ice_netdev_priv *np = netdev_priv(netdev);
49 
50 	return np->repr;
51 }
52 
53 /**
54  * ice_repr_open - Enable port representor's network interface
55  * @netdev: network interface device structure
56  *
57  * The open entry point is called when a port representor's network
58  * interface is made active by the system (IFF_UP). Corresponding
59  * VF is notified about link status change.
60  *
61  * Returns 0 on success
62  */
63 static int ice_repr_open(struct net_device *netdev)
64 {
65 	struct ice_repr *repr = ice_netdev_to_repr(netdev);
66 	struct ice_vf *vf;
67 
68 	vf = repr->vf;
69 	vf->link_forced = true;
70 	vf->link_up = true;
71 	ice_vc_notify_vf_link_state(vf);
72 
73 	netif_carrier_on(netdev);
74 	netif_tx_start_all_queues(netdev);
75 
76 	return 0;
77 }
78 
79 /**
80  * ice_repr_stop - Disable port representor's network interface
81  * @netdev: network interface device structure
82  *
83  * The stop entry point is called when a port representor's network
84  * interface is de-activated by the system. Corresponding
85  * VF is notified about link status change.
86  *
87  * Returns 0 on success
88  */
89 static int ice_repr_stop(struct net_device *netdev)
90 {
91 	struct ice_repr *repr = ice_netdev_to_repr(netdev);
92 	struct ice_vf *vf;
93 
94 	vf = repr->vf;
95 	vf->link_forced = true;
96 	vf->link_up = false;
97 	ice_vc_notify_vf_link_state(vf);
98 
99 	netif_carrier_off(netdev);
100 	netif_tx_stop_all_queues(netdev);
101 
102 	return 0;
103 }
104 
105 static struct devlink_port *
106 ice_repr_get_devlink_port(struct net_device *netdev)
107 {
108 	struct ice_repr *repr = ice_netdev_to_repr(netdev);
109 
110 	return &repr->vf->devlink_port;
111 }
112 
113 static const struct net_device_ops ice_repr_netdev_ops = {
114 	.ndo_get_phys_port_name = ice_repr_get_phys_port_name,
115 	.ndo_open = ice_repr_open,
116 	.ndo_stop = ice_repr_stop,
117 	.ndo_get_devlink_port = ice_repr_get_devlink_port,
118 };
119 
120 /**
121  * ice_is_port_repr_netdev - Check if a given netdevice is a port representor netdev
122  * @netdev: pointer to netdev
123  */
124 bool ice_is_port_repr_netdev(struct net_device *netdev)
125 {
126 	return netdev && (netdev->netdev_ops == &ice_repr_netdev_ops);
127 }
128 
129 /**
130  * ice_repr_reg_netdev - register port representor netdev
131  * @netdev: pointer to port representor netdev
132  */
133 static int
134 ice_repr_reg_netdev(struct net_device *netdev)
135 {
136 	eth_hw_addr_random(netdev);
137 	netdev->netdev_ops = &ice_repr_netdev_ops;
138 
139 	netif_carrier_off(netdev);
140 	netif_tx_stop_all_queues(netdev);
141 
142 	return register_netdev(netdev);
143 }
144 
145 /**
146  * ice_repr_add - add representor for VF
147  * @vf: pointer to VF structure
148  */
149 static int ice_repr_add(struct ice_vf *vf)
150 {
151 	struct ice_q_vector *q_vector;
152 	struct ice_netdev_priv *np;
153 	struct ice_repr *repr;
154 	int err;
155 
156 	repr = kzalloc(sizeof(*repr), GFP_KERNEL);
157 	if (!repr)
158 		return -ENOMEM;
159 
160 	repr->netdev = alloc_etherdev(sizeof(struct ice_netdev_priv));
161 	if (!repr->netdev) {
162 		err =  -ENOMEM;
163 		goto err_alloc;
164 	}
165 
166 	repr->src_vsi = ice_get_vf_vsi(vf);
167 	repr->vf = vf;
168 	vf->repr = repr;
169 	np = netdev_priv(repr->netdev);
170 	np->repr = repr;
171 
172 	q_vector = kzalloc(sizeof(*q_vector), GFP_KERNEL);
173 	if (!q_vector) {
174 		err = -ENOMEM;
175 		goto err_alloc_q_vector;
176 	}
177 	repr->q_vector = q_vector;
178 
179 	err = ice_devlink_create_vf_port(vf);
180 	if (err)
181 		goto err_devlink;
182 
183 	err = ice_repr_reg_netdev(repr->netdev);
184 	if (err)
185 		goto err_netdev;
186 
187 	devlink_port_type_eth_set(&vf->devlink_port, repr->netdev);
188 
189 	return 0;
190 
191 err_netdev:
192 	ice_devlink_destroy_vf_port(vf);
193 err_devlink:
194 	kfree(repr->q_vector);
195 	vf->repr->q_vector = NULL;
196 err_alloc_q_vector:
197 	free_netdev(repr->netdev);
198 	repr->netdev = NULL;
199 err_alloc:
200 	kfree(repr);
201 	vf->repr = NULL;
202 	return err;
203 }
204 
205 /**
206  * ice_repr_rem - remove representor from VF
207  * @vf: pointer to VF structure
208  */
209 static void ice_repr_rem(struct ice_vf *vf)
210 {
211 	ice_devlink_destroy_vf_port(vf);
212 	kfree(vf->repr->q_vector);
213 	vf->repr->q_vector = NULL;
214 	unregister_netdev(vf->repr->netdev);
215 	free_netdev(vf->repr->netdev);
216 	vf->repr->netdev = NULL;
217 	kfree(vf->repr);
218 	vf->repr = NULL;
219 }
220 
221 /**
222  * ice_repr_add_for_all_vfs - add port representor for all VFs
223  * @pf: pointer to PF structure
224  */
225 int ice_repr_add_for_all_vfs(struct ice_pf *pf)
226 {
227 	int err;
228 	int i;
229 
230 	ice_for_each_vf(pf, i) {
231 		err = ice_repr_add(&pf->vf[i]);
232 		if (err)
233 			goto err;
234 	}
235 	return 0;
236 
237 err:
238 	for (i = i - 1; i >= 0; i--)
239 		ice_repr_rem(&pf->vf[i]);
240 
241 	return err;
242 }
243 
244 /**
245  * ice_repr_rem_from_all_vfs - remove port representor for all VFs
246  * @pf: pointer to PF structure
247  */
248 void ice_repr_rem_from_all_vfs(struct ice_pf *pf)
249 {
250 	int i;
251 
252 	ice_for_each_vf(pf, i)
253 		ice_repr_rem(&pf->vf[i]);
254 }
255