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-all
mailing list