svn commit: r209611 - head/sys/dev/e1000

Fabien Thomas fabien.thomas at netasq.com
Wed Jun 30 20:37:09 UTC 2010


great!
have you some plan to do it on ixgbe too ?

fabien

On 30 juin 2010, at 19:26, Jack F Vogel wrote:

> Author: jfv
> Date: Wed Jun 30 17:26:47 2010
> New Revision: 209611
> URL: http://svn.freebsd.org/changeset/base/209611
> 
> Log:
>  SR-IOV support added to igb
> 
>  What this provides is support for the 'virtual function'
>  interface that a FreeBSD VM may be assigned from a host
>  like KVM on Linux, or newer versions of Xen with such
>  support.
> 
>  When the guest is set up with the capability, a special
>  limited function 82576 PCI device is present in its virtual
>  PCI space, so with this driver installed in the guest that
>  device will be detected and function nearly like the bare
>  metal, as it were.
> 
>  The interface is only allowed a single queue in this configuration
>  however initial performance tests have looked very good.
> 
>  Enjoy!!
> 
> Modified:
>  head/sys/dev/e1000/if_igb.c
>  head/sys/dev/e1000/if_igb.h
> 
> Modified: head/sys/dev/e1000/if_igb.c
> ==============================================================================
> --- head/sys/dev/e1000/if_igb.c	Wed Jun 30 17:20:33 2010	(r209610)
> +++ head/sys/dev/e1000/if_igb.c	Wed Jun 30 17:26:47 2010	(r209611)
> @@ -99,7 +99,7 @@ int	igb_display_debug_stats = 0;
> /*********************************************************************
>  *  Driver version:
>  *********************************************************************/
> -char igb_driver_version[] = "version - 1.9.6";
> +char igb_driver_version[] = "version - 2.0.1";
> 
> 
> /*********************************************************************
> @@ -128,6 +128,7 @@ static igb_vendor_info_t igb_vendor_info
> 						PCI_ANY_ID, PCI_ANY_ID, 0},
> 	{ 0x8086, E1000_DEV_ID_82576_QUAD_COPPER,
> 						PCI_ANY_ID, PCI_ANY_ID, 0},
> +	{ 0x8086, E1000_DEV_ID_82576_VF,	PCI_ANY_ID, PCI_ANY_ID, 0},
> 	{ 0x8086, E1000_DEV_ID_82580_COPPER,	PCI_ANY_ID, PCI_ANY_ID, 0},
> 	{ 0x8086, E1000_DEV_ID_82580_FIBER,	PCI_ANY_ID, PCI_ANY_ID, 0},
> 	{ 0x8086, E1000_DEV_ID_82580_SERDES,	PCI_ANY_ID, PCI_ANY_ID, 0},
> @@ -226,7 +227,11 @@ static void	igb_dma_free(struct adapter 
> static int	igb_sysctl_nvm_info(SYSCTL_HANDLER_ARGS);
> static void	igb_print_nvm_info(struct adapter *);
> static int 	igb_is_valid_ether_addr(u8 *);
> -static void     igb_add_hw_stats(struct adapter *adapter);
> +static void     igb_add_hw_stats(struct adapter *);
> +
> +static void	igb_vf_init_stats(struct adapter *);
> +static void	igb_update_vf_stats_counters(struct adapter *);
> +
> /* Management and WOL Support */
> static void	igb_init_manageability(struct adapter *);
> static void	igb_release_manageability(struct adapter *);
> @@ -494,6 +499,17 @@ igb_attach(device_t dev)
> 		goto err_pci;
> 	}
> 
> +	/* Allocate the appropriate stats memory */
> +	if (adapter->hw.mac.type == e1000_vfadapt) {
> +		adapter->stats =
> +		    (struct e1000_vf_stats *)malloc(sizeof \
> +		    (struct e1000_vf_stats), M_DEVBUF, M_NOWAIT | M_ZERO);
> +		igb_vf_init_stats(adapter);
> +	} else
> +		adapter->stats =
> +		    (struct e1000_hw_stats *)malloc(sizeof \
> +		    (struct e1000_hw_stats), M_DEVBUF, M_NOWAIT | M_ZERO);
> +
> 	/*
> 	** Start from a known state, this is
> 	** important in reading the nvm and
> @@ -1788,30 +1804,39 @@ static void
> igb_set_promisc(struct adapter *adapter)
> {
> 	struct ifnet	*ifp = adapter->ifp;
> -	uint32_t	reg_rctl;
> +	struct e1000_hw *hw = &adapter->hw;
> +	u32		reg;
> 
> -	reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
> +	if (hw->mac.type == e1000_vfadapt) {
> +		e1000_promisc_set_vf(hw, e1000_promisc_enabled);
> +		return;
> +	}
> 
> +	reg = E1000_READ_REG(hw, E1000_RCTL);
> 	if (ifp->if_flags & IFF_PROMISC) {
> -		reg_rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
> -		E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl);
> +		reg |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
> +		E1000_WRITE_REG(hw, E1000_RCTL, reg);
> 	} else if (ifp->if_flags & IFF_ALLMULTI) {
> -		reg_rctl |= E1000_RCTL_MPE;
> -		reg_rctl &= ~E1000_RCTL_UPE;
> -		E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl);
> +		reg |= E1000_RCTL_MPE;
> +		reg &= ~E1000_RCTL_UPE;
> +		E1000_WRITE_REG(hw, E1000_RCTL, reg);
> 	}
> }
> 
> static void
> igb_disable_promisc(struct adapter *adapter)
> {
> -	uint32_t	reg_rctl;
> -
> -	reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
> +	struct e1000_hw *hw = &adapter->hw;
> +	u32		reg;
> 
> -	reg_rctl &=  (~E1000_RCTL_UPE);
> -	reg_rctl &=  (~E1000_RCTL_MPE);
> -	E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl);
> +	if (hw->mac.type == e1000_vfadapt) {
> +		e1000_promisc_set_vf(hw, e1000_promisc_disabled);
> +		return;
> +	}
> +	reg = E1000_READ_REG(hw, E1000_RCTL);
> +	reg &=  (~E1000_RCTL_UPE);
> +	reg &=  (~E1000_RCTL_MPE);
> +	E1000_WRITE_REG(hw, E1000_RCTL, reg);
> }
> 
> 
> @@ -1939,8 +1964,12 @@ igb_update_link_status(struct adapter *a
>                 e1000_check_for_link(hw);
>                 link_check = adapter->hw.mac.serdes_has_link;
>                 break;
> -        default:
> +	/* VF device is type_unknown */
>         case e1000_media_type_unknown:
> +                e1000_check_for_link(hw);
> +		link_check = !hw->mac.get_link_status;
> +		/* Fall thru */
> +        default:
>                 break;
>         }
> 
> @@ -2025,8 +2054,8 @@ igb_identify_hardware(struct adapter *ad
> 	adapter->hw.bus.pci_cmd_word = pci_read_config(dev, PCIR_COMMAND, 2);
> 	if (!((adapter->hw.bus.pci_cmd_word & PCIM_CMD_BUSMASTEREN) &&
> 	    (adapter->hw.bus.pci_cmd_word & PCIM_CMD_MEMEN))) {
> -		device_printf(dev, "Memory Access and/or Bus Master bits "
> -		    "were not set!\n");
> +		INIT_DEBUGOUT("Memory Access and/or Bus Master "
> +		    "bits were not set!\n");
> 		adapter->hw.bus.pci_cmd_word |=
> 		(PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN);
> 		pci_write_config(dev, PCIR_COMMAND,
> @@ -2041,12 +2070,6 @@ igb_identify_hardware(struct adapter *ad
> 	    pci_read_config(dev, PCIR_SUBVEND_0, 2);
> 	adapter->hw.subsystem_device_id =
> 	    pci_read_config(dev, PCIR_SUBDEV_0, 2);
> -
> -	/* Do Shared Code Init and Setup */
> -	if (e1000_set_mac_type(&adapter->hw)) {
> -		device_printf(dev, "Setup init failure\n");
> -		return;
> -	}
> }
> 
> static int
> @@ -2225,6 +2248,7 @@ igb_configure_queues(struct adapter *ada
> 	/* Turn on MSIX */
> 	switch (adapter->hw.mac.type) {
> 	case e1000_82580:
> +	case e1000_vfadapt:
> 		/* RX entries */
> 		for (int i = 0; i < adapter->num_queues; i++) {
> 			u32 index = i >> 1;
> @@ -2446,6 +2470,10 @@ igb_setup_msix(struct adapter *adapter)
> 	if ((adapter->hw.mac.type == e1000_82575) && (queues > 4))
> 		queues = 4;
> 
> +	/* Limit the VF adapter to one queues */
> +	if ((adapter->hw.mac.type == e1000_vfadapt) && (queues > 2))
> +		queues = 1;
> +
> 	/*
> 	** One vector (RX/TX pair) per queue
> 	** plus an additional for Link interrupt
> @@ -2503,6 +2531,7 @@ igb_reset(struct adapter *adapter)
> 		pba = E1000_PBA_32K;
> 		break;
> 	case e1000_82576:
> +	case e1000_vfadapt:
> 		pba = E1000_PBA_64K;
> 		break;
> 	case e1000_82580:
> @@ -3074,7 +3103,8 @@ igb_initialize_transmit_units(struct ada
> 	struct e1000_hw *hw = &adapter->hw;
> 	u32		tctl, txdctl;
> 
> -	 INIT_DEBUGOUT("igb_initialize_transmit_units: begin");
> +	INIT_DEBUGOUT("igb_initialize_transmit_units: begin");
> +	tctl = txdctl = 0;
> 
> 	/* Setup the Tx Descriptor Rings */
> 	for (int i = 0; i < adapter->num_queues; i++, txr++) {
> @@ -3097,7 +3127,6 @@ igb_initialize_transmit_units(struct ada
> 
> 		txr->watchdog_check = FALSE;
> 
> -		txdctl = E1000_READ_REG(hw, E1000_TXDCTL(i));
> 		txdctl |= IGB_TX_PTHRESH;
> 		txdctl |= IGB_TX_HTHRESH << 8;
> 		txdctl |= IGB_TX_WTHRESH << 16;
> @@ -3105,6 +3134,9 @@ igb_initialize_transmit_units(struct ada
> 		E1000_WRITE_REG(hw, E1000_TXDCTL(i), txdctl);
> 	}
> 
> +	if (adapter->hw.mac.type == e1000_vfadapt)
> +		return;
> +
> 	/* Program the Transmit Control Register */
> 	tctl = E1000_READ_REG(hw, E1000_TCTL);
> 	tctl &= ~E1000_TCTL_CT;
> @@ -3505,7 +3537,7 @@ igb_txeof(struct tx_ring *txr)
> 		/* All clean, turn off the watchdog */
>                 if (txr->tx_avail == adapter->num_tx_desc) {
> 			txr->watchdog_check = FALSE;
> -			return FALSE;
> +			return (FALSE);
> 		}
>         }
> 
> @@ -4504,23 +4536,32 @@ igb_setup_vlan_hw_support(struct adapter
> 	** we need to repopulate it now.
> 	*/
> 	for (int i = 0; i < IGB_VFTA_SIZE; i++)
> -                if (igb_shadow_vfta[i] != 0)
> -			E1000_WRITE_REG_ARRAY(hw, E1000_VFTA,
> -                            i, igb_shadow_vfta[i]);
> -
> -	reg = E1000_READ_REG(hw, E1000_CTRL);
> -	reg |= E1000_CTRL_VME;
> -	E1000_WRITE_REG(hw, E1000_CTRL, reg);
> -
> -	/* Enable the Filter Table */
> -	reg = E1000_READ_REG(hw, E1000_RCTL);
> -	reg &= ~E1000_RCTL_CFIEN;
> -	reg |= E1000_RCTL_VFE;
> -	E1000_WRITE_REG(hw, E1000_RCTL, reg);
> +                if (igb_shadow_vfta[i] != 0) {
> +			if (hw->mac.type == e1000_vfadapt)
> +				e1000_vfta_set_vf(hw, igb_shadow_vfta[i], TRUE);
> +			else
> +				E1000_WRITE_REG_ARRAY(hw, E1000_VFTA,
> +                           	 i, igb_shadow_vfta[i]);
> +		}
> 
> -	/* Update the frame size */
> -	E1000_WRITE_REG(&adapter->hw, E1000_RLPML,
> -	    adapter->max_frame_size + VLAN_TAG_SIZE);
> +	if (hw->mac.type == e1000_vfadapt)
> +		e1000_rlpml_set_vf(hw,
> +		    adapter->max_frame_size + VLAN_TAG_SIZE);
> +	else {
> +		reg = E1000_READ_REG(hw, E1000_CTRL);
> +		reg |= E1000_CTRL_VME;
> +		E1000_WRITE_REG(hw, E1000_CTRL, reg);
> +
> +		/* Enable the Filter Table */
> +		reg = E1000_READ_REG(hw, E1000_RCTL);
> +		reg &= ~E1000_RCTL_CFIEN;
> +		reg |= E1000_RCTL_VFE;
> +		E1000_WRITE_REG(hw, E1000_RCTL, reg);
> +
> +		/* Update the frame size */
> +		E1000_WRITE_REG(&adapter->hw, E1000_RLPML,
> +		    adapter->max_frame_size + VLAN_TAG_SIZE);
> +	}
> }
> 
> static void
> @@ -4610,6 +4651,9 @@ igb_get_hw_control(struct adapter *adapt
> {
> 	u32 ctrl_ext;
> 
> +	if (adapter->hw.mac.type == e1000_vfadapt)
> +		return;
> +
> 	/* Let firmware know the driver has taken over */
> 	ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT);
> 	E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT,
> @@ -4627,6 +4671,9 @@ igb_release_hw_control(struct adapter *a
> {
> 	u32 ctrl_ext;
> 
> +	if (adapter->hw.mac.type == e1000_vfadapt)
> +		return;
> +
> 	/* Let firmware taken over control of h/w */
> 	ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT);
> 	E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT,
> @@ -4694,138 +4741,190 @@ igb_led_func(void *arg, int onoff)
> static void
> igb_update_stats_counters(struct adapter *adapter)
> {
> -	struct ifnet   *ifp;
> +	struct ifnet		*ifp;
> +        struct e1000_hw		*hw = &adapter->hw;
> +	struct e1000_hw_stats	*stats;
> 
> -	if (adapter->hw.phy.media_type == e1000_media_type_copper ||
> -	   (E1000_READ_REG(&adapter->hw, E1000_STATUS) & E1000_STATUS_LU)) {
> -		adapter->stats.symerrs +=
> -		    E1000_READ_REG(&adapter->hw, E1000_SYMERRS);
> -		adapter->stats.sec +=
> -		    E1000_READ_REG(&adapter->hw, E1000_SEC);
> -	}
> -	adapter->stats.crcerrs += E1000_READ_REG(&adapter->hw, E1000_CRCERRS);
> -	adapter->stats.mpc += E1000_READ_REG(&adapter->hw, E1000_MPC);
> -	adapter->stats.scc += E1000_READ_REG(&adapter->hw, E1000_SCC);
> -	adapter->stats.ecol += E1000_READ_REG(&adapter->hw, E1000_ECOL);
> -
> -	adapter->stats.mcc += E1000_READ_REG(&adapter->hw, E1000_MCC);
> -	adapter->stats.latecol += E1000_READ_REG(&adapter->hw, E1000_LATECOL);
> -	adapter->stats.colc += E1000_READ_REG(&adapter->hw, E1000_COLC);
> -	adapter->stats.dc += E1000_READ_REG(&adapter->hw, E1000_DC);
> -	adapter->stats.rlec += E1000_READ_REG(&adapter->hw, E1000_RLEC);
> -	adapter->stats.xonrxc += E1000_READ_REG(&adapter->hw, E1000_XONRXC);
> -	adapter->stats.xontxc += E1000_READ_REG(&adapter->hw, E1000_XONTXC);
> -	adapter->stats.xoffrxc += E1000_READ_REG(&adapter->hw, E1000_XOFFRXC);
> -	adapter->stats.xofftxc += E1000_READ_REG(&adapter->hw, E1000_XOFFTXC);
> -	adapter->stats.fcruc += E1000_READ_REG(&adapter->hw, E1000_FCRUC);
> -	adapter->stats.prc64 += E1000_READ_REG(&adapter->hw, E1000_PRC64);
> -	adapter->stats.prc127 += E1000_READ_REG(&adapter->hw, E1000_PRC127);
> -	adapter->stats.prc255 += E1000_READ_REG(&adapter->hw, E1000_PRC255);
> -	adapter->stats.prc511 += E1000_READ_REG(&adapter->hw, E1000_PRC511);
> -	adapter->stats.prc1023 += E1000_READ_REG(&adapter->hw, E1000_PRC1023);
> -	adapter->stats.prc1522 += E1000_READ_REG(&adapter->hw, E1000_PRC1522);
> -	adapter->stats.gprc += E1000_READ_REG(&adapter->hw, E1000_GPRC);
> -	adapter->stats.bprc += E1000_READ_REG(&adapter->hw, E1000_BPRC);
> -	adapter->stats.mprc += E1000_READ_REG(&adapter->hw, E1000_MPRC);
> -	adapter->stats.gptc += E1000_READ_REG(&adapter->hw, E1000_GPTC);
> +	/* 
> +	** The virtual function adapter has only a
> +	** small controlled set of stats, do only 
> +	** those and return.
> +	*/
> +	if (adapter->hw.mac.type == e1000_vfadapt) {
> +		igb_update_vf_stats_counters(adapter);
> +		return;
> +	}
> +
> +	stats = (struct e1000_hw_stats	*)adapter->stats;
> +
> +	if(adapter->hw.phy.media_type == e1000_media_type_copper ||
> +	   (E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_LU)) {
> +		stats->symerrs +=
> +		    E1000_READ_REG(hw,E1000_SYMERRS);
> +		stats->sec += E1000_READ_REG(hw, E1000_SEC);
> +	}
> +
> +	stats->crcerrs += E1000_READ_REG(hw, E1000_CRCERRS);
> +	stats->mpc += E1000_READ_REG(hw, E1000_MPC);
> +	stats->scc += E1000_READ_REG(hw, E1000_SCC);
> +	stats->ecol += E1000_READ_REG(hw, E1000_ECOL);
> +
> +	stats->mcc += E1000_READ_REG(hw, E1000_MCC);
> +	stats->latecol += E1000_READ_REG(hw, E1000_LATECOL);
> +	stats->colc += E1000_READ_REG(hw, E1000_COLC);
> +	stats->dc += E1000_READ_REG(hw, E1000_DC);
> +	stats->rlec += E1000_READ_REG(hw, E1000_RLEC);
> +	stats->xonrxc += E1000_READ_REG(hw, E1000_XONRXC);
> +	stats->xontxc += E1000_READ_REG(hw, E1000_XONTXC);
> +	stats->xoffrxc += E1000_READ_REG(hw, E1000_XOFFRXC);
> +	stats->xofftxc += E1000_READ_REG(hw, E1000_XOFFTXC);
> +	stats->fcruc += E1000_READ_REG(hw, E1000_FCRUC);
> +	stats->prc64 += E1000_READ_REG(hw, E1000_PRC64);
> +	stats->prc127 += E1000_READ_REG(hw, E1000_PRC127);
> +	stats->prc255 += E1000_READ_REG(hw, E1000_PRC255);
> +	stats->prc511 += E1000_READ_REG(hw, E1000_PRC511);
> +	stats->prc1023 += E1000_READ_REG(hw, E1000_PRC1023);
> +	stats->prc1522 += E1000_READ_REG(hw, E1000_PRC1522);
> +	stats->gprc += E1000_READ_REG(hw, E1000_GPRC);
> +	stats->bprc += E1000_READ_REG(hw, E1000_BPRC);
> +	stats->mprc += E1000_READ_REG(hw, E1000_MPRC);
> +	stats->gptc += E1000_READ_REG(hw, E1000_GPTC);
> 
> 	/* For the 64-bit byte counters the low dword must be read first. */
> 	/* Both registers clear on the read of the high dword */
> 
> -	adapter->stats.gorc += E1000_READ_REG(&adapter->hw, E1000_GORCL) +
> -	  ((u64)E1000_READ_REG(&adapter->hw, E1000_GORCH) << 32);
> -	adapter->stats.gotc += E1000_READ_REG(&adapter->hw, E1000_GOTCL) +
> -	  ((u64)E1000_READ_REG(&adapter->hw, E1000_GOTCH) << 32) ;
> -
> -	adapter->stats.rnbc += E1000_READ_REG(&adapter->hw, E1000_RNBC);
> -	adapter->stats.ruc += E1000_READ_REG(&adapter->hw, E1000_RUC);
> -	adapter->stats.rfc += E1000_READ_REG(&adapter->hw, E1000_RFC);
> -	adapter->stats.roc += E1000_READ_REG(&adapter->hw, E1000_ROC);
> -	adapter->stats.rjc += E1000_READ_REG(&adapter->hw, E1000_RJC);
> -
> -	adapter->stats.tor += E1000_READ_REG(&adapter->hw, E1000_TORH);
> -	adapter->stats.tot += E1000_READ_REG(&adapter->hw, E1000_TOTH);
> -
> -	adapter->stats.tpr += E1000_READ_REG(&adapter->hw, E1000_TPR);
> -	adapter->stats.tpt += E1000_READ_REG(&adapter->hw, E1000_TPT);
> -	adapter->stats.ptc64 += E1000_READ_REG(&adapter->hw, E1000_PTC64);
> -	adapter->stats.ptc127 += E1000_READ_REG(&adapter->hw, E1000_PTC127);
> -	adapter->stats.ptc255 += E1000_READ_REG(&adapter->hw, E1000_PTC255);
> -	adapter->stats.ptc511 += E1000_READ_REG(&adapter->hw, E1000_PTC511);
> -	adapter->stats.ptc1023 += E1000_READ_REG(&adapter->hw, E1000_PTC1023);
> -	adapter->stats.ptc1522 += E1000_READ_REG(&adapter->hw, E1000_PTC1522);
> -	adapter->stats.mptc += E1000_READ_REG(&adapter->hw, E1000_MPTC);
> -	adapter->stats.bptc += E1000_READ_REG(&adapter->hw, E1000_BPTC);
> +	stats->gorc += E1000_READ_REG(hw, E1000_GORCL) +
> +	  ((u64)E1000_READ_REG(hw, E1000_GORCH) << 32);
> +	stats->gotc += E1000_READ_REG(hw, E1000_GOTCL) +
> +	  ((u64)E1000_READ_REG(hw, E1000_GOTCH) << 32) ;
> +
> +	stats->rnbc += E1000_READ_REG(hw, E1000_RNBC);
> +	stats->ruc += E1000_READ_REG(hw, E1000_RUC);
> +	stats->rfc += E1000_READ_REG(hw, E1000_RFC);
> +	stats->roc += E1000_READ_REG(hw, E1000_ROC);
> +	stats->rjc += E1000_READ_REG(hw, E1000_RJC);
> +
> +	stats->tor += E1000_READ_REG(hw, E1000_TORH);
> +	stats->tot += E1000_READ_REG(hw, E1000_TOTH);
> +
> +	stats->tpr += E1000_READ_REG(hw, E1000_TPR);
> +	stats->tpt += E1000_READ_REG(hw, E1000_TPT);
> +	stats->ptc64 += E1000_READ_REG(hw, E1000_PTC64);
> +	stats->ptc127 += E1000_READ_REG(hw, E1000_PTC127);
> +	stats->ptc255 += E1000_READ_REG(hw, E1000_PTC255);
> +	stats->ptc511 += E1000_READ_REG(hw, E1000_PTC511);
> +	stats->ptc1023 += E1000_READ_REG(hw, E1000_PTC1023);
> +	stats->ptc1522 += E1000_READ_REG(hw, E1000_PTC1522);
> +	stats->mptc += E1000_READ_REG(hw, E1000_MPTC);
> +	stats->bptc += E1000_READ_REG(hw, E1000_BPTC);
> 
> 	/* Interrupt Counts */
> 
> -	adapter->stats.iac += E1000_READ_REG(&adapter->hw, E1000_IAC);
> -	adapter->stats.icrxptc += E1000_READ_REG(&adapter->hw, E1000_ICRXPTC);
> -	adapter->stats.icrxatc += E1000_READ_REG(&adapter->hw, E1000_ICRXATC);
> -	adapter->stats.ictxptc += E1000_READ_REG(&adapter->hw, E1000_ICTXPTC);
> -	adapter->stats.ictxatc += E1000_READ_REG(&adapter->hw, E1000_ICTXATC);
> -	adapter->stats.ictxqec += E1000_READ_REG(&adapter->hw, E1000_ICTXQEC);
> -	adapter->stats.ictxqmtc += E1000_READ_REG(&adapter->hw, E1000_ICTXQMTC);
> -	adapter->stats.icrxdmtc += E1000_READ_REG(&adapter->hw, E1000_ICRXDMTC);
> -	adapter->stats.icrxoc += E1000_READ_REG(&adapter->hw, E1000_ICRXOC);
> +	stats->iac += E1000_READ_REG(hw, E1000_IAC);
> +	stats->icrxptc += E1000_READ_REG(hw, E1000_ICRXPTC);
> +	stats->icrxatc += E1000_READ_REG(hw, E1000_ICRXATC);
> +	stats->ictxptc += E1000_READ_REG(hw, E1000_ICTXPTC);
> +	stats->ictxatc += E1000_READ_REG(hw, E1000_ICTXATC);
> +	stats->ictxqec += E1000_READ_REG(hw, E1000_ICTXQEC);
> +	stats->ictxqmtc += E1000_READ_REG(hw, E1000_ICTXQMTC);
> +	stats->icrxdmtc += E1000_READ_REG(hw, E1000_ICRXDMTC);
> +	stats->icrxoc += E1000_READ_REG(hw, E1000_ICRXOC);
> 
> 	/* Host to Card Statistics */
> 
> -	adapter->stats.cbtmpc += E1000_READ_REG(&adapter->hw, E1000_CBTMPC);
> -	adapter->stats.htdpmc += E1000_READ_REG(&adapter->hw, E1000_HTDPMC);
> -	adapter->stats.cbrdpc += E1000_READ_REG(&adapter->hw, E1000_CBRDPC);
> -	adapter->stats.cbrmpc += E1000_READ_REG(&adapter->hw, E1000_CBRMPC);
> -	adapter->stats.rpthc += E1000_READ_REG(&adapter->hw, E1000_RPTHC);
> -	adapter->stats.hgptc += E1000_READ_REG(&adapter->hw, E1000_HGPTC);
> -	adapter->stats.htcbdpc += E1000_READ_REG(&adapter->hw, E1000_HTCBDPC);
> -	adapter->stats.hgorc += (E1000_READ_REG(&adapter->hw, E1000_HGORCL) +
> -				 ((u64)E1000_READ_REG(&adapter->hw, 
> -						      E1000_HGORCH) << 32));
> -
> -	adapter->stats.hgotc += (E1000_READ_REG(&adapter->hw, E1000_HGOTCL) +
> -				 ((u64)E1000_READ_REG(&adapter->hw, 
> -						      E1000_HGOTCH) << 32));
> -	adapter->stats.lenerrs += E1000_READ_REG(&adapter->hw, E1000_LENERRS);
> -	adapter->stats.scvpc += E1000_READ_REG(&adapter->hw, E1000_SCVPC);
> -	adapter->stats.hrmpc += E1000_READ_REG(&adapter->hw, E1000_HRMPC);
> -
> -	adapter->stats.algnerrc += 
> -		E1000_READ_REG(&adapter->hw, E1000_ALGNERRC);
> -	adapter->stats.rxerrc += 
> -		E1000_READ_REG(&adapter->hw, E1000_RXERRC);
> -	adapter->stats.tncrs += 
> -		E1000_READ_REG(&adapter->hw, E1000_TNCRS);
> -	adapter->stats.cexterr += 
> -		E1000_READ_REG(&adapter->hw, E1000_CEXTERR);
> -	adapter->stats.tsctc += 
> -		E1000_READ_REG(&adapter->hw, E1000_TSCTC);
> -	adapter->stats.tsctfc += 
> -		E1000_READ_REG(&adapter->hw, E1000_TSCTFC);
> +	stats->cbtmpc += E1000_READ_REG(hw, E1000_CBTMPC);
> +	stats->htdpmc += E1000_READ_REG(hw, E1000_HTDPMC);
> +	stats->cbrdpc += E1000_READ_REG(hw, E1000_CBRDPC);
> +	stats->cbrmpc += E1000_READ_REG(hw, E1000_CBRMPC);
> +	stats->rpthc += E1000_READ_REG(hw, E1000_RPTHC);
> +	stats->hgptc += E1000_READ_REG(hw, E1000_HGPTC);
> +	stats->htcbdpc += E1000_READ_REG(hw, E1000_HTCBDPC);
> +	stats->hgorc += (E1000_READ_REG(hw, E1000_HGORCL) +
> +	    ((u64)E1000_READ_REG(hw, E1000_HGORCH) << 32));
> +	stats->hgotc += (E1000_READ_REG(hw, E1000_HGOTCL) +
> +	    ((u64)E1000_READ_REG(hw, E1000_HGOTCH) << 32));
> +	stats->lenerrs += E1000_READ_REG(hw, E1000_LENERRS);
> +	stats->scvpc += E1000_READ_REG(hw, E1000_SCVPC);
> +	stats->hrmpc += E1000_READ_REG(hw, E1000_HRMPC);
> +
> +	stats->algnerrc += E1000_READ_REG(hw, E1000_ALGNERRC);
> +	stats->rxerrc += E1000_READ_REG(hw, E1000_RXERRC);
> +	stats->tncrs += E1000_READ_REG(hw, E1000_TNCRS);
> +	stats->cexterr += E1000_READ_REG(hw, E1000_CEXTERR);
> +	stats->tsctc += E1000_READ_REG(hw, E1000_TSCTC);
> +	stats->tsctfc += E1000_READ_REG(hw, E1000_TSCTFC);
> 	ifp = adapter->ifp;
> 
> -	ifp->if_collisions = adapter->stats.colc;
> +	ifp = adapter->ifp;
> +	ifp->if_collisions = stats->colc;
> 
> 	/* Rx Errors */
> -	ifp->if_ierrors = adapter->dropped_pkts + adapter->stats.rxerrc +
> -	    adapter->stats.crcerrs + adapter->stats.algnerrc +
> -	    adapter->stats.ruc + adapter->stats.roc +
> -	    adapter->stats.mpc + adapter->stats.cexterr;
> +	ifp->if_ierrors = adapter->dropped_pkts + stats->rxerrc +
> +	    stats->crcerrs + stats->algnerrc +
> +	    stats->ruc + stats->roc + stats->mpc + stats->cexterr;
> 
> 	/* Tx Errors */
> -	ifp->if_oerrors = adapter->stats.ecol +
> -	    adapter->stats.latecol + adapter->watchdog_events;
> +	ifp->if_oerrors = stats->ecol +
> +	    stats->latecol + adapter->watchdog_events;
> 
> 	/* Driver specific counters */
> -	adapter->device_control = E1000_READ_REG(&adapter->hw, E1000_CTRL);
> -	adapter->rx_control = E1000_READ_REG(&adapter->hw, E1000_RCTL);
> -	adapter->int_mask = E1000_READ_REG(&adapter->hw, E1000_IMS);
> -	adapter->eint_mask = E1000_READ_REG(&adapter->hw, E1000_EIMS);
> -	adapter->packet_buf_alloc_tx = ((E1000_READ_REG(&adapter->hw, E1000_PBA)
> -					& 0xffff0000) >> 16);
> +	adapter->device_control = E1000_READ_REG(hw, E1000_CTRL);
> +	adapter->rx_control = E1000_READ_REG(hw, E1000_RCTL);
> +	adapter->int_mask = E1000_READ_REG(hw, E1000_IMS);
> +	adapter->eint_mask = E1000_READ_REG(hw, E1000_EIMS);
> +	adapter->packet_buf_alloc_tx =
> +	    ((E1000_READ_REG(hw, E1000_PBA) & 0xffff0000) >> 16);
> +	adapter->packet_buf_alloc_rx =
> +	    ((E1000_READ_REG(hw, E1000_PBA) & 0xffff);
> +}
> 
> -	adapter->packet_buf_alloc_rx = (E1000_READ_REG(&adapter->hw, E1000_PBA) 
> -					& 0xffff);
> 
> +/**********************************************************************
> + *
> + *  Initialize the VF board statistics counters.
> + *
> + **********************************************************************/
> +static void
> +igb_vf_init_stats(struct adapter *adapter)
> +{
> +        struct e1000_hw *hw = &adapter->hw;
> +	struct e1000_vf_stats	*stats;
> +
> +	stats = (struct e1000_vf_stats	*)adapter->stats;
> +
> +        stats->last_gprc = E1000_READ_REG(hw, E1000_VFGPRC);
> +        stats->last_gorc = E1000_READ_REG(hw, E1000_VFGORC);
> +        stats->last_gptc = E1000_READ_REG(hw, E1000_VFGPTC);
> +        stats->last_gotc = E1000_READ_REG(hw, E1000_VFGOTC);
> +        stats->last_mprc = E1000_READ_REG(hw, E1000_VFMPRC);
> +}
> + 
> +/**********************************************************************
> + *
> + *  Update the VF board statistics counters.
> + *
> + **********************************************************************/
> +static void
> +igb_update_vf_stats_counters(struct adapter *adapter)
> +{
> +	struct e1000_hw *hw = &adapter->hw;
> +	struct e1000_vf_stats	*stats;
> +
> +	if (adapter->link_speed == 0)
> +		return;
> +
> +	stats = (struct e1000_vf_stats	*)adapter->stats;
> +
> +	UPDATE_VF_REG(E1000_VFGPRC,
> +	    stats->last_gprc, stats->gprc);
> +	UPDATE_VF_REG(E1000_VFGORC,
> +	    stats->last_gorc, stats->gorc);
> +	UPDATE_VF_REG(E1000_VFGPTC,
> +	    stats->last_gptc, stats->gptc);
> +	UPDATE_VF_REG(E1000_VFGOTC,
> +	    stats->last_gotc, stats->gotc);
> +	UPDATE_VF_REG(E1000_VFMPRC,
> +	    stats->last_mprc, stats->mprc);
> }
> 
> 
> @@ -4895,10 +4994,14 @@ igb_add_hw_stats(struct adapter *adapter
> 		queue_list = SYSCTL_CHILDREN(queue_node);
> 
> 		SYSCTL_ADD_UINT(ctx, queue_list, OID_AUTO, "txd_head",
> -				CTLFLAG_RD, &txr->tdh, 0,
> +				CTLFLAG_RD,
> +				E1000_READ_REG(&adapter->hw,
> +				E1000_TDH(txr->me)), 0,
> 				"Transmit Descriptor Head");
> 		SYSCTL_ADD_UINT(ctx, queue_list, OID_AUTO, "txd_tail",
> -				CTLFLAG_RD, &txr->tdt, 0,
> +				CTLFLAG_RD,
> +				E1000_READ_REG(&adapter->hw,
> +				E1000_TDT(txr->me))), 0,
> 				"Transmit Descriptor Tail");
> 		SYSCTL_ADD_QUAD(ctx, queue_list, OID_AUTO, "no_desc_avail", 
> 				CTLFLAG_RD, &txr->no_desc_avail,
> @@ -4947,6 +5050,29 @@ igb_add_hw_stats(struct adapter *adapter
> 				    CTLFLAG_RD, NULL, "MAC Statistics");
> 	stat_list = SYSCTL_CHILDREN(stat_node);
> 
> +	/*
> +	** VF adapter has a very limited set of stats
> +	** since its not managing the metal, so to speak.
> +	*/
> +	if (adapter->hw.mac.type == e1000_vfadapt) {
> +	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_pkts_recvd",
> +			CTLFLAG_RD, &adapter->stats.gprc,
> +			"Good Packets Received");
> +	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_pkts_txd",
> +			CTLFLAG_RD, &adapter->stats.gptc,
> +			"Good Packets Transmitted");
> + 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_octets_recvd", 
> + 			CTLFLAG_RD, &adapter->stats.gorc, 
> + 			"Good Octets Received"); 
> + 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_octest_txd", 
> + 			CTLFLAG_RD, &adapter->stats.gotc, 
> + 			"Good Octest Transmitted"); 
> +	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_recvd",
> +			CTLFLAG_RD, &adapter->stats.mprc,
> +			"Multicast Packets Received");
> +		return;
> +	}
> +
> 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "excess_coll", 
> 			CTLFLAG_RD, &stats->ecol,
> 			"Excessive collisions");
> @@ -4989,12 +5115,6 @@ igb_add_hw_stats(struct adapter *adapter
> 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_jabber",
> 			CTLFLAG_RD, &adapter->stats.rjc,
> 			"Recevied Jabber");
> -
> -	/* RLEC is inaccurate on some hardware, calculate our own. */
> -/* 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_len_errs", */
> -/* 			CTLFLAG_RD, adapter->stats.roc + adapter->stats.ruc, */
> -/* 			"Receive Length Errors"); */
> -
> 	SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "recv_errs",
> 			CTLFLAG_RD, &adapter->stats.rxerrc,
> 			"Receive Errors");
> @@ -5200,9 +5320,9 @@ igb_add_hw_stats(struct adapter *adapter
> 	SYSCTL_ADD_QUAD(ctx, host_list, OID_AUTO, "header_redir_missed",
> 			CTLFLAG_RD, &adapter->stats.hrmpc,
> 			"Header Redirection Missed Packet Count");
> +}
> 
> 
> -}
> /**********************************************************************
>  *
>  *  This routine provides a way to dump out the adapter eeprom,
> 
> Modified: head/sys/dev/e1000/if_igb.h
> ==============================================================================
> --- head/sys/dev/e1000/if_igb.h	Wed Jun 30 17:20:33 2010	(r209610)
> +++ head/sys/dev/e1000/if_igb.h	Wed Jun 30 17:26:47 2010	(r209611)
> @@ -180,7 +180,8 @@
> 
> #define IGB_TX_PTHRESH			8
> #define IGB_TX_HTHRESH			1
> -#define IGB_TX_WTHRESH			((hw->mac.type == e1000_82576 && \
> +#define IGB_TX_WTHRESH			(((hw->mac.type == e1000_82576 || \
> +					  hw->mac.type == e1000_vfadapt) && \
>                                           adapter->msix_mem) ? 1 : 16)
> 
> #define MAX_NUM_MULTICAST_ADDRESSES     128
> @@ -317,9 +318,6 @@ struct tx_ring {
> 	int			watchdog_time;
> 	u64			no_desc_avail;
> 	u64			tx_packets;
> -	/* Statistics for reporting, ONLY. */
> -	u32			tdh; /* Transmit Descriptor Head */
> -	u32			tdt; /* Transmit Descriptor Tail */
> };
> 
> /*
> @@ -356,9 +354,6 @@ struct rx_ring {
> 	u64			rx_discarded;
> 	u64			rx_packets;
> 	u64			rx_bytes;
> -	/* Statistics for reporting, ONLY. */
> -	u32			rdh; /* Transmit Descriptor Head */
> -	u32			rdt; /* Transmit Descriptor Tail */
> };
> 
> struct adapter {
> @@ -449,7 +444,7 @@ struct adapter {
> 	struct hwtstamp_ctrl    hwtstamp;
> #endif
> 
> -	struct e1000_hw_stats stats;
> +	void 			*stats;
> };
> 
> /* ******************************************************************************
> @@ -497,7 +492,17 @@ struct igb_rx_buf {
> #define	IGB_RX_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->rx_mtx)
> #define	IGB_RX_LOCK(_sc)		mtx_lock(&(_sc)->rx_mtx)
> #define	IGB_RX_UNLOCK(_sc)		mtx_unlock(&(_sc)->rx_mtx)
> -#define	IGB_TX_LOCK_ASSERT(_sc)		mtx_assert(&(_sc)->tx_mtx, MA_OWNED)
> +#define	IGB_RX_LOCK_ASSERT(_sc)		mtx_assert(&(_sc)->rx_mtx, MA_OWNED)
> +
> +#define UPDATE_VF_REG(reg, last, cur)		\
> +{						\
> +	u32 new = E1000_READ_REG(hw, reg);	\
> +	if (new < last)				\
> +		cur += 0x100000000LL;		\
> +	last = new;				\
> +	cur &= 0xFFFFFFFF00000000LL;		\
> +	cur |= new;				\
> +}
> 
> #endif /* _IGB_H_DEFINED_ */
> 



More information about the svn-src-head mailing list