xref: /linux/drivers/net/ethernet/huawei/hinic3/hinic3_main.c (revision 0d2ab5f922e75d10162e7199826e14df9cfae5cc)
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
3 
4 #include <linux/etherdevice.h>
5 #include <linux/netdevice.h>
6 
7 #include "hinic3_common.h"
8 #include "hinic3_hw_comm.h"
9 #include "hinic3_hwdev.h"
10 #include "hinic3_hwif.h"
11 #include "hinic3_lld.h"
12 #include "hinic3_nic_cfg.h"
13 #include "hinic3_nic_dev.h"
14 #include "hinic3_nic_io.h"
15 #include "hinic3_rx.h"
16 #include "hinic3_tx.h"
17 
18 #define HINIC3_NIC_DRV_DESC  "Intelligent Network Interface Card Driver"
19 
20 #define HINIC3_RX_BUF_LEN          2048
21 #define HINIC3_LRO_REPLENISH_THLD  256
22 #define HINIC3_NIC_DEV_WQ_NAME     "hinic3_nic_dev_wq"
23 
24 #define HINIC3_SQ_DEPTH            1024
25 #define HINIC3_RQ_DEPTH            1024
26 
27 #define HINIC3_DEFAULT_TXRX_MSIX_PENDING_LIMIT      2
28 #define HINIC3_DEFAULT_TXRX_MSIX_COALESC_TIMER_CFG  25
29 #define HINIC3_DEFAULT_TXRX_MSIX_RESEND_TIMER_CFG   7
30 
31 static void init_intr_coal_param(struct net_device *netdev)
32 {
33 	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
34 	struct hinic3_intr_coal_info *info;
35 	u16 i;
36 
37 	for (i = 0; i < nic_dev->max_qps; i++) {
38 		info = &nic_dev->intr_coalesce[i];
39 		info->pending_limit = HINIC3_DEFAULT_TXRX_MSIX_PENDING_LIMIT;
40 		info->coalesce_timer_cfg = HINIC3_DEFAULT_TXRX_MSIX_COALESC_TIMER_CFG;
41 		info->resend_timer_cfg = HINIC3_DEFAULT_TXRX_MSIX_RESEND_TIMER_CFG;
42 	}
43 }
44 
45 static int hinic3_init_intr_coalesce(struct net_device *netdev)
46 {
47 	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
48 
49 	nic_dev->intr_coalesce = kcalloc(nic_dev->max_qps,
50 					 sizeof(*nic_dev->intr_coalesce),
51 					 GFP_KERNEL);
52 
53 	if (!nic_dev->intr_coalesce)
54 		return -ENOMEM;
55 
56 	init_intr_coal_param(netdev);
57 
58 	return 0;
59 }
60 
61 static void hinic3_free_intr_coalesce(struct net_device *netdev)
62 {
63 	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
64 
65 	kfree(nic_dev->intr_coalesce);
66 }
67 
68 static int hinic3_alloc_txrxqs(struct net_device *netdev)
69 {
70 	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
71 	struct hinic3_hwdev *hwdev = nic_dev->hwdev;
72 	int err;
73 
74 	err = hinic3_alloc_txqs(netdev);
75 	if (err) {
76 		dev_err(hwdev->dev, "Failed to alloc txqs\n");
77 		return err;
78 	}
79 
80 	err = hinic3_alloc_rxqs(netdev);
81 	if (err) {
82 		dev_err(hwdev->dev, "Failed to alloc rxqs\n");
83 		goto err_free_txqs;
84 	}
85 
86 	err = hinic3_init_intr_coalesce(netdev);
87 	if (err) {
88 		dev_err(hwdev->dev, "Failed to init_intr_coalesce\n");
89 		goto err_free_rxqs;
90 	}
91 
92 	return 0;
93 
94 err_free_rxqs:
95 	hinic3_free_rxqs(netdev);
96 
97 err_free_txqs:
98 	hinic3_free_txqs(netdev);
99 
100 	return err;
101 }
102 
103 static void hinic3_free_txrxqs(struct net_device *netdev)
104 {
105 	hinic3_free_intr_coalesce(netdev);
106 	hinic3_free_rxqs(netdev);
107 	hinic3_free_txqs(netdev);
108 }
109 
110 static int hinic3_init_nic_dev(struct net_device *netdev,
111 			       struct hinic3_hwdev *hwdev)
112 {
113 	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
114 	struct pci_dev *pdev = hwdev->pdev;
115 
116 	nic_dev->netdev = netdev;
117 	SET_NETDEV_DEV(netdev, &pdev->dev);
118 	nic_dev->hwdev = hwdev;
119 	nic_dev->pdev = pdev;
120 
121 	nic_dev->rx_buf_len = HINIC3_RX_BUF_LEN;
122 	nic_dev->lro_replenish_thld = HINIC3_LRO_REPLENISH_THLD;
123 	nic_dev->nic_svc_cap = hwdev->cfg_mgmt->cap.nic_svc_cap;
124 
125 	return 0;
126 }
127 
128 static int hinic3_sw_init(struct net_device *netdev)
129 {
130 	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
131 	struct hinic3_hwdev *hwdev = nic_dev->hwdev;
132 	int err;
133 
134 	nic_dev->q_params.sq_depth = HINIC3_SQ_DEPTH;
135 	nic_dev->q_params.rq_depth = HINIC3_RQ_DEPTH;
136 
137 	/* VF driver always uses random MAC address. During VM migration to a
138 	 * new device, the new device should learn the VMs old MAC rather than
139 	 * provide its own MAC. The product design assumes that every VF is
140 	 * suspectable to migration so the device avoids offering MAC address
141 	 * to VFs.
142 	 */
143 	eth_hw_addr_random(netdev);
144 	err = hinic3_set_mac(hwdev, netdev->dev_addr, 0,
145 			     hinic3_global_func_id(hwdev));
146 	if (err) {
147 		dev_err(hwdev->dev, "Failed to set default MAC\n");
148 		return err;
149 	}
150 
151 	err = hinic3_alloc_txrxqs(netdev);
152 	if (err) {
153 		dev_err(hwdev->dev, "Failed to alloc qps\n");
154 		goto err_del_mac;
155 	}
156 
157 	return 0;
158 
159 err_del_mac:
160 	hinic3_del_mac(hwdev, netdev->dev_addr, 0,
161 		       hinic3_global_func_id(hwdev));
162 
163 	return err;
164 }
165 
166 static void hinic3_sw_uninit(struct net_device *netdev)
167 {
168 	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
169 
170 	hinic3_free_txrxqs(netdev);
171 	hinic3_del_mac(nic_dev->hwdev, netdev->dev_addr, 0,
172 		       hinic3_global_func_id(nic_dev->hwdev));
173 }
174 
175 static void hinic3_assign_netdev_ops(struct net_device *netdev)
176 {
177 	hinic3_set_netdev_ops(netdev);
178 }
179 
180 static void netdev_feature_init(struct net_device *netdev)
181 {
182 	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
183 	netdev_features_t cso_fts = 0;
184 	netdev_features_t tso_fts = 0;
185 	netdev_features_t dft_fts;
186 
187 	dft_fts = NETIF_F_SG | NETIF_F_HIGHDMA;
188 	if (hinic3_test_support(nic_dev, HINIC3_NIC_F_CSUM))
189 		cso_fts |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM;
190 	if (hinic3_test_support(nic_dev, HINIC3_NIC_F_SCTP_CRC))
191 		cso_fts |= NETIF_F_SCTP_CRC;
192 	if (hinic3_test_support(nic_dev, HINIC3_NIC_F_TSO))
193 		tso_fts |= NETIF_F_TSO | NETIF_F_TSO6;
194 
195 	netdev->features |= dft_fts | cso_fts | tso_fts;
196 }
197 
198 static int hinic3_set_default_hw_feature(struct net_device *netdev)
199 {
200 	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
201 	struct hinic3_hwdev *hwdev = nic_dev->hwdev;
202 	int err;
203 
204 	err = hinic3_set_nic_feature_to_hw(nic_dev);
205 	if (err) {
206 		dev_err(hwdev->dev, "Failed to set nic features\n");
207 		return err;
208 	}
209 
210 	return 0;
211 }
212 
213 static void hinic3_link_status_change(struct net_device *netdev,
214 				      bool link_status_up)
215 {
216 	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
217 
218 	if (link_status_up) {
219 		if (netif_carrier_ok(netdev))
220 			return;
221 
222 		nic_dev->link_status_up = true;
223 		netif_carrier_on(netdev);
224 		netdev_dbg(netdev, "Link is up\n");
225 	} else {
226 		if (!netif_carrier_ok(netdev))
227 			return;
228 
229 		nic_dev->link_status_up = false;
230 		netif_carrier_off(netdev);
231 		netdev_dbg(netdev, "Link is down\n");
232 	}
233 }
234 
235 static void hinic3_nic_event(struct auxiliary_device *adev,
236 			     struct hinic3_event_info *event)
237 {
238 	struct hinic3_nic_dev *nic_dev = dev_get_drvdata(&adev->dev);
239 	struct net_device *netdev;
240 
241 	netdev = nic_dev->netdev;
242 
243 	switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
244 	case HINIC3_SRV_EVENT_TYPE(HINIC3_EVENT_SRV_NIC,
245 				   HINIC3_NIC_EVENT_LINK_UP):
246 		hinic3_link_status_change(netdev, true);
247 		break;
248 	case HINIC3_SRV_EVENT_TYPE(HINIC3_EVENT_SRV_NIC,
249 				   HINIC3_NIC_EVENT_LINK_DOWN):
250 		hinic3_link_status_change(netdev, false);
251 		break;
252 	default:
253 		break;
254 	}
255 }
256 
257 static int hinic3_nic_probe(struct auxiliary_device *adev,
258 			    const struct auxiliary_device_id *id)
259 {
260 	struct hinic3_hwdev *hwdev = hinic3_adev_get_hwdev(adev);
261 	struct pci_dev *pdev = hwdev->pdev;
262 	struct hinic3_nic_dev *nic_dev;
263 	struct net_device *netdev;
264 	u16 max_qps, glb_func_id;
265 	int err;
266 
267 	if (!hinic3_support_nic(hwdev)) {
268 		dev_dbg(&adev->dev, "HW doesn't support nic\n");
269 		return 0;
270 	}
271 
272 	hinic3_adev_event_register(adev, hinic3_nic_event);
273 
274 	glb_func_id = hinic3_global_func_id(hwdev);
275 	err = hinic3_func_reset(hwdev, glb_func_id, COMM_FUNC_RESET_BIT_NIC);
276 	if (err) {
277 		dev_err(&adev->dev, "Failed to reset function\n");
278 		goto err_unregister_adev_event;
279 	}
280 
281 	max_qps = hinic3_func_max_qnum(hwdev);
282 	netdev = alloc_etherdev_mq(sizeof(*nic_dev), max_qps);
283 	if (!netdev) {
284 		dev_err(&adev->dev, "Failed to allocate netdev\n");
285 		err = -ENOMEM;
286 		goto err_unregister_adev_event;
287 	}
288 
289 	nic_dev = netdev_priv(netdev);
290 	dev_set_drvdata(&adev->dev, nic_dev);
291 	err = hinic3_init_nic_dev(netdev, hwdev);
292 	if (err)
293 		goto err_free_netdev;
294 
295 	err = hinic3_init_nic_io(nic_dev);
296 	if (err)
297 		goto err_free_netdev;
298 
299 	err = hinic3_sw_init(netdev);
300 	if (err)
301 		goto err_free_nic_io;
302 
303 	hinic3_assign_netdev_ops(netdev);
304 
305 	netdev_feature_init(netdev);
306 	err = hinic3_set_default_hw_feature(netdev);
307 	if (err)
308 		goto err_uninit_sw;
309 
310 	netif_carrier_off(netdev);
311 
312 	err = register_netdev(netdev);
313 	if (err)
314 		goto err_uninit_nic_feature;
315 
316 	return 0;
317 
318 err_uninit_nic_feature:
319 	hinic3_update_nic_feature(nic_dev, 0);
320 	hinic3_set_nic_feature_to_hw(nic_dev);
321 
322 err_uninit_sw:
323 	hinic3_sw_uninit(netdev);
324 
325 err_free_nic_io:
326 	hinic3_free_nic_io(nic_dev);
327 
328 err_free_netdev:
329 	free_netdev(netdev);
330 
331 err_unregister_adev_event:
332 	hinic3_adev_event_unregister(adev);
333 	dev_err(&pdev->dev, "NIC service probe failed\n");
334 
335 	return err;
336 }
337 
338 static void hinic3_nic_remove(struct auxiliary_device *adev)
339 {
340 	struct hinic3_nic_dev *nic_dev = dev_get_drvdata(&adev->dev);
341 	struct net_device *netdev;
342 
343 	if (!hinic3_support_nic(nic_dev->hwdev))
344 		return;
345 
346 	netdev = nic_dev->netdev;
347 	unregister_netdev(netdev);
348 
349 	hinic3_update_nic_feature(nic_dev, 0);
350 	hinic3_set_nic_feature_to_hw(nic_dev);
351 	hinic3_sw_uninit(netdev);
352 
353 	hinic3_free_nic_io(nic_dev);
354 
355 	free_netdev(netdev);
356 }
357 
358 static const struct auxiliary_device_id hinic3_nic_id_table[] = {
359 	{
360 		.name = HINIC3_NIC_DRV_NAME ".nic",
361 	},
362 	{}
363 };
364 
365 static struct auxiliary_driver hinic3_nic_driver = {
366 	.probe    = hinic3_nic_probe,
367 	.remove   = hinic3_nic_remove,
368 	.suspend  = NULL,
369 	.resume   = NULL,
370 	.name     = "nic",
371 	.id_table = hinic3_nic_id_table,
372 };
373 
374 static __init int hinic3_nic_lld_init(void)
375 {
376 	int err;
377 
378 	err = hinic3_lld_init();
379 	if (err)
380 		return err;
381 
382 	err = auxiliary_driver_register(&hinic3_nic_driver);
383 	if (err) {
384 		hinic3_lld_exit();
385 		return err;
386 	}
387 
388 	return 0;
389 }
390 
391 static __exit void hinic3_nic_lld_exit(void)
392 {
393 	auxiliary_driver_unregister(&hinic3_nic_driver);
394 
395 	hinic3_lld_exit();
396 }
397 
398 module_init(hinic3_nic_lld_init);
399 module_exit(hinic3_nic_lld_exit);
400 
401 MODULE_AUTHOR("Huawei Technologies CO., Ltd");
402 MODULE_DESCRIPTION(HINIC3_NIC_DRV_DESC);
403 MODULE_LICENSE("GPL");
404