xref: /linux/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c (revision cf4cebcec619d963fa7496018f03cb0ff00dc257)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) Meta Platforms, Inc. and affiliates. */
3 
4 #include <linux/etherdevice.h>
5 #include <linux/ipv6.h>
6 #include <linux/types.h>
7 
8 #include "fbnic.h"
9 #include "fbnic_netdev.h"
10 #include "fbnic_txrx.h"
11 
12 int __fbnic_open(struct fbnic_net *fbn)
13 {
14 	struct fbnic_dev *fbd = fbn->fbd;
15 	int err;
16 
17 	err = fbnic_alloc_napi_vectors(fbn);
18 	if (err)
19 		return err;
20 
21 	err = fbnic_alloc_resources(fbn);
22 	if (err)
23 		goto free_napi_vectors;
24 
25 	err = netif_set_real_num_tx_queues(fbn->netdev,
26 					   fbn->num_tx_queues);
27 	if (err)
28 		goto free_resources;
29 
30 	err = netif_set_real_num_rx_queues(fbn->netdev,
31 					   fbn->num_rx_queues);
32 	if (err)
33 		goto free_resources;
34 
35 	/* Send ownership message and flush to verify FW has seen it */
36 	err = fbnic_fw_xmit_ownership_msg(fbd, true);
37 	if (err) {
38 		dev_warn(fbd->dev,
39 			 "Error %d sending host ownership message to the firmware\n",
40 			 err);
41 		goto free_resources;
42 	}
43 
44 	err = fbnic_fw_init_heartbeat(fbd, false);
45 	if (err)
46 		goto release_ownership;
47 
48 	err = fbnic_pcs_irq_enable(fbd);
49 	if (err)
50 		goto release_ownership;
51 	/* Pull the BMC config and initialize the RPC */
52 	fbnic_bmc_rpc_init(fbd);
53 	fbnic_rss_reinit(fbd, fbn);
54 
55 	return 0;
56 release_ownership:
57 	fbnic_fw_xmit_ownership_msg(fbn->fbd, false);
58 free_resources:
59 	fbnic_free_resources(fbn);
60 free_napi_vectors:
61 	fbnic_free_napi_vectors(fbn);
62 	return err;
63 }
64 
65 static int fbnic_open(struct net_device *netdev)
66 {
67 	struct fbnic_net *fbn = netdev_priv(netdev);
68 	int err;
69 
70 	err = __fbnic_open(fbn);
71 	if (!err)
72 		fbnic_up(fbn);
73 
74 	return err;
75 }
76 
77 static int fbnic_stop(struct net_device *netdev)
78 {
79 	struct fbnic_net *fbn = netdev_priv(netdev);
80 
81 	fbnic_down(fbn);
82 	fbnic_pcs_irq_disable(fbn->fbd);
83 
84 	fbnic_fw_xmit_ownership_msg(fbn->fbd, false);
85 
86 	fbnic_free_resources(fbn);
87 	fbnic_free_napi_vectors(fbn);
88 
89 	return 0;
90 }
91 
92 static int fbnic_uc_sync(struct net_device *netdev, const unsigned char *addr)
93 {
94 	struct fbnic_net *fbn = netdev_priv(netdev);
95 	struct fbnic_mac_addr *avail_addr;
96 
97 	if (WARN_ON(!is_valid_ether_addr(addr)))
98 		return -EADDRNOTAVAIL;
99 
100 	avail_addr = __fbnic_uc_sync(fbn->fbd, addr);
101 	if (!avail_addr)
102 		return -ENOSPC;
103 
104 	/* Add type flag indicating this address is in use by the host */
105 	set_bit(FBNIC_MAC_ADDR_T_UNICAST, avail_addr->act_tcam);
106 
107 	return 0;
108 }
109 
110 static int fbnic_uc_unsync(struct net_device *netdev, const unsigned char *addr)
111 {
112 	struct fbnic_net *fbn = netdev_priv(netdev);
113 	struct fbnic_dev *fbd = fbn->fbd;
114 	int i, ret;
115 
116 	/* Scan from middle of list to bottom, filling bottom up.
117 	 * Skip the first entry which is reserved for dev_addr and
118 	 * leave the last entry to use for promiscuous filtering.
119 	 */
120 	for (i = fbd->mac_addr_boundary, ret = -ENOENT;
121 	     i < FBNIC_RPC_TCAM_MACDA_HOST_ADDR_IDX && ret; i++) {
122 		struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[i];
123 
124 		if (!ether_addr_equal(mac_addr->value.addr8, addr))
125 			continue;
126 
127 		ret = __fbnic_uc_unsync(mac_addr);
128 	}
129 
130 	return ret;
131 }
132 
133 static int fbnic_mc_sync(struct net_device *netdev, const unsigned char *addr)
134 {
135 	struct fbnic_net *fbn = netdev_priv(netdev);
136 	struct fbnic_mac_addr *avail_addr;
137 
138 	if (WARN_ON(!is_multicast_ether_addr(addr)))
139 		return -EADDRNOTAVAIL;
140 
141 	avail_addr = __fbnic_mc_sync(fbn->fbd, addr);
142 	if (!avail_addr)
143 		return -ENOSPC;
144 
145 	/* Add type flag indicating this address is in use by the host */
146 	set_bit(FBNIC_MAC_ADDR_T_MULTICAST, avail_addr->act_tcam);
147 
148 	return 0;
149 }
150 
151 static int fbnic_mc_unsync(struct net_device *netdev, const unsigned char *addr)
152 {
153 	struct fbnic_net *fbn = netdev_priv(netdev);
154 	struct fbnic_dev *fbd = fbn->fbd;
155 	int i, ret;
156 
157 	/* Scan from middle of list to top, filling top down.
158 	 * Skip over the address reserved for the BMC MAC and
159 	 * exclude index 0 as that belongs to the broadcast address
160 	 */
161 	for (i = fbd->mac_addr_boundary, ret = -ENOENT;
162 	     --i > FBNIC_RPC_TCAM_MACDA_BROADCAST_IDX && ret;) {
163 		struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[i];
164 
165 		if (!ether_addr_equal(mac_addr->value.addr8, addr))
166 			continue;
167 
168 		ret = __fbnic_mc_unsync(mac_addr);
169 	}
170 
171 	return ret;
172 }
173 
174 void __fbnic_set_rx_mode(struct net_device *netdev)
175 {
176 	struct fbnic_net *fbn = netdev_priv(netdev);
177 	bool uc_promisc = false, mc_promisc = false;
178 	struct fbnic_dev *fbd = fbn->fbd;
179 	struct fbnic_mac_addr *mac_addr;
180 	int err;
181 
182 	/* Populate host address from dev_addr */
183 	mac_addr = &fbd->mac_addr[FBNIC_RPC_TCAM_MACDA_HOST_ADDR_IDX];
184 	if (!ether_addr_equal(mac_addr->value.addr8, netdev->dev_addr) ||
185 	    mac_addr->state != FBNIC_TCAM_S_VALID) {
186 		ether_addr_copy(mac_addr->value.addr8, netdev->dev_addr);
187 		mac_addr->state = FBNIC_TCAM_S_UPDATE;
188 		set_bit(FBNIC_MAC_ADDR_T_UNICAST, mac_addr->act_tcam);
189 	}
190 
191 	/* Populate broadcast address if broadcast is enabled */
192 	mac_addr = &fbd->mac_addr[FBNIC_RPC_TCAM_MACDA_BROADCAST_IDX];
193 	if (netdev->flags & IFF_BROADCAST) {
194 		if (!is_broadcast_ether_addr(mac_addr->value.addr8) ||
195 		    mac_addr->state != FBNIC_TCAM_S_VALID) {
196 			eth_broadcast_addr(mac_addr->value.addr8);
197 			mac_addr->state = FBNIC_TCAM_S_ADD;
198 		}
199 		set_bit(FBNIC_MAC_ADDR_T_BROADCAST, mac_addr->act_tcam);
200 	} else if (mac_addr->state == FBNIC_TCAM_S_VALID) {
201 		__fbnic_xc_unsync(mac_addr, FBNIC_MAC_ADDR_T_BROADCAST);
202 	}
203 
204 	/* Synchronize unicast and multicast address lists */
205 	err = __dev_uc_sync(netdev, fbnic_uc_sync, fbnic_uc_unsync);
206 	if (err == -ENOSPC)
207 		uc_promisc = true;
208 	err = __dev_mc_sync(netdev, fbnic_mc_sync, fbnic_mc_unsync);
209 	if (err == -ENOSPC)
210 		mc_promisc = true;
211 
212 	uc_promisc |= !!(netdev->flags & IFF_PROMISC);
213 	mc_promisc |= !!(netdev->flags & IFF_ALLMULTI) || uc_promisc;
214 
215 	/* Populate last TCAM entry with promiscuous entry and 0/1 bit mask */
216 	mac_addr = &fbd->mac_addr[FBNIC_RPC_TCAM_MACDA_PROMISC_IDX];
217 	if (uc_promisc) {
218 		if (!is_zero_ether_addr(mac_addr->value.addr8) ||
219 		    mac_addr->state != FBNIC_TCAM_S_VALID) {
220 			eth_zero_addr(mac_addr->value.addr8);
221 			eth_broadcast_addr(mac_addr->mask.addr8);
222 			clear_bit(FBNIC_MAC_ADDR_T_ALLMULTI,
223 				  mac_addr->act_tcam);
224 			set_bit(FBNIC_MAC_ADDR_T_PROMISC,
225 				mac_addr->act_tcam);
226 			mac_addr->state = FBNIC_TCAM_S_ADD;
227 		}
228 	} else if (mc_promisc &&
229 		   (!fbnic_bmc_present(fbd) || !fbd->fw_cap.all_multi)) {
230 		/* We have to add a special handler for multicast as the
231 		 * BMC may have an all-multi rule already in place. As such
232 		 * adding a rule ourselves won't do any good so we will have
233 		 * to modify the rules for the ALL MULTI below if the BMC
234 		 * already has the rule in place.
235 		 */
236 		if (!is_multicast_ether_addr(mac_addr->value.addr8) ||
237 		    mac_addr->state != FBNIC_TCAM_S_VALID) {
238 			eth_zero_addr(mac_addr->value.addr8);
239 			eth_broadcast_addr(mac_addr->mask.addr8);
240 			mac_addr->value.addr8[0] ^= 1;
241 			mac_addr->mask.addr8[0] ^= 1;
242 			set_bit(FBNIC_MAC_ADDR_T_ALLMULTI,
243 				mac_addr->act_tcam);
244 			clear_bit(FBNIC_MAC_ADDR_T_PROMISC,
245 				  mac_addr->act_tcam);
246 			mac_addr->state = FBNIC_TCAM_S_ADD;
247 		}
248 	} else if (mac_addr->state == FBNIC_TCAM_S_VALID) {
249 		if (test_bit(FBNIC_MAC_ADDR_T_BMC, mac_addr->act_tcam)) {
250 			clear_bit(FBNIC_MAC_ADDR_T_ALLMULTI,
251 				  mac_addr->act_tcam);
252 			clear_bit(FBNIC_MAC_ADDR_T_PROMISC,
253 				  mac_addr->act_tcam);
254 		} else {
255 			mac_addr->state = FBNIC_TCAM_S_DELETE;
256 		}
257 	}
258 
259 	/* Add rules for BMC all multicast if it is enabled */
260 	fbnic_bmc_rpc_all_multi_config(fbd, mc_promisc);
261 
262 	/* Sift out any unshared BMC rules and place them in BMC only section */
263 	fbnic_sift_macda(fbd);
264 
265 	/* Write updates to hardware */
266 	fbnic_write_rules(fbd);
267 	fbnic_write_macda(fbd);
268 }
269 
270 static void fbnic_set_rx_mode(struct net_device *netdev)
271 {
272 	/* No need to update the hardware if we are not running */
273 	if (netif_running(netdev))
274 		__fbnic_set_rx_mode(netdev);
275 }
276 
277 static int fbnic_set_mac(struct net_device *netdev, void *p)
278 {
279 	struct sockaddr *addr = p;
280 
281 	if (!is_valid_ether_addr(addr->sa_data))
282 		return -EADDRNOTAVAIL;
283 
284 	eth_hw_addr_set(netdev, addr->sa_data);
285 
286 	fbnic_set_rx_mode(netdev);
287 
288 	return 0;
289 }
290 
291 void fbnic_clear_rx_mode(struct net_device *netdev)
292 {
293 	struct fbnic_net *fbn = netdev_priv(netdev);
294 	struct fbnic_dev *fbd = fbn->fbd;
295 	int idx;
296 
297 	for (idx = ARRAY_SIZE(fbd->mac_addr); idx--;) {
298 		struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[idx];
299 
300 		if (mac_addr->state != FBNIC_TCAM_S_VALID)
301 			continue;
302 
303 		bitmap_clear(mac_addr->act_tcam,
304 			     FBNIC_MAC_ADDR_T_HOST_START,
305 			     FBNIC_MAC_ADDR_T_HOST_LEN);
306 
307 		if (bitmap_empty(mac_addr->act_tcam,
308 				 FBNIC_RPC_TCAM_ACT_NUM_ENTRIES))
309 			mac_addr->state = FBNIC_TCAM_S_DELETE;
310 	}
311 
312 	/* Write updates to hardware */
313 	fbnic_write_macda(fbd);
314 
315 	__dev_uc_unsync(netdev, NULL);
316 	__dev_mc_unsync(netdev, NULL);
317 }
318 
319 static const struct net_device_ops fbnic_netdev_ops = {
320 	.ndo_open		= fbnic_open,
321 	.ndo_stop		= fbnic_stop,
322 	.ndo_validate_addr	= eth_validate_addr,
323 	.ndo_start_xmit		= fbnic_xmit_frame,
324 	.ndo_features_check	= fbnic_features_check,
325 	.ndo_set_mac_address	= fbnic_set_mac,
326 	.ndo_set_rx_mode	= fbnic_set_rx_mode,
327 };
328 
329 void fbnic_reset_queues(struct fbnic_net *fbn,
330 			unsigned int tx, unsigned int rx)
331 {
332 	struct fbnic_dev *fbd = fbn->fbd;
333 	unsigned int max_napis;
334 
335 	max_napis = fbd->num_irqs - FBNIC_NON_NAPI_VECTORS;
336 
337 	tx = min(tx, max_napis);
338 	fbn->num_tx_queues = tx;
339 
340 	rx = min(rx, max_napis);
341 	fbn->num_rx_queues = rx;
342 
343 	fbn->num_napi = max(tx, rx);
344 }
345 
346 /**
347  * fbnic_netdev_free - Free the netdev associate with fbnic
348  * @fbd: Driver specific structure to free netdev from
349  *
350  * Allocate and initialize the netdev and netdev private structure. Bind
351  * together the hardware, netdev, and pci data structures.
352  **/
353 void fbnic_netdev_free(struct fbnic_dev *fbd)
354 {
355 	struct fbnic_net *fbn = netdev_priv(fbd->netdev);
356 
357 	if (fbn->phylink)
358 		phylink_destroy(fbn->phylink);
359 
360 	free_netdev(fbd->netdev);
361 	fbd->netdev = NULL;
362 }
363 
364 /**
365  * fbnic_netdev_alloc - Allocate a netdev and associate with fbnic
366  * @fbd: Driver specific structure to associate netdev with
367  *
368  * Allocate and initialize the netdev and netdev private structure. Bind
369  * together the hardware, netdev, and pci data structures.
370  *
371  *  Return: 0 on success, negative on failure
372  **/
373 struct net_device *fbnic_netdev_alloc(struct fbnic_dev *fbd)
374 {
375 	struct net_device *netdev;
376 	struct fbnic_net *fbn;
377 	int default_queues;
378 
379 	netdev = alloc_etherdev_mq(sizeof(*fbn), FBNIC_MAX_RXQS);
380 	if (!netdev)
381 		return NULL;
382 
383 	SET_NETDEV_DEV(netdev, fbd->dev);
384 	fbd->netdev = netdev;
385 
386 	netdev->netdev_ops = &fbnic_netdev_ops;
387 
388 	fbn = netdev_priv(netdev);
389 
390 	fbn->netdev = netdev;
391 	fbn->fbd = fbd;
392 	INIT_LIST_HEAD(&fbn->napis);
393 
394 	fbn->txq_size = FBNIC_TXQ_SIZE_DEFAULT;
395 	fbn->hpq_size = FBNIC_HPQ_SIZE_DEFAULT;
396 	fbn->ppq_size = FBNIC_PPQ_SIZE_DEFAULT;
397 	fbn->rcq_size = FBNIC_RCQ_SIZE_DEFAULT;
398 
399 	default_queues = netif_get_num_default_rss_queues();
400 	if (default_queues > fbd->max_num_queues)
401 		default_queues = fbd->max_num_queues;
402 
403 	fbnic_reset_queues(fbn, default_queues, default_queues);
404 
405 	fbnic_reset_indir_tbl(fbn);
406 	fbnic_rss_key_fill(fbn->rss_key);
407 	fbnic_rss_init_en_mask(fbn);
408 
409 	netdev->features |=
410 		NETIF_F_RXHASH |
411 		NETIF_F_SG |
412 		NETIF_F_HW_CSUM |
413 		NETIF_F_RXCSUM;
414 
415 	netdev->hw_features |= netdev->features;
416 	netdev->vlan_features |= netdev->features;
417 	netdev->hw_enc_features |= netdev->features;
418 
419 	netdev->min_mtu = IPV6_MIN_MTU;
420 	netdev->max_mtu = FBNIC_MAX_JUMBO_FRAME_SIZE - ETH_HLEN;
421 
422 	/* TBD: This is workaround for BMC as phylink doesn't have support
423 	 * for leavling the link enabled if a BMC is present.
424 	 */
425 	netdev->ethtool->wol_enabled = true;
426 
427 	fbn->fec = FBNIC_FEC_AUTO | FBNIC_FEC_RS;
428 	fbn->link_mode = FBNIC_LINK_AUTO | FBNIC_LINK_50R2;
429 	netif_carrier_off(netdev);
430 
431 	netif_tx_stop_all_queues(netdev);
432 
433 	if (fbnic_phylink_init(netdev)) {
434 		fbnic_netdev_free(fbd);
435 		return NULL;
436 	}
437 
438 	return netdev;
439 }
440 
441 static int fbnic_dsn_to_mac_addr(u64 dsn, char *addr)
442 {
443 	addr[0] = (dsn >> 56) & 0xFF;
444 	addr[1] = (dsn >> 48) & 0xFF;
445 	addr[2] = (dsn >> 40) & 0xFF;
446 	addr[3] = (dsn >> 16) & 0xFF;
447 	addr[4] = (dsn >> 8) & 0xFF;
448 	addr[5] = dsn & 0xFF;
449 
450 	return is_valid_ether_addr(addr) ? 0 : -EINVAL;
451 }
452 
453 /**
454  * fbnic_netdev_register - Initialize general software structures
455  * @netdev: Netdev containing structure to initialize and register
456  *
457  * Initialize the MAC address for the netdev and register it.
458  *
459  *  Return: 0 on success, negative on failure
460  **/
461 int fbnic_netdev_register(struct net_device *netdev)
462 {
463 	struct fbnic_net *fbn = netdev_priv(netdev);
464 	struct fbnic_dev *fbd = fbn->fbd;
465 	u64 dsn = fbd->dsn;
466 	u8 addr[ETH_ALEN];
467 	int err;
468 
469 	err = fbnic_dsn_to_mac_addr(dsn, addr);
470 	if (!err) {
471 		ether_addr_copy(netdev->perm_addr, addr);
472 		eth_hw_addr_set(netdev, addr);
473 	} else {
474 		/* A randomly assigned MAC address will cause provisioning
475 		 * issues so instead just fail to spawn the netdev and
476 		 * avoid any confusion.
477 		 */
478 		dev_err(fbd->dev, "MAC addr %pM invalid\n", addr);
479 		return err;
480 	}
481 
482 	return register_netdev(netdev);
483 }
484 
485 void fbnic_netdev_unregister(struct net_device *netdev)
486 {
487 	unregister_netdev(netdev);
488 }
489