xref: /linux/drivers/net/ethernet/huawei/hinic3/hinic3_main.c (revision 189f164e573e18d9f8876dbd3ad8fcbe11f93037)
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 #define HINIC3_RX_PENDING_LIMIT_LOW   2
33 #define HINIC3_RX_PENDING_LIMIT_HIGH  8
34 
init_intr_coal_param(struct net_device * netdev)35 static void init_intr_coal_param(struct net_device *netdev)
36 {
37 	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
38 	struct hinic3_intr_coal_info *info;
39 	u16 i;
40 
41 	for (i = 0; i < nic_dev->max_qps; i++) {
42 		info = &nic_dev->intr_coalesce[i];
43 		info->pending_limit = HINIC3_DEFAULT_TXRX_MSIX_PENDING_LIMIT;
44 		info->coalesce_timer_cfg =
45 			HINIC3_DEFAULT_TXRX_MSIX_COALESC_TIMER_CFG;
46 		info->resend_timer_cfg =
47 			HINIC3_DEFAULT_TXRX_MSIX_RESEND_TIMER_CFG;
48 
49 		info->rx_pending_limit_high = HINIC3_RX_PENDING_LIMIT_HIGH;
50 		info->rx_pending_limit_low = HINIC3_RX_PENDING_LIMIT_LOW;
51 	}
52 
53 	nic_dev->adaptive_rx_coal = 1;
54 }
55 
hinic3_init_intr_coalesce(struct net_device * netdev)56 static int hinic3_init_intr_coalesce(struct net_device *netdev)
57 {
58 	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
59 
60 	nic_dev->intr_coalesce = kzalloc_objs(*nic_dev->intr_coalesce,
61 					      nic_dev->max_qps);
62 
63 	if (!nic_dev->intr_coalesce)
64 		return -ENOMEM;
65 
66 	init_intr_coal_param(netdev);
67 
68 	return 0;
69 }
70 
hinic3_free_intr_coalesce(struct net_device * netdev)71 static void hinic3_free_intr_coalesce(struct net_device *netdev)
72 {
73 	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
74 
75 	kfree(nic_dev->intr_coalesce);
76 }
77 
hinic3_alloc_txrxqs(struct net_device * netdev)78 static int hinic3_alloc_txrxqs(struct net_device *netdev)
79 {
80 	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
81 	struct hinic3_hwdev *hwdev = nic_dev->hwdev;
82 	int err;
83 
84 	err = hinic3_alloc_txqs(netdev);
85 	if (err) {
86 		dev_err(hwdev->dev, "Failed to alloc txqs\n");
87 		return err;
88 	}
89 
90 	err = hinic3_alloc_rxqs(netdev);
91 	if (err) {
92 		dev_err(hwdev->dev, "Failed to alloc rxqs\n");
93 		goto err_free_txqs;
94 	}
95 
96 	err = hinic3_init_intr_coalesce(netdev);
97 	if (err) {
98 		dev_err(hwdev->dev, "Failed to init_intr_coalesce\n");
99 		goto err_free_rxqs;
100 	}
101 
102 	return 0;
103 
104 err_free_rxqs:
105 	hinic3_free_rxqs(netdev);
106 err_free_txqs:
107 	hinic3_free_txqs(netdev);
108 
109 	return err;
110 }
111 
hinic3_free_txrxqs(struct net_device * netdev)112 static void hinic3_free_txrxqs(struct net_device *netdev)
113 {
114 	hinic3_free_intr_coalesce(netdev);
115 	hinic3_free_rxqs(netdev);
116 	hinic3_free_txqs(netdev);
117 }
118 
hinic3_periodic_work_handler(struct work_struct * work)119 static void hinic3_periodic_work_handler(struct work_struct *work)
120 {
121 	struct delayed_work *delay = to_delayed_work(work);
122 	struct hinic3_nic_dev *nic_dev;
123 
124 	nic_dev = container_of(delay, struct hinic3_nic_dev, periodic_work);
125 	if (test_and_clear_bit(HINIC3_EVENT_WORK_TX_TIMEOUT,
126 			       &nic_dev->event_flag))
127 		dev_info(nic_dev->hwdev->dev,
128 			 "Fault event report, src: %u, level: %u\n",
129 			 HINIC3_FAULT_SRC_TX_TIMEOUT,
130 			 HINIC3_FAULT_LEVEL_SERIOUS_FLR);
131 
132 	queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
133 }
134 
hinic3_init_nic_dev(struct net_device * netdev,struct hinic3_hwdev * hwdev)135 static int hinic3_init_nic_dev(struct net_device *netdev,
136 			       struct hinic3_hwdev *hwdev)
137 {
138 	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
139 	struct pci_dev *pdev = hwdev->pdev;
140 
141 	nic_dev->netdev = netdev;
142 	SET_NETDEV_DEV(netdev, &pdev->dev);
143 	nic_dev->hwdev = hwdev;
144 	nic_dev->pdev = pdev;
145 
146 	nic_dev->rx_buf_len = HINIC3_RX_BUF_LEN;
147 	nic_dev->lro_replenish_thld = HINIC3_LRO_REPLENISH_THLD;
148 	nic_dev->vlan_bitmap = kzalloc(HINIC3_VLAN_BITMAP_SIZE(nic_dev),
149 				       GFP_KERNEL);
150 	if (!nic_dev->vlan_bitmap)
151 		return -ENOMEM;
152 
153 	nic_dev->nic_svc_cap = hwdev->cfg_mgmt->cap.nic_svc_cap;
154 
155 	nic_dev->workq = create_singlethread_workqueue(HINIC3_NIC_DEV_WQ_NAME);
156 	if (!nic_dev->workq) {
157 		dev_err(hwdev->dev, "Failed to initialize nic workqueue\n");
158 		kfree(nic_dev->vlan_bitmap);
159 		return -ENOMEM;
160 	}
161 
162 	INIT_DELAYED_WORK(&nic_dev->periodic_work,
163 			  hinic3_periodic_work_handler);
164 
165 	INIT_LIST_HEAD(&nic_dev->uc_filter_list);
166 	INIT_LIST_HEAD(&nic_dev->mc_filter_list);
167 	INIT_WORK(&nic_dev->rx_mode_work, hinic3_set_rx_mode_work);
168 
169 	return 0;
170 }
171 
hinic3_sw_init(struct net_device * netdev)172 static int hinic3_sw_init(struct net_device *netdev)
173 {
174 	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
175 	struct hinic3_hwdev *hwdev = nic_dev->hwdev;
176 	u8 mac_addr[ETH_ALEN];
177 	int err;
178 
179 	mutex_init(&nic_dev->port_state_mutex);
180 
181 	nic_dev->q_params.sq_depth = HINIC3_SQ_DEPTH;
182 	nic_dev->q_params.rq_depth = HINIC3_RQ_DEPTH;
183 
184 	hinic3_try_to_enable_rss(netdev);
185 
186 	if (HINIC3_IS_VF(hwdev)) {
187 		/* VF driver always uses random MAC address. During VM migration
188 		 * to a new device, the new device should learn the VMs old MAC
189 		 * rather than provide its own MAC. The product design assumes
190 		 * that every VF is susceptible to migration so the device
191 		 * avoids offering MAC address to VFs.
192 		 */
193 		eth_hw_addr_random(netdev);
194 	} else {
195 		err = hinic3_get_default_mac(hwdev, mac_addr);
196 		if (err) {
197 			dev_err(hwdev->dev, "Failed to get MAC address\n");
198 			goto err_clear_rss_config;
199 		}
200 		eth_hw_addr_set(netdev, mac_addr);
201 	}
202 
203 	err = hinic3_set_mac(hwdev, netdev->dev_addr, 0,
204 			     hinic3_global_func_id(hwdev));
205 	/* Failure to set MAC is not a fatal error for VF since its MAC may have
206 	 * already been set by PF
207 	 */
208 	if (err && err != -EADDRINUSE) {
209 		dev_err(hwdev->dev, "Failed to set default MAC\n");
210 		goto err_clear_rss_config;
211 	}
212 
213 	err = hinic3_alloc_txrxqs(netdev);
214 	if (err) {
215 		dev_err(hwdev->dev, "Failed to alloc qps\n");
216 		goto err_del_mac;
217 	}
218 
219 	return 0;
220 
221 err_del_mac:
222 	hinic3_del_mac(hwdev, netdev->dev_addr, 0,
223 		       hinic3_global_func_id(hwdev));
224 err_clear_rss_config:
225 	hinic3_clear_rss_config(netdev);
226 
227 	return err;
228 }
229 
hinic3_sw_uninit(struct net_device * netdev)230 static void hinic3_sw_uninit(struct net_device *netdev)
231 {
232 	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
233 
234 	hinic3_free_txrxqs(netdev);
235 	hinic3_clean_mac_list_filter(netdev);
236 	hinic3_del_mac(nic_dev->hwdev, netdev->dev_addr, 0,
237 		       hinic3_global_func_id(nic_dev->hwdev));
238 	hinic3_clear_rss_config(netdev);
239 }
240 
hinic3_assign_netdev_ops(struct net_device * netdev)241 static void hinic3_assign_netdev_ops(struct net_device *netdev)
242 {
243 	hinic3_set_netdev_ops(netdev);
244 }
245 
netdev_feature_init(struct net_device * netdev)246 static void netdev_feature_init(struct net_device *netdev)
247 {
248 	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
249 	netdev_features_t hw_features = 0;
250 	netdev_features_t vlan_fts = 0;
251 	netdev_features_t cso_fts = 0;
252 	netdev_features_t tso_fts = 0;
253 	netdev_features_t dft_fts;
254 
255 	dft_fts = NETIF_F_SG | NETIF_F_HIGHDMA;
256 	if (hinic3_test_support(nic_dev, HINIC3_NIC_F_CSUM))
257 		cso_fts |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM;
258 	if (hinic3_test_support(nic_dev, HINIC3_NIC_F_SCTP_CRC))
259 		cso_fts |= NETIF_F_SCTP_CRC;
260 	if (hinic3_test_support(nic_dev, HINIC3_NIC_F_TSO))
261 		tso_fts |= NETIF_F_TSO | NETIF_F_TSO6;
262 
263 	if (hinic3_test_support(nic_dev, HINIC3_NIC_F_RX_VLAN_STRIP |
264 				HINIC3_NIC_F_TX_VLAN_INSERT))
265 		vlan_fts |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX;
266 
267 	if (hinic3_test_support(nic_dev, HINIC3_NIC_F_RX_VLAN_FILTER))
268 		vlan_fts |= NETIF_F_HW_VLAN_CTAG_FILTER;
269 
270 	if (hinic3_test_support(nic_dev, HINIC3_NIC_F_VXLAN_OFFLOAD))
271 		tso_fts |= NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_UDP_TUNNEL_CSUM;
272 
273 	/* LRO is disabled by default, only set hw features */
274 	if (hinic3_test_support(nic_dev, HINIC3_NIC_F_LRO))
275 		hw_features |= NETIF_F_LRO;
276 
277 	netdev->features |= dft_fts | cso_fts | tso_fts | vlan_fts;
278 	netdev->vlan_features |= dft_fts | cso_fts | tso_fts;
279 	hw_features |= netdev->hw_features | netdev->features;
280 	netdev->hw_features = hw_features;
281 	netdev->priv_flags |= IFF_UNICAST_FLT;
282 
283 	netdev->hw_enc_features |= dft_fts;
284 	if (hinic3_test_support(nic_dev, HINIC3_NIC_F_VXLAN_OFFLOAD))
285 		netdev->hw_enc_features |= cso_fts | tso_fts | NETIF_F_TSO_ECN;
286 }
287 
hinic3_set_default_hw_feature(struct net_device * netdev)288 static int hinic3_set_default_hw_feature(struct net_device *netdev)
289 {
290 	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
291 	struct hinic3_hwdev *hwdev = nic_dev->hwdev;
292 	int err;
293 
294 	err = hinic3_set_nic_feature_to_hw(nic_dev);
295 	if (err) {
296 		dev_err(hwdev->dev, "Failed to set nic features\n");
297 		return err;
298 	}
299 
300 	err = hinic3_set_hw_features(netdev);
301 	if (err) {
302 		hinic3_update_nic_feature(nic_dev, 0);
303 		hinic3_set_nic_feature_to_hw(nic_dev);
304 		return err;
305 	}
306 
307 	return 0;
308 }
309 
hinic3_link_status_change(struct net_device * netdev,bool link_status_up)310 static void hinic3_link_status_change(struct net_device *netdev,
311 				      bool link_status_up)
312 {
313 	struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
314 
315 	if (link_status_up) {
316 		if (netif_carrier_ok(netdev))
317 			return;
318 
319 		nic_dev->link_status_up = true;
320 		netif_carrier_on(netdev);
321 		netdev_dbg(netdev, "Link is up\n");
322 	} else {
323 		if (!netif_carrier_ok(netdev))
324 			return;
325 
326 		nic_dev->link_status_up = false;
327 		netif_carrier_off(netdev);
328 		netdev_dbg(netdev, "Link is down\n");
329 	}
330 }
331 
hinic3_port_module_event_handler(struct net_device * netdev,struct hinic3_event_info * event)332 static void hinic3_port_module_event_handler(struct net_device *netdev,
333 					     struct hinic3_event_info *event)
334 {
335 	const char *g_hinic3_module_link_err[LINK_ERR_NUM] = {
336 		"Unrecognized module"
337 	};
338 	struct hinic3_port_module_event *module_event;
339 	enum port_module_event_type type;
340 	enum link_err_type err_type;
341 
342 	module_event = (struct hinic3_port_module_event *)event->event_data;
343 	type = module_event->type;
344 	err_type = module_event->err_type;
345 
346 	switch (type) {
347 	case HINIC3_PORT_MODULE_CABLE_PLUGGED:
348 	case HINIC3_PORT_MODULE_CABLE_UNPLUGGED:
349 		netdev_info(netdev, "Port module event: Cable %s\n",
350 			    type == HINIC3_PORT_MODULE_CABLE_PLUGGED ?
351 			    "plugged" : "unplugged");
352 		break;
353 	case HINIC3_PORT_MODULE_LINK_ERR:
354 		if (err_type >= LINK_ERR_NUM) {
355 			netdev_info(netdev, "Link failed, Unknown error type: 0x%x\n",
356 				    err_type);
357 		} else {
358 			netdev_info(netdev,
359 				    "Link failed, error type: 0x%x: %s\n",
360 				    err_type,
361 				    g_hinic3_module_link_err[err_type]);
362 		}
363 		break;
364 	default:
365 		netdev_err(netdev, "Unknown port module type %d\n", type);
366 		break;
367 	}
368 }
369 
hinic3_nic_event(struct auxiliary_device * adev,struct hinic3_event_info * event)370 static void hinic3_nic_event(struct auxiliary_device *adev,
371 			     struct hinic3_event_info *event)
372 {
373 	struct hinic3_nic_dev *nic_dev = dev_get_drvdata(&adev->dev);
374 	struct net_device *netdev;
375 
376 	netdev = nic_dev->netdev;
377 
378 	switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) {
379 	case HINIC3_SRV_EVENT_TYPE(HINIC3_EVENT_SRV_NIC,
380 				   HINIC3_NIC_EVENT_LINK_UP):
381 		hinic3_link_status_change(netdev, true);
382 		break;
383 	case HINIC3_SRV_EVENT_TYPE(HINIC3_EVENT_SRV_NIC,
384 				   HINIC3_NIC_EVENT_PORT_MODULE_EVENT):
385 		hinic3_port_module_event_handler(netdev, event);
386 		break;
387 	case HINIC3_SRV_EVENT_TYPE(HINIC3_EVENT_SRV_NIC,
388 				   HINIC3_NIC_EVENT_LINK_DOWN):
389 	case HINIC3_SRV_EVENT_TYPE(HINIC3_EVENT_SRV_COMM,
390 				   HINIC3_COMM_EVENT_FAULT):
391 	case HINIC3_SRV_EVENT_TYPE(HINIC3_EVENT_SRV_COMM,
392 				   HINIC3_COMM_EVENT_PCIE_LINK_DOWN):
393 	case HINIC3_SRV_EVENT_TYPE(HINIC3_EVENT_SRV_COMM,
394 				   HINIC3_COMM_EVENT_HEART_LOST):
395 	case HINIC3_SRV_EVENT_TYPE(HINIC3_EVENT_SRV_COMM,
396 				   HINIC3_COMM_EVENT_MGMT_WATCHDOG):
397 		hinic3_link_status_change(netdev, false);
398 		break;
399 	default:
400 		break;
401 	}
402 }
403 
hinic3_free_nic_dev(struct hinic3_nic_dev * nic_dev)404 static void hinic3_free_nic_dev(struct hinic3_nic_dev *nic_dev)
405 {
406 	destroy_workqueue(nic_dev->workq);
407 	kfree(nic_dev->vlan_bitmap);
408 }
409 
hinic3_nic_probe(struct auxiliary_device * adev,const struct auxiliary_device_id * id)410 static int hinic3_nic_probe(struct auxiliary_device *adev,
411 			    const struct auxiliary_device_id *id)
412 {
413 	struct hinic3_hwdev *hwdev = hinic3_adev_get_hwdev(adev);
414 	struct pci_dev *pdev = hwdev->pdev;
415 	struct hinic3_nic_dev *nic_dev;
416 	struct net_device *netdev;
417 	u16 max_qps, glb_func_id;
418 	int err;
419 
420 	if (!hinic3_support_nic(hwdev)) {
421 		dev_dbg(&adev->dev, "HW doesn't support nic\n");
422 		return 0;
423 	}
424 
425 	hinic3_adev_event_register(adev, hinic3_nic_event);
426 
427 	glb_func_id = hinic3_global_func_id(hwdev);
428 	err = hinic3_func_reset(hwdev, glb_func_id, COMM_FUNC_RESET_BIT_NIC);
429 	if (err) {
430 		dev_err(&adev->dev, "Failed to reset function\n");
431 		goto err_unregister_adev_event;
432 	}
433 
434 	max_qps = hinic3_func_max_qnum(hwdev);
435 	netdev = alloc_etherdev_mq(sizeof(*nic_dev), max_qps);
436 	if (!netdev) {
437 		dev_err(&adev->dev, "Failed to allocate netdev\n");
438 		err = -ENOMEM;
439 		goto err_unregister_adev_event;
440 	}
441 
442 	nic_dev = netdev_priv(netdev);
443 	dev_set_drvdata(&adev->dev, nic_dev);
444 	err = hinic3_init_nic_dev(netdev, hwdev);
445 	if (err)
446 		goto err_free_netdev;
447 
448 	err = hinic3_init_nic_io(nic_dev);
449 	if (err)
450 		goto err_free_nic_dev;
451 
452 	err = hinic3_sw_init(netdev);
453 	if (err)
454 		goto err_free_nic_io;
455 
456 	hinic3_assign_netdev_ops(netdev);
457 
458 	netdev_feature_init(netdev);
459 	err = hinic3_set_default_hw_feature(netdev);
460 	if (err)
461 		goto err_uninit_sw;
462 
463 	queue_delayed_work(nic_dev->workq, &nic_dev->periodic_work, HZ);
464 	netif_carrier_off(netdev);
465 
466 	err = register_netdev(netdev);
467 	if (err)
468 		goto err_uninit_nic_feature;
469 
470 	return 0;
471 
472 err_uninit_nic_feature:
473 	disable_delayed_work_sync(&nic_dev->periodic_work);
474 	hinic3_update_nic_feature(nic_dev, 0);
475 	hinic3_set_nic_feature_to_hw(nic_dev);
476 err_uninit_sw:
477 	hinic3_sw_uninit(netdev);
478 err_free_nic_io:
479 	hinic3_free_nic_io(nic_dev);
480 err_free_nic_dev:
481 	hinic3_free_nic_dev(nic_dev);
482 err_free_netdev:
483 	free_netdev(netdev);
484 err_unregister_adev_event:
485 	hinic3_adev_event_unregister(adev);
486 	dev_err(&pdev->dev, "NIC service probe failed\n");
487 
488 	return err;
489 }
490 
hinic3_nic_remove(struct auxiliary_device * adev)491 static void hinic3_nic_remove(struct auxiliary_device *adev)
492 {
493 	struct hinic3_nic_dev *nic_dev = dev_get_drvdata(&adev->dev);
494 	struct net_device *netdev;
495 
496 	if (!hinic3_support_nic(nic_dev->hwdev))
497 		return;
498 
499 	netdev = nic_dev->netdev;
500 	unregister_netdev(netdev);
501 
502 	disable_delayed_work_sync(&nic_dev->periodic_work);
503 	cancel_work_sync(&nic_dev->rx_mode_work);
504 	hinic3_free_nic_dev(nic_dev);
505 
506 	hinic3_update_nic_feature(nic_dev, 0);
507 	hinic3_set_nic_feature_to_hw(nic_dev);
508 	hinic3_sw_uninit(netdev);
509 
510 	hinic3_free_nic_io(nic_dev);
511 
512 	free_netdev(netdev);
513 }
514 
515 static const struct auxiliary_device_id hinic3_nic_id_table[] = {
516 	{
517 		.name = HINIC3_NIC_DRV_NAME ".nic",
518 	},
519 	{}
520 };
521 
522 static struct auxiliary_driver hinic3_nic_driver = {
523 	.probe    = hinic3_nic_probe,
524 	.remove   = hinic3_nic_remove,
525 	.suspend  = NULL,
526 	.resume   = NULL,
527 	.name     = "nic",
528 	.id_table = hinic3_nic_id_table,
529 };
530 
hinic3_nic_lld_init(void)531 static __init int hinic3_nic_lld_init(void)
532 {
533 	int err;
534 
535 	err = hinic3_lld_init();
536 	if (err)
537 		return err;
538 
539 	err = auxiliary_driver_register(&hinic3_nic_driver);
540 	if (err) {
541 		hinic3_lld_exit();
542 		return err;
543 	}
544 
545 	return 0;
546 }
547 
hinic3_nic_lld_exit(void)548 static __exit void hinic3_nic_lld_exit(void)
549 {
550 	auxiliary_driver_unregister(&hinic3_nic_driver);
551 
552 	hinic3_lld_exit();
553 }
554 
555 module_init(hinic3_nic_lld_init);
556 module_exit(hinic3_nic_lld_exit);
557 
558 MODULE_AUTHOR("Huawei Technologies CO., Ltd");
559 MODULE_DESCRIPTION(HINIC3_NIC_DRV_DESC);
560 MODULE_LICENSE("GPL");
561