2 * aQuantia Corporation Network Driver
3 * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
10 /* File aq_pci_func.c: Definition of PCI functions. */
12 #include "aq_pci_func.h"
16 #include <linux/interrupt.h>
18 struct aq_pci_func_s
{
20 struct aq_nic_s
*port
[AQ_CFG_PCI_FUNC_PORTS
];
22 void *aq_vec
[AQ_CFG_PCI_FUNC_MSIX_IRQS
];
23 resource_size_t mmio_pa
;
24 unsigned int msix_entry_mask
;
28 bool is_pci_using_dac
;
29 struct aq_hw_caps_s aq_hw_caps
;
32 struct aq_pci_func_s
*aq_pci_func_alloc(struct aq_hw_ops
*aq_hw_ops
,
34 const struct net_device_ops
*ndev_ops
,
35 const struct ethtool_ops
*eth_ops
)
37 struct aq_pci_func_s
*self
= NULL
;
39 unsigned int port
= 0U;
45 self
= kzalloc(sizeof(*self
), GFP_KERNEL
);
51 pci_set_drvdata(pdev
, self
);
54 err
= aq_hw_ops
->get_hw_caps(NULL
, &self
->aq_hw_caps
);
58 self
->ports
= self
->aq_hw_caps
.ports
;
60 for (port
= 0; port
< self
->ports
; ++port
) {
61 struct aq_nic_s
*aq_nic
= aq_nic_alloc_cold(ndev_ops
, eth_ops
,
69 self
->port
[port
] = aq_nic
;
75 aq_pci_func_free(self
);
83 int aq_pci_func_init(struct aq_pci_func_s
*self
)
86 unsigned int bar
= 0U;
87 unsigned int port
= 0U;
89 err
= pci_enable_device(self
->pdev
);
93 self
->is_pci_enabled
= true;
95 err
= pci_set_dma_mask(self
->pdev
, DMA_BIT_MASK(64));
97 err
= pci_set_consistent_dma_mask(self
->pdev
, DMA_BIT_MASK(64));
98 self
->is_pci_using_dac
= 1;
101 err
= pci_set_dma_mask(self
->pdev
, DMA_BIT_MASK(32));
103 err
= pci_set_consistent_dma_mask(self
->pdev
,
105 self
->is_pci_using_dac
= 0;
112 err
= pci_request_regions(self
->pdev
, AQ_CFG_DRV_NAME
"_mmio");
116 self
->is_regions
= true;
118 pci_set_master(self
->pdev
);
120 for (bar
= 0; bar
< 4; ++bar
) {
121 if (IORESOURCE_MEM
& pci_resource_flags(self
->pdev
, bar
)) {
122 resource_size_t reg_sz
;
124 self
->mmio_pa
= pci_resource_start(self
->pdev
, bar
);
125 if (self
->mmio_pa
== 0U) {
130 reg_sz
= pci_resource_len(self
->pdev
, bar
);
131 if ((reg_sz
<= 24 /*ATL_REGS_SIZE*/)) {
136 self
->mmio
= ioremap_nocache(self
->mmio_pa
, reg_sz
);
145 /*enable interrupts */
146 #if !AQ_CFG_FORCE_LEGACY_INT
147 err
= pci_alloc_irq_vectors(self
->pdev
, self
->aq_hw_caps
.msix_irqs
,
148 self
->aq_hw_caps
.msix_irqs
, PCI_IRQ_MSIX
);
151 err
= pci_alloc_irq_vectors(self
->pdev
, 1, 1,
152 PCI_IRQ_MSI
| PCI_IRQ_LEGACY
);
158 /* net device init */
159 for (port
= 0; port
< self
->ports
; ++port
) {
160 if (!self
->port
[port
])
163 err
= aq_nic_cfg_start(self
->port
[port
]);
167 err
= aq_nic_ndev_init(self
->port
[port
]);
171 err
= aq_nic_ndev_register(self
->port
[port
]);
178 aq_pci_func_deinit(self
);
182 int aq_pci_func_alloc_irq(struct aq_pci_func_s
*self
, unsigned int i
,
183 char *name
, void *aq_vec
, cpumask_t
*affinity_mask
)
185 struct pci_dev
*pdev
= self
->pdev
;
188 if (pdev
->msix_enabled
|| pdev
->msi_enabled
)
189 err
= request_irq(pci_irq_vector(pdev
, i
), aq_vec_isr
, 0,
192 err
= request_irq(pci_irq_vector(pdev
, i
), aq_vec_isr_legacy
,
193 IRQF_SHARED
, name
, aq_vec
);
196 self
->msix_entry_mask
|= (1 << i
);
197 self
->aq_vec
[i
] = aq_vec
;
199 if (pdev
->msix_enabled
)
200 irq_set_affinity_hint(pci_irq_vector(pdev
, i
),
207 void aq_pci_func_free_irqs(struct aq_pci_func_s
*self
)
209 struct pci_dev
*pdev
= self
->pdev
;
212 for (i
= 32U; i
--;) {
213 if (!((1U << i
) & self
->msix_entry_mask
))
216 if (pdev
->msix_enabled
)
217 irq_set_affinity_hint(pci_irq_vector(pdev
, i
), NULL
);
218 free_irq(pci_irq_vector(pdev
, i
), self
->aq_vec
[i
]);
219 self
->msix_entry_mask
&= ~(1U << i
);
223 void __iomem
*aq_pci_func_get_mmio(struct aq_pci_func_s
*self
)
228 unsigned int aq_pci_func_get_irq_type(struct aq_pci_func_s
*self
)
230 if (self
->pdev
->msix_enabled
)
231 return AQ_HW_IRQ_MSIX
;
232 if (self
->pdev
->msi_enabled
)
233 return AQ_HW_IRQ_MSIX
;
234 return AQ_HW_IRQ_LEGACY
;
237 void aq_pci_func_deinit(struct aq_pci_func_s
*self
)
242 aq_pci_func_free_irqs(self
);
243 pci_free_irq_vectors(self
->pdev
);
245 if (self
->is_regions
)
246 pci_release_regions(self
->pdev
);
248 if (self
->is_pci_enabled
)
249 pci_disable_device(self
->pdev
);
254 void aq_pci_func_free(struct aq_pci_func_s
*self
)
256 unsigned int port
= 0U;
261 for (port
= 0; port
< self
->ports
; ++port
) {
262 if (!self
->port
[port
])
265 aq_nic_ndev_free(self
->port
[port
]);
273 int aq_pci_func_change_pm_state(struct aq_pci_func_s
*self
,
274 pm_message_t
*pm_msg
)
277 unsigned int port
= 0U;
283 for (port
= 0; port
< self
->ports
; ++port
) {
284 if (!self
->port
[port
])
287 (void)aq_nic_change_pm_state(self
->port
[port
], pm_msg
);