Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

emx: Use MSI, if device supports it

  • Loading branch information...
commit 704b62870b417f0401ec5576113c809065f70359 1 parent 9783883
authored December 27, 2011
42  sys/dev/netif/emx/if_emx.c
@@ -276,12 +276,13 @@ DRIVER_MODULE(if_emx, pci, emx_driver, emx_devclass, NULL, NULL);
276 276
 static int	emx_int_throttle_ceil = EMX_DEFAULT_ITR;
277 277
 static int	emx_rxd = EMX_DEFAULT_RXD;
278 278
 static int	emx_txd = EMX_DEFAULT_TXD;
279  
-static int	emx_smart_pwr_down = FALSE;
  279
+static int	emx_smart_pwr_down = 0;
280 280
 
281 281
 /* Controls whether promiscuous also shows bad packets */
282 282
 static int	emx_debug_sbp = FALSE;
283 283
 
284  
-static int	emx_82573_workaround = TRUE;
  284
+static int	emx_82573_workaround = 1;
  285
+static int	emx_msi_enable = 1;
285 286
 
286 287
 TUNABLE_INT("hw.emx.int_throttle_ceil", &emx_int_throttle_ceil);
287 288
 TUNABLE_INT("hw.emx.rxd", &emx_rxd);
@@ -289,6 +290,7 @@ TUNABLE_INT("hw.emx.txd", &emx_txd);
289 290
 TUNABLE_INT("hw.emx.smart_pwr_down", &emx_smart_pwr_down);
290 291
 TUNABLE_INT("hw.emx.sbp", &emx_debug_sbp);
291 292
 TUNABLE_INT("hw.emx.82573_workaround", &emx_82573_workaround);
  293
+TUNABLE_INT("hw.emx.msi.enable", &emx_msi_enable);
292 294
 
293 295
 /* Global used in WOL setup with multiport cards */
294 296
 static int	emx_global_quad_port_a = 0;
@@ -398,8 +400,10 @@ emx_attach(device_t dev)
398 400
 {
399 401
 	struct emx_softc *sc = device_get_softc(dev);
400 402
 	struct ifnet *ifp = &sc->arpcom.ac_if;
401  
-	int error = 0, i;
  403
+	int error = 0, i, msi_enable;
  404
+	u_int intr_flags;
402 405
 	uint16_t eeprom_data, device_id, apme_mask;
  406
+	char env[64];
403 407
 
404 408
 	lwkt_serialize_init(&sc->main_serialize);
405 409
 	lwkt_serialize_init(&sc->tx_serialize);
@@ -452,12 +456,37 @@ emx_attach(device_t dev)
452 456
 	/*
453 457
 	 * Allocate interrupt
454 458
 	 */
  459
+	msi_enable = emx_msi_enable;
  460
+	ksnprintf(env, sizeof(env), "hw.%s.msi.enable",
  461
+	    device_get_nameunit(dev));
  462
+	kgetenv_int(env, &msi_enable);
  463
+
455 464
 	sc->intr_rid = 0;
  465
+	sc->intr_type = EMX_INTR_TYPE_LEGACY;
  466
+	intr_flags = RF_SHAREABLE | RF_ACTIVE;
  467
+
  468
+	if (msi_enable) {
  469
+		int cpu = -1;
  470
+
  471
+		ksnprintf(env, sizeof(env), "hw.%s.msi.cpu",
  472
+		    device_get_nameunit(dev));
  473
+		kgetenv_int(env, &cpu);
  474
+		if (cpu >= ncpus)
  475
+			cpu = ncpus - 1;
  476
+
  477
+		if (pci_alloc_msi(dev, &sc->intr_rid, 1, cpu) == 0) {
  478
+			intr_flags &= ~RF_SHAREABLE;
  479
+			sc->intr_type = EMX_INTR_TYPE_MSI;
  480
+		}
  481
+	}
  482
+
456 483
 	sc->intr_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->intr_rid,
457  
-					      RF_SHAREABLE | RF_ACTIVE);
  484
+	    intr_flags);
458 485
 	if (sc->intr_res == NULL) {
459 486
 		device_printf(dev, "Unable to allocate bus resource: "
460 487
 		    "interrupt\n");
  488
+		if (sc->intr_rid != 0)
  489
+			pci_release_msi(dev);
461 490
 		error = ENXIO;
462 491
 		goto fail;
463 492
 	}
@@ -686,7 +715,7 @@ emx_attach(device_t dev)
686 715
 		goto fail;
687 716
 	}
688 717
 
689  
-	ifp->if_cpuid = ithread_cpuid(rman_get_start(sc->intr_res));
  718
+	ifp->if_cpuid = rman_get_cpuid(sc->intr_res);
690 719
 	KKASSERT(ifp->if_cpuid >= 0 && ifp->if_cpuid < ncpus);
691 720
 	return (0);
692 721
 fail:
@@ -732,6 +761,9 @@ emx_detach(device_t dev)
732 761
 				     sc->intr_res);
733 762
 	}
734 763
 
  764
+	if (sc->intr_type == EMX_INTR_TYPE_MSI)
  765
+		pci_release_msi(dev);
  766
+
735 767
 	if (sc->memory != NULL) {
736 768
 		bus_release_resource(dev, SYS_RES_MEMORY, sc->memory_rid,
737 769
 				     sc->memory);
4  sys/dev/netif/emx/if_emx.h
@@ -252,6 +252,7 @@ struct emx_softc {
252 252
 	struct resource		*intr_res;
253 253
 	void			*intr_tag;
254 254
 	int			intr_rid;
  255
+	int			intr_type;
255 256
 
256 257
 	struct ifmedia		media;
257 258
 	struct callout		timer;
@@ -376,6 +377,9 @@ struct emx_softc {
376 377
 	struct e1000_hw_stats	stats;
377 378
 };
378 379
 
  380
+#define EMX_INTR_TYPE_LEGACY	0
  381
+#define EMX_INTR_TYPE_MSI	1
  382
+
379 383
 struct emx_txbuf {
380 384
 	struct mbuf	*m_head;
381 385
 	bus_dmamap_t	map;

0 notes on commit 704b628

Please sign in to comment.
Something went wrong with that request. Please try again.