From owner-svn-src-all@FreeBSD.ORG Wed Jun 30 20:37:09 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id F37F1106566C; Wed, 30 Jun 2010 20:37:08 +0000 (UTC) (envelope-from fabien.thomas@netasq.com) Received: from work.netasq.com (mars.netasq.com [91.212.116.3]) by mx1.freebsd.org (Postfix) with ESMTP id B7E0E8FC08; Wed, 30 Jun 2010 20:37:07 +0000 (UTC) Received: from [192.168.0.1] (unknown [172.16.0.46]) by work.netasq.com (Postfix) with ESMTPSA id F3607740004; Wed, 30 Jun 2010 22:36:56 +0200 (CEST) Mime-Version: 1.0 (Apple Message framework v1081) Content-Type: text/plain; charset=us-ascii From: Fabien Thomas In-Reply-To: <201006301726.o5UHQl7n011935@svn.freebsd.org> Date: Wed, 30 Jun 2010 22:37:05 +0200 Content-Transfer-Encoding: quoted-printable Message-Id: References: <201006301726.o5UHQl7n011935@svn.freebsd.org> To: Jack F Vogel X-Mailer: Apple Mail (2.1081) Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r209611 - head/sys/dev/e1000 X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 30 Jun 2010 20:37:09 -0000 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 >=20 > Log: > SR-IOV support added to igb >=20 > 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. >=20 > 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. >=20 > The interface is only allowed a single queue in this configuration > however initial performance tests have looked very good. >=20 > Enjoy!! >=20 > Modified: > head/sys/dev/e1000/if_igb.c > head/sys/dev/e1000/if_igb.h >=20 > Modified: head/sys/dev/e1000/if_igb.c > = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D > --- 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 =3D 0; > /********************************************************************* > * Driver version: > = *********************************************************************/ > -char igb_driver_version[] =3D "version - 1.9.6"; > +char igb_driver_version[] =3D "version - 2.0.1"; >=20 >=20 > /********************************************************************* > @@ -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=20 > 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; > } >=20 > + /* Allocate the appropriate stats memory */ > + if (adapter->hw.mac.type =3D=3D e1000_vfadapt) { > + adapter->stats =3D > + (struct e1000_vf_stats *)malloc(sizeof \ > + (struct e1000_vf_stats), M_DEVBUF, M_NOWAIT | = M_ZERO); > + igb_vf_init_stats(adapter); > + } else > + adapter->stats =3D > + (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 =3D adapter->ifp; > - uint32_t reg_rctl; > + struct e1000_hw *hw =3D &adapter->hw; > + u32 reg; >=20 > - reg_rctl =3D E1000_READ_REG(&adapter->hw, E1000_RCTL); > + if (hw->mac.type =3D=3D e1000_vfadapt) { > + e1000_promisc_set_vf(hw, e1000_promisc_enabled); > + return; > + } >=20 > + reg =3D E1000_READ_REG(hw, E1000_RCTL); > if (ifp->if_flags & IFF_PROMISC) { > - reg_rctl |=3D (E1000_RCTL_UPE | E1000_RCTL_MPE); > - E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl); > + reg |=3D (E1000_RCTL_UPE | E1000_RCTL_MPE); > + E1000_WRITE_REG(hw, E1000_RCTL, reg); > } else if (ifp->if_flags & IFF_ALLMULTI) { > - reg_rctl |=3D E1000_RCTL_MPE; > - reg_rctl &=3D ~E1000_RCTL_UPE; > - E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl); > + reg |=3D E1000_RCTL_MPE; > + reg &=3D ~E1000_RCTL_UPE; > + E1000_WRITE_REG(hw, E1000_RCTL, reg); > } > } >=20 > static void > igb_disable_promisc(struct adapter *adapter) > { > - uint32_t reg_rctl; > - > - reg_rctl =3D E1000_READ_REG(&adapter->hw, E1000_RCTL); > + struct e1000_hw *hw =3D &adapter->hw; > + u32 reg; >=20 > - reg_rctl &=3D (~E1000_RCTL_UPE); > - reg_rctl &=3D (~E1000_RCTL_MPE); > - E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl); > + if (hw->mac.type =3D=3D e1000_vfadapt) { > + e1000_promisc_set_vf(hw, e1000_promisc_disabled); > + return; > + } > + reg =3D E1000_READ_REG(hw, E1000_RCTL); > + reg &=3D (~E1000_RCTL_UPE); > + reg &=3D (~E1000_RCTL_MPE); > + E1000_WRITE_REG(hw, E1000_RCTL, reg); > } >=20 >=20 > @@ -1939,8 +1964,12 @@ igb_update_link_status(struct adapter *a > e1000_check_for_link(hw); > link_check =3D 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 =3D !hw->mac.get_link_status; > + /* Fall thru */ > + default: > break; > } >=20 > @@ -2025,8 +2054,8 @@ igb_identify_hardware(struct adapter *ad > adapter->hw.bus.pci_cmd_word =3D 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 |=3D > (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 =3D > 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; > - } > } >=20 > 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 =3D 0; i < adapter->num_queues; i++) { > u32 index =3D i >> 1; > @@ -2446,6 +2470,10 @@ igb_setup_msix(struct adapter *adapter) > if ((adapter->hw.mac.type =3D=3D e1000_82575) && (queues > 4)) > queues =3D 4; >=20 > + /* Limit the VF adapter to one queues */ > + if ((adapter->hw.mac.type =3D=3D e1000_vfadapt) && (queues > 2)) > + queues =3D 1; > + > /* > ** One vector (RX/TX pair) per queue > ** plus an additional for Link interrupt > @@ -2503,6 +2531,7 @@ igb_reset(struct adapter *adapter) > pba =3D E1000_PBA_32K; > break; > case e1000_82576: > + case e1000_vfadapt: > pba =3D E1000_PBA_64K; > break; > case e1000_82580: > @@ -3074,7 +3103,8 @@ igb_initialize_transmit_units(struct ada > struct e1000_hw *hw =3D &adapter->hw; > u32 tctl, txdctl; >=20 > - INIT_DEBUGOUT("igb_initialize_transmit_units: begin"); > + INIT_DEBUGOUT("igb_initialize_transmit_units: begin"); > + tctl =3D txdctl =3D 0; >=20 > /* Setup the Tx Descriptor Rings */ > for (int i =3D 0; i < adapter->num_queues; i++, txr++) { > @@ -3097,7 +3127,6 @@ igb_initialize_transmit_units(struct ada >=20 > txr->watchdog_check =3D FALSE; >=20 > - txdctl =3D E1000_READ_REG(hw, E1000_TXDCTL(i)); > txdctl |=3D IGB_TX_PTHRESH; > txdctl |=3D IGB_TX_HTHRESH << 8; > txdctl |=3D IGB_TX_WTHRESH << 16; > @@ -3105,6 +3134,9 @@ igb_initialize_transmit_units(struct ada > E1000_WRITE_REG(hw, E1000_TXDCTL(i), txdctl); > } >=20 > + if (adapter->hw.mac.type =3D=3D e1000_vfadapt) > + return; > + > /* Program the Transmit Control Register */ > tctl =3D E1000_READ_REG(hw, E1000_TCTL); > tctl &=3D ~E1000_TCTL_CT; > @@ -3505,7 +3537,7 @@ igb_txeof(struct tx_ring *txr) > /* All clean, turn off the watchdog */ > if (txr->tx_avail =3D=3D adapter->num_tx_desc) { > txr->watchdog_check =3D FALSE; > - return FALSE; > + return (FALSE); > } > } >=20 > @@ -4504,23 +4536,32 @@ igb_setup_vlan_hw_support(struct adapter > ** we need to repopulate it now. > */ > for (int i =3D 0; i < IGB_VFTA_SIZE; i++) > - if (igb_shadow_vfta[i] !=3D 0) > - E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, > - i, igb_shadow_vfta[i]); > - > - reg =3D E1000_READ_REG(hw, E1000_CTRL); > - reg |=3D E1000_CTRL_VME; > - E1000_WRITE_REG(hw, E1000_CTRL, reg); > - > - /* Enable the Filter Table */ > - reg =3D E1000_READ_REG(hw, E1000_RCTL); > - reg &=3D ~E1000_RCTL_CFIEN; > - reg |=3D E1000_RCTL_VFE; > - E1000_WRITE_REG(hw, E1000_RCTL, reg); > + if (igb_shadow_vfta[i] !=3D 0) { > + if (hw->mac.type =3D=3D 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]); > + } >=20 > - /* Update the frame size */ > - E1000_WRITE_REG(&adapter->hw, E1000_RLPML, > - adapter->max_frame_size + VLAN_TAG_SIZE); > + if (hw->mac.type =3D=3D e1000_vfadapt) > + e1000_rlpml_set_vf(hw, > + adapter->max_frame_size + VLAN_TAG_SIZE); > + else { > + reg =3D E1000_READ_REG(hw, E1000_CTRL); > + reg |=3D E1000_CTRL_VME; > + E1000_WRITE_REG(hw, E1000_CTRL, reg); > + > + /* Enable the Filter Table */ > + reg =3D E1000_READ_REG(hw, E1000_RCTL); > + reg &=3D ~E1000_RCTL_CFIEN; > + reg |=3D 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); > + } > } >=20 > static void > @@ -4610,6 +4651,9 @@ igb_get_hw_control(struct adapter *adapt > { > u32 ctrl_ext; >=20 > + if (adapter->hw.mac.type =3D=3D e1000_vfadapt) > + return; > + > /* Let firmware know the driver has taken over */ > ctrl_ext =3D 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; >=20 > + if (adapter->hw.mac.type =3D=3D e1000_vfadapt) > + return; > + > /* Let firmware taken over control of h/w */ > ctrl_ext =3D 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 =3D &adapter->hw; > + struct e1000_hw_stats *stats; >=20 > - if (adapter->hw.phy.media_type =3D=3D e1000_media_type_copper || > - (E1000_READ_REG(&adapter->hw, E1000_STATUS) & = E1000_STATUS_LU)) { > - adapter->stats.symerrs +=3D > - E1000_READ_REG(&adapter->hw, E1000_SYMERRS); > - adapter->stats.sec +=3D > - E1000_READ_REG(&adapter->hw, E1000_SEC); > - } > - adapter->stats.crcerrs +=3D E1000_READ_REG(&adapter->hw, = E1000_CRCERRS); > - adapter->stats.mpc +=3D E1000_READ_REG(&adapter->hw, E1000_MPC); > - adapter->stats.scc +=3D E1000_READ_REG(&adapter->hw, E1000_SCC); > - adapter->stats.ecol +=3D E1000_READ_REG(&adapter->hw, = E1000_ECOL); > - > - adapter->stats.mcc +=3D E1000_READ_REG(&adapter->hw, E1000_MCC); > - adapter->stats.latecol +=3D E1000_READ_REG(&adapter->hw, = E1000_LATECOL); > - adapter->stats.colc +=3D E1000_READ_REG(&adapter->hw, = E1000_COLC); > - adapter->stats.dc +=3D E1000_READ_REG(&adapter->hw, E1000_DC); > - adapter->stats.rlec +=3D E1000_READ_REG(&adapter->hw, = E1000_RLEC); > - adapter->stats.xonrxc +=3D E1000_READ_REG(&adapter->hw, = E1000_XONRXC); > - adapter->stats.xontxc +=3D E1000_READ_REG(&adapter->hw, = E1000_XONTXC); > - adapter->stats.xoffrxc +=3D E1000_READ_REG(&adapter->hw, = E1000_XOFFRXC); > - adapter->stats.xofftxc +=3D E1000_READ_REG(&adapter->hw, = E1000_XOFFTXC); > - adapter->stats.fcruc +=3D E1000_READ_REG(&adapter->hw, = E1000_FCRUC); > - adapter->stats.prc64 +=3D E1000_READ_REG(&adapter->hw, = E1000_PRC64); > - adapter->stats.prc127 +=3D E1000_READ_REG(&adapter->hw, = E1000_PRC127); > - adapter->stats.prc255 +=3D E1000_READ_REG(&adapter->hw, = E1000_PRC255); > - adapter->stats.prc511 +=3D E1000_READ_REG(&adapter->hw, = E1000_PRC511); > - adapter->stats.prc1023 +=3D E1000_READ_REG(&adapter->hw, = E1000_PRC1023); > - adapter->stats.prc1522 +=3D E1000_READ_REG(&adapter->hw, = E1000_PRC1522); > - adapter->stats.gprc +=3D E1000_READ_REG(&adapter->hw, = E1000_GPRC); > - adapter->stats.bprc +=3D E1000_READ_REG(&adapter->hw, = E1000_BPRC); > - adapter->stats.mprc +=3D E1000_READ_REG(&adapter->hw, = E1000_MPRC); > - adapter->stats.gptc +=3D E1000_READ_REG(&adapter->hw, = E1000_GPTC); > + /*=20 > + ** The virtual function adapter has only a > + ** small controlled set of stats, do only=20 > + ** those and return. > + */ > + if (adapter->hw.mac.type =3D=3D e1000_vfadapt) { > + igb_update_vf_stats_counters(adapter); > + return; > + } > + > + stats =3D (struct e1000_hw_stats *)adapter->stats; > + > + if(adapter->hw.phy.media_type =3D=3D e1000_media_type_copper || > + (E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_LU)) { > + stats->symerrs +=3D > + E1000_READ_REG(hw,E1000_SYMERRS); > + stats->sec +=3D E1000_READ_REG(hw, E1000_SEC); > + } > + > + stats->crcerrs +=3D E1000_READ_REG(hw, E1000_CRCERRS); > + stats->mpc +=3D E1000_READ_REG(hw, E1000_MPC); > + stats->scc +=3D E1000_READ_REG(hw, E1000_SCC); > + stats->ecol +=3D E1000_READ_REG(hw, E1000_ECOL); > + > + stats->mcc +=3D E1000_READ_REG(hw, E1000_MCC); > + stats->latecol +=3D E1000_READ_REG(hw, E1000_LATECOL); > + stats->colc +=3D E1000_READ_REG(hw, E1000_COLC); > + stats->dc +=3D E1000_READ_REG(hw, E1000_DC); > + stats->rlec +=3D E1000_READ_REG(hw, E1000_RLEC); > + stats->xonrxc +=3D E1000_READ_REG(hw, E1000_XONRXC); > + stats->xontxc +=3D E1000_READ_REG(hw, E1000_XONTXC); > + stats->xoffrxc +=3D E1000_READ_REG(hw, E1000_XOFFRXC); > + stats->xofftxc +=3D E1000_READ_REG(hw, E1000_XOFFTXC); > + stats->fcruc +=3D E1000_READ_REG(hw, E1000_FCRUC); > + stats->prc64 +=3D E1000_READ_REG(hw, E1000_PRC64); > + stats->prc127 +=3D E1000_READ_REG(hw, E1000_PRC127); > + stats->prc255 +=3D E1000_READ_REG(hw, E1000_PRC255); > + stats->prc511 +=3D E1000_READ_REG(hw, E1000_PRC511); > + stats->prc1023 +=3D E1000_READ_REG(hw, E1000_PRC1023); > + stats->prc1522 +=3D E1000_READ_REG(hw, E1000_PRC1522); > + stats->gprc +=3D E1000_READ_REG(hw, E1000_GPRC); > + stats->bprc +=3D E1000_READ_REG(hw, E1000_BPRC); > + stats->mprc +=3D E1000_READ_REG(hw, E1000_MPRC); > + stats->gptc +=3D E1000_READ_REG(hw, E1000_GPTC); >=20 > /* For the 64-bit byte counters the low dword must be read = first. */ > /* Both registers clear on the read of the high dword */ >=20 > - adapter->stats.gorc +=3D E1000_READ_REG(&adapter->hw, = E1000_GORCL) + > - ((u64)E1000_READ_REG(&adapter->hw, E1000_GORCH) << 32); > - adapter->stats.gotc +=3D E1000_READ_REG(&adapter->hw, = E1000_GOTCL) + > - ((u64)E1000_READ_REG(&adapter->hw, E1000_GOTCH) << 32) ; > - > - adapter->stats.rnbc +=3D E1000_READ_REG(&adapter->hw, = E1000_RNBC); > - adapter->stats.ruc +=3D E1000_READ_REG(&adapter->hw, E1000_RUC); > - adapter->stats.rfc +=3D E1000_READ_REG(&adapter->hw, E1000_RFC); > - adapter->stats.roc +=3D E1000_READ_REG(&adapter->hw, E1000_ROC); > - adapter->stats.rjc +=3D E1000_READ_REG(&adapter->hw, E1000_RJC); > - > - adapter->stats.tor +=3D E1000_READ_REG(&adapter->hw, = E1000_TORH); > - adapter->stats.tot +=3D E1000_READ_REG(&adapter->hw, = E1000_TOTH); > - > - adapter->stats.tpr +=3D E1000_READ_REG(&adapter->hw, E1000_TPR); > - adapter->stats.tpt +=3D E1000_READ_REG(&adapter->hw, E1000_TPT); > - adapter->stats.ptc64 +=3D E1000_READ_REG(&adapter->hw, = E1000_PTC64); > - adapter->stats.ptc127 +=3D E1000_READ_REG(&adapter->hw, = E1000_PTC127); > - adapter->stats.ptc255 +=3D E1000_READ_REG(&adapter->hw, = E1000_PTC255); > - adapter->stats.ptc511 +=3D E1000_READ_REG(&adapter->hw, = E1000_PTC511); > - adapter->stats.ptc1023 +=3D E1000_READ_REG(&adapter->hw, = E1000_PTC1023); > - adapter->stats.ptc1522 +=3D E1000_READ_REG(&adapter->hw, = E1000_PTC1522); > - adapter->stats.mptc +=3D E1000_READ_REG(&adapter->hw, = E1000_MPTC); > - adapter->stats.bptc +=3D E1000_READ_REG(&adapter->hw, = E1000_BPTC); > + stats->gorc +=3D E1000_READ_REG(hw, E1000_GORCL) + > + ((u64)E1000_READ_REG(hw, E1000_GORCH) << 32); > + stats->gotc +=3D E1000_READ_REG(hw, E1000_GOTCL) + > + ((u64)E1000_READ_REG(hw, E1000_GOTCH) << 32) ; > + > + stats->rnbc +=3D E1000_READ_REG(hw, E1000_RNBC); > + stats->ruc +=3D E1000_READ_REG(hw, E1000_RUC); > + stats->rfc +=3D E1000_READ_REG(hw, E1000_RFC); > + stats->roc +=3D E1000_READ_REG(hw, E1000_ROC); > + stats->rjc +=3D E1000_READ_REG(hw, E1000_RJC); > + > + stats->tor +=3D E1000_READ_REG(hw, E1000_TORH); > + stats->tot +=3D E1000_READ_REG(hw, E1000_TOTH); > + > + stats->tpr +=3D E1000_READ_REG(hw, E1000_TPR); > + stats->tpt +=3D E1000_READ_REG(hw, E1000_TPT); > + stats->ptc64 +=3D E1000_READ_REG(hw, E1000_PTC64); > + stats->ptc127 +=3D E1000_READ_REG(hw, E1000_PTC127); > + stats->ptc255 +=3D E1000_READ_REG(hw, E1000_PTC255); > + stats->ptc511 +=3D E1000_READ_REG(hw, E1000_PTC511); > + stats->ptc1023 +=3D E1000_READ_REG(hw, E1000_PTC1023); > + stats->ptc1522 +=3D E1000_READ_REG(hw, E1000_PTC1522); > + stats->mptc +=3D E1000_READ_REG(hw, E1000_MPTC); > + stats->bptc +=3D E1000_READ_REG(hw, E1000_BPTC); >=20 > /* Interrupt Counts */ >=20 > - adapter->stats.iac +=3D E1000_READ_REG(&adapter->hw, E1000_IAC); > - adapter->stats.icrxptc +=3D E1000_READ_REG(&adapter->hw, = E1000_ICRXPTC); > - adapter->stats.icrxatc +=3D E1000_READ_REG(&adapter->hw, = E1000_ICRXATC); > - adapter->stats.ictxptc +=3D E1000_READ_REG(&adapter->hw, = E1000_ICTXPTC); > - adapter->stats.ictxatc +=3D E1000_READ_REG(&adapter->hw, = E1000_ICTXATC); > - adapter->stats.ictxqec +=3D E1000_READ_REG(&adapter->hw, = E1000_ICTXQEC); > - adapter->stats.ictxqmtc +=3D E1000_READ_REG(&adapter->hw, = E1000_ICTXQMTC); > - adapter->stats.icrxdmtc +=3D E1000_READ_REG(&adapter->hw, = E1000_ICRXDMTC); > - adapter->stats.icrxoc +=3D E1000_READ_REG(&adapter->hw, = E1000_ICRXOC); > + stats->iac +=3D E1000_READ_REG(hw, E1000_IAC); > + stats->icrxptc +=3D E1000_READ_REG(hw, E1000_ICRXPTC); > + stats->icrxatc +=3D E1000_READ_REG(hw, E1000_ICRXATC); > + stats->ictxptc +=3D E1000_READ_REG(hw, E1000_ICTXPTC); > + stats->ictxatc +=3D E1000_READ_REG(hw, E1000_ICTXATC); > + stats->ictxqec +=3D E1000_READ_REG(hw, E1000_ICTXQEC); > + stats->ictxqmtc +=3D E1000_READ_REG(hw, E1000_ICTXQMTC); > + stats->icrxdmtc +=3D E1000_READ_REG(hw, E1000_ICRXDMTC); > + stats->icrxoc +=3D E1000_READ_REG(hw, E1000_ICRXOC); >=20 > /* Host to Card Statistics */ >=20 > - adapter->stats.cbtmpc +=3D E1000_READ_REG(&adapter->hw, = E1000_CBTMPC); > - adapter->stats.htdpmc +=3D E1000_READ_REG(&adapter->hw, = E1000_HTDPMC); > - adapter->stats.cbrdpc +=3D E1000_READ_REG(&adapter->hw, = E1000_CBRDPC); > - adapter->stats.cbrmpc +=3D E1000_READ_REG(&adapter->hw, = E1000_CBRMPC); > - adapter->stats.rpthc +=3D E1000_READ_REG(&adapter->hw, = E1000_RPTHC); > - adapter->stats.hgptc +=3D E1000_READ_REG(&adapter->hw, = E1000_HGPTC); > - adapter->stats.htcbdpc +=3D E1000_READ_REG(&adapter->hw, = E1000_HTCBDPC); > - adapter->stats.hgorc +=3D (E1000_READ_REG(&adapter->hw, = E1000_HGORCL) + > - ((u64)E1000_READ_REG(&adapter->hw,=20 > - E1000_HGORCH) << = 32)); > - > - adapter->stats.hgotc +=3D (E1000_READ_REG(&adapter->hw, = E1000_HGOTCL) + > - ((u64)E1000_READ_REG(&adapter->hw,=20 > - E1000_HGOTCH) << = 32)); > - adapter->stats.lenerrs +=3D E1000_READ_REG(&adapter->hw, = E1000_LENERRS); > - adapter->stats.scvpc +=3D E1000_READ_REG(&adapter->hw, = E1000_SCVPC); > - adapter->stats.hrmpc +=3D E1000_READ_REG(&adapter->hw, = E1000_HRMPC); > - > - adapter->stats.algnerrc +=3D=20 > - E1000_READ_REG(&adapter->hw, E1000_ALGNERRC); > - adapter->stats.rxerrc +=3D=20 > - E1000_READ_REG(&adapter->hw, E1000_RXERRC); > - adapter->stats.tncrs +=3D=20 > - E1000_READ_REG(&adapter->hw, E1000_TNCRS); > - adapter->stats.cexterr +=3D=20 > - E1000_READ_REG(&adapter->hw, E1000_CEXTERR); > - adapter->stats.tsctc +=3D=20 > - E1000_READ_REG(&adapter->hw, E1000_TSCTC); > - adapter->stats.tsctfc +=3D=20 > - E1000_READ_REG(&adapter->hw, E1000_TSCTFC); > + stats->cbtmpc +=3D E1000_READ_REG(hw, E1000_CBTMPC); > + stats->htdpmc +=3D E1000_READ_REG(hw, E1000_HTDPMC); > + stats->cbrdpc +=3D E1000_READ_REG(hw, E1000_CBRDPC); > + stats->cbrmpc +=3D E1000_READ_REG(hw, E1000_CBRMPC); > + stats->rpthc +=3D E1000_READ_REG(hw, E1000_RPTHC); > + stats->hgptc +=3D E1000_READ_REG(hw, E1000_HGPTC); > + stats->htcbdpc +=3D E1000_READ_REG(hw, E1000_HTCBDPC); > + stats->hgorc +=3D (E1000_READ_REG(hw, E1000_HGORCL) + > + ((u64)E1000_READ_REG(hw, E1000_HGORCH) << 32)); > + stats->hgotc +=3D (E1000_READ_REG(hw, E1000_HGOTCL) + > + ((u64)E1000_READ_REG(hw, E1000_HGOTCH) << 32)); > + stats->lenerrs +=3D E1000_READ_REG(hw, E1000_LENERRS); > + stats->scvpc +=3D E1000_READ_REG(hw, E1000_SCVPC); > + stats->hrmpc +=3D E1000_READ_REG(hw, E1000_HRMPC); > + > + stats->algnerrc +=3D E1000_READ_REG(hw, E1000_ALGNERRC); > + stats->rxerrc +=3D E1000_READ_REG(hw, E1000_RXERRC); > + stats->tncrs +=3D E1000_READ_REG(hw, E1000_TNCRS); > + stats->cexterr +=3D E1000_READ_REG(hw, E1000_CEXTERR); > + stats->tsctc +=3D E1000_READ_REG(hw, E1000_TSCTC); > + stats->tsctfc +=3D E1000_READ_REG(hw, E1000_TSCTFC); > ifp =3D adapter->ifp; >=20 > - ifp->if_collisions =3D adapter->stats.colc; > + ifp =3D adapter->ifp; > + ifp->if_collisions =3D stats->colc; >=20 > /* Rx Errors */ > - ifp->if_ierrors =3D 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 =3D adapter->dropped_pkts + stats->rxerrc + > + stats->crcerrs + stats->algnerrc + > + stats->ruc + stats->roc + stats->mpc + stats->cexterr; >=20 > /* Tx Errors */ > - ifp->if_oerrors =3D adapter->stats.ecol + > - adapter->stats.latecol + adapter->watchdog_events; > + ifp->if_oerrors =3D stats->ecol + > + stats->latecol + adapter->watchdog_events; >=20 > /* Driver specific counters */ > - adapter->device_control =3D E1000_READ_REG(&adapter->hw, = E1000_CTRL); > - adapter->rx_control =3D E1000_READ_REG(&adapter->hw, = E1000_RCTL); > - adapter->int_mask =3D E1000_READ_REG(&adapter->hw, E1000_IMS); > - adapter->eint_mask =3D E1000_READ_REG(&adapter->hw, E1000_EIMS); > - adapter->packet_buf_alloc_tx =3D ((E1000_READ_REG(&adapter->hw, = E1000_PBA) > - & 0xffff0000) >> 16); > + adapter->device_control =3D E1000_READ_REG(hw, E1000_CTRL); > + adapter->rx_control =3D E1000_READ_REG(hw, E1000_RCTL); > + adapter->int_mask =3D E1000_READ_REG(hw, E1000_IMS); > + adapter->eint_mask =3D E1000_READ_REG(hw, E1000_EIMS); > + adapter->packet_buf_alloc_tx =3D > + ((E1000_READ_REG(hw, E1000_PBA) & 0xffff0000) >> 16); > + adapter->packet_buf_alloc_rx =3D > + ((E1000_READ_REG(hw, E1000_PBA) & 0xffff); > +} >=20 > - adapter->packet_buf_alloc_rx =3D (E1000_READ_REG(&adapter->hw, = E1000_PBA)=20 > - & 0xffff); >=20 > = +/********************************************************************** > + * > + * Initialize the VF board statistics counters. > + * > + = **********************************************************************/ > +static void > +igb_vf_init_stats(struct adapter *adapter) > +{ > + struct e1000_hw *hw =3D &adapter->hw; > + struct e1000_vf_stats *stats; > + > + stats =3D (struct e1000_vf_stats *)adapter->stats; > + > + stats->last_gprc =3D E1000_READ_REG(hw, E1000_VFGPRC); > + stats->last_gorc =3D E1000_READ_REG(hw, E1000_VFGORC); > + stats->last_gptc =3D E1000_READ_REG(hw, E1000_VFGPTC); > + stats->last_gotc =3D E1000_READ_REG(hw, E1000_VFGOTC); > + stats->last_mprc =3D E1000_READ_REG(hw, E1000_VFMPRC); > +} > +=20 > = +/********************************************************************** > + * > + * Update the VF board statistics counters. > + * > + = **********************************************************************/ > +static void > +igb_update_vf_stats_counters(struct adapter *adapter) > +{ > + struct e1000_hw *hw =3D &adapter->hw; > + struct e1000_vf_stats *stats; > + > + if (adapter->link_speed =3D=3D 0) > + return; > + > + stats =3D (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); > } >=20 >=20 > @@ -4895,10 +4994,14 @@ igb_add_hw_stats(struct adapter *adapter > queue_list =3D SYSCTL_CHILDREN(queue_node); >=20 > 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",=20 > CTLFLAG_RD, &txr->no_desc_avail, > @@ -4947,6 +5050,29 @@ igb_add_hw_stats(struct adapter *adapter > CTLFLAG_RD, NULL, "MAC Statistics"); > stat_list =3D SYSCTL_CHILDREN(stat_node); >=20 > + /* > + ** VF adapter has a very limited set of stats > + ** since its not managing the metal, so to speak. > + */ > + if (adapter->hw.mac.type =3D=3D 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",=20= > + CTLFLAG_RD, &adapter->stats.gorc,=20 > + "Good Octets Received");=20 > + SYSCTL_ADD_QUAD(ctx, stat_list, OID_AUTO, "good_octest_txd",=20 > + CTLFLAG_RD, &adapter->stats.gotc,=20 > + "Good Octest Transmitted");=20 > + 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",=20 > 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"); > +} >=20 >=20 > -} > = /********************************************************************** > * > * This routine provides a way to dump out the adapter eeprom, >=20 > Modified: head/sys/dev/e1000/if_igb.h > = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D > --- 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 @@ >=20 > #define IGB_TX_PTHRESH 8 > #define IGB_TX_HTHRESH 1 > -#define IGB_TX_WTHRESH ((hw->mac.type =3D=3D = e1000_82576 && \ > +#define IGB_TX_WTHRESH (((hw->mac.type =3D=3D = e1000_82576 || \ > + hw->mac.type =3D=3D = e1000_vfadapt) && \ > adapter->msix_mem) ? 1 : 16) >=20 > #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 */ > }; >=20 > /* > @@ -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 */ > }; >=20 > struct adapter { > @@ -449,7 +444,7 @@ struct adapter { > struct hwtstamp_ctrl hwtstamp; > #endif >=20 > - struct e1000_hw_stats stats; > + void *stats; > }; >=20 > /* = **************************************************************************= **** > @@ -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 =3D E1000_READ_REG(hw, reg); \ > + if (new < last) \ > + cur +=3D 0x100000000LL; \ > + last =3D new; \ > + cur &=3D 0xFFFFFFFF00000000LL; \ > + cur |=3D new; \ > +} >=20 > #endif /* _IGB_H_DEFINED_ */ >=20