xref: /linux/drivers/net/ethernet/microsoft/mana/gdma_cdx.c (revision 3d6792ea46056816196bf72243903b216a2fb06f)
1*3d6792eaSManish Awasthi // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2*3d6792eaSManish Awasthi /* Copyright (c) 2025, Microsoft Corporation. */
3*3d6792eaSManish Awasthi #include <linux/module.h>
4*3d6792eaSManish Awasthi #include <linux/bitmap.h>
5*3d6792eaSManish Awasthi #include <linux/cdx/cdx_bus.h>
6*3d6792eaSManish Awasthi #include <linux/msi.h>
7*3d6792eaSManish Awasthi #include <linux/xarray.h>
8*3d6792eaSManish Awasthi 
9*3d6792eaSManish Awasthi #include <net/mana/mana.h>
10*3d6792eaSManish Awasthi 
11*3d6792eaSManish Awasthi #define MANA_CDX_GDMA_REGS_SIZE	(GDMA_REG_SHM_OFFSET + sizeof(u64))
12*3d6792eaSManish Awasthi 
13*3d6792eaSManish Awasthi static int mana_cdx_msix_virq(struct gdma_context *gc, int msi)
14*3d6792eaSManish Awasthi {
15*3d6792eaSManish Awasthi 	unsigned int virq = msi_get_virq(gc->dev, msi);
16*3d6792eaSManish Awasthi 
17*3d6792eaSManish Awasthi 	/* CDX allocates its whole vector pool in mana_cdx_setup_hwc_irqs(),
18*3d6792eaSManish Awasthi 	 * so a vector with no Linux IRQ was never part of that pool.
19*3d6792eaSManish Awasthi 	 */
20*3d6792eaSManish Awasthi 	return virq ? virq : -EINVAL;
21*3d6792eaSManish Awasthi }
22*3d6792eaSManish Awasthi 
23*3d6792eaSManish Awasthi static int mana_cdx_dev_reset(struct gdma_context *gc)
24*3d6792eaSManish Awasthi {
25*3d6792eaSManish Awasthi 	return cdx_dev_reset(gc->dev);
26*3d6792eaSManish Awasthi }
27*3d6792eaSManish Awasthi 
28*3d6792eaSManish Awasthi static int mana_cdx_setup_hwc_irqs(struct gdma_context *gc)
29*3d6792eaSManish Awasthi {
30*3d6792eaSManish Awasthi 	struct cdx_device *cdx_dev = to_cdx_device(gc->dev);
31*3d6792eaSManish Awasthi 	struct gdma_irq_context *gic;
32*3d6792eaSManish Awasthi 	unsigned int max_irqs;
33*3d6792eaSManish Awasthi 	int nvec;
34*3d6792eaSManish Awasthi 	int err, i = 0, j;
35*3d6792eaSManish Awasthi 
36*3d6792eaSManish Awasthi 	max_irqs = cdx_dev->num_msi;
37*3d6792eaSManish Awasthi 
38*3d6792eaSManish Awasthi 	/* Need 1 IRQ for HWC and at least 1 for the data path queues */
39*3d6792eaSManish Awasthi 	if (max_irqs < 2) {
40*3d6792eaSManish Awasthi 		dev_err(&cdx_dev->dev, "Not enough MSI vectors: %u\n",
41*3d6792eaSManish Awasthi 			max_irqs);
42*3d6792eaSManish Awasthi 		return -ENOSPC;
43*3d6792eaSManish Awasthi 	}
44*3d6792eaSManish Awasthi 
45*3d6792eaSManish Awasthi 	/* Constrain the device to 32-bit DMA addresses, for both the MSI
46*3d6792eaSManish Awasthi 	 * doorbells and the data path buffers, and never widen it afterwards.
47*3d6792eaSManish Awasthi 	 *
48*3d6792eaSManish Awasthi 	 * The MSI doorbell address has to land within the low 4GB. The data
49*3d6792eaSManish Awasthi 	 * path carries a second constraint: the device does not perform
50*3d6792eaSManish Awasthi 	 * writes to the final page of the 48-bit IOVA window, and
51*3d6792eaSManish Awasthi 	 * iommu_dma_alloc_iova() allocates downwards from the top of that
52*3d6792eaSManish Awasthi 	 * window, so the first queue created lands on the unusable page and
53*3d6792eaSManish Awasthi 	 * its event queue stalls permanently. PCI devices are shielded from
54*3d6792eaSManish Awasthi 	 * this by the low-4GB first attempt in iommu_dma_alloc_iova(), but
55*3d6792eaSManish Awasthi 	 * that attempt is gated on dev_is_pci() and CDX devices do not
56*3d6792eaSManish Awasthi 	 * qualify.
57*3d6792eaSManish Awasthi 	 */
58*3d6792eaSManish Awasthi 	err = dma_set_mask_and_coherent(gc->dev, DMA_BIT_MASK(32));
59*3d6792eaSManish Awasthi 	if (err) {
60*3d6792eaSManish Awasthi 		dev_err(&cdx_dev->dev, "Failed to set 32-bit DMA mask\n");
61*3d6792eaSManish Awasthi 		return err;
62*3d6792eaSManish Awasthi 	}
63*3d6792eaSManish Awasthi 
64*3d6792eaSManish Awasthi 	/* The PCI path also calls dma_set_max_seg_size(), but that is
65*3d6792eaSManish Awasthi 	 * deliberately omitted here: the CDX core does not attach a
66*3d6792eaSManish Awasthi 	 * dma_parms to the device, so the helper would only WARN, and MANA
67*3d6792eaSManish Awasthi 	 * never builds scatter-gather lists, so the limit is never read.
68*3d6792eaSManish Awasthi 	 */
69*3d6792eaSManish Awasthi 
70*3d6792eaSManish Awasthi 	err = cdx_enable_msi(cdx_dev);
71*3d6792eaSManish Awasthi 	if (err) {
72*3d6792eaSManish Awasthi 		dev_err(&cdx_dev->dev, "Failed to enable MSI\n");
73*3d6792eaSManish Awasthi 		return err;
74*3d6792eaSManish Awasthi 	}
75*3d6792eaSManish Awasthi 
76*3d6792eaSManish Awasthi 	err = msi_domain_alloc_irqs(gc->dev, MSI_DEFAULT_DOMAIN, max_irqs);
77*3d6792eaSManish Awasthi 	if (err) {
78*3d6792eaSManish Awasthi 		dev_err(&cdx_dev->dev, "Failed to alloc MSI IRQs\n");
79*3d6792eaSManish Awasthi 		cdx_disable_msi(cdx_dev);
80*3d6792eaSManish Awasthi 		return err;
81*3d6792eaSManish Awasthi 	}
82*3d6792eaSManish Awasthi 
83*3d6792eaSManish Awasthi 	nvec = max_irqs;
84*3d6792eaSManish Awasthi 
85*3d6792eaSManish Awasthi 	xa_init(&gc->irq_contexts);
86*3d6792eaSManish Awasthi 
87*3d6792eaSManish Awasthi 	/* No IRQ affinity hint is applied here. The PCI transport spreads its
88*3d6792eaSManish Awasthi 	 * vectors over the NUMA node local to the device; the CDX platforms
89*3d6792eaSManish Awasthi 	 * this driver targets are single-node, so there is nothing to spread
90*3d6792eaSManish Awasthi 	 * over. Affinity management can be added when a multi-node CDX host
91*3d6792eaSManish Awasthi 	 * exists to validate it against.
92*3d6792eaSManish Awasthi 	 */
93*3d6792eaSManish Awasthi 	for (i = 0; i < nvec; i++) {
94*3d6792eaSManish Awasthi 		int msi = i;
95*3d6792eaSManish Awasthi 
96*3d6792eaSManish Awasthi 		gic = mana_gd_get_gic(gc, false, &msi);
97*3d6792eaSManish Awasthi 		if (IS_ERR(gic)) {
98*3d6792eaSManish Awasthi 			err = PTR_ERR(gic);
99*3d6792eaSManish Awasthi 			goto free_irq;
100*3d6792eaSManish Awasthi 		}
101*3d6792eaSManish Awasthi 	}
102*3d6792eaSManish Awasthi 
103*3d6792eaSManish Awasthi 	gc->max_num_msix = nvec;
104*3d6792eaSManish Awasthi 	gc->num_msix_usable = nvec;
105*3d6792eaSManish Awasthi 
106*3d6792eaSManish Awasthi 	/* CDX sizes its MSI pool at probe time and cannot grow it later, so
107*3d6792eaSManish Awasthi 	 * never share vectors: vector 0 is reserved for the HWC and each of
108*3d6792eaSManish Awasthi 	 * the remaining nvec - 1 vectors backs exactly one EQ. That bounds
109*3d6792eaSManish Awasthi 	 * the queue count at nvec - 1 and guarantees the HWC vector is never
110*3d6792eaSManish Awasthi 	 * handed out to a data queue.
111*3d6792eaSManish Awasthi 	 */
112*3d6792eaSManish Awasthi 	gc->msi_sharing = false;
113*3d6792eaSManish Awasthi 
114*3d6792eaSManish Awasthi 	gc->msi_bitmap = bitmap_zalloc(nvec, GFP_KERNEL);
115*3d6792eaSManish Awasthi 	if (!gc->msi_bitmap) {
116*3d6792eaSManish Awasthi 		err = -ENOMEM;
117*3d6792eaSManish Awasthi 		goto free_irq;
118*3d6792eaSManish Awasthi 	}
119*3d6792eaSManish Awasthi 
120*3d6792eaSManish Awasthi 	/* Reserve the HWC vector */
121*3d6792eaSManish Awasthi 	set_bit(0, gc->msi_bitmap);
122*3d6792eaSManish Awasthi 
123*3d6792eaSManish Awasthi 	return 0;
124*3d6792eaSManish Awasthi 
125*3d6792eaSManish Awasthi free_irq:
126*3d6792eaSManish Awasthi 	for (j = i - 1; j >= 0; j--)
127*3d6792eaSManish Awasthi 		mana_gd_put_gic(gc, false, j);
128*3d6792eaSManish Awasthi 
129*3d6792eaSManish Awasthi 	xa_destroy(&gc->irq_contexts);
130*3d6792eaSManish Awasthi 	msi_domain_free_irqs_all(gc->dev, MSI_DEFAULT_DOMAIN);
131*3d6792eaSManish Awasthi 	cdx_disable_msi(cdx_dev);
132*3d6792eaSManish Awasthi 	return err;
133*3d6792eaSManish Awasthi }
134*3d6792eaSManish Awasthi 
135*3d6792eaSManish Awasthi static void mana_cdx_remove_irqs(struct gdma_context *gc)
136*3d6792eaSManish Awasthi {
137*3d6792eaSManish Awasthi 	struct cdx_device *cdx_dev = to_cdx_device(gc->dev);
138*3d6792eaSManish Awasthi 	int i;
139*3d6792eaSManish Awasthi 
140*3d6792eaSManish Awasthi 	if (gc->max_num_msix < 1)
141*3d6792eaSManish Awasthi 		return;
142*3d6792eaSManish Awasthi 
143*3d6792eaSManish Awasthi 	for (i = 0; i < gc->max_num_msix; i++) {
144*3d6792eaSManish Awasthi 		if (!xa_load(&gc->irq_contexts, i))
145*3d6792eaSManish Awasthi 			continue;
146*3d6792eaSManish Awasthi 
147*3d6792eaSManish Awasthi 		mana_gd_put_gic(gc, false, i);
148*3d6792eaSManish Awasthi 	}
149*3d6792eaSManish Awasthi 
150*3d6792eaSManish Awasthi 	WARN_ON(!xa_empty(&gc->irq_contexts));
151*3d6792eaSManish Awasthi 
152*3d6792eaSManish Awasthi 	xa_destroy(&gc->irq_contexts);
153*3d6792eaSManish Awasthi 	msi_domain_free_irqs_all(gc->dev, MSI_DEFAULT_DOMAIN);
154*3d6792eaSManish Awasthi 	cdx_disable_msi(cdx_dev);
155*3d6792eaSManish Awasthi 
156*3d6792eaSManish Awasthi 	bitmap_free(gc->msi_bitmap);
157*3d6792eaSManish Awasthi 	gc->msi_bitmap = NULL;
158*3d6792eaSManish Awasthi 	gc->max_num_msix = 0;
159*3d6792eaSManish Awasthi 	gc->num_msix_usable = 0;
160*3d6792eaSManish Awasthi }
161*3d6792eaSManish Awasthi 
162*3d6792eaSManish Awasthi static int mana_cdx_setup_remaining_irqs(struct gdma_context *gc)
163*3d6792eaSManish Awasthi {
164*3d6792eaSManish Awasthi 	unsigned int max_queues_vport;
165*3d6792eaSManish Awasthi 
166*3d6792eaSManish Awasthi 	/* mana_gd_query_max_resources() may turn MSI sharing back on and round
167*3d6792eaSManish Awasthi 	 * the per-vPort queue count up to MANA_DEF_NUM_QUEUES. CDX sizes its
168*3d6792eaSManish Awasthi 	 * vector pool at probe time and cannot grow it later, and the HWC
169*3d6792eaSManish Awasthi 	 * vector must stay private, so give every vPort a private slice of the
170*3d6792eaSManish Awasthi 	 * remaining vectors instead. gc->max_num_queues is already capped at
171*3d6792eaSManish Awasthi 	 * num_msix_usable - 1 by the core.
172*3d6792eaSManish Awasthi 	 */
173*3d6792eaSManish Awasthi 	gc->msi_sharing = false;
174*3d6792eaSManish Awasthi 	max_queues_vport = (gc->num_msix_usable - 1) / gc->num_ports;
175*3d6792eaSManish Awasthi 	if (!max_queues_vport) {
176*3d6792eaSManish Awasthi 		dev_err(gc->dev, "%u MSI vectors cannot serve %u vPorts\n",
177*3d6792eaSManish Awasthi 			gc->num_msix_usable, gc->num_ports);
178*3d6792eaSManish Awasthi 		return -ENOSPC;
179*3d6792eaSManish Awasthi 	}
180*3d6792eaSManish Awasthi 
181*3d6792eaSManish Awasthi 	gc->max_num_queues_vport = min(gc->max_num_queues, max_queues_vport);
182*3d6792eaSManish Awasthi 
183*3d6792eaSManish Awasthi 	dev_dbg(gc->dev, "%u MSI vectors, %u vPorts, %u queues, no MSI sharing\n",
184*3d6792eaSManish Awasthi 		gc->num_msix_usable, gc->num_ports, gc->max_num_queues_vport);
185*3d6792eaSManish Awasthi 
186*3d6792eaSManish Awasthi 	return 0;
187*3d6792eaSManish Awasthi }
188*3d6792eaSManish Awasthi 
189*3d6792eaSManish Awasthi static const struct gdma_bus_ops mana_cdx_bus_ops = {
190*3d6792eaSManish Awasthi 	.bus_name		= "cdx",
191*3d6792eaSManish Awasthi 	.adev_prefix		= "mana_cdx",
192*3d6792eaSManish Awasthi 	.msix_virq		= mana_cdx_msix_virq,
193*3d6792eaSManish Awasthi 	.setup_hwc_irqs		= mana_cdx_setup_hwc_irqs,
194*3d6792eaSManish Awasthi 	.setup_remaining_irqs	= mana_cdx_setup_remaining_irqs,
195*3d6792eaSManish Awasthi 	.remove_irqs		= mana_cdx_remove_irqs,
196*3d6792eaSManish Awasthi 	.dev_reset		= mana_cdx_dev_reset,
197*3d6792eaSManish Awasthi };
198*3d6792eaSManish Awasthi 
199*3d6792eaSManish Awasthi static int mana_cdx_gd_probe(struct cdx_device *cdx_dev)
200*3d6792eaSManish Awasthi {
201*3d6792eaSManish Awasthi 	struct gdma_context *gc;
202*3d6792eaSManish Awasthi 	void __iomem *bar0_va;
203*3d6792eaSManish Awasthi 	int err;
204*3d6792eaSManish Awasthi 
205*3d6792eaSManish Awasthi 	/* Each port has 2 CQs, each CQ has at most 1 EQE at a time */
206*3d6792eaSManish Awasthi 	BUILD_BUG_ON(2 * MAX_PORTS_IN_MANA_DEV * GDMA_EQE_SIZE > EQ_SIZE);
207*3d6792eaSManish Awasthi 
208*3d6792eaSManish Awasthi 	err = cdx_dev_reset(&cdx_dev->dev);
209*3d6792eaSManish Awasthi 	if (err)
210*3d6792eaSManish Awasthi 		return err;
211*3d6792eaSManish Awasthi 
212*3d6792eaSManish Awasthi 	err = cdx_set_master(cdx_dev);
213*3d6792eaSManish Awasthi 	if (err)
214*3d6792eaSManish Awasthi 		return err;
215*3d6792eaSManish Awasthi 
216*3d6792eaSManish Awasthi 	gc = vzalloc(sizeof(*gc));
217*3d6792eaSManish Awasthi 	if (!gc) {
218*3d6792eaSManish Awasthi 		err = -ENOMEM;
219*3d6792eaSManish Awasthi 		goto clear_master;
220*3d6792eaSManish Awasthi 	}
221*3d6792eaSManish Awasthi 
222*3d6792eaSManish Awasthi 	mutex_init(&gc->eq_test_event_mutex);
223*3d6792eaSManish Awasthi 	mutex_init(&gc->gic_mutex);
224*3d6792eaSManish Awasthi 	dev_set_drvdata(&cdx_dev->dev, gc);
225*3d6792eaSManish Awasthi 	gc->bar0_pa = cdx_resource_start(cdx_dev, 0);
226*3d6792eaSManish Awasthi 	gc->bar0_size = cdx_resource_len(cdx_dev, 0);
227*3d6792eaSManish Awasthi 	if (gc->bar0_size < MANA_CDX_GDMA_REGS_SIZE) {
228*3d6792eaSManish Awasthi 		dev_err(&cdx_dev->dev, "BAR0 size %#llx is too small\n",
229*3d6792eaSManish Awasthi 			(u64)gc->bar0_size);
230*3d6792eaSManish Awasthi 		err = -EINVAL;
231*3d6792eaSManish Awasthi 		goto free_gc;
232*3d6792eaSManish Awasthi 	}
233*3d6792eaSManish Awasthi 
234*3d6792eaSManish Awasthi 	bar0_va = ioremap(gc->bar0_pa, gc->bar0_size);
235*3d6792eaSManish Awasthi 	if (!bar0_va) {
236*3d6792eaSManish Awasthi 		err = -ENOMEM;
237*3d6792eaSManish Awasthi 		goto free_gc;
238*3d6792eaSManish Awasthi 	}
239*3d6792eaSManish Awasthi 
240*3d6792eaSManish Awasthi 	gc->numa_node = dev_to_node(&cdx_dev->dev);
241*3d6792eaSManish Awasthi 	gc->bar0_va = bar0_va;
242*3d6792eaSManish Awasthi 	gc->dev = &cdx_dev->dev;
243*3d6792eaSManish Awasthi 	gc->bus_ops = &mana_cdx_bus_ops;
244*3d6792eaSManish Awasthi 
245*3d6792eaSManish Awasthi 	/* gc->is_pf is intentionally left clear: this device uses the VF
246*3d6792eaSManish Awasthi 	 * register layout, and the vPort and MAC filter registration that
247*3d6792eaSManish Awasthi 	 * is_pf selects is not required on this bus.
248*3d6792eaSManish Awasthi 	 */
249*3d6792eaSManish Awasthi 
250*3d6792eaSManish Awasthi 	err = mana_gd_setup(gc);
251*3d6792eaSManish Awasthi 	if (err)
252*3d6792eaSManish Awasthi 		goto unmap_bar;
253*3d6792eaSManish Awasthi 
254*3d6792eaSManish Awasthi 	err = mana_probe(&gc->mana, false);
255*3d6792eaSManish Awasthi 	if (err)
256*3d6792eaSManish Awasthi 		goto cleanup_gd;
257*3d6792eaSManish Awasthi 
258*3d6792eaSManish Awasthi 	err = mana_rdma_probe(&gc->mana_ib);
259*3d6792eaSManish Awasthi 	if (err)
260*3d6792eaSManish Awasthi 		goto remove_mana;
261*3d6792eaSManish Awasthi 
262*3d6792eaSManish Awasthi 	/* If a hardware reset event arrived over HWC during probe, roll back:
263*3d6792eaSManish Awasthi 	 * the device state the rest of probe observed is no longer valid.
264*3d6792eaSManish Awasthi 	 */
265*3d6792eaSManish Awasthi 	if (test_and_set_bit(GC_PROBE_SUCCEEDED, &gc->flags)) {
266*3d6792eaSManish Awasthi 		err = -EPROTO;
267*3d6792eaSManish Awasthi 		goto remove_rdma;
268*3d6792eaSManish Awasthi 	}
269*3d6792eaSManish Awasthi 
270*3d6792eaSManish Awasthi 	return 0;
271*3d6792eaSManish Awasthi 
272*3d6792eaSManish Awasthi remove_rdma:
273*3d6792eaSManish Awasthi 	mana_rdma_remove(&gc->mana_ib);
274*3d6792eaSManish Awasthi remove_mana:
275*3d6792eaSManish Awasthi 	mana_remove(&gc->mana, false);
276*3d6792eaSManish Awasthi cleanup_gd:
277*3d6792eaSManish Awasthi 	mana_gd_cleanup(gc);
278*3d6792eaSManish Awasthi unmap_bar:
279*3d6792eaSManish Awasthi 	iounmap(bar0_va);
280*3d6792eaSManish Awasthi free_gc:
281*3d6792eaSManish Awasthi 	dev_set_drvdata(&cdx_dev->dev, NULL);
282*3d6792eaSManish Awasthi 	vfree(gc);
283*3d6792eaSManish Awasthi clear_master:
284*3d6792eaSManish Awasthi 	cdx_clear_master(cdx_dev);
285*3d6792eaSManish Awasthi 	return err;
286*3d6792eaSManish Awasthi }
287*3d6792eaSManish Awasthi 
288*3d6792eaSManish Awasthi static int mana_cdx_gd_remove(struct cdx_device *cdx_dev)
289*3d6792eaSManish Awasthi {
290*3d6792eaSManish Awasthi 	struct gdma_context *gc = dev_get_drvdata(&cdx_dev->dev);
291*3d6792eaSManish Awasthi 
292*3d6792eaSManish Awasthi 	mana_rdma_remove(&gc->mana_ib);
293*3d6792eaSManish Awasthi 	mana_remove(&gc->mana, false);
294*3d6792eaSManish Awasthi 
295*3d6792eaSManish Awasthi 	mana_gd_cleanup(gc);
296*3d6792eaSManish Awasthi 	cdx_clear_master(cdx_dev);
297*3d6792eaSManish Awasthi 
298*3d6792eaSManish Awasthi 	iounmap(gc->bar0_va);
299*3d6792eaSManish Awasthi 
300*3d6792eaSManish Awasthi 	dev_set_drvdata(&cdx_dev->dev, NULL);
301*3d6792eaSManish Awasthi 	vfree(gc);
302*3d6792eaSManish Awasthi 	return 0;
303*3d6792eaSManish Awasthi }
304*3d6792eaSManish Awasthi 
305*3d6792eaSManish Awasthi /* Quiesce the device for kexec. This is also called upon reboot/shutdown. */
306*3d6792eaSManish Awasthi static void mana_cdx_gd_shutdown(struct cdx_device *cdx_dev)
307*3d6792eaSManish Awasthi {
308*3d6792eaSManish Awasthi 	struct gdma_context *gc = dev_get_drvdata(&cdx_dev->dev);
309*3d6792eaSManish Awasthi 
310*3d6792eaSManish Awasthi 	mana_rdma_remove(&gc->mana_ib);
311*3d6792eaSManish Awasthi 	mana_remove(&gc->mana, true);
312*3d6792eaSManish Awasthi 
313*3d6792eaSManish Awasthi 	mana_gd_cleanup(gc);
314*3d6792eaSManish Awasthi 	cdx_clear_master(cdx_dev);
315*3d6792eaSManish Awasthi }
316*3d6792eaSManish Awasthi 
317*3d6792eaSManish Awasthi #define CDX_VENDOR_ID_MICROSOFT 0x1414
318*3d6792eaSManish Awasthi static const struct cdx_device_id mana_cdx_table[] = {
319*3d6792eaSManish Awasthi 	{ CDX_DEVICE(CDX_VENDOR_ID_MICROSOFT, MANA_CDX_DEVICE_ID) },
320*3d6792eaSManish Awasthi 	{}
321*3d6792eaSManish Awasthi };
322*3d6792eaSManish Awasthi 
323*3d6792eaSManish Awasthi MODULE_DEVICE_TABLE(cdx, mana_cdx_table);
324*3d6792eaSManish Awasthi 
325*3d6792eaSManish Awasthi static struct cdx_driver gdma_cdx_driver = {
326*3d6792eaSManish Awasthi 	.match_id_table	= mana_cdx_table,
327*3d6792eaSManish Awasthi 	.probe		= mana_cdx_gd_probe,
328*3d6792eaSManish Awasthi 	.remove		= mana_cdx_gd_remove,
329*3d6792eaSManish Awasthi 	.shutdown	= mana_cdx_gd_shutdown,
330*3d6792eaSManish Awasthi 	.driver	= {
331*3d6792eaSManish Awasthi 		.name	= "mana_cdx",
332*3d6792eaSManish Awasthi 	},
333*3d6792eaSManish Awasthi };
334*3d6792eaSManish Awasthi 
335*3d6792eaSManish Awasthi module_driver(gdma_cdx_driver, cdx_driver_register, cdx_driver_unregister);
336*3d6792eaSManish Awasthi 
337*3d6792eaSManish Awasthi MODULE_LICENSE("Dual BSD/GPL");
338*3d6792eaSManish Awasthi MODULE_DESCRIPTION("Microsoft Azure Network Adapter driver for the CDX bus");
339*3d6792eaSManish Awasthi MODULE_IMPORT_NS("CDX_BUS");
340*3d6792eaSManish Awasthi MODULE_IMPORT_NS("NET_MANA");
341