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_ */ > _______________________________________________ svn-src-head@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"