diff options
author | Tom Lendacky <thomas.lendacky@amd.com> | 2017-01-13 03:05:53 -0500 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2017-01-13 12:07:03 -0500 |
commit | e75377404726be171d66c154f8ea1e6cf840811d (patch) | |
tree | b31f391603109c180dcad7db9636869663ea446c | |
parent | e8e8dd6d20fa55ff974460ad742fcbf35b301062 (diff) |
amd-xgbe: Update PCI support to use new IRQ functions
Some of the PCI MSI/MSI-X functions have been deprecated and it is
recommended to use the new pci_alloc_irq_vectors() function. Convert the
code over to use the new function. Also, modify the way in which the IRQs
are requested - try for multiple MSI-X/MSI first, then a single MSI/legacy
interrupt.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-rw-r--r-- | drivers/net/ethernet/amd/xgbe/xgbe-pci.c | 128 | ||||
-rw-r--r-- | drivers/net/ethernet/amd/xgbe/xgbe.h | 8 |
2 files changed, 41 insertions, 95 deletions
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-pci.c b/drivers/net/ethernet/amd/xgbe/xgbe-pci.c index e76b7f65b805..e43690288c59 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-pci.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-pci.c | |||
@@ -122,104 +122,40 @@ | |||
122 | #include "xgbe.h" | 122 | #include "xgbe.h" |
123 | #include "xgbe-common.h" | 123 | #include "xgbe-common.h" |
124 | 124 | ||
125 | static int xgbe_config_msi(struct xgbe_prv_data *pdata) | 125 | static int xgbe_config_multi_msi(struct xgbe_prv_data *pdata) |
126 | { | 126 | { |
127 | unsigned int msi_count; | 127 | unsigned int vector_count; |
128 | unsigned int i, j; | 128 | unsigned int i, j; |
129 | int ret; | 129 | int ret; |
130 | 130 | ||
131 | msi_count = XGBE_MSIX_BASE_COUNT; | 131 | vector_count = XGBE_MSI_BASE_COUNT; |
132 | msi_count += max(pdata->rx_ring_count, | 132 | vector_count += max(pdata->rx_ring_count, |
133 | pdata->tx_ring_count); | 133 | pdata->tx_ring_count); |
134 | msi_count = roundup_pow_of_two(msi_count); | ||
135 | 134 | ||
136 | ret = pci_enable_msi_exact(pdata->pcidev, msi_count); | 135 | ret = pci_alloc_irq_vectors(pdata->pcidev, XGBE_MSI_MIN_COUNT, |
136 | vector_count, PCI_IRQ_MSI | PCI_IRQ_MSIX); | ||
137 | if (ret < 0) { | 137 | if (ret < 0) { |
138 | dev_info(pdata->dev, "MSI request for %u interrupts failed\n", | 138 | dev_info(pdata->dev, "multi MSI/MSI-X enablement failed\n"); |
139 | msi_count); | ||
140 | |||
141 | ret = pci_enable_msi(pdata->pcidev); | ||
142 | if (ret < 0) { | ||
143 | dev_info(pdata->dev, "MSI enablement failed\n"); | ||
144 | return ret; | ||
145 | } | ||
146 | |||
147 | msi_count = 1; | ||
148 | } | ||
149 | |||
150 | pdata->irq_count = msi_count; | ||
151 | |||
152 | pdata->dev_irq = pdata->pcidev->irq; | ||
153 | |||
154 | if (msi_count > 1) { | ||
155 | pdata->ecc_irq = pdata->pcidev->irq + 1; | ||
156 | pdata->i2c_irq = pdata->pcidev->irq + 2; | ||
157 | pdata->an_irq = pdata->pcidev->irq + 3; | ||
158 | |||
159 | for (i = XGBE_MSIX_BASE_COUNT, j = 0; | ||
160 | (i < msi_count) && (j < XGBE_MAX_DMA_CHANNELS); | ||
161 | i++, j++) | ||
162 | pdata->channel_irq[j] = pdata->pcidev->irq + i; | ||
163 | pdata->channel_irq_count = j; | ||
164 | |||
165 | pdata->per_channel_irq = 1; | ||
166 | pdata->channel_irq_mode = XGBE_IRQ_MODE_LEVEL; | ||
167 | } else { | ||
168 | pdata->ecc_irq = pdata->pcidev->irq; | ||
169 | pdata->i2c_irq = pdata->pcidev->irq; | ||
170 | pdata->an_irq = pdata->pcidev->irq; | ||
171 | } | ||
172 | |||
173 | if (netif_msg_probe(pdata)) | ||
174 | dev_dbg(pdata->dev, "MSI interrupts enabled\n"); | ||
175 | |||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | static int xgbe_config_msix(struct xgbe_prv_data *pdata) | ||
180 | { | ||
181 | unsigned int msix_count; | ||
182 | unsigned int i, j; | ||
183 | int ret; | ||
184 | |||
185 | msix_count = XGBE_MSIX_BASE_COUNT; | ||
186 | msix_count += max(pdata->rx_ring_count, | ||
187 | pdata->tx_ring_count); | ||
188 | |||
189 | pdata->msix_entries = devm_kcalloc(pdata->dev, msix_count, | ||
190 | sizeof(struct msix_entry), | ||
191 | GFP_KERNEL); | ||
192 | if (!pdata->msix_entries) | ||
193 | return -ENOMEM; | ||
194 | |||
195 | for (i = 0; i < msix_count; i++) | ||
196 | pdata->msix_entries[i].entry = i; | ||
197 | |||
198 | ret = pci_enable_msix_range(pdata->pcidev, pdata->msix_entries, | ||
199 | XGBE_MSIX_MIN_COUNT, msix_count); | ||
200 | if (ret < 0) { | ||
201 | dev_info(pdata->dev, "MSI-X enablement failed\n"); | ||
202 | devm_kfree(pdata->dev, pdata->msix_entries); | ||
203 | pdata->msix_entries = NULL; | ||
204 | return ret; | 139 | return ret; |
205 | } | 140 | } |
206 | 141 | ||
207 | pdata->irq_count = ret; | 142 | pdata->irq_count = ret; |
208 | 143 | ||
209 | pdata->dev_irq = pdata->msix_entries[0].vector; | 144 | pdata->dev_irq = pci_irq_vector(pdata->pcidev, 0); |
210 | pdata->ecc_irq = pdata->msix_entries[1].vector; | 145 | pdata->ecc_irq = pci_irq_vector(pdata->pcidev, 1); |
211 | pdata->i2c_irq = pdata->msix_entries[2].vector; | 146 | pdata->i2c_irq = pci_irq_vector(pdata->pcidev, 2); |
212 | pdata->an_irq = pdata->msix_entries[3].vector; | 147 | pdata->an_irq = pci_irq_vector(pdata->pcidev, 3); |
213 | 148 | ||
214 | for (i = XGBE_MSIX_BASE_COUNT, j = 0; i < ret; i++, j++) | 149 | for (i = XGBE_MSI_BASE_COUNT, j = 0; i < ret; i++, j++) |
215 | pdata->channel_irq[j] = pdata->msix_entries[i].vector; | 150 | pdata->channel_irq[j] = pci_irq_vector(pdata->pcidev, i); |
216 | pdata->channel_irq_count = j; | 151 | pdata->channel_irq_count = j; |
217 | 152 | ||
218 | pdata->per_channel_irq = 1; | 153 | pdata->per_channel_irq = 1; |
219 | pdata->channel_irq_mode = XGBE_IRQ_MODE_LEVEL; | 154 | pdata->channel_irq_mode = XGBE_IRQ_MODE_LEVEL; |
220 | 155 | ||
221 | if (netif_msg_probe(pdata)) | 156 | if (netif_msg_probe(pdata)) |
222 | dev_dbg(pdata->dev, "MSI-X interrupts enabled\n"); | 157 | dev_dbg(pdata->dev, "multi %s interrupts enabled\n", |
158 | pdata->pcidev->msix_enabled ? "MSI-X" : "MSI"); | ||
223 | 159 | ||
224 | return 0; | 160 | return 0; |
225 | } | 161 | } |
@@ -228,21 +164,28 @@ static int xgbe_config_irqs(struct xgbe_prv_data *pdata) | |||
228 | { | 164 | { |
229 | int ret; | 165 | int ret; |
230 | 166 | ||
231 | ret = xgbe_config_msix(pdata); | 167 | ret = xgbe_config_multi_msi(pdata); |
232 | if (!ret) | 168 | if (!ret) |
233 | goto out; | 169 | goto out; |
234 | 170 | ||
235 | ret = xgbe_config_msi(pdata); | 171 | ret = pci_alloc_irq_vectors(pdata->pcidev, 1, 1, |
236 | if (!ret) | 172 | PCI_IRQ_LEGACY | PCI_IRQ_MSI); |
237 | goto out; | 173 | if (ret < 0) { |
174 | dev_info(pdata->dev, "single IRQ enablement failed\n"); | ||
175 | return ret; | ||
176 | } | ||
238 | 177 | ||
239 | pdata->irq_count = 1; | 178 | pdata->irq_count = 1; |
240 | pdata->irq_shared = 1; | 179 | pdata->channel_irq_count = 1; |
180 | |||
181 | pdata->dev_irq = pci_irq_vector(pdata->pcidev, 0); | ||
182 | pdata->ecc_irq = pci_irq_vector(pdata->pcidev, 0); | ||
183 | pdata->i2c_irq = pci_irq_vector(pdata->pcidev, 0); | ||
184 | pdata->an_irq = pci_irq_vector(pdata->pcidev, 0); | ||
241 | 185 | ||
242 | pdata->dev_irq = pdata->pcidev->irq; | 186 | if (netif_msg_probe(pdata)) |
243 | pdata->ecc_irq = pdata->pcidev->irq; | 187 | dev_dbg(pdata->dev, "single %s interrupt enabled\n", |
244 | pdata->i2c_irq = pdata->pcidev->irq; | 188 | pdata->pcidev->msi_enabled ? "MSI" : "legacy"); |
245 | pdata->an_irq = pdata->pcidev->irq; | ||
246 | 189 | ||
247 | out: | 190 | out: |
248 | if (netif_msg_probe(pdata)) { | 191 | if (netif_msg_probe(pdata)) { |
@@ -412,12 +355,15 @@ static int xgbe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
412 | /* Configure the netdev resource */ | 355 | /* Configure the netdev resource */ |
413 | ret = xgbe_config_netdev(pdata); | 356 | ret = xgbe_config_netdev(pdata); |
414 | if (ret) | 357 | if (ret) |
415 | goto err_pci_enable; | 358 | goto err_irq_vectors; |
416 | 359 | ||
417 | netdev_notice(pdata->netdev, "net device enabled\n"); | 360 | netdev_notice(pdata->netdev, "net device enabled\n"); |
418 | 361 | ||
419 | return 0; | 362 | return 0; |
420 | 363 | ||
364 | err_irq_vectors: | ||
365 | pci_free_irq_vectors(pdata->pcidev); | ||
366 | |||
421 | err_pci_enable: | 367 | err_pci_enable: |
422 | xgbe_free_pdata(pdata); | 368 | xgbe_free_pdata(pdata); |
423 | 369 | ||
@@ -433,6 +379,8 @@ static void xgbe_pci_remove(struct pci_dev *pdev) | |||
433 | 379 | ||
434 | xgbe_deconfig_netdev(pdata); | 380 | xgbe_deconfig_netdev(pdata); |
435 | 381 | ||
382 | pci_free_irq_vectors(pdata->pcidev); | ||
383 | |||
436 | xgbe_free_pdata(pdata); | 384 | xgbe_free_pdata(pdata); |
437 | } | 385 | } |
438 | 386 | ||
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h index f52a9bd05bac..99f1c87df818 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe.h | |||
@@ -211,9 +211,9 @@ | |||
211 | #define XGBE_MAC_PROP_OFFSET 0x1d000 | 211 | #define XGBE_MAC_PROP_OFFSET 0x1d000 |
212 | #define XGBE_I2C_CTRL_OFFSET 0x1e000 | 212 | #define XGBE_I2C_CTRL_OFFSET 0x1e000 |
213 | 213 | ||
214 | /* PCI MSIx support */ | 214 | /* PCI MSI/MSIx support */ |
215 | #define XGBE_MSIX_BASE_COUNT 4 | 215 | #define XGBE_MSI_BASE_COUNT 4 |
216 | #define XGBE_MSIX_MIN_COUNT (XGBE_MSIX_BASE_COUNT + 1) | 216 | #define XGBE_MSI_MIN_COUNT (XGBE_MSI_BASE_COUNT + 1) |
217 | 217 | ||
218 | /* PCI clock frequencies */ | 218 | /* PCI clock frequencies */ |
219 | #define XGBE_V2_DMA_CLOCK_FREQ 500000000 /* 500 MHz */ | 219 | #define XGBE_V2_DMA_CLOCK_FREQ 500000000 /* 500 MHz */ |
@@ -980,14 +980,12 @@ struct xgbe_prv_data { | |||
980 | unsigned int desc_ded_count; | 980 | unsigned int desc_ded_count; |
981 | unsigned int desc_sec_count; | 981 | unsigned int desc_sec_count; |
982 | 982 | ||
983 | struct msix_entry *msix_entries; | ||
984 | int dev_irq; | 983 | int dev_irq; |
985 | int ecc_irq; | 984 | int ecc_irq; |
986 | int i2c_irq; | 985 | int i2c_irq; |
987 | int channel_irq[XGBE_MAX_DMA_CHANNELS]; | 986 | int channel_irq[XGBE_MAX_DMA_CHANNELS]; |
988 | 987 | ||
989 | unsigned int per_channel_irq; | 988 | unsigned int per_channel_irq; |
990 | unsigned int irq_shared; | ||
991 | unsigned int irq_count; | 989 | unsigned int irq_count; |
992 | unsigned int channel_irq_count; | 990 | unsigned int channel_irq_count; |
993 | unsigned int channel_irq_mode; | 991 | unsigned int channel_irq_mode; |