static int igb_setup_all_rx_resources(struct igb_adapter *);
static void igb_free_all_tx_resources(struct igb_adapter *);
static void igb_free_all_rx_resources(struct igb_adapter *);
+static void igb_setup_mrqc(struct igb_adapter *);
void igb_update_stats(struct igb_adapter *);
static int igb_probe(struct pci_dev *, const struct pci_device_id *);
static void __devexit igb_remove(struct pci_dev *pdev);
static int igb_close(struct net_device *);
static void igb_configure_tx(struct igb_adapter *);
static void igb_configure_rx(struct igb_adapter *);
-static void igb_setup_tctl(struct igb_adapter *);
-static void igb_setup_rctl(struct igb_adapter *);
static void igb_clean_all_tx_rings(struct igb_adapter *);
static void igb_clean_all_rx_rings(struct igb_adapter *);
static void igb_clean_tx_ring(struct igb_ring *);
static void igb_update_phy_info(unsigned long);
static void igb_watchdog(unsigned long);
static void igb_watchdog_task(struct work_struct *);
-static netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *,
- struct net_device *,
- struct igb_ring *);
-static netdev_tx_t igb_xmit_frame_adv(struct sk_buff *skb,
- struct net_device *);
+static netdev_tx_t igb_xmit_frame_adv(struct sk_buff *skb, struct net_device *);
static struct net_device_stats *igb_get_stats(struct net_device *);
static int igb_change_mtu(struct net_device *, int);
static int igb_set_mac(struct net_device *, void *);
static bool igb_clean_tx_irq(struct igb_q_vector *);
static int igb_poll(struct napi_struct *, int);
static bool igb_clean_rx_irq_adv(struct igb_q_vector *, int *, int);
-static void igb_alloc_rx_buffers_adv(struct igb_ring *, int);
static int igb_ioctl(struct net_device *, struct ifreq *, int cmd);
static void igb_tx_timeout(struct net_device *);
static void igb_reset_task(struct work_struct *);
static void igb_rar_set_qsel(struct igb_adapter *, u8 *, u32 , u8);
static void igb_ping_all_vfs(struct igb_adapter *);
static void igb_msg_task(struct igb_adapter *);
-static int igb_rcv_msg_from_vf(struct igb_adapter *, u32);
static void igb_vmm_control(struct igb_adapter *);
-static int igb_set_vf_mac(struct igb_adapter *adapter, int, unsigned char *);
+static int igb_set_vf_mac(struct igb_adapter *, int, unsigned char *);
static void igb_restore_vf_multicasts(struct igb_adapter *adapter);
static inline void igb_set_vmolr(struct e1000_hw *hw, int vfn)
MODULE_VERSION(DRV_VERSION);
/**
- * Scale the NIC clock cycle by a large factor so that
- * relatively small clock corrections can be added or
- * substracted at each clock tick. The drawbacks of a
- * large factor are a) that the clock register overflows
- * more quickly (not such a big deal) and b) that the
- * increment per tick has to fit into 24 bits.
- *
- * Note that
- * TIMINCA = IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS *
- * IGB_TSYNC_SCALE
- * TIMINCA += TIMINCA * adjustment [ppm] / 1e9
- *
- * The base scale factor is intentionally a power of two
- * so that the division in %struct timecounter can be done with
- * a shift.
- */
-#define IGB_TSYNC_SHIFT (19)
-#define IGB_TSYNC_SCALE (1<<IGB_TSYNC_SHIFT)
-
-/**
- * The duration of one clock cycle of the NIC.
- *
- * @todo This hard-coded value is part of the specification and might change
- * in future hardware revisions. Add revision check.
- */
-#define IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS 16
-
-#if (IGB_TSYNC_SCALE * IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS) >= (1<<24)
-# error IGB_TSYNC_SCALE and/or IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS are too large to fit into TIMINCA
-#endif
-
-/**
* igb_read_clock - read raw cycle counter (to be used by time counter)
*/
static cycle_t igb_read_clock(const struct cyclecounter *tc)
struct igb_adapter *adapter =
container_of(tc, struct igb_adapter, cycles);
struct e1000_hw *hw = &adapter->hw;
- u64 stamp;
-
- stamp = rd32(E1000_SYSTIML);
- stamp |= (u64)rd32(E1000_SYSTIMH) << 32ULL;
+ u64 stamp = 0;
+ int shift = 0;
+ stamp |= (u64)rd32(E1000_SYSTIML) << shift;
+ stamp |= (u64)rd32(E1000_SYSTIMH) << (shift + 32);
return stamp;
}
#endif
/**
- * igb_desc_unused - calculate if we have unused descriptors
- **/
-static int igb_desc_unused(struct igb_ring *ring)
-{
- if (ring->next_to_clean > ring->next_to_use)
- return ring->next_to_clean - ring->next_to_use - 1;
-
- return ring->count + ring->next_to_clean - ring->next_to_use - 1;
-}
-
-/**
* igb_init_module - Driver Registration Routine
*
* igb_init_module is the first routine called when the driver is
struct igb_ring *ring = &(adapter->tx_ring[i]);
ring->count = adapter->tx_ring_count;
ring->queue_index = i;
+ ring->pdev = adapter->pdev;
+ ring->netdev = adapter->netdev;
+ /* For 82575, context index must be unique per ring. */
+ if (adapter->hw.mac.type == e1000_82575)
+ ring->flags = IGB_RING_FLAG_TX_CTX_IDX;
}
+
for (i = 0; i < adapter->num_rx_queues; i++) {
struct igb_ring *ring = &(adapter->rx_ring[i]);
ring->count = adapter->rx_ring_count;
ring->queue_index = i;
+ ring->pdev = adapter->pdev;
+ ring->netdev = adapter->netdev;
+ ring->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
+ ring->flags = IGB_RING_FLAG_RX_CSUM; /* enable rx checksum */
+ /* set flag indicating ring supports SCTP checksum offload */
+ if (adapter->hw.mac.type >= e1000_82576)
+ ring->flags |= IGB_RING_FLAG_RX_SCTP_CSUM;
}
igb_cache_ring_register(adapter);
dev_info(&adapter->pdev->dev, "IOV Disabled\n");
}
#endif
+ adapter->vfs_allocated_count = 0;
+ adapter->flags |= IGB_FLAG_QUEUE_PAIRS;
adapter->num_rx_queues = 1;
adapter->num_tx_queues = 1;
adapter->num_q_vectors = 1;
q_vector = adapter->q_vector[v_idx];
q_vector->rx_ring = &adapter->rx_ring[ring_idx];
q_vector->rx_ring->q_vector = q_vector;
- q_vector->itr_val = adapter->itr;
+ q_vector->itr_val = adapter->rx_itr_setting;
+ if (q_vector->itr_val && q_vector->itr_val <= 3)
+ q_vector->itr_val = IGB_START_ITR;
}
static void igb_map_tx_ring_to_vector(struct igb_adapter *adapter,
q_vector = adapter->q_vector[v_idx];
q_vector->tx_ring = &adapter->tx_ring[ring_idx];
q_vector->tx_ring->q_vector = q_vector;
- q_vector->itr_val = adapter->itr;
+ q_vector->itr_val = adapter->tx_itr_setting;
+ if (q_vector->itr_val && q_vector->itr_val <= 3)
+ q_vector->itr_val = IGB_START_ITR;
}
/**
igb_restore_vlan(adapter);
igb_setup_tctl(adapter);
+ igb_setup_mrqc(adapter);
igb_setup_rctl(adapter);
igb_configure_tx(adapter);
if (adapter->msix_entries)
igb_configure_msix(adapter);
- igb_vmm_control(adapter);
igb_set_vmolr(hw, adapter->vfs_allocated_count);
/* Clear any pending interrupts. */
rd32(E1000_ICR);
igb_irq_enable(adapter);
+ /* notify VFs that reset has been completed */
+ if (adapter->vfs_allocated_count) {
+ u32 reg_data = rd32(E1000_CTRL_EXT);
+ reg_data |= E1000_CTRL_EXT_PFRSTD;
+ wr32(E1000_CTRL_EXT, reg_data);
+ }
+
netif_tx_start_all_queues(adapter->netdev);
/* Fire a link change interrupt to start the watchdog. */
*/
switch (mac->type) {
case e1000_82576:
- pba = E1000_PBA_64K;
+ pba = rd32(E1000_RXPBS);
+ pba &= E1000_RXPBS_SIZE_MASK_82576;
break;
case e1000_82575:
default:
if (adapter->vfs_allocated_count) {
int i;
for (i = 0 ; i < adapter->vfs_allocated_count; i++)
- adapter->vf_data[i].clear_to_send = false;
+ adapter->vf_data[i].flags = 0;
/* ping all the active vfs to let them know we are going down */
- igb_ping_all_vfs(adapter);
+ igb_ping_all_vfs(adapter);
/* disable transmits and receives */
wr32(E1000_VFRE, 0);
igb_get_bus_info_pcie(hw);
- /* set flags */
- switch (hw->mac.type) {
- case e1000_82575:
- adapter->flags |= IGB_FLAG_NEED_CTX_IDX;
- break;
- case e1000_82576:
- default:
- break;
- }
-
hw->phy.autoneg_wait_to_complete = false;
hw->mac.adaptive_ifs = true;
hw->fc.requested_mode = e1000_fc_default;
hw->fc.current_mode = e1000_fc_default;
- adapter->itr_setting = IGB_DEFAULT_ITR;
- adapter->itr = IGB_START_ITR;
-
igb_validate_mdi_setting(hw);
/* Initial Wake on LAN setting If APM wake is enabled in the EEPROM,
dev_info(&pdev->dev, "DCA enabled\n");
igb_setup_dca(adapter);
}
-#endif
- /*
- * Initialize hardware timer: we keep it running just in case
- * that some program needs it later on.
- */
- memset(&adapter->cycles, 0, sizeof(adapter->cycles));
- adapter->cycles.read = igb_read_clock;
- adapter->cycles.mask = CLOCKSOURCE_MASK(64);
- adapter->cycles.mult = 1;
- adapter->cycles.shift = IGB_TSYNC_SHIFT;
- wr32(E1000_TIMINCA,
- (1<<24) |
- IGB_TSYNC_CYCLE_TIME_IN_NANOSECONDS * IGB_TSYNC_SCALE);
-#if 0
- /*
- * Avoid rollover while we initialize by resetting the time counter.
- */
- wr32(E1000_SYSTIML, 0x00000000);
- wr32(E1000_SYSTIMH, 0x00000000);
-#else
- /*
- * Set registers so that rollover occurs soon to test this.
- */
- wr32(E1000_SYSTIML, 0x00000000);
- wr32(E1000_SYSTIMH, 0xFF800000);
#endif
- wrfl();
- timecounter_init(&adapter->clock,
- &adapter->cycles,
- ktime_to_ns(ktime_get_real()));
-
- /*
- * Synchronize our NIC clock against system wall clock. NIC
- * time stamp reading requires ~3us per sample, each sample
- * was pretty stable even under load => only require 10
- * samples for each offset comparison.
- */
- memset(&adapter->compare, 0, sizeof(adapter->compare));
- adapter->compare.source = &adapter->clock;
- adapter->compare.target = ktime_get_real;
- adapter->compare.num_samples = 10;
- timecompare_update(&adapter->compare, 0);
-#ifdef DEBUG
- {
- char buffer[160];
- printk(KERN_DEBUG
- "igb: %s: hw %p initialized timer\n",
- igb_get_time_str(adapter, buffer),
- &adapter->hw);
+ switch (hw->mac.type) {
+ case e1000_82576:
+ /*
+ * Initialize hardware timer: we keep it running just in case
+ * that some program needs it later on.
+ */
+ memset(&adapter->cycles, 0, sizeof(adapter->cycles));
+ adapter->cycles.read = igb_read_clock;
+ adapter->cycles.mask = CLOCKSOURCE_MASK(64);
+ adapter->cycles.mult = 1;
+ /**
+ * Scale the NIC clock cycle by a large factor so that
+ * relatively small clock corrections can be added or
+ * substracted at each clock tick. The drawbacks of a large
+ * factor are a) that the clock register overflows more quickly
+ * (not such a big deal) and b) that the increment per tick has
+ * to fit into 24 bits. As a result we need to use a shift of
+ * 19 so we can fit a value of 16 into the TIMINCA register.
+ */
+ adapter->cycles.shift = IGB_82576_TSYNC_SHIFT;
+ wr32(E1000_TIMINCA,
+ (1 << E1000_TIMINCA_16NS_SHIFT) |
+ (16 << IGB_82576_TSYNC_SHIFT));
+
+ /* Set registers so that rollover occurs soon to test this. */
+ wr32(E1000_SYSTIML, 0x00000000);
+ wr32(E1000_SYSTIMH, 0xFF800000);
+ wrfl();
+
+ timecounter_init(&adapter->clock,
+ &adapter->cycles,
+ ktime_to_ns(ktime_get_real()));
+ /*
+ * Synchronize our NIC clock against system wall clock. NIC
+ * time stamp reading requires ~3us per sample, each sample
+ * was pretty stable even under load => only require 10
+ * samples for each offset comparison.
+ */
+ memset(&adapter->compare, 0, sizeof(adapter->compare));
+ adapter->compare.source = &adapter->clock;
+ adapter->compare.target = ktime_get_real;
+ adapter->compare.num_samples = 10;
+ timecompare_update(&adapter->compare, 0);
+ break;
+ case e1000_82575:
+ /* 82575 does not support timesync */
+ default:
+ break;
}
-#endif
dev_info(&pdev->dev, "Intel(R) Gigabit Ethernet Network Connection\n");
/* print bus type/speed/width info */
adapter->tx_ring_count = IGB_DEFAULT_TXD;
adapter->rx_ring_count = IGB_DEFAULT_RXD;
- adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
+ adapter->rx_itr_setting = IGB_DEFAULT_ITR;
+ adapter->tx_itr_setting = IGB_DEFAULT_ITR;
+
adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
* clean_rx handler before we do so. */
igb_configure(adapter);
- igb_vmm_control(adapter);
igb_set_vmolr(hw, adapter->vfs_allocated_count);
err = igb_request_irq(adapter);
igb_irq_enable(adapter);
+ /* notify VFs that reset has been completed */
+ if (adapter->vfs_allocated_count) {
+ u32 reg_data = rd32(E1000_CTRL_EXT);
+ reg_data |= E1000_CTRL_EXT_PFRSTD;
+ wr32(E1000_CTRL_EXT, reg_data);
+ }
+
netif_tx_start_all_queues(netdev);
/* Fire a link status change interrupt to start the watchdog. */
/**
* igb_setup_tx_resources - allocate Tx resources (Descriptors)
- * @adapter: board private structure
* @tx_ring: tx descriptor ring (for a specific queue) to setup
*
* Return 0 on success, negative on failure
**/
-int igb_setup_tx_resources(struct igb_adapter *adapter,
- struct igb_ring *tx_ring)
+int igb_setup_tx_resources(struct igb_ring *tx_ring)
{
- struct pci_dev *pdev = adapter->pdev;
+ struct pci_dev *pdev = tx_ring->pdev;
int size;
size = sizeof(struct igb_buffer) * tx_ring->count;
int r_idx;
for (i = 0; i < adapter->num_tx_queues; i++) {
- err = igb_setup_tx_resources(adapter, &adapter->tx_ring[i]);
+ err = igb_setup_tx_resources(&adapter->tx_ring[i]);
if (err) {
dev_err(&adapter->pdev->dev,
"Allocation for Tx Queue %u failed\n", i);
* igb_setup_tctl - configure the transmit control registers
* @adapter: Board private structure
**/
-static void igb_setup_tctl(struct igb_adapter *adapter)
+void igb_setup_tctl(struct igb_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
u32 tctl;
*
* Configure a transmit ring after a reset.
**/
-static void igb_configure_tx_ring(struct igb_adapter *adapter,
- struct igb_ring *ring)
+void igb_configure_tx_ring(struct igb_adapter *adapter,
+ struct igb_ring *ring)
{
struct e1000_hw *hw = &adapter->hw;
u32 txdctl;
for (i = 0; i < adapter->num_tx_queues; i++)
igb_configure_tx_ring(adapter, &adapter->tx_ring[i]);
-
- /* Setup Transmit Descriptor Settings for eop descriptor */
- adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_RS;
}
/**
* igb_setup_rx_resources - allocate Rx resources (Descriptors)
- * @adapter: board private structure
* @rx_ring: rx descriptor ring (for a specific queue) to setup
*
* Returns 0 on success, negative on failure
**/
-int igb_setup_rx_resources(struct igb_adapter *adapter,
- struct igb_ring *rx_ring)
+int igb_setup_rx_resources(struct igb_ring *rx_ring)
{
- struct pci_dev *pdev = adapter->pdev;
+ struct pci_dev *pdev = rx_ring->pdev;
int size, desc_len;
size = sizeof(struct igb_buffer) * rx_ring->count;
err:
vfree(rx_ring->buffer_info);
- dev_err(&adapter->pdev->dev, "Unable to allocate memory for "
+ dev_err(&pdev->dev, "Unable to allocate memory for "
"the receive descriptor ring\n");
return -ENOMEM;
}
int i, err = 0;
for (i = 0; i < adapter->num_rx_queues; i++) {
- err = igb_setup_rx_resources(adapter, &adapter->rx_ring[i]);
+ err = igb_setup_rx_resources(&adapter->rx_ring[i]);
if (err) {
dev_err(&adapter->pdev->dev,
"Allocation for Rx Queue %u failed\n", i);
}
/**
+ * igb_setup_mrqc - configure the multiple receive queue control registers
+ * @adapter: Board private structure
+ **/
+static void igb_setup_mrqc(struct igb_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 mrqc, rxcsum;
+ u32 j, num_rx_queues, shift = 0, shift2 = 0;
+ union e1000_reta {
+ u32 dword;
+ u8 bytes[4];
+ } reta;
+ static const u8 rsshash[40] = {
+ 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, 0x41, 0x67,
+ 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, 0xd0, 0xca, 0x2b, 0xcb,
+ 0xae, 0x7b, 0x30, 0xb4, 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30,
+ 0xf2, 0x0c, 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa };
+
+ /* Fill out hash function seeds */
+ for (j = 0; j < 10; j++) {
+ u32 rsskey = rsshash[(j * 4)];
+ rsskey |= rsshash[(j * 4) + 1] << 8;
+ rsskey |= rsshash[(j * 4) + 2] << 16;
+ rsskey |= rsshash[(j * 4) + 3] << 24;
+ array_wr32(E1000_RSSRK(0), j, rsskey);
+ }
+
+ num_rx_queues = adapter->num_rx_queues;
+
+ if (adapter->vfs_allocated_count) {
+ /* 82575 and 82576 supports 2 RSS queues for VMDq */
+ switch (hw->mac.type) {
+ case e1000_82576:
+ shift = 3;
+ num_rx_queues = 2;
+ break;
+ case e1000_82575:
+ shift = 2;
+ shift2 = 6;
+ default:
+ break;
+ }
+ } else {
+ if (hw->mac.type == e1000_82575)
+ shift = 6;
+ }
+
+ for (j = 0; j < (32 * 4); j++) {
+ reta.bytes[j & 3] = (j % num_rx_queues) << shift;
+ if (shift2)
+ reta.bytes[j & 3] |= num_rx_queues << shift2;
+ if ((j & 3) == 3)
+ wr32(E1000_RETA(j >> 2), reta.dword);
+ }
+
+ /*
+ * Disable raw packet checksumming so that RSS hash is placed in
+ * descriptor on writeback. No need to enable TCP/UDP/IP checksum
+ * offloads as they are enabled by default
+ */
+ rxcsum = rd32(E1000_RXCSUM);
+ rxcsum |= E1000_RXCSUM_PCSD;
+
+ if (adapter->hw.mac.type >= e1000_82576)
+ /* Enable Receive Checksum Offload for SCTP */
+ rxcsum |= E1000_RXCSUM_CRCOFL;
+
+ /* Don't need to set TUOFL or IPOFL, they default to 1 */
+ wr32(E1000_RXCSUM, rxcsum);
+
+ /* If VMDq is enabled then we set the appropriate mode for that, else
+ * we default to RSS so that an RSS hash is calculated per packet even
+ * if we are only using one queue */
+ if (adapter->vfs_allocated_count) {
+ if (hw->mac.type > e1000_82575) {
+ /* Set the default pool for the PF's first queue */
+ u32 vtctl = rd32(E1000_VT_CTL);
+ vtctl &= ~(E1000_VT_CTL_DEFAULT_POOL_MASK |
+ E1000_VT_CTL_DISABLE_DEF_POOL);
+ vtctl |= adapter->vfs_allocated_count <<
+ E1000_VT_CTL_DEFAULT_POOL_SHIFT;
+ wr32(E1000_VT_CTL, vtctl);
+ }
+ if (adapter->num_rx_queues > 1)
+ mrqc = E1000_MRQC_ENABLE_VMDQ_RSS_2Q;
+ else
+ mrqc = E1000_MRQC_ENABLE_VMDQ;
+ } else {
+ mrqc = E1000_MRQC_ENABLE_RSS_4Q;
+ }
+ igb_vmm_control(adapter);
+
+ mrqc |= (E1000_MRQC_RSS_FIELD_IPV4 |
+ E1000_MRQC_RSS_FIELD_IPV4_TCP);
+ mrqc |= (E1000_MRQC_RSS_FIELD_IPV6 |
+ E1000_MRQC_RSS_FIELD_IPV6_TCP);
+ mrqc |= (E1000_MRQC_RSS_FIELD_IPV4_UDP |
+ E1000_MRQC_RSS_FIELD_IPV6_UDP);
+ mrqc |= (E1000_MRQC_RSS_FIELD_IPV6_UDP_EX |
+ E1000_MRQC_RSS_FIELD_IPV6_TCP_EX);
+
+ wr32(E1000_MRQC, mrqc);
+}
+
+/**
* igb_setup_rctl - configure the receive control registers
* @adapter: Board private structure
**/
-static void igb_setup_rctl(struct igb_adapter *adapter)
+void igb_setup_rctl(struct igb_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
u32 rctl;
}
/**
- * igb_configure_vt_default_pool - Configure VT default pool
- * @adapter: board private structure
- *
- * Configure the default pool
- **/
-static void igb_configure_vt_default_pool(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u16 pf_id = adapter->vfs_allocated_count;
- u32 vtctl;
-
- /* not in sr-iov mode - do nothing */
- if (!pf_id)
- return;
-
- vtctl = rd32(E1000_VT_CTL);
- vtctl &= ~(E1000_VT_CTL_DEFAULT_POOL_MASK |
- E1000_VT_CTL_DISABLE_DEF_POOL);
- vtctl |= pf_id << E1000_VT_CTL_DEFAULT_POOL_SHIFT;
- wr32(E1000_VT_CTL, vtctl);
-}
-
-/**
* igb_configure_rx_ring - Configure a receive ring after Reset
* @adapter: board private structure
* @ring: receive ring to be configured
*
* Configure the Rx unit of the MAC after a reset.
**/
-static void igb_configure_rx_ring(struct igb_adapter *adapter,
- struct igb_ring *ring)
+void igb_configure_rx_ring(struct igb_adapter *adapter,
+ struct igb_ring *ring)
{
struct e1000_hw *hw = &adapter->hw;
u64 rdba = ring->dma;
writel(0, ring->tail);
/* set descriptor configuration */
- if (adapter->rx_buffer_len < IGB_RXBUFFER_1024) {
- srrctl = ALIGN(adapter->rx_buffer_len, 64) <<
+ if (ring->rx_buffer_len < IGB_RXBUFFER_1024) {
+ srrctl = ALIGN(ring->rx_buffer_len, 64) <<
E1000_SRRCTL_BSIZEHDRSIZE_SHIFT;
#if (PAGE_SIZE / 2) > IGB_RXBUFFER_16384
srrctl |= IGB_RXBUFFER_16384 >>
#endif
srrctl |= E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
} else {
- srrctl = ALIGN(adapter->rx_buffer_len, 1024) >>
+ srrctl = ALIGN(ring->rx_buffer_len, 1024) >>
E1000_SRRCTL_BSIZEPKT_SHIFT;
srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF;
}
**/
static void igb_configure_rx(struct igb_adapter *adapter)
{
- struct e1000_hw *hw = &adapter->hw;
- u32 rctl, rxcsum;
int i;
- /* disable receives while setting up the descriptors */
- rctl = rd32(E1000_RCTL);
- wr32(E1000_RCTL, rctl & ~E1000_RCTL_EN);
- wrfl();
- mdelay(10);
-
- if (adapter->itr_setting > 3)
- wr32(E1000_ITR, adapter->itr);
-
- /* Setup the HW Rx Head and Tail Descriptor Pointers and
- * the Base and Length of the Rx Descriptor Ring */
- for (i = 0; i < adapter->num_rx_queues; i++)
- igb_configure_rx_ring(adapter, &adapter->rx_ring[i]);
-
- if (adapter->num_rx_queues > 1) {
- u32 random[10];
- u32 mrqc;
- u32 j, shift;
- union e1000_reta {
- u32 dword;
- u8 bytes[4];
- } reta;
-
- get_random_bytes(&random[0], 40);
-
- if (hw->mac.type >= e1000_82576)
- shift = 0;
- else
- shift = 6;
- for (j = 0; j < (32 * 4); j++) {
- reta.bytes[j & 3] =
- adapter->rx_ring[(j % adapter->num_rx_queues)].reg_idx << shift;
- if ((j & 3) == 3)
- writel(reta.dword,
- hw->hw_addr + E1000_RETA(0) + (j & ~3));
- }
- if (adapter->vfs_allocated_count)
- mrqc = E1000_MRQC_ENABLE_VMDQ_RSS_2Q;
- else
- mrqc = E1000_MRQC_ENABLE_RSS_4Q;
-
- /* Fill out hash function seeds */
- for (j = 0; j < 10; j++)
- array_wr32(E1000_RSSRK(0), j, random[j]);
-
- mrqc |= (E1000_MRQC_RSS_FIELD_IPV4 |
- E1000_MRQC_RSS_FIELD_IPV4_TCP);
- mrqc |= (E1000_MRQC_RSS_FIELD_IPV6 |
- E1000_MRQC_RSS_FIELD_IPV6_TCP);
- mrqc |= (E1000_MRQC_RSS_FIELD_IPV4_UDP |
- E1000_MRQC_RSS_FIELD_IPV6_UDP);
- mrqc |= (E1000_MRQC_RSS_FIELD_IPV6_UDP_EX |
- E1000_MRQC_RSS_FIELD_IPV6_TCP_EX);
-
- wr32(E1000_MRQC, mrqc);
- } else if (adapter->vfs_allocated_count) {
- /* Enable multi-queue for sr-iov */
- wr32(E1000_MRQC, E1000_MRQC_ENABLE_VMDQ);
- }
-
- /* Enable Receive Checksum Offload for TCP and UDP */
- rxcsum = rd32(E1000_RXCSUM);
- /* Disable raw packet checksumming */
- rxcsum |= E1000_RXCSUM_PCSD;
-
- if (adapter->hw.mac.type == e1000_82576)
- /* Enable Receive Checksum Offload for SCTP */
- rxcsum |= E1000_RXCSUM_CRCOFL;
-
- /* Don't need to set TUOFL or IPOFL, they default to 1 */
- wr32(E1000_RXCSUM, rxcsum);
-
- /* Set the default pool for the PF's first queue */
- igb_configure_vt_default_pool(adapter);
-
/* set UTA to appropriate mode */
igb_set_uta(adapter);
igb_rar_set_qsel(adapter, adapter->hw.mac.addr, 0,
adapter->vfs_allocated_count);
- igb_rlpml_set(adapter);
-
- /* Enable Receives */
- wr32(E1000_RCTL, rctl);
+ /* Setup the HW Rx Head and Tail Descriptor Pointers and
+ * the Base and Length of the Rx Descriptor Ring */
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ igb_configure_rx_ring(adapter, &adapter->rx_ring[i]);
}
/**
**/
void igb_free_tx_resources(struct igb_ring *tx_ring)
{
- struct pci_dev *pdev = tx_ring->q_vector->adapter->pdev;
-
igb_clean_tx_ring(tx_ring);
vfree(tx_ring->buffer_info);
tx_ring->buffer_info = NULL;
- pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);
+ pci_free_consistent(tx_ring->pdev, tx_ring->size,
+ tx_ring->desc, tx_ring->dma);
tx_ring->desc = NULL;
}
igb_free_tx_resources(&adapter->tx_ring[i]);
}
-static void igb_unmap_and_free_tx_resource(struct igb_adapter *adapter,
- struct igb_buffer *buffer_info)
+void igb_unmap_and_free_tx_resource(struct igb_ring *tx_ring,
+ struct igb_buffer *buffer_info)
{
buffer_info->dma = 0;
if (buffer_info->skb) {
- skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb,
+ skb_dma_unmap(&tx_ring->pdev->dev,
+ buffer_info->skb,
DMA_TO_DEVICE);
dev_kfree_skb_any(buffer_info->skb);
buffer_info->skb = NULL;
**/
static void igb_clean_tx_ring(struct igb_ring *tx_ring)
{
- struct igb_adapter *adapter = tx_ring->q_vector->adapter;
struct igb_buffer *buffer_info;
unsigned long size;
unsigned int i;
for (i = 0; i < tx_ring->count; i++) {
buffer_info = &tx_ring->buffer_info[i];
- igb_unmap_and_free_tx_resource(adapter, buffer_info);
+ igb_unmap_and_free_tx_resource(tx_ring, buffer_info);
}
size = sizeof(struct igb_buffer) * tx_ring->count;
**/
void igb_free_rx_resources(struct igb_ring *rx_ring)
{
- struct pci_dev *pdev = rx_ring->q_vector->adapter->pdev;
-
igb_clean_rx_ring(rx_ring);
vfree(rx_ring->buffer_info);
rx_ring->buffer_info = NULL;
- pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
+ pci_free_consistent(rx_ring->pdev, rx_ring->size,
+ rx_ring->desc, rx_ring->dma);
rx_ring->desc = NULL;
}
**/
static void igb_clean_rx_ring(struct igb_ring *rx_ring)
{
- struct igb_adapter *adapter = rx_ring->q_vector->adapter;
struct igb_buffer *buffer_info;
- struct pci_dev *pdev = adapter->pdev;
unsigned long size;
unsigned int i;
for (i = 0; i < rx_ring->count; i++) {
buffer_info = &rx_ring->buffer_info[i];
if (buffer_info->dma) {
- pci_unmap_single(pdev, buffer_info->dma,
- adapter->rx_buffer_len,
+ pci_unmap_single(rx_ring->pdev,
+ buffer_info->dma,
+ rx_ring->rx_buffer_len,
PCI_DMA_FROMDEVICE);
buffer_info->dma = 0;
}
buffer_info->skb = NULL;
}
if (buffer_info->page_dma) {
- pci_unmap_page(pdev, buffer_info->page_dma,
+ pci_unmap_page(rx_ring->pdev,
+ buffer_info->page_dma,
PAGE_SIZE / 2,
PCI_DMA_FROMDEVICE);
buffer_info->page_dma = 0;
latency_invalid = 255
};
-
/**
* igb_update_ring_itr - update the dynamic ITR value based on packet size
*
current_itr = max(adapter->rx_itr, adapter->tx_itr);
/* conservative mode (itr 3) eliminates the lowest_latency setting */
- if (adapter->itr_setting == 3 && current_itr == lowest_latency)
+ if (adapter->rx_itr_setting == 3 && current_itr == lowest_latency)
current_itr = low_latency;
switch (current_itr) {
#define IGB_TX_FLAGS_VLAN_MASK 0xffff0000
#define IGB_TX_FLAGS_VLAN_SHIFT 16
-static inline int igb_tso_adv(struct igb_adapter *adapter,
- struct igb_ring *tx_ring,
+static inline int igb_tso_adv(struct igb_ring *tx_ring,
struct sk_buff *skb, u32 tx_flags, u8 *hdr_len)
{
struct e1000_adv_tx_context_desc *context_desc;
mss_l4len_idx |= (l4len << E1000_ADVTXD_L4LEN_SHIFT);
/* For 82575, context index must be unique per ring. */
- if (adapter->flags & IGB_FLAG_NEED_CTX_IDX)
- mss_l4len_idx |= tx_ring->queue_index << 4;
+ if (tx_ring->flags & IGB_RING_FLAG_TX_CTX_IDX)
+ mss_l4len_idx |= tx_ring->reg_idx << 4;
context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx);
context_desc->seqnum_seed = 0;
return true;
}
-static inline bool igb_tx_csum_adv(struct igb_adapter *adapter,
- struct igb_ring *tx_ring,
- struct sk_buff *skb, u32 tx_flags)
+static inline bool igb_tx_csum_adv(struct igb_ring *tx_ring,
+ struct sk_buff *skb, u32 tx_flags)
{
struct e1000_adv_tx_context_desc *context_desc;
- unsigned int i;
+ struct pci_dev *pdev = tx_ring->pdev;
struct igb_buffer *buffer_info;
u32 info = 0, tu_cmd = 0;
+ unsigned int i;
if ((skb->ip_summed == CHECKSUM_PARTIAL) ||
(tx_flags & IGB_TX_FLAGS_VLAN)) {
break;
default:
if (unlikely(net_ratelimit()))
- dev_warn(&adapter->pdev->dev,
+ dev_warn(&pdev->dev,
"partial checksum but proto=%x!\n",
skb->protocol);
break;
context_desc->type_tucmd_mlhl = cpu_to_le32(tu_cmd);
context_desc->seqnum_seed = 0;
- if (adapter->flags & IGB_FLAG_NEED_CTX_IDX)
+ if (tx_ring->flags & IGB_RING_FLAG_TX_CTX_IDX)
context_desc->mss_l4len_idx =
- cpu_to_le32(tx_ring->queue_index << 4);
- else
- context_desc->mss_l4len_idx = 0;
+ cpu_to_le32(tx_ring->reg_idx << 4);
buffer_info->time_stamp = jiffies;
buffer_info->next_to_watch = i;
#define IGB_MAX_TXD_PWR 16
#define IGB_MAX_DATA_PER_TXD (1<<IGB_MAX_TXD_PWR)
-static inline int igb_tx_map_adv(struct igb_adapter *adapter,
- struct igb_ring *tx_ring, struct sk_buff *skb,
+static inline int igb_tx_map_adv(struct igb_ring *tx_ring, struct sk_buff *skb,
unsigned int first)
{
struct igb_buffer *buffer_info;
+ struct pci_dev *pdev = tx_ring->pdev;
unsigned int len = skb_headlen(skb);
unsigned int count = 0, i;
unsigned int f;
i = tx_ring->next_to_use;
- if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
- dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
+ if (skb_dma_map(&pdev->dev, skb, DMA_TO_DEVICE)) {
+ dev_err(&pdev->dev, "TX DMA map failed\n");
return 0;
}
return count + 1;
}
-static inline void igb_tx_queue_adv(struct igb_adapter *adapter,
- struct igb_ring *tx_ring,
+static inline void igb_tx_queue_adv(struct igb_ring *tx_ring,
int tx_flags, int count, u32 paylen,
u8 hdr_len)
{
olinfo_status |= E1000_TXD_POPTS_TXSM << 8;
}
- if ((adapter->flags & IGB_FLAG_NEED_CTX_IDX) &&
- (tx_flags & (IGB_TX_FLAGS_CSUM | IGB_TX_FLAGS_TSO |
+ if ((tx_ring->flags & IGB_RING_FLAG_TX_CTX_IDX) &&
+ (tx_flags & (IGB_TX_FLAGS_CSUM |
+ IGB_TX_FLAGS_TSO |
IGB_TX_FLAGS_VLAN)))
- olinfo_status |= tx_ring->queue_index << 4;
+ olinfo_status |= tx_ring->reg_idx << 4;
olinfo_status |= ((paylen - hdr_len) << E1000_ADVTXD_PAYLEN_SHIFT);
i = 0;
}
- tx_desc->read.cmd_type_len |= cpu_to_le32(adapter->txd_cmd);
+ tx_desc->read.cmd_type_len |= cpu_to_le32(IGB_ADVTXD_DCMD);
/* Force memory writes to complete before letting h/w
* know there are new descriptors to fetch. (Only
* applicable for weak-ordered memory model archs,
mmiowb();
}
-static int __igb_maybe_stop_tx(struct net_device *netdev,
- struct igb_ring *tx_ring, int size)
+static int __igb_maybe_stop_tx(struct igb_ring *tx_ring, int size)
{
- struct igb_adapter *adapter = netdev_priv(netdev);
+ struct net_device *netdev = tx_ring->netdev;
netif_stop_subqueue(netdev, tx_ring->queue_index);
/* A reprieve! */
netif_wake_subqueue(netdev, tx_ring->queue_index);
- ++adapter->restart_queue;
+ tx_ring->tx_stats.restart_queue++;
return 0;
}
-static int igb_maybe_stop_tx(struct net_device *netdev,
- struct igb_ring *tx_ring, int size)
+static int igb_maybe_stop_tx(struct igb_ring *tx_ring, int size)
{
if (igb_desc_unused(tx_ring) >= size)
return 0;
- return __igb_maybe_stop_tx(netdev, tx_ring, size);
+ return __igb_maybe_stop_tx(tx_ring, size);
}
-static netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb,
- struct net_device *netdev,
- struct igb_ring *tx_ring)
+netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb,
+ struct igb_ring *tx_ring)
{
- struct igb_adapter *adapter = netdev_priv(netdev);
+ struct igb_adapter *adapter = netdev_priv(tx_ring->netdev);
unsigned int first;
unsigned int tx_flags = 0;
u8 hdr_len = 0;
int count = 0;
int tso = 0;
- union skb_shared_tx *shtx;
-
- if (test_bit(__IGB_DOWN, &adapter->state)) {
- dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
- }
-
- if (skb->len <= 0) {
- dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
- }
+ union skb_shared_tx *shtx = skb_tx(skb);
/* need: 1 descriptor per page,
* + 2 desc gap to keep tail from touching head,
* + 1 desc for skb->data,
* + 1 desc for context descriptor,
* otherwise try next time */
- if (igb_maybe_stop_tx(netdev, tx_ring, skb_shinfo(skb)->nr_frags + 4)) {
+ if (igb_maybe_stop_tx(tx_ring, skb_shinfo(skb)->nr_frags + 4)) {
/* this is a hard error */
return NETDEV_TX_BUSY;
}
- /*
- * TODO: check that there currently is no other packet with
- * time stamping in the queue
- *
- * When doing time stamping, keep the connection to the socket
- * a while longer: it is still needed by skb_hwtstamp_tx(),
- * called either in igb_tx_hwtstamp() or by our caller when
- * doing software time stamping.
- */
- shtx = skb_tx(skb);
if (unlikely(shtx->hardware)) {
shtx->in_progress = 1;
tx_flags |= IGB_TX_FLAGS_TSTAMP;
tx_flags |= IGB_TX_FLAGS_IPV4;
first = tx_ring->next_to_use;
- tso = skb_is_gso(skb) ? igb_tso_adv(adapter, tx_ring, skb, tx_flags,
- &hdr_len) : 0;
-
- if (tso < 0) {
- dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
+ if (skb_is_gso(skb)) {
+ tso = igb_tso_adv(tx_ring, skb, tx_flags, &hdr_len);
+ if (tso < 0) {
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
}
if (tso)
tx_flags |= IGB_TX_FLAGS_TSO;
- else if (igb_tx_csum_adv(adapter, tx_ring, skb, tx_flags) &&
+ else if (igb_tx_csum_adv(tx_ring, skb, tx_flags) &&
(skb->ip_summed == CHECKSUM_PARTIAL))
tx_flags |= IGB_TX_FLAGS_CSUM;
* count reflects descriptors mapped, if 0 then mapping error
* has occured and we need to rewind the descriptor queue
*/
- count = igb_tx_map_adv(adapter, tx_ring, skb, first);
+ count = igb_tx_map_adv(tx_ring, skb, first);
- if (count) {
- igb_tx_queue_adv(adapter, tx_ring, tx_flags, count,
- skb->len, hdr_len);
- /* Make sure there is space in the ring for the next send. */
- igb_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 4);
- } else {
+ if (!count) {
dev_kfree_skb_any(skb);
tx_ring->buffer_info[first].time_stamp = 0;
tx_ring->next_to_use = first;
+ return NETDEV_TX_OK;
}
+ igb_tx_queue_adv(tx_ring, tx_flags, count, skb->len, hdr_len);
+
+ /* Make sure there is space in the ring for the next send. */
+ igb_maybe_stop_tx(tx_ring, MAX_SKB_FRAGS + 4);
+
return NETDEV_TX_OK;
}
{
struct igb_adapter *adapter = netdev_priv(netdev);
struct igb_ring *tx_ring;
-
int r_idx = 0;
+
+ if (test_bit(__IGB_DOWN, &adapter->state)) {
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+
+ if (skb->len <= 0) {
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+
r_idx = skb->queue_mapping & (IGB_ABS_MAX_TX_QUEUES - 1);
tx_ring = adapter->multi_tx_table[r_idx];
* to a flow. Right now, performance is impacted slightly negatively
* if using multiple tx queues. If the stack breaks away from a
* single qdisc implementation, we can look at this again. */
- return igb_xmit_frame_ring_adv(skb, netdev, tx_ring);
+ return igb_xmit_frame_ring_adv(skb, tx_ring);
}
/**
{
struct igb_adapter *adapter = netdev_priv(netdev);
int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
+ u32 rx_buffer_len, i;
if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
(max_frame > MAX_JUMBO_FRAME_SIZE)) {
/* igb_down has a dependency on max_frame_size */
adapter->max_frame_size = max_frame;
- if (netif_running(netdev))
- igb_down(adapter);
-
/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
* means we reserve 2 more, this pushes us to allocate from the next
* larger slab size.
*/
if (max_frame <= IGB_RXBUFFER_1024)
- adapter->rx_buffer_len = IGB_RXBUFFER_1024;
+ rx_buffer_len = IGB_RXBUFFER_1024;
else if (max_frame <= MAXIMUM_ETHERNET_VLAN_SIZE)
- adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
+ rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
else
- adapter->rx_buffer_len = IGB_RXBUFFER_128;
+ rx_buffer_len = IGB_RXBUFFER_128;
+
+ if (netif_running(netdev))
+ igb_down(adapter);
dev_info(&adapter->pdev->dev, "changing MTU from %d to %d\n",
netdev->mtu, new_mtu);
netdev->mtu = new_mtu;
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ adapter->rx_ring[i].rx_buffer_len = rx_buffer_len;
+
if (netif_running(netdev))
igb_up(adapter);
else
for (i = 0 ; i < adapter->vfs_allocated_count; i++) {
ping = E1000_PF_CONTROL_MSG;
- if (adapter->vf_data[i].clear_to_send)
+ if (adapter->vf_data[i].flags & IGB_VF_FLAG_CTS)
ping |= E1000_VT_MSGTYPE_CTS;
igb_write_mbx(hw, &ping, 1, i);
}
return igb_vlvf_set(adapter, vid, add, vf);
}
-static inline void igb_vf_reset_event(struct igb_adapter *adapter, u32 vf)
+static inline void igb_vf_reset(struct igb_adapter *adapter, u32 vf)
{
- struct e1000_hw *hw = &adapter->hw;
-
- /* disable mailbox functionality for vf */
- adapter->vf_data[vf].clear_to_send = false;
+ /* clear all flags */
+ adapter->vf_data[vf].flags = 0;
+ adapter->vf_data[vf].last_nack = jiffies;
/* reset offloads to defaults */
- igb_set_vmolr(hw, vf);
+ igb_set_vmolr(&adapter->hw, vf);
/* reset vlans for device */
igb_clear_vf_vfta(adapter, vf);
igb_set_rx_mode(adapter->netdev);
}
-static inline void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf)
+static void igb_vf_reset_event(struct igb_adapter *adapter, u32 vf)
+{
+ unsigned char *vf_mac = adapter->vf_data[vf].vf_mac_addresses;
+
+ /* generate a new mac address as we were hotplug removed/added */
+ random_ether_addr(vf_mac);
+
+ /* process remaining reset events */
+ igb_vf_reset(adapter, vf);
+}
+
+static void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf)
{
struct e1000_hw *hw = &adapter->hw;
unsigned char *vf_mac = adapter->vf_data[vf].vf_mac_addresses;
u8 *addr = (u8 *)(&msgbuf[1]);
/* process all the same items cleared in a function level reset */
- igb_vf_reset_event(adapter, vf);
+ igb_vf_reset(adapter, vf);
/* set vf mac address */
igb_rar_set_qsel(adapter, vf_mac, rar_entry, vf);
reg = rd32(E1000_VFRE);
wr32(E1000_VFRE, reg | (1 << vf));
- /* enable mailbox functionality for vf */
- adapter->vf_data[vf].clear_to_send = true;
+ adapter->vf_data[vf].flags = IGB_VF_FLAG_CTS;
/* reply to reset with ack and vf mac address */
msgbuf[0] = E1000_VF_RESET | E1000_VT_MSGTYPE_ACK;
static int igb_set_vf_mac_addr(struct igb_adapter *adapter, u32 *msg, int vf)
{
- unsigned char *addr = (char *)&msg[1];
- int err = -1;
-
- if (is_valid_ether_addr(addr))
- err = igb_set_vf_mac(adapter, vf, addr);
+ unsigned char *addr = (char *)&msg[1];
+ int err = -1;
- return err;
+ if (is_valid_ether_addr(addr))
+ err = igb_set_vf_mac(adapter, vf, addr);
+ return err;
}
static void igb_rcv_ack_from_vf(struct igb_adapter *adapter, u32 vf)
{
struct e1000_hw *hw = &adapter->hw;
+ struct vf_data_storage *vf_data = &adapter->vf_data[vf];
u32 msg = E1000_VT_MSGTYPE_NACK;
/* if device isn't clear to send it shouldn't be reading either */
- if (!adapter->vf_data[vf].clear_to_send)
+ if (!(vf_data->flags & IGB_VF_FLAG_CTS) &&
+ time_after(jiffies, vf_data->last_nack + (2 * HZ))) {
igb_write_mbx(hw, &msg, 1, vf);
-}
-
-
-static void igb_msg_task(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
- u32 vf;
-
- for (vf = 0; vf < adapter->vfs_allocated_count; vf++) {
- /* process any reset requests */
- if (!igb_check_for_rst(hw, vf)) {
- adapter->vf_data[vf].clear_to_send = false;
- igb_vf_reset_event(adapter, vf);
- }
-
- /* process any messages pending */
- if (!igb_check_for_msg(hw, vf))
- igb_rcv_msg_from_vf(adapter, vf);
-
- /* process any acks */
- if (!igb_check_for_ack(hw, vf))
- igb_rcv_ack_from_vf(adapter, vf);
-
+ vf_data->last_nack = jiffies;
}
}
-static int igb_rcv_msg_from_vf(struct igb_adapter *adapter, u32 vf)
+static void igb_rcv_msg_from_vf(struct igb_adapter *adapter, u32 vf)
{
- u32 mbx_size = E1000_VFMAILBOX_SIZE;
- u32 msgbuf[mbx_size];
+ struct pci_dev *pdev = adapter->pdev;
+ u32 msgbuf[E1000_VFMAILBOX_SIZE];
struct e1000_hw *hw = &adapter->hw;
+ struct vf_data_storage *vf_data = &adapter->vf_data[vf];
s32 retval;
- retval = igb_read_mbx(hw, msgbuf, mbx_size, vf);
+ retval = igb_read_mbx(hw, msgbuf, E1000_VFMAILBOX_SIZE, vf);
if (retval)
- dev_err(&adapter->pdev->dev,
- "Error receiving message from VF\n");
+ dev_err(&pdev->dev, "Error receiving message from VF\n");
/* this is a message we already processed, do nothing */
if (msgbuf[0] & (E1000_VT_MSGTYPE_ACK | E1000_VT_MSGTYPE_NACK))
- return retval;
+ return;
/*
* until the vf completes a reset it should not be
if (msgbuf[0] == E1000_VF_RESET) {
igb_vf_reset_msg(adapter, vf);
-
- return retval;
+ return;
}
- if (!adapter->vf_data[vf].clear_to_send) {
- msgbuf[0] |= E1000_VT_MSGTYPE_NACK;
- igb_write_mbx(hw, msgbuf, 1, vf);
- return retval;
+ if (!(vf_data->flags & IGB_VF_FLAG_CTS)) {
+ msgbuf[0] = E1000_VT_MSGTYPE_NACK;
+ if (time_after(jiffies, vf_data->last_nack + (2 * HZ))) {
+ igb_write_mbx(hw, msgbuf, 1, vf);
+ vf_data->last_nack = jiffies;
+ }
+ return;
}
switch ((msgbuf[0] & 0xFFFF)) {
msgbuf[0] |= E1000_VT_MSGTYPE_CTS;
igb_write_mbx(hw, msgbuf, 1, vf);
+}
- return retval;
+static void igb_msg_task(struct igb_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 vf;
+
+ for (vf = 0; vf < adapter->vfs_allocated_count; vf++) {
+ /* process any reset requests */
+ if (!igb_check_for_rst(hw, vf))
+ igb_vf_reset_event(adapter, vf);
+
+ /* process any messages pending */
+ if (!igb_check_for_msg(hw, vf))
+ igb_rcv_msg_from_vf(adapter, vf);
+
+ /* process any acks */
+ if (!igb_check_for_ack(hw, vf))
+ igb_rcv_ack_from_vf(adapter, vf);
+ }
}
/**
struct igb_adapter *adapter = q_vector->adapter;
struct e1000_hw *hw = &adapter->hw;
- if (adapter->itr_setting & 3) {
+ if ((q_vector->rx_ring && (adapter->rx_itr_setting & 3)) ||
+ (!q_vector->rx_ring && (adapter->tx_itr_setting & 3))) {
if (!adapter->msix_entries)
igb_set_itr(adapter);
else
}
/**
- * igb_hwtstamp - utility function which checks for TX time stamp
+ * igb_systim_to_hwtstamp - convert system time value to hw timestamp
* @adapter: board private structure
+ * @shhwtstamps: timestamp structure to update
+ * @regval: unsigned 64bit system time value.
+ *
+ * We need to convert the system time value stored in the RX/TXSTMP registers
+ * into a hwtstamp which can be used by the upper level timestamping functions
+ */
+static void igb_systim_to_hwtstamp(struct igb_adapter *adapter,
+ struct skb_shared_hwtstamps *shhwtstamps,
+ u64 regval)
+{
+ u64 ns;
+
+ ns = timecounter_cyc2time(&adapter->clock, regval);
+ timecompare_update(&adapter->compare, ns);
+ memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps));
+ shhwtstamps->hwtstamp = ns_to_ktime(ns);
+ shhwtstamps->syststamp = timecompare_transform(&adapter->compare, ns);
+}
+
+/**
+ * igb_tx_hwtstamp - utility function which checks for TX time stamp
+ * @q_vector: pointer to q_vector containing needed info
* @skb: packet that was just sent
*
* If we were asked to do hardware stamping and such a time stamp is
* available, then it must have been for this skb here because we only
* allow only one such packet into the queue.
*/
-static void igb_tx_hwtstamp(struct igb_adapter *adapter, struct sk_buff *skb)
+static void igb_tx_hwtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb)
{
+ struct igb_adapter *adapter = q_vector->adapter;
union skb_shared_tx *shtx = skb_tx(skb);
struct e1000_hw *hw = &adapter->hw;
+ struct skb_shared_hwtstamps shhwtstamps;
+ u64 regval;
- if (unlikely(shtx->hardware)) {
- u32 valid = rd32(E1000_TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID;
- if (valid) {
- u64 regval = rd32(E1000_TXSTMPL);
- u64 ns;
- struct skb_shared_hwtstamps shhwtstamps;
-
- memset(&shhwtstamps, 0, sizeof(shhwtstamps));
- regval |= (u64)rd32(E1000_TXSTMPH) << 32;
- ns = timecounter_cyc2time(&adapter->clock,
- regval);
- timecompare_update(&adapter->compare, ns);
- shhwtstamps.hwtstamp = ns_to_ktime(ns);
- shhwtstamps.syststamp =
- timecompare_transform(&adapter->compare, ns);
- skb_tstamp_tx(skb, &shhwtstamps);
- }
- }
+ /* if skb does not support hw timestamp or TX stamp not valid exit */
+ if (likely(!shtx->hardware) ||
+ !(rd32(E1000_TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID))
+ return;
+
+ regval = rd32(E1000_TXSTMPL);
+ regval |= (u64)rd32(E1000_TXSTMPH) << 32;
+
+ igb_systim_to_hwtstamp(adapter, &shhwtstamps, regval);
+ skb_tstamp_tx(skb, &shhwtstamps);
}
/**
{
struct igb_adapter *adapter = q_vector->adapter;
struct igb_ring *tx_ring = q_vector->tx_ring;
- struct net_device *netdev = adapter->netdev;
+ struct net_device *netdev = tx_ring->netdev;
struct e1000_hw *hw = &adapter->hw;
struct igb_buffer *buffer_info;
struct sk_buff *skb;
total_packets += segs;
total_bytes += bytecount;
- igb_tx_hwtstamp(adapter, skb);
+ igb_tx_hwtstamp(q_vector, skb);
}
- igb_unmap_and_free_tx_resource(adapter, buffer_info);
+ igb_unmap_and_free_tx_resource(tx_ring, buffer_info);
tx_desc->wb.status = 0;
i++;
if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) &&
!(test_bit(__IGB_DOWN, &adapter->state))) {
netif_wake_subqueue(netdev, tx_ring->queue_index);
- ++adapter->restart_queue;
+ tx_ring->tx_stats.restart_queue++;
}
}
E1000_STATUS_TXOFF)) {
/* detected Tx unit hang */
- dev_err(&adapter->pdev->dev,
+ dev_err(&tx_ring->pdev->dev,
"Detected Tx Unit Hang\n"
" Tx Queue <%d>\n"
" TDH <%x>\n"
napi_gro_receive(&q_vector->napi, skb);
}
-static inline void igb_rx_checksum_adv(struct igb_adapter *adapter,
+static inline void igb_rx_checksum_adv(struct igb_ring *ring,
u32 status_err, struct sk_buff *skb)
{
skb->ip_summed = CHECKSUM_NONE;
/* Ignore Checksum bit is set or checksum is disabled through ethtool */
- if ((status_err & E1000_RXD_STAT_IXSM) ||
- (adapter->flags & IGB_FLAG_RX_CSUM_DISABLED))
+ if (!(ring->flags & IGB_RING_FLAG_RX_CSUM) ||
+ (status_err & E1000_RXD_STAT_IXSM))
return;
+
/* TCP/UDP checksum error bit is set */
if (status_err &
(E1000_RXDEXT_STATERR_TCPE | E1000_RXDEXT_STATERR_IPE)) {
* L4E bit is set incorrectly on 64 byte (60 byte w/o crc)
* packets, (aka let the stack check the crc32c)
*/
- if (!((adapter->hw.mac.type == e1000_82576) &&
- (skb->len == 60)))
- adapter->hw_csum_err++;
+ if ((skb->len == 60) &&
+ (ring->flags & IGB_RING_FLAG_RX_SCTP_CSUM))
+ ring->rx_stats.csum_err++;
+
/* let the stack verify checksum errors */
return;
}
if (status_err & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS))
skb->ip_summed = CHECKSUM_UNNECESSARY;
- dev_dbg(&adapter->pdev->dev, "cksum success: bits %08X\n", status_err);
+ dev_dbg(&ring->pdev->dev, "cksum success: bits %08X\n", status_err);
}
-static inline u16 igb_get_hlen(struct igb_adapter *adapter,
+static inline void igb_rx_hwtstamp(struct igb_q_vector *q_vector, u32 staterr,
+ struct sk_buff *skb)
+{
+ struct igb_adapter *adapter = q_vector->adapter;
+ struct e1000_hw *hw = &adapter->hw;
+ u64 regval;
+
+ /*
+ * If this bit is set, then the RX registers contain the time stamp. No
+ * other packet will be time stamped until we read these registers, so
+ * read the registers to make them available again. Because only one
+ * packet can be time stamped at a time, we know that the register
+ * values must belong to this one here and therefore we don't need to
+ * compare any of the additional attributes stored for it.
+ *
+ * If nothing went wrong, then it should have a skb_shared_tx that we
+ * can turn into a skb_shared_hwtstamps.
+ */
+ if (likely(!(staterr & E1000_RXDADV_STAT_TS)))
+ return;
+ if (!(rd32(E1000_TSYNCRXCTL) & E1000_TSYNCRXCTL_VALID))
+ return;
+
+ regval = rd32(E1000_RXSTMPL);
+ regval |= (u64)rd32(E1000_RXSTMPH) << 32;
+
+ igb_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), regval);
+}
+static inline u16 igb_get_hlen(struct igb_ring *rx_ring,
union e1000_adv_rx_desc *rx_desc)
{
/* HW will not DMA in data larger than the given buffer, even if it
*/
u16 hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hdr_info) &
E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT;
- if (hlen > adapter->rx_buffer_len)
- hlen = adapter->rx_buffer_len;
+ if (hlen > rx_ring->rx_buffer_len)
+ hlen = rx_ring->rx_buffer_len;
return hlen;
}
static bool igb_clean_rx_irq_adv(struct igb_q_vector *q_vector,
int *work_done, int budget)
{
- struct igb_adapter *adapter = q_vector->adapter;
- struct net_device *netdev = adapter->netdev;
struct igb_ring *rx_ring = q_vector->rx_ring;
- struct e1000_hw *hw = &adapter->hw;
- struct pci_dev *pdev = adapter->pdev;
+ struct net_device *netdev = rx_ring->netdev;
+ struct pci_dev *pdev = rx_ring->pdev;
union e1000_adv_rx_desc *rx_desc , *next_rxd;
struct igb_buffer *buffer_info , *next_buffer;
struct sk_buff *skb;
if (buffer_info->dma) {
pci_unmap_single(pdev, buffer_info->dma,
- adapter->rx_buffer_len,
+ rx_ring->rx_buffer_len,
PCI_DMA_FROMDEVICE);
buffer_info->dma = 0;
- if (adapter->rx_buffer_len >= IGB_RXBUFFER_1024) {
+ if (rx_ring->rx_buffer_len >= IGB_RXBUFFER_1024) {
skb_put(skb, length);
goto send_up;
}
- skb_put(skb, igb_get_hlen(adapter, rx_desc));
+ skb_put(skb, igb_get_hlen(rx_ring, rx_desc));
}
if (length) {
goto next_desc;
}
send_up:
- /*
- * If this bit is set, then the RX registers contain
- * the time stamp. No other packet will be time
- * stamped until we read these registers, so read the
- * registers to make them available again. Because
- * only one packet can be time stamped at a time, we
- * know that the register values must belong to this
- * one here and therefore we don't need to compare
- * any of the additional attributes stored for it.
- *
- * If nothing went wrong, then it should have a
- * skb_shared_tx that we can turn into a
- * skb_shared_hwtstamps.
- *
- * TODO: can time stamping be triggered (thus locking
- * the registers) without the packet reaching this point
- * here? In that case RX time stamping would get stuck.
- *
- * TODO: in "time stamp all packets" mode this bit is
- * not set. Need a global flag for this mode and then
- * always read the registers. Cannot be done without
- * a race condition.
- */
- if (unlikely(staterr & E1000_RXD_STAT_TS)) {
- u64 regval;
- u64 ns;
- struct skb_shared_hwtstamps *shhwtstamps =
- skb_hwtstamps(skb);
-
- WARN(!(rd32(E1000_TSYNCRXCTL) & E1000_TSYNCRXCTL_VALID),
- "igb: no RX time stamp available for time stamped packet");
- regval = rd32(E1000_RXSTMPL);
- regval |= (u64)rd32(E1000_RXSTMPH) << 32;
- ns = timecounter_cyc2time(&adapter->clock, regval);
- timecompare_update(&adapter->compare, ns);
- memset(shhwtstamps, 0, sizeof(*shhwtstamps));
- shhwtstamps->hwtstamp = ns_to_ktime(ns);
- shhwtstamps->syststamp =
- timecompare_transform(&adapter->compare, ns);
- }
-
if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) {
dev_kfree_skb_irq(skb);
goto next_desc;
}
+ igb_rx_hwtstamp(q_vector, staterr, skb);
total_bytes += skb->len;
total_packets++;
- igb_rx_checksum_adv(adapter, staterr, skb);
+ igb_rx_checksum_adv(rx_ring, staterr, skb);
skb->protocol = eth_type_trans(skb, netdev);
skb_record_rx_queue(skb, rx_ring->queue_index);
* igb_alloc_rx_buffers_adv - Replace used receive buffers; packet split
* @adapter: address of board private structure
**/
-static void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring,
- int cleaned_count)
+void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring, int cleaned_count)
{
- struct igb_adapter *adapter = rx_ring->q_vector->adapter;
- struct net_device *netdev = adapter->netdev;
- struct pci_dev *pdev = adapter->pdev;
+ struct net_device *netdev = rx_ring->netdev;
union e1000_adv_rx_desc *rx_desc;
struct igb_buffer *buffer_info;
struct sk_buff *skb;
i = rx_ring->next_to_use;
buffer_info = &rx_ring->buffer_info[i];
- bufsz = adapter->rx_buffer_len;
+ bufsz = rx_ring->rx_buffer_len;
while (cleaned_count--) {
rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
if (!buffer_info->page) {
buffer_info->page = alloc_page(GFP_ATOMIC);
if (!buffer_info->page) {
- adapter->alloc_rx_buff_failed++;
+ rx_ring->rx_stats.alloc_failed++;
goto no_buffers;
}
buffer_info->page_offset = 0;
buffer_info->page_offset ^= PAGE_SIZE / 2;
}
buffer_info->page_dma =
- pci_map_page(pdev, buffer_info->page,
+ pci_map_page(rx_ring->pdev, buffer_info->page,
buffer_info->page_offset,
PAGE_SIZE / 2,
PCI_DMA_FROMDEVICE);
if (!buffer_info->skb) {
skb = netdev_alloc_skb_ip_align(netdev, bufsz);
if (!skb) {
- adapter->alloc_rx_buff_failed++;
+ rx_ring->rx_stats.alloc_failed++;
goto no_buffers;
}
buffer_info->skb = skb;
- buffer_info->dma = pci_map_single(pdev, skb->data,
+ buffer_info->dma = pci_map_single(rx_ring->pdev,
+ skb->data,
bufsz,
PCI_DMA_FROMDEVICE);
}
struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
struct hwtstamp_config config;
- u32 tsync_tx_ctl_bit = E1000_TSYNCTXCTL_ENABLED;
- u32 tsync_rx_ctl_bit = E1000_TSYNCRXCTL_ENABLED;
- u32 tsync_rx_ctl_type = 0;
+ u32 tsync_tx_ctl = E1000_TSYNCTXCTL_ENABLED;
+ u32 tsync_rx_ctl = E1000_TSYNCRXCTL_ENABLED;
u32 tsync_rx_cfg = 0;
- int is_l4 = 0;
- int is_l2 = 0;
- short port = 319; /* PTP */
+ bool is_l4 = false;
+ bool is_l2 = false;
u32 regval;
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
switch (config.tx_type) {
case HWTSTAMP_TX_OFF:
- tsync_tx_ctl_bit = 0;
- break;
+ tsync_tx_ctl = 0;
case HWTSTAMP_TX_ON:
- tsync_tx_ctl_bit = E1000_TSYNCTXCTL_ENABLED;
break;
default:
return -ERANGE;
switch (config.rx_filter) {
case HWTSTAMP_FILTER_NONE:
- tsync_rx_ctl_bit = 0;
+ tsync_rx_ctl = 0;
break;
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
* possible to time stamp both Sync and Delay_Req messages
* => fall back to time stamping all packets
*/
- tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_ALL;
+ tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_ALL;
config.rx_filter = HWTSTAMP_FILTER_ALL;
break;
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
- tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L4_V1;
+ tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L4_V1;
tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V1_SYNC_MESSAGE;
- is_l4 = 1;
+ is_l4 = true;
break;
case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
- tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L4_V1;
+ tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L4_V1;
tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V1_DELAY_REQ_MESSAGE;
- is_l4 = 1;
+ is_l4 = true;
break;
case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
- tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L2_L4_V2;
+ tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_L4_V2;
tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V2_SYNC_MESSAGE;
- is_l2 = 1;
- is_l4 = 1;
+ is_l2 = true;
+ is_l4 = true;
config.rx_filter = HWTSTAMP_FILTER_SOME;
break;
case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
- tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_L2_L4_V2;
+ tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_L4_V2;
tsync_rx_cfg = E1000_TSYNCRXCFG_PTP_V2_DELAY_REQ_MESSAGE;
- is_l2 = 1;
- is_l4 = 1;
+ is_l2 = true;
+ is_l4 = true;
config.rx_filter = HWTSTAMP_FILTER_SOME;
break;
case HWTSTAMP_FILTER_PTP_V2_EVENT:
case HWTSTAMP_FILTER_PTP_V2_SYNC:
case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
- tsync_rx_ctl_type = E1000_TSYNCRXCTL_TYPE_EVENT_V2;
+ tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_EVENT_V2;
config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
- is_l2 = 1;
+ is_l2 = true;
break;
default:
return -ERANGE;
}
+ if (hw->mac.type == e1000_82575) {
+ if (tsync_rx_ctl | tsync_tx_ctl)
+ return -EINVAL;
+ return 0;
+ }
+
/* enable/disable TX */
regval = rd32(E1000_TSYNCTXCTL);
- regval = (regval & ~E1000_TSYNCTXCTL_ENABLED) | tsync_tx_ctl_bit;
+ regval &= ~E1000_TSYNCTXCTL_ENABLED;
+ regval |= tsync_tx_ctl;
wr32(E1000_TSYNCTXCTL, regval);
- /* enable/disable RX, define which PTP packets are time stamped */
+ /* enable/disable RX */
regval = rd32(E1000_TSYNCRXCTL);
- regval = (regval & ~E1000_TSYNCRXCTL_ENABLED) | tsync_rx_ctl_bit;
- regval = (regval & ~0xE) | tsync_rx_ctl_type;
+ regval &= ~(E1000_TSYNCRXCTL_ENABLED | E1000_TSYNCRXCTL_TYPE_MASK);
+ regval |= tsync_rx_ctl;
wr32(E1000_TSYNCRXCTL, regval);
- wr32(E1000_TSYNCRXCFG, tsync_rx_cfg);
- /*
- * Ethertype Filter Queue Filter[0][15:0] = 0x88F7
- * (Ethertype to filter on)
- * Ethertype Filter Queue Filter[0][26] = 0x1 (Enable filter)
- * Ethertype Filter Queue Filter[0][30] = 0x1 (Enable Timestamping)
- */
- wr32(E1000_ETQF0, is_l2 ? 0x440088f7 : 0);
-
- /* L4 Queue Filter[0]: only filter by source and destination port */
- wr32(E1000_SPQF0, htons(port));
- wr32(E1000_IMIREXT(0), is_l4 ?
- ((1<<12) | (1<<19) /* bypass size and control flags */) : 0);
- wr32(E1000_IMIR(0), is_l4 ?
- (htons(port)
- | (0<<16) /* immediate interrupt disabled */
- | 0 /* (1<<17) bit cleared: do not bypass
- destination port check */)
- : 0);
- wr32(E1000_FTQF0, is_l4 ?
- (0x11 /* UDP */
- | (1<<15) /* VF not compared */
- | (1<<27) /* Enable Timestamping */
- | (7<<28) /* only source port filter enabled,
- source/target address and protocol
- masked */)
- : ((1<<15) | (15<<28) /* all mask bits set = filter not
- enabled */));
+ /* define which PTP packets are time stamped */
+ wr32(E1000_TSYNCRXCFG, tsync_rx_cfg);
+ /* define ethertype filter for timestamped packets */
+ if (is_l2)
+ wr32(E1000_ETQF(3),
+ (E1000_ETQF_FILTER_ENABLE | /* enable filter */
+ E1000_ETQF_1588 | /* enable timestamping */
+ ETH_P_1588)); /* 1588 eth protocol type */
+ else
+ wr32(E1000_ETQF(3), 0);
+
+#define PTP_PORT 319
+ /* L4 Queue Filter[3]: filter by destination port and protocol */
+ if (is_l4) {
+ u32 ftqf = (IPPROTO_UDP /* UDP */
+ | E1000_FTQF_VF_BP /* VF not compared */
+ | E1000_FTQF_1588_TIME_STAMP /* Enable Timestamping */
+ | E1000_FTQF_MASK); /* mask all inputs */
+ ftqf &= ~E1000_FTQF_MASK_PROTO_BP; /* enable protocol check */
+
+ wr32(E1000_IMIR(3), htons(PTP_PORT));
+ wr32(E1000_IMIREXT(3),
+ (E1000_IMIREXT_SIZE_BP | E1000_IMIREXT_CTRL_BP));
+ if (hw->mac.type == e1000_82576) {
+ /* enable source port check */
+ wr32(E1000_SPQF(3), htons(PTP_PORT));
+ ftqf &= ~E1000_FTQF_MASK_SOURCE_PORT_BP;
+ }
+ wr32(E1000_FTQF(3), ftqf);
+ } else {
+ wr32(E1000_FTQF(3), E1000_FTQF_MASK);
+ }
wrfl();
adapter->hwtstamp_config = config;
static void igb_vmm_control(struct igb_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
- u32 reg_data;
+ u32 reg;
- if (!adapter->vfs_allocated_count)
+ /* replication is not supported for 82575 */
+ if (hw->mac.type == e1000_82575)
return;
- /* VF's need PF reset indication before they
- * can send/receive mail */
- reg_data = rd32(E1000_CTRL_EXT);
- reg_data |= E1000_CTRL_EXT_PFRSTD;
- wr32(E1000_CTRL_EXT, reg_data);
+ /* enable replication vlan tag stripping */
+ reg = rd32(E1000_RPLOLR);
+ reg |= E1000_RPLOLR_STRVLAN;
+ wr32(E1000_RPLOLR, reg);
+
+ /* notify HW that the MAC is adding vlan tags */
+ reg = rd32(E1000_DTXCTL);
+ reg |= E1000_DTXCTL_VLAN_ADDED;
+ wr32(E1000_DTXCTL, reg);
- igb_vmdq_set_loopback_pf(hw, true);
- igb_vmdq_set_replication_pf(hw, true);
+ if (adapter->vfs_allocated_count) {
+ igb_vmdq_set_loopback_pf(hw, true);
+ igb_vmdq_set_replication_pf(hw, true);
+ } else {
+ igb_vmdq_set_loopback_pf(hw, false);
+ igb_vmdq_set_replication_pf(hw, false);
+ }
}
/* igb_main.c */