File Index
Files and directories
Sign in
FILE

main.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/apm/xgene-v2/main.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Applied Micro X-Gene SoC Ethernet v2 Driver
  4 *
  5 * Copyright (c) 2017, Applied Micro Circuits Corporation
  6 * Author(s): Iyappan Subramanian <isubramanian@apm.com>
  7 *	      Keyur Chudgar <kchudgar@apm.com>
  8 */
  9
 10#include "main.h"
 11
 12static int xge_get_resources(struct xge_pdata *pdata)
 13{
 14	struct platform_device *pdev;
 15	struct net_device *ndev;
 16	int phy_mode, ret = 0;
 17	struct resource *res;
 18	struct device *dev;
 19
 20	pdev = pdata->pdev;
 21	dev = &pdev->dev;
 22	ndev = pdata->ndev;
 23
 24	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 25	if (!res) {
 26		dev_err(dev, "Resource enet_csr not defined\n");
 27		return -ENODEV;
 28	}
 29
 30	pdata->resources.base_addr = devm_ioremap(dev, res->start,
 31						  resource_size(res));
 32	if (!pdata->resources.base_addr) {
 33		dev_err(dev, "Unable to retrieve ENET Port CSR region\n");
 34		return -ENOMEM;
 35	}
 36
 37	if (device_get_ethdev_address(dev, ndev))
 38		eth_hw_addr_random(ndev);
 39
 40	memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len);
 41
 42	phy_mode = device_get_phy_mode(dev);
 43	if (phy_mode < 0) {
 44		dev_err(dev, "Unable to get phy-connection-type\n");
 45		return phy_mode;
 46	}
 47	pdata->resources.phy_mode = phy_mode;
 48
 49	if (pdata->resources.phy_mode != PHY_INTERFACE_MODE_RGMII) {
 50		dev_err(dev, "Incorrect phy-connection-type specified\n");
 51		return -ENODEV;
 52	}
 53
 54	ret = platform_get_irq(pdev, 0);
 55	if (ret < 0)
 56		return ret;
 57	pdata->resources.irq = ret;
 58
 59	return 0;
 60}
 61
 62static int xge_refill_buffers(struct net_device *ndev, u32 nbuf)
 63{
 64	struct xge_pdata *pdata = netdev_priv(ndev);
 65	struct xge_desc_ring *ring = pdata->rx_ring;
 66	const u8 slots = XGENE_ENET_NUM_DESC - 1;
 67	struct device *dev = &pdata->pdev->dev;
 68	struct xge_raw_desc *raw_desc;
 69	u64 addr_lo, addr_hi;
 70	u8 tail = ring->tail;
 71	struct sk_buff *skb;
 72	dma_addr_t dma_addr;
 73	u16 len;
 74	int i;
 75
 76	for (i = 0; i < nbuf; i++) {
 77		raw_desc = &ring->raw_desc[tail];
 78
 79		len = XGENE_ENET_STD_MTU;
 80		skb = netdev_alloc_skb(ndev, len);
 81		if (unlikely(!skb))
 82			return -ENOMEM;
 83
 84		dma_addr = dma_map_single(dev, skb->data, len, DMA_FROM_DEVICE);
 85		if (dma_mapping_error(dev, dma_addr)) {
 86			netdev_err(ndev, "DMA mapping error\n");
 87			dev_kfree_skb_any(skb);
 88			return -EINVAL;
 89		}
 90
 91		ring->pkt_info[tail].skb = skb;
 92		ring->pkt_info[tail].dma_addr = dma_addr;
 93
 94		addr_hi = GET_BITS(NEXT_DESC_ADDRH, le64_to_cpu(raw_desc->m1));
 95		addr_lo = GET_BITS(NEXT_DESC_ADDRL, le64_to_cpu(raw_desc->m1));
 96		raw_desc->m1 = cpu_to_le64(SET_BITS(NEXT_DESC_ADDRL, addr_lo) |
 97					   SET_BITS(NEXT_DESC_ADDRH, addr_hi) |
 98					   SET_BITS(PKT_ADDRH,
 99						    upper_32_bits(dma_addr)));
100
101		dma_wmb();
102		raw_desc->m0 = cpu_to_le64(SET_BITS(PKT_ADDRL, dma_addr) |
103					   SET_BITS(E, 1));
104		tail = (tail + 1) & slots;
105	}
106
107	ring->tail = tail;
108
109	return 0;
110}
111
112static int xge_init_hw(struct net_device *ndev)
113{
114	struct xge_pdata *pdata = netdev_priv(ndev);
115	int ret;
116
117	ret = xge_port_reset(ndev);
118	if (ret)
119		return ret;
120
121	xge_port_init(ndev);
122	pdata->nbufs = NUM_BUFS;
123
124	return 0;
125}
126
127static irqreturn_t xge_irq(const int irq, void *data)
128{
129	struct xge_pdata *pdata = data;
130
131	if (napi_schedule_prep(&pdata->napi)) {
132		xge_intr_disable(pdata);
133		__napi_schedule(&pdata->napi);
134	}
135
136	return IRQ_HANDLED;
137}
138
139static int xge_request_irq(struct net_device *ndev)
140{
141	struct xge_pdata *pdata = netdev_priv(ndev);
142	int ret;
143
144	snprintf(pdata->irq_name, IRQ_ID_SIZE, "%s", ndev->name);
145
146	ret = request_irq(pdata->resources.irq, xge_irq, 0, pdata->irq_name,
147			  pdata);
148	if (ret)
149		netdev_err(ndev, "Failed to request irq %s\n", pdata->irq_name);
150
151	return ret;
152}
153
154static void xge_free_irq(struct net_device *ndev)
155{
156	struct xge_pdata *pdata = netdev_priv(ndev);
157
158	free_irq(pdata->resources.irq, pdata);
159}
160
161static bool is_tx_slot_available(struct xge_raw_desc *raw_desc)
162{
163	if (GET_BITS(E, le64_to_cpu(raw_desc->m0)) &&
164	    (GET_BITS(PKT_SIZE, le64_to_cpu(raw_desc->m0)) == SLOT_EMPTY))
165		return true;
166
167	return false;
168}
169
170static netdev_tx_t xge_start_xmit(struct sk_buff *skb, struct net_device *ndev)
171{
172	struct xge_pdata *pdata = netdev_priv(ndev);
173	struct device *dev = &pdata->pdev->dev;
174	struct xge_desc_ring *tx_ring;
175	struct xge_raw_desc *raw_desc;
176	static dma_addr_t dma_addr;
177	u64 addr_lo, addr_hi;
178	void *pkt_buf;
179	u8 tail;
180	u16 len;
181
182	tx_ring = pdata->tx_ring;
183	tail = tx_ring->tail;
184	len = skb_headlen(skb);
185	raw_desc = &tx_ring->raw_desc[tail];
186
187	if (!is_tx_slot_available(raw_desc)) {
188		netif_stop_queue(ndev);
189		return NETDEV_TX_BUSY;
190	}
191
192	/* Packet buffers should be 64B aligned */
193	pkt_buf = dma_alloc_coherent(dev, XGENE_ENET_STD_MTU, &dma_addr,
194				     GFP_ATOMIC);
195	if (unlikely(!pkt_buf)) {
196		dev_kfree_skb_any(skb);
197		return NETDEV_TX_OK;
198	}
199	memcpy(pkt_buf, skb->data, len);
200
201	addr_hi = GET_BITS(NEXT_DESC_ADDRH, le64_to_cpu(raw_desc->m1));
202	addr_lo = GET_BITS(NEXT_DESC_ADDRL, le64_to_cpu(raw_desc->m1));
203	raw_desc->m1 = cpu_to_le64(SET_BITS(NEXT_DESC_ADDRL, addr_lo) |
204				   SET_BITS(NEXT_DESC_ADDRH, addr_hi) |
205				   SET_BITS(PKT_ADDRH,
206					    upper_32_bits(dma_addr)));
207
208	tx_ring->pkt_info[tail].skb = skb;
209	tx_ring->pkt_info[tail].dma_addr = dma_addr;
210	tx_ring->pkt_info[tail].pkt_buf = pkt_buf;
211
212	dma_wmb();
213
214	raw_desc->m0 = cpu_to_le64(SET_BITS(PKT_ADDRL, dma_addr) |
215				   SET_BITS(PKT_SIZE, len) |
216				   SET_BITS(E, 0));
217	skb_tx_timestamp(skb);
218	xge_wr_csr(pdata, DMATXCTRL, 1);
219
220	tx_ring->tail = (tail + 1) & (XGENE_ENET_NUM_DESC - 1);
221
222	return NETDEV_TX_OK;
223}
224
225static bool is_tx_hw_done(struct xge_raw_desc *raw_desc)
226{
227	if (GET_BITS(E, le64_to_cpu(raw_desc->m0)) &&
228	    !GET_BITS(PKT_SIZE, le64_to_cpu(raw_desc->m0)))
229		return true;
230
231	return false;
232}
233
234static void xge_txc_poll(struct net_device *ndev)
235{
236	struct xge_pdata *pdata = netdev_priv(ndev);
237	struct device *dev = &pdata->pdev->dev;
238	struct xge_desc_ring *tx_ring;
239	struct xge_raw_desc *raw_desc;
240	dma_addr_t dma_addr;
241	struct sk_buff *skb;
242	void *pkt_buf;
243	u32 data;
244	u8 head;
245
246	tx_ring = pdata->tx_ring;
247	head = tx_ring->head;
248
249	data = xge_rd_csr(pdata, DMATXSTATUS);
250	if (!GET_BITS(TXPKTCOUNT, data))
251		return;
252
253	while (1) {
254		raw_desc = &tx_ring->raw_desc[head];
255
256		if (!is_tx_hw_done(raw_desc))
257			break;
258
259		dma_rmb();
260
261		skb = tx_ring->pkt_info[head].skb;
262		dma_addr = tx_ring->pkt_info[head].dma_addr;
263		pkt_buf = tx_ring->pkt_info[head].pkt_buf;
264		pdata->stats.tx_packets++;
265		pdata->stats.tx_bytes += skb->len;
266		dma_free_coherent(dev, XGENE_ENET_STD_MTU, pkt_buf, dma_addr);
267		dev_kfree_skb_any(skb);
268
269		/* clear pktstart address and pktsize */
270		raw_desc->m0 = cpu_to_le64(SET_BITS(E, 1) |
271					   SET_BITS(PKT_SIZE, SLOT_EMPTY));
272		xge_wr_csr(pdata, DMATXSTATUS, 1);
273
274		head = (head + 1) & (XGENE_ENET_NUM_DESC - 1);
275	}
276
277	if (netif_queue_stopped(ndev))
278		netif_wake_queue(ndev);
279
280	tx_ring->head = head;
281}
282
283static int xge_rx_poll(struct net_device *ndev, unsigned int budget)
284{
285	struct xge_pdata *pdata = netdev_priv(ndev);
286	struct device *dev = &pdata->pdev->dev;
287	struct xge_desc_ring *rx_ring;
288	struct xge_raw_desc *raw_desc;
289	struct sk_buff *skb;
290	dma_addr_t dma_addr;
291	int processed = 0;
292	u8 head, rx_error;
293	int i, ret;
294	u32 data;
295	u16 len;
296
297	rx_ring = pdata->rx_ring;
298	head = rx_ring->head;
299
300	data = xge_rd_csr(pdata, DMARXSTATUS);
301	if (!GET_BITS(RXPKTCOUNT, data))
302		return 0;
303
304	for (i = 0; i < budget; i++) {
305		raw_desc = &rx_ring->raw_desc[head];
306
307		if (GET_BITS(E, le64_to_cpu(raw_desc->m0)))
308			break;
309
310		dma_rmb();
311
312		skb = rx_ring->pkt_info[head].skb;
313		rx_ring->pkt_info[head].skb = NULL;
314		dma_addr = rx_ring->pkt_info[head].dma_addr;
315		len = GET_BITS(PKT_SIZE, le64_to_cpu(raw_desc->m0));
316		dma_unmap_single(dev, dma_addr, XGENE_ENET_STD_MTU,
317				 DMA_FROM_DEVICE);
318
319		rx_error = GET_BITS(D, le64_to_cpu(raw_desc->m2));
320		if (unlikely(rx_error)) {
321			pdata->stats.rx_errors++;
322			dev_kfree_skb_any(skb);
323			goto out;
324		}
325
326		skb_put(skb, len);
327		skb->protocol = eth_type_trans(skb, ndev);
328
329		pdata->stats.rx_packets++;
330		pdata->stats.rx_bytes += len;
331		napi_gro_receive(&pdata->napi, skb);
332out:
333		ret = xge_refill_buffers(ndev, 1);
334		xge_wr_csr(pdata, DMARXSTATUS, 1);
335		xge_wr_csr(pdata, DMARXCTRL, 1);
336
337		if (ret)
338			break;
339
340		head = (head + 1) & (XGENE_ENET_NUM_DESC - 1);
341		processed++;
342	}
343
344	rx_ring->head = head;
345
346	return processed;
347}
348
349static void xge_delete_desc_ring(struct net_device *ndev,
350				 struct xge_desc_ring *ring)
351{
352	struct xge_pdata *pdata = netdev_priv(ndev);
353	struct device *dev = &pdata->pdev->dev;
354	u16 size;
355
356	if (!ring)
357		return;
358
359	size = XGENE_ENET_DESC_SIZE * XGENE_ENET_NUM_DESC;
360	if (ring->desc_addr)
361		dma_free_coherent(dev, size, ring->desc_addr, ring->dma_addr);
362
363	kfree(ring->pkt_info);
364	kfree(ring);
365}
366
367static void xge_free_buffers(struct net_device *ndev)
368{
369	struct xge_pdata *pdata = netdev_priv(ndev);
370	struct xge_desc_ring *ring = pdata->rx_ring;
371	struct device *dev = &pdata->pdev->dev;
372	struct sk_buff *skb;
373	dma_addr_t dma_addr;
374	int i;
375
376	for (i = 0; i < XGENE_ENET_NUM_DESC; i++) {
377		skb = ring->pkt_info[i].skb;
378		dma_addr = ring->pkt_info[i].dma_addr;
379
380		if (!skb)
381			continue;
382
383		dma_unmap_single(dev, dma_addr, XGENE_ENET_STD_MTU,
384				 DMA_FROM_DEVICE);
385		dev_kfree_skb_any(skb);
386	}
387}
388
389static void xge_delete_desc_rings(struct net_device *ndev)
390{
391	struct xge_pdata *pdata = netdev_priv(ndev);
392
393	xge_txc_poll(ndev);
394	xge_delete_desc_ring(ndev, pdata->tx_ring);
395
396	xge_rx_poll(ndev, 64);
397	xge_free_buffers(ndev);
398	xge_delete_desc_ring(ndev, pdata->rx_ring);
399}
400
401static struct xge_desc_ring *xge_create_desc_ring(struct net_device *ndev)
402{
403	struct xge_pdata *pdata = netdev_priv(ndev);
404	struct device *dev = &pdata->pdev->dev;
405	struct xge_desc_ring *ring;
406	u16 size;
407
408	ring = kzalloc(sizeof(*ring), GFP_KERNEL);
409	if (!ring)
410		return NULL;
411
412	ring->ndev = ndev;
413
414	size = XGENE_ENET_DESC_SIZE * XGENE_ENET_NUM_DESC;
415	ring->desc_addr = dma_alloc_coherent(dev, size, &ring->dma_addr,
416					     GFP_KERNEL);
417	if (!ring->desc_addr)
418		goto err;
419
420	ring->pkt_info = kcalloc(XGENE_ENET_NUM_DESC, sizeof(*ring->pkt_info),
421				 GFP_KERNEL);
422	if (!ring->pkt_info)
423		goto err;
424
425	xge_setup_desc(ring);
426
427	return ring;
428
429err:
430	xge_delete_desc_ring(ndev, ring);
431
432	return NULL;
433}
434
435static int xge_create_desc_rings(struct net_device *ndev)
436{
437	struct xge_pdata *pdata = netdev_priv(ndev);
438	struct xge_desc_ring *ring;
439	int ret;
440
441	/* create tx ring */
442	ring = xge_create_desc_ring(ndev);
443	if (!ring)
444		goto err;
445
446	pdata->tx_ring = ring;
447	xge_update_tx_desc_addr(pdata);
448
449	/* create rx ring */
450	ring = xge_create_desc_ring(ndev);
451	if (!ring)
452		goto err;
453
454	pdata->rx_ring = ring;
455	xge_update_rx_desc_addr(pdata);
456
457	ret = xge_refill_buffers(ndev, XGENE_ENET_NUM_DESC);
458	if (ret)
459		goto err;
460
461	return 0;
462err:
463	xge_delete_desc_rings(ndev);
464
465	return -ENOMEM;
466}
467
468static int xge_open(struct net_device *ndev)
469{
470	struct xge_pdata *pdata = netdev_priv(ndev);
471	int ret;
472
473	ret = xge_create_desc_rings(ndev);
474	if (ret)
475		return ret;
476
477	napi_enable(&pdata->napi);
478	ret = xge_request_irq(ndev);
479	if (ret)
480		return ret;
481
482	xge_intr_enable(pdata);
483	xge_wr_csr(pdata, DMARXCTRL, 1);
484
485	phy_start(ndev->phydev);
486	xge_mac_enable(pdata);
487	netif_start_queue(ndev);
488
489	return 0;
490}
491
492static int xge_close(struct net_device *ndev)
493{
494	struct xge_pdata *pdata = netdev_priv(ndev);
495
496	netif_stop_queue(ndev);
497	xge_mac_disable(pdata);
498	phy_stop(ndev->phydev);
499
500	xge_intr_disable(pdata);
501	xge_free_irq(ndev);
502	napi_disable(&pdata->napi);
503	xge_delete_desc_rings(ndev);
504
505	return 0;
506}
507
508static int xge_napi(struct napi_struct *napi, const int budget)
509{
510	struct net_device *ndev = napi->dev;
511	struct xge_pdata *pdata;
512	int processed;
513
514	pdata = netdev_priv(ndev);
515
516	xge_txc_poll(ndev);
517	processed = xge_rx_poll(ndev, budget);
518
519	if (processed < budget) {
520		napi_complete_done(napi, processed);
521		xge_intr_enable(pdata);
522	}
523
524	return processed;
525}
526
527static int xge_set_mac_addr(struct net_device *ndev, void *addr)
528{
529	struct xge_pdata *pdata = netdev_priv(ndev);
530	int ret;
531
532	ret = eth_mac_addr(ndev, addr);
533	if (ret)
534		return ret;
535
536	xge_mac_set_station_addr(pdata);
537
538	return 0;
539}
540
541static bool is_tx_pending(struct xge_raw_desc *raw_desc)
542{
543	if (!GET_BITS(E, le64_to_cpu(raw_desc->m0)))
544		return true;
545
546	return false;
547}
548
549static void xge_free_pending_skb(struct net_device *ndev)
550{
551	struct xge_pdata *pdata = netdev_priv(ndev);
552	struct device *dev = &pdata->pdev->dev;
553	struct xge_desc_ring *tx_ring;
554	struct xge_raw_desc *raw_desc;
555	dma_addr_t dma_addr;
556	struct sk_buff *skb;
557	void *pkt_buf;
558	int i;
559
560	tx_ring = pdata->tx_ring;
561
562	for (i = 0; i < XGENE_ENET_NUM_DESC; i++) {
563		raw_desc = &tx_ring->raw_desc[i];
564
565		if (!is_tx_pending(raw_desc))
566			continue;
567
568		skb = tx_ring->pkt_info[i].skb;
569		dma_addr = tx_ring->pkt_info[i].dma_addr;
570		pkt_buf = tx_ring->pkt_info[i].pkt_buf;
571		dma_free_coherent(dev, XGENE_ENET_STD_MTU, pkt_buf, dma_addr);
572		dev_kfree_skb_any(skb);
573	}
574}
575
576static void xge_timeout(struct net_device *ndev, unsigned int txqueue)
577{
578	struct xge_pdata *pdata = netdev_priv(ndev);
579
580	rtnl_lock();
581
582	if (!netif_running(ndev))
583		goto out;
584
585	netif_stop_queue(ndev);
586	xge_intr_disable(pdata);
587	napi_disable(&pdata->napi);
588
589	xge_wr_csr(pdata, DMATXCTRL, 0);
590	xge_txc_poll(ndev);
591	xge_free_pending_skb(ndev);
592	xge_wr_csr(pdata, DMATXSTATUS, ~0U);
593
594	xge_setup_desc(pdata->tx_ring);
595	xge_update_tx_desc_addr(pdata);
596	xge_mac_init(pdata);
597
598	napi_enable(&pdata->napi);
599	xge_intr_enable(pdata);
600	xge_mac_enable(pdata);
601	netif_start_queue(ndev);
602
603out:
604	rtnl_unlock();
605}
606
607static void xge_get_stats64(struct net_device *ndev,
608			    struct rtnl_link_stats64 *storage)
609{
610	struct xge_pdata *pdata = netdev_priv(ndev);
611	struct xge_stats *stats = &pdata->stats;
612
613	storage->tx_packets += stats->tx_packets;
614	storage->tx_bytes += stats->tx_bytes;
615
616	storage->rx_packets += stats->rx_packets;
617	storage->rx_bytes += stats->rx_bytes;
618	storage->rx_errors += stats->rx_errors;
619}
620
621static const struct net_device_ops xgene_ndev_ops = {
622	.ndo_open = xge_open,
623	.ndo_stop = xge_close,
624	.ndo_start_xmit = xge_start_xmit,
625	.ndo_set_mac_address = xge_set_mac_addr,
626	.ndo_tx_timeout = xge_timeout,
627	.ndo_get_stats64 = xge_get_stats64,
628};
629
630static int xge_probe(struct platform_device *pdev)
631{
632	struct device *dev = &pdev->dev;
633	struct net_device *ndev;
634	struct xge_pdata *pdata;
635	int ret;
636
637	ndev = alloc_etherdev(sizeof(*pdata));
638	if (!ndev)
639		return -ENOMEM;
640
641	pdata = netdev_priv(ndev);
642
643	pdata->pdev = pdev;
644	pdata->ndev = ndev;
645	SET_NETDEV_DEV(ndev, dev);
646	platform_set_drvdata(pdev, pdata);
647	ndev->netdev_ops = &xgene_ndev_ops;
648
649	ndev->features |= NETIF_F_GSO |
650			  NETIF_F_GRO;
651
652	ret = xge_get_resources(pdata);
653	if (ret)
654		goto err;
655
656	ndev->hw_features = ndev->features;
657	xge_set_ethtool_ops(ndev);
658
659	ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64));
660	if (ret) {
661		netdev_err(ndev, "No usable DMA configuration\n");
662		goto err;
663	}
664
665	ret = xge_init_hw(ndev);
666	if (ret)
667		goto err;
668
669	ret = xge_mdio_config(ndev);
670	if (ret)
671		goto err;
672
673	netif_napi_add(ndev, &pdata->napi, xge_napi);
674
675	ret = register_netdev(ndev);
676	if (ret) {
677		netdev_err(ndev, "Failed to register netdev\n");
678		goto err_mdio_remove;
679	}
680
681	return 0;
682
683err_mdio_remove:
684	xge_mdio_remove(ndev);
685err:
686	free_netdev(ndev);
687
688	return ret;
689}
690
691static void xge_remove(struct platform_device *pdev)
692{
693	struct xge_pdata *pdata;
694	struct net_device *ndev;
695
696	pdata = platform_get_drvdata(pdev);
697	ndev = pdata->ndev;
698
699	rtnl_lock();
700	if (netif_running(ndev))
701		dev_close(ndev);
702	rtnl_unlock();
703
704	xge_mdio_remove(ndev);
705	unregister_netdev(ndev);
706	free_netdev(ndev);
707}
708
709static void xge_shutdown(struct platform_device *pdev)
710{
711	struct xge_pdata *pdata;
712
713	pdata = platform_get_drvdata(pdev);
714	if (!pdata)
715		return;
716
717	if (!pdata->ndev)
718		return;
719
720	xge_remove(pdev);
721}
722
723static const struct acpi_device_id xge_acpi_match[] = {
724	{ "APMC0D80" },
725	{ }
726};
727MODULE_DEVICE_TABLE(acpi, xge_acpi_match);
728
729static struct platform_driver xge_driver = {
730	.driver = {
731		   .name = "xgene-enet-v2",
732		   .acpi_match_table = xge_acpi_match,
733	},
734	.probe = xge_probe,
735	.remove = xge_remove,
736	.shutdown = xge_shutdown,
737};
738module_platform_driver(xge_driver);
739
740MODULE_DESCRIPTION("APM X-Gene SoC Ethernet v2 driver");
741MODULE_AUTHOR("Iyappan Subramanian <isubramanian@apm.com>");
742MODULE_LICENSE("GPL");
~/ Read-only file preview.