@@ -2176,17 +2176,82 @@ static void cleanup_debugfs(struct adapter *adapter)
2176
2176
/* nothing to do */
2177
2177
}
2178
2178
2179
+ /* Figure out how many Ports and Queue Sets we can support. This depends on
2180
+ * knowing our Virtual Function Resources and may be called a second time if
2181
+ * we fall back from MSI-X to MSI Interrupt Mode.
2182
+ */
2183
+ static void size_nports_qsets (struct adapter * adapter )
2184
+ {
2185
+ struct vf_resources * vfres = & adapter -> params .vfres ;
2186
+ unsigned int ethqsets , pmask_nports ;
2187
+
2188
+ /* The number of "ports" which we support is equal to the number of
2189
+ * Virtual Interfaces with which we've been provisioned.
2190
+ */
2191
+ adapter -> params .nports = vfres -> nvi ;
2192
+ if (adapter -> params .nports > MAX_NPORTS ) {
2193
+ dev_warn (adapter -> pdev_dev , "only using %d of %d maximum"
2194
+ " allowed virtual interfaces\n" , MAX_NPORTS ,
2195
+ adapter -> params .nports );
2196
+ adapter -> params .nports = MAX_NPORTS ;
2197
+ }
2198
+
2199
+ /* We may have been provisioned with more VIs than the number of
2200
+ * ports we're allowed to access (our Port Access Rights Mask).
2201
+ * This is obviously a configuration conflict but we don't want to
2202
+ * crash the kernel or anything silly just because of that.
2203
+ */
2204
+ pmask_nports = hweight32 (adapter -> params .vfres .pmask );
2205
+ if (pmask_nports < adapter -> params .nports ) {
2206
+ dev_warn (adapter -> pdev_dev , "only using %d of %d provissioned"
2207
+ " virtual interfaces; limited by Port Access Rights"
2208
+ " mask %#x\n" , pmask_nports , adapter -> params .nports ,
2209
+ adapter -> params .vfres .pmask );
2210
+ adapter -> params .nports = pmask_nports ;
2211
+ }
2212
+
2213
+ /* We need to reserve an Ingress Queue for the Asynchronous Firmware
2214
+ * Event Queue. And if we're using MSI Interrupts, we'll also need to
2215
+ * reserve an Ingress Queue for a Forwarded Interrupts.
2216
+ *
2217
+ * The rest of the FL/Intr-capable ingress queues will be matched up
2218
+ * one-for-one with Ethernet/Control egress queues in order to form
2219
+ * "Queue Sets" which will be aportioned between the "ports". For
2220
+ * each Queue Set, we'll need the ability to allocate two Egress
2221
+ * Contexts -- one for the Ingress Queue Free List and one for the TX
2222
+ * Ethernet Queue.
2223
+ *
2224
+ * Note that even if we're currently configured to use MSI-X
2225
+ * Interrupts (module variable msi == MSI_MSIX) we may get downgraded
2226
+ * to MSI Interrupts if we can't get enough MSI-X Interrupts. If that
2227
+ * happens we'll need to adjust things later.
2228
+ */
2229
+ ethqsets = vfres -> niqflint - 1 - (msi == MSI_MSI );
2230
+ if (vfres -> nethctrl != ethqsets )
2231
+ ethqsets = min (vfres -> nethctrl , ethqsets );
2232
+ if (vfres -> neq < ethqsets * 2 )
2233
+ ethqsets = vfres -> neq /2 ;
2234
+ if (ethqsets > MAX_ETH_QSETS )
2235
+ ethqsets = MAX_ETH_QSETS ;
2236
+ adapter -> sge .max_ethqsets = ethqsets ;
2237
+
2238
+ if (adapter -> sge .max_ethqsets < adapter -> params .nports ) {
2239
+ dev_warn (adapter -> pdev_dev , "only using %d of %d available"
2240
+ " virtual interfaces (too few Queue Sets)\n" ,
2241
+ adapter -> sge .max_ethqsets , adapter -> params .nports );
2242
+ adapter -> params .nports = adapter -> sge .max_ethqsets ;
2243
+ }
2244
+ }
2245
+
2179
2246
/*
2180
2247
* Perform early "adapter" initialization. This is where we discover what
2181
2248
* adapter parameters we're going to be using and initialize basic adapter
2182
2249
* hardware support.
2183
2250
*/
2184
2251
static int adap_init0 (struct adapter * adapter )
2185
2252
{
2186
- struct vf_resources * vfres = & adapter -> params .vfres ;
2187
2253
struct sge_params * sge_params = & adapter -> params .sge ;
2188
2254
struct sge * s = & adapter -> sge ;
2189
- unsigned int ethqsets ;
2190
2255
int err ;
2191
2256
u32 param , val = 0 ;
2192
2257
@@ -2295,69 +2360,18 @@ static int adap_init0(struct adapter *adapter)
2295
2360
return err ;
2296
2361
}
2297
2362
2298
- /*
2299
- * The number of "ports" which we support is equal to the number of
2300
- * Virtual Interfaces with which we've been provisioned.
2301
- */
2302
- adapter -> params .nports = vfres -> nvi ;
2303
- if (adapter -> params .nports > MAX_NPORTS ) {
2304
- dev_warn (adapter -> pdev_dev , "only using %d of %d allowed"
2305
- " virtual interfaces\n" , MAX_NPORTS ,
2306
- adapter -> params .nports );
2307
- adapter -> params .nports = MAX_NPORTS ;
2308
- }
2309
-
2310
- /*
2311
- * We need to reserve a number of the ingress queues with Free List
2312
- * and Interrupt capabilities for special interrupt purposes (like
2313
- * asynchronous firmware messages, or forwarded interrupts if we're
2314
- * using MSI). The rest of the FL/Intr-capable ingress queues will be
2315
- * matched up one-for-one with Ethernet/Control egress queues in order
2316
- * to form "Queue Sets" which will be aportioned between the "ports".
2317
- * For each Queue Set, we'll need the ability to allocate two Egress
2318
- * Contexts -- one for the Ingress Queue Free List and one for the TX
2319
- * Ethernet Queue.
2320
- */
2321
- ethqsets = vfres -> niqflint - INGQ_EXTRAS ;
2322
- if (vfres -> nethctrl != ethqsets ) {
2323
- dev_warn (adapter -> pdev_dev , "unequal number of [available]"
2324
- " ingress/egress queues (%d/%d); using minimum for"
2325
- " number of Queue Sets\n" , ethqsets , vfres -> nethctrl );
2326
- ethqsets = min (vfres -> nethctrl , ethqsets );
2327
- }
2328
- if (vfres -> neq < ethqsets * 2 ) {
2329
- dev_warn (adapter -> pdev_dev , "Not enough Egress Contexts (%d)"
2330
- " to support Queue Sets (%d); reducing allowed Queue"
2331
- " Sets\n" , vfres -> neq , ethqsets );
2332
- ethqsets = vfres -> neq /2 ;
2333
- }
2334
- if (ethqsets > MAX_ETH_QSETS ) {
2335
- dev_warn (adapter -> pdev_dev , "only using %d of %d allowed Queue"
2336
- " Sets\n" , MAX_ETH_QSETS , adapter -> sge .max_ethqsets );
2337
- ethqsets = MAX_ETH_QSETS ;
2338
- }
2339
- if (vfres -> niq != 0 || vfres -> neq > ethqsets * 2 ) {
2340
- dev_warn (adapter -> pdev_dev , "unused resources niq/neq (%d/%d)"
2341
- " ignored\n" , vfres -> niq , vfres -> neq - ethqsets * 2 );
2342
- }
2343
- adapter -> sge .max_ethqsets = ethqsets ;
2344
-
2345
- /*
2346
- * Check for various parameter sanity issues. Most checks simply
2347
- * result in us using fewer resources than our provissioning but we
2348
- * do need at least one "port" with which to work ...
2349
- */
2350
- if (adapter -> sge .max_ethqsets < adapter -> params .nports ) {
2351
- dev_warn (adapter -> pdev_dev , "only using %d of %d available"
2352
- " virtual interfaces (too few Queue Sets)\n" ,
2353
- adapter -> sge .max_ethqsets , adapter -> params .nports );
2354
- adapter -> params .nports = adapter -> sge .max_ethqsets ;
2355
- }
2356
- if (adapter -> params .nports == 0 ) {
2363
+ /* Check for various parameter sanity issues */
2364
+ if (adapter -> params .vfres .nvi == 0 ) {
2357
2365
dev_err (adapter -> pdev_dev , "no virtual interfaces configured/"
2358
2366
"usable!\n" );
2359
2367
return - EINVAL ;
2360
2368
}
2369
+
2370
+ /* Initialize nports and max_ethqsets now that we have our Virtual
2371
+ * Function Resources.
2372
+ */
2373
+ size_nports_qsets (adapter );
2374
+
2361
2375
return 0 ;
2362
2376
}
2363
2377
@@ -2779,16 +2793,32 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev,
2779
2793
if (msi == MSI_MSIX && enable_msix (adapter ) == 0 )
2780
2794
adapter -> flags |= USING_MSIX ;
2781
2795
else {
2796
+ if (msi == MSI_MSIX ) {
2797
+ dev_info (adapter -> pdev_dev ,
2798
+ "Unable to use MSI-X Interrupts; falling "
2799
+ "back to MSI Interrupts\n" );
2800
+
2801
+ /* We're going to need a Forwarded Interrupt Queue so
2802
+ * that may cut into how many Queue Sets we can
2803
+ * support.
2804
+ */
2805
+ msi = MSI_MSI ;
2806
+ size_nports_qsets (adapter );
2807
+ }
2782
2808
err = pci_enable_msi (pdev );
2783
2809
if (err ) {
2784
- dev_err (& pdev -> dev , "Unable to allocate %s interrupts;"
2785
- " err=%d\n" ,
2786
- msi == MSI_MSIX ? "MSI-X or MSI" : "MSI" , err );
2810
+ dev_err (& pdev -> dev , "Unable to allocate MSI Interrupts;"
2811
+ " err=%d\n" , err );
2787
2812
goto err_free_dev ;
2788
2813
}
2789
2814
adapter -> flags |= USING_MSI ;
2790
2815
}
2791
2816
2817
+ /* Now that we know how many "ports" we have and what interrupt
2818
+ * mechanism we're going to use, we can configure our queue resources.
2819
+ */
2820
+ cfg_queues (adapter );
2821
+
2792
2822
/*
2793
2823
* The "card" is now ready to go. If any errors occur during device
2794
2824
* registration we do not fail the whole "card" but rather proceed
@@ -2828,13 +2858,6 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev,
2828
2858
setup_debugfs (adapter );
2829
2859
}
2830
2860
2831
- /*
2832
- * Now that we know how many "ports" we have and what their types are,
2833
- * and how many Queue Sets we can support, we can configure our queue
2834
- * resources.
2835
- */
2836
- cfg_queues (adapter );
2837
-
2838
2861
/*
2839
2862
* Print a short notice on the existence and configuration of the new
2840
2863
* VF network device ...
0 commit comments