Skip to content

Commit

Permalink
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/jkirsher/net

Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates

This series contains updates to e1000, e1000e, igb, igbvf, ixgb, ixgbe,
ixgbevf and i40evf.

Mark fixes an issue with ixgbe and ixgbevf by adding a bit to indicate
when workqueues have been initialized.  This permits the register read
error handling from attempting to use them prior to that, which also
generates warnings.  Checking for a detected removal after initializing
the work queues allows the probe function to return an error without
getting the workqueue involved.  Further, if the error_detected
callback is entered before the workqueues are initialized, exit without
recovery since the device initialization was so truncated.

Francois Romieu provides several patches to all the drivers to remove
the open coded skb_cow_head.

Jakub Kicinski provides a fix for igb where last_rx_timestamp should be
updated only when Rx time stamp is read.

Mitch provides a fix for i40evf where a recent change broke the RSS LUT
programming causing it to be programmed with all 0's.
====================

Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
davem330 committed Apr 12, 2014
2 parents 0f2eea4 + 5b7af02 commit dcfba94
Show file tree
Hide file tree
Showing 14 changed files with 91 additions and 203 deletions.
124 changes: 0 additions & 124 deletions drivers/net/ethernet/intel/e1000/e1000_hw.c

Large diffs are not rendered by default.

11 changes: 5 additions & 6 deletions drivers/net/ethernet/intel/e1000/e1000_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2682,14 +2682,13 @@ static int e1000_tso(struct e1000_adapter *adapter,
u32 cmd_length = 0;
u16 ipcse = 0, tucse, mss;
u8 ipcss, ipcso, tucss, tucso, hdr_len;
int err;

if (skb_is_gso(skb)) {
if (skb_header_cloned(skb)) {
err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
if (err)
return err;
}
int err;

err = skb_cow_head(skb, 0);
if (err < 0)
return err;

hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
mss = skb_shinfo(skb)->gso_size;
Expand Down
10 changes: 4 additions & 6 deletions drivers/net/ethernet/intel/e1000e/netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -5100,16 +5100,14 @@ static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb)
u32 cmd_length = 0;
u16 ipcse = 0, mss;
u8 ipcss, ipcso, tucss, tucso, hdr_len;
int err;

if (!skb_is_gso(skb))
return 0;

if (skb_header_cloned(skb)) {
int err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);

if (err)
return err;
}
err = skb_cow_head(skb, 0);
if (err < 0)
return err;

hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
mss = skb_shinfo(skb)->gso_size;
Expand Down
10 changes: 4 additions & 6 deletions drivers/net/ethernet/intel/i40evf/i40e_txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1114,20 +1114,18 @@ static int i40e_tso(struct i40e_ring *tx_ring, struct sk_buff *skb,
u64 *cd_type_cmd_tso_mss, u32 *cd_tunneling)
{
u32 cd_cmd, cd_tso_len, cd_mss;
struct ipv6hdr *ipv6h;
struct tcphdr *tcph;
struct iphdr *iph;
u32 l4len;
int err;
struct ipv6hdr *ipv6h;

if (!skb_is_gso(skb))
return 0;

if (skb_header_cloned(skb)) {
err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
if (err)
return err;
}
err = skb_cow_head(skb, 0);
if (err < 0)
return err;

if (protocol == htons(ETH_P_IP)) {
iph = skb->encapsulation ? inner_ip_hdr(skb) : ip_hdr(skb);
Expand Down
20 changes: 16 additions & 4 deletions drivers/net/ethernet/intel/i40evf/i40evf_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1412,6 +1412,14 @@ static void i40evf_watchdog_task(struct work_struct *work)
schedule_work(&adapter->adminq_task);
}

/**
* i40evf_configure_rss - increment to next available tx queue
* @adapter: board private structure
* @j: queue counter
*
* Helper function for RSS programming to increment through available
* queus. Returns the next queue value.
**/
static int next_queue(struct i40evf_adapter *adapter, int j)
{
j += 1;
Expand Down Expand Up @@ -1451,10 +1459,14 @@ static void i40evf_configure_rss(struct i40evf_adapter *adapter)
/* Populate the LUT with max no. of queues in round robin fashion */
j = adapter->vsi_res->num_queue_pairs;
for (i = 0; i <= I40E_VFQF_HLUT_MAX_INDEX; i++) {
lut = next_queue(adapter, j);
lut |= next_queue(adapter, j) << 8;
lut |= next_queue(adapter, j) << 16;
lut |= next_queue(adapter, j) << 24;
j = next_queue(adapter, j);
lut = j;
j = next_queue(adapter, j);
lut |= j << 8;
j = next_queue(adapter, j);
lut |= j << 16;
j = next_queue(adapter, j);
lut |= j << 24;
wr32(hw, I40E_VFQF_HLUT(i), lut);
}
i40e_flush(hw);
Expand Down
16 changes: 1 addition & 15 deletions drivers/net/ethernet/intel/igb/igb.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,6 @@ struct igb_ring {
struct igb_tx_buffer *tx_buffer_info;
struct igb_rx_buffer *rx_buffer_info;
};
unsigned long last_rx_timestamp;
void *desc; /* descriptor ring memory */
unsigned long flags; /* ring specific flags */
void __iomem *tail; /* pointer to ring tail register */
Expand Down Expand Up @@ -437,6 +436,7 @@ struct igb_adapter {
struct hwtstamp_config tstamp_config;
unsigned long ptp_tx_start;
unsigned long last_rx_ptp_check;
unsigned long last_rx_timestamp;
spinlock_t tmreg_lock;
struct cyclecounter cc;
struct timecounter tc;
Expand Down Expand Up @@ -533,20 +533,6 @@ void igb_ptp_rx_hang(struct igb_adapter *adapter);
void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb);
void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, unsigned char *va,
struct sk_buff *skb);
static inline void igb_ptp_rx_hwtstamp(struct igb_ring *rx_ring,
union e1000_adv_rx_desc *rx_desc,
struct sk_buff *skb)
{
if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TS) &&
!igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP))
igb_ptp_rx_rgtstamp(rx_ring->q_vector, skb);

/* Update the last_rx_timestamp timer in order to enable watchdog check
* for error case of latched timestamp on a dropped packet.
*/
rx_ring->last_rx_timestamp = jiffies;
}

int igb_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr);
int igb_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr);
#ifdef CONFIG_IGB_HWMON
Expand Down
13 changes: 7 additions & 6 deletions drivers/net/ethernet/intel/igb/igb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4605,18 +4605,17 @@ static int igb_tso(struct igb_ring *tx_ring,
struct sk_buff *skb = first->skb;
u32 vlan_macip_lens, type_tucmd;
u32 mss_l4len_idx, l4len;
int err;

if (skb->ip_summed != CHECKSUM_PARTIAL)
return 0;

if (!skb_is_gso(skb))
return 0;

if (skb_header_cloned(skb)) {
int err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
if (err)
return err;
}
err = skb_cow_head(skb, 0);
if (err < 0)
return err;

/* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */
type_tucmd = E1000_ADVTXD_TUCMD_L4T_TCP;
Expand Down Expand Up @@ -6955,7 +6954,9 @@ static void igb_process_skb_fields(struct igb_ring *rx_ring,

igb_rx_checksum(rx_ring, rx_desc, skb);

igb_ptp_rx_hwtstamp(rx_ring, rx_desc, skb);
if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TS) &&
!igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP))
igb_ptp_rx_rgtstamp(rx_ring->q_vector, skb);

if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
igb_test_staterr(rx_desc, E1000_RXD_STAT_VP)) {
Expand Down
14 changes: 7 additions & 7 deletions drivers/net/ethernet/intel/igb/igb_ptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -427,10 +427,8 @@ static void igb_ptp_overflow_check(struct work_struct *work)
void igb_ptp_rx_hang(struct igb_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
struct igb_ring *rx_ring;
u32 tsyncrxctl = rd32(E1000_TSYNCRXCTL);
unsigned long rx_event;
int n;

if (hw->mac.type != e1000_82576)
return;
Expand All @@ -445,11 +443,8 @@ void igb_ptp_rx_hang(struct igb_adapter *adapter)

/* Determine the most recent watchdog or rx_timestamp event */
rx_event = adapter->last_rx_ptp_check;
for (n = 0; n < adapter->num_rx_queues; n++) {
rx_ring = adapter->rx_ring[n];
if (time_after(rx_ring->last_rx_timestamp, rx_event))
rx_event = rx_ring->last_rx_timestamp;
}
if (time_after(adapter->last_rx_timestamp, rx_event))
rx_event = adapter->last_rx_timestamp;

/* Only need to read the high RXSTMP register to clear the lock */
if (time_is_before_jiffies(rx_event + 5 * HZ)) {
Expand Down Expand Up @@ -540,6 +535,11 @@ void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector,
regval |= (u64)rd32(E1000_RXSTMPH) << 32;

igb_ptp_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), regval);

/* Update the last_rx_timestamp timer in order to enable watchdog check
* for error case of latched timestamp on a dropped packet.
*/
adapter->last_rx_timestamp = jiffies;
}

/**
Expand Down
16 changes: 7 additions & 9 deletions drivers/net/ethernet/intel/igbvf/netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -1910,20 +1910,18 @@ static int igbvf_tso(struct igbvf_adapter *adapter,
struct sk_buff *skb, u32 tx_flags, u8 *hdr_len)
{
struct e1000_adv_tx_context_desc *context_desc;
unsigned int i;
int err;
struct igbvf_buffer *buffer_info;
u32 info = 0, tu_cmd = 0;
u32 mss_l4len_idx, l4len;
unsigned int i;
int err;

*hdr_len = 0;

if (skb_header_cloned(skb)) {
err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
if (err) {
dev_err(&adapter->pdev->dev,
"igbvf_tso returning an error\n");
return err;
}
err = skb_cow_head(skb, 0);
if (err < 0) {
dev_err(&adapter->pdev->dev, "igbvf_tso returning an error\n");
return err;
}

l4len = tcp_hdrlen(skb);
Expand Down
10 changes: 4 additions & 6 deletions drivers/net/ethernet/intel/ixgb/ixgb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1220,17 +1220,15 @@ ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb)
unsigned int i;
u8 ipcss, ipcso, tucss, tucso, hdr_len;
u16 ipcse, tucse, mss;
int err;

if (likely(skb_is_gso(skb))) {
struct ixgb_buffer *buffer_info;
struct iphdr *iph;
int err;

if (skb_header_cloned(skb)) {
err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
if (err)
return err;
}
err = skb_cow_head(skb, 0);
if (err < 0)
return err;

hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
mss = skb_shinfo(skb)->gso_size;
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/ixgbe/ixgbe.h
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,7 @@ enum ixgbe_state_t {
__IXGBE_DISABLED,
__IXGBE_REMOVING,
__IXGBE_SERVICE_SCHED,
__IXGBE_SERVICE_INITED,
__IXGBE_IN_SFP_INIT,
__IXGBE_PTP_RUNNING,
__IXGBE_PTP_TX_IN_PROGRESS,
Expand Down
28 changes: 20 additions & 8 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,8 @@ static void ixgbe_remove_adapter(struct ixgbe_hw *hw)
return;
hw->hw_addr = NULL;
e_dev_err("Adapter removed\n");
ixgbe_service_event_schedule(adapter);
if (test_bit(__IXGBE_SERVICE_INITED, &adapter->state))
ixgbe_service_event_schedule(adapter);
}

void ixgbe_check_remove(struct ixgbe_hw *hw, u32 reg)
Expand Down Expand Up @@ -6509,18 +6510,17 @@ static int ixgbe_tso(struct ixgbe_ring *tx_ring,
struct sk_buff *skb = first->skb;
u32 vlan_macip_lens, type_tucmd;
u32 mss_l4len_idx, l4len;
int err;

if (skb->ip_summed != CHECKSUM_PARTIAL)
return 0;

if (!skb_is_gso(skb))
return 0;

if (skb_header_cloned(skb)) {
int err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
if (err)
return err;
}
err = skb_cow_head(skb, 0);
if (err < 0)
return err;

/* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */
type_tucmd = IXGBE_ADVTXD_TUCMD_L4T_TCP;
Expand Down Expand Up @@ -7077,8 +7077,8 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
IXGBE_TX_FLAGS_VLAN_PRIO_SHIFT;
if (tx_flags & IXGBE_TX_FLAGS_SW_VLAN) {
struct vlan_ethhdr *vhdr;
if (skb_header_cloned(skb) &&
pskb_expand_head(skb, 0, 0, GFP_ATOMIC))

if (skb_cow_head(skb, 0))
goto out_drop;
vhdr = (struct vlan_ethhdr *)skb->data;
vhdr->h_vlan_TCI = htons(tx_flags >>
Expand Down Expand Up @@ -8023,6 +8023,10 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* EEPROM */
memcpy(&hw->eeprom.ops, ii->eeprom_ops, sizeof(hw->eeprom.ops));
eec = IXGBE_READ_REG(hw, IXGBE_EEC);
if (ixgbe_removed(hw->hw_addr)) {
err = -EIO;
goto err_ioremap;
}
/* If EEPROM is valid (bit 8 = 1), use default otherwise use bit bang */
if (!(eec & (1 << 8)))
hw->eeprom.ops.read = &ixgbe_read_eeprom_bit_bang_generic;
Expand Down Expand Up @@ -8185,7 +8189,12 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
setup_timer(&adapter->service_timer, &ixgbe_service_timer,
(unsigned long) adapter);

if (ixgbe_removed(hw->hw_addr)) {
err = -EIO;
goto err_sw_init;
}
INIT_WORK(&adapter->service_task, ixgbe_service_task);
set_bit(__IXGBE_SERVICE_INITED, &adapter->state);
clear_bit(__IXGBE_SERVICE_SCHED, &adapter->state);

err = ixgbe_init_interrupt_scheme(adapter);
Expand Down Expand Up @@ -8494,6 +8503,9 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,

skip_bad_vf_detection:
#endif /* CONFIG_PCI_IOV */
if (!test_bit(__IXGBE_SERVICE_INITED, &adapter->state))
return PCI_ERS_RESULT_DISCONNECT;

rtnl_lock();
netif_device_detach(netdev);

Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@ enum ixbgevf_state_t {
__IXGBEVF_DOWN,
__IXGBEVF_DISABLED,
__IXGBEVF_REMOVING,
__IXGBEVF_WORK_INIT,
};

struct ixgbevf_cb {
Expand Down
Loading

0 comments on commit dcfba94

Please sign in to comment.