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

Jack Vogel jfvogel at gmail.com
Wed Jun 30 20:41:10 UTC 2010


Yes, work is in progress to add it to ixgbe as well, it turned out to be a
bit messier
because the owners of the shared code did things a bit differently. I am
still designing
it so that its just a special case in the main driver, this is different
than Linux which made
both of them as seperate 'vf' driver.  Of course in Linux they actually have
the host side
support, ala PF, if the day ever comes that FreeBSD has such ability maybe
I'll have to
change it again... but not holding my breath.

I'd say the ixgbe changes might be ready in a few weeks.

Jack


On Wed, Jun 30, 2010 at 1:37 PM, Fabien Thomas <fabien.thomas at netasq.com>wrote:

> 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