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