Commit d7ed7474 authored by David S. Miller's avatar David S. Miller

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next

Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates 2015-03-07

This series contains updates to i40e and i40evf only.

Most notably, Greg provides the patch to remove the dreaded configfs
changes in the driver.

Shannon cleans up a sparse warning by simply straighting out the code
so it is less convoluted.  Fixes an issue where the vector allocation
was trying too hard to save vectors for VMDq, to the point of not giving
the PF enough when in a tight situation, such as an NPAR partition.
Changed the driver to make sure that the PF will get all the queues and
vectors it wants to fill out its destiny.  Cleans up reporting to only
print the port and VEB stats if it is the first partition of a
multiplexed port.

Catherine cleans up some duplicated code by simply removing the duplicate
code.

Kamil cleans up the driver by removing an un-needed endian conversion
because it is already done by a register read function.

Jesse fixes a variable width of a datatype, where a u16 should have been
a u32.  Also cleans up debug_read_register() to resolve some sparse
warnings.  Updates the driver to use prefetch() to get the next Tx
descriptor, like in ixgbe, to improve performance.

Akeem moves around code to enable/disable loopback so that other non-SRIOV
supported driver functions can take advantage of the changes.

Anjali cleans up the logging for adding/deleting FD-SB filters, since
ethtool shows all the filters on an interface.  Updates the driver to
use l4_tunnel type generically to keep code flow simple.  Simplifies
the RSS code since the driver initializes the rss_size_max in sw_init.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 04b0a80b cd77f5e1
......@@ -303,15 +303,6 @@ config I40E_FCOE
If unsure, say N.
config I40E_CONFIGFS_FS
bool "Config File System Support (configfs)"
default n
depends on I40E && CONFIGFS_FS && !(I40E=y && CONFIGFS_FS=m)
---help---
Provides support for the configfs file system for additional
driver configuration. Say Y here if you want to use the
configuration file system in the driver.
config I40EVF
tristate "Intel(R) XL710 X710 Virtual Function Ethernet support"
depends on PCI_MSI
......
......@@ -37,7 +37,6 @@ i40e-objs := i40e_main.o \
i40e_hmc.o \
i40e_lan_hmc.o \
i40e_nvm.o \
i40e_configfs.o \
i40e_debugfs.o \
i40e_diag.o \
i40e_txrx.o \
......
......@@ -175,6 +175,7 @@ struct i40e_lump_tracking {
#define I40E_FDIR_MAX_RAW_PACKET_SIZE 512
#define I40E_FDIR_BUFFER_FULL_MARGIN 10
#define I40E_FDIR_BUFFER_HEAD_ROOM 32
#define I40E_FDIR_BUFFER_HEAD_ROOM_FOR_ATR (I40E_FDIR_BUFFER_HEAD_ROOM * 4)
enum i40e_fd_stat_idx {
I40E_FD_STAT_ATR,
......@@ -276,7 +277,7 @@ struct i40e_pf {
enum i40e_interrupt_policy int_policy;
u16 rx_itr_default;
u16 tx_itr_default;
u16 msg_enable;
u32 msg_enable;
char int_name[I40E_INT_NAME_STR_LEN];
u16 adminq_work_limit; /* num of admin receive queue desc to process */
unsigned long service_timer_period;
......@@ -636,9 +637,10 @@ int i40e_program_fdir_filter(struct i40e_fdir_filter *fdir_data, u8 *raw_packet,
int i40e_add_del_fdir(struct i40e_vsi *vsi,
struct i40e_fdir_filter *input, bool add);
void i40e_fdir_check_and_reenable(struct i40e_pf *pf);
int i40e_get_current_fd_count(struct i40e_pf *pf);
int i40e_get_cur_guaranteed_fd_count(struct i40e_pf *pf);
int i40e_get_current_atr_cnt(struct i40e_pf *pf);
u32 i40e_get_current_fd_count(struct i40e_pf *pf);
u32 i40e_get_cur_guaranteed_fd_count(struct i40e_pf *pf);
u32 i40e_get_current_atr_cnt(struct i40e_pf *pf);
u32 i40e_get_global_fd_count(struct i40e_pf *pf);
bool i40e_set_ntuple(struct i40e_pf *pf, netdev_features_t features);
void i40e_set_ethtool_ops(struct net_device *netdev);
struct i40e_mac_filter *i40e_add_filter(struct i40e_vsi *vsi,
......@@ -747,10 +749,6 @@ int i40e_ptp_get_ts_config(struct i40e_pf *pf, struct ifreq *ifr);
void i40e_ptp_init(struct i40e_pf *pf);
void i40e_ptp_stop(struct i40e_pf *pf);
int i40e_is_vsi_uplink_mode_veb(struct i40e_vsi *vsi);
#if IS_ENABLED(CONFIG_I40E_CONFIGFS_FS)
int i40e_configfs_init(void);
void i40e_configfs_exit(void);
#endif /* CONFIG_I40E_CONFIGFS_FS */
i40e_status i40e_get_npar_bw_setting(struct i40e_pf *pf);
i40e_status i40e_set_npar_bw_setting(struct i40e_pf *pf);
i40e_status i40e_commit_npar_bw_setting(struct i40e_pf *pf);
......
......@@ -85,9 +85,8 @@ void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
{
struct i40e_aq_desc *aq_desc = (struct i40e_aq_desc *)desc;
u16 len = le16_to_cpu(aq_desc->datalen);
u8 *aq_buffer = (u8 *)buffer;
u32 data[4];
u32 i = 0;
u8 *buf = (u8 *)buffer;
u16 i = 0;
if ((!(mask & hw->debug_mask)) || (desc == NULL))
return;
......@@ -109,29 +108,30 @@ void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
le32_to_cpu(aq_desc->params.external.addr_low));
if ((buffer != NULL) && (aq_desc->datalen != 0)) {
memset(data, 0, sizeof(data));
i40e_debug(hw, mask, "AQ CMD Buffer:\n");
if (buf_len < len)
len = buf_len;
for (i = 0; i < len; i++) {
data[((i % 16) / 4)] |=
((u32)aq_buffer[i]) << (8 * (i % 4));
if ((i % 16) == 15) {
i40e_debug(hw, mask,
"\t0x%04X %08X %08X %08X %08X\n",
i - 15, le32_to_cpu(data[0]),
le32_to_cpu(data[1]),
le32_to_cpu(data[2]),
le32_to_cpu(data[3]));
memset(data, 0, sizeof(data));
}
/* write the full 16-byte chunks */
for (i = 0; i < (len - 16); i += 16)
i40e_debug(hw, mask,
"\t0x%04X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
i, buf[i], buf[i + 1], buf[i + 2],
buf[i + 3], buf[i + 4], buf[i + 5],
buf[i + 6], buf[i + 7], buf[i + 8],
buf[i + 9], buf[i + 10], buf[i + 11],
buf[i + 12], buf[i + 13], buf[i + 14],
buf[i + 15]);
/* write whatever's left over without overrunning the buffer */
if (i < len) {
char d_buf[80];
int j = 0;
memset(d_buf, 0, sizeof(d_buf));
j += sprintf(d_buf, "\t0x%04X ", i);
while (i < len)
j += sprintf(&d_buf[j], " %02X", buf[i++]);
i40e_debug(hw, mask, "%s\n", d_buf);
}
if ((i % 16) != 0)
i40e_debug(hw, mask, "\t0x%04X %08X %08X %08X %08X\n",
i - (i % 16), le32_to_cpu(data[0]),
le32_to_cpu(data[1]),
le32_to_cpu(data[2]),
le32_to_cpu(data[3]));
}
}
......@@ -2126,7 +2126,7 @@ i40e_status i40e_aq_send_msg_to_vf(struct i40e_hw *hw, u16 vfid,
* Read the register using the admin queue commands
**/
i40e_status i40e_aq_debug_read_register(struct i40e_hw *hw,
u32 reg_addr, u64 *reg_val,
u32 reg_addr, u64 *reg_val,
struct i40e_asq_cmd_details *cmd_details)
{
struct i40e_aq_desc desc;
......@@ -2137,17 +2137,15 @@ i40e_status i40e_aq_debug_read_register(struct i40e_hw *hw,
if (reg_val == NULL)
return I40E_ERR_PARAM;
i40e_fill_default_direct_cmd_desc(&desc,
i40e_aqc_opc_debug_read_reg);
i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_debug_read_reg);
cmd_resp->address = cpu_to_le32(reg_addr);
status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
if (!status) {
*reg_val = ((u64)cmd_resp->value_high << 32) |
(u64)cmd_resp->value_low;
*reg_val = le64_to_cpu(*reg_val);
*reg_val = ((u64)le32_to_cpu(cmd_resp->value_high) << 32) |
(u64)le32_to_cpu(cmd_resp->value_low);
}
return status;
......@@ -3409,9 +3407,9 @@ i40e_status i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
* is not passed then only register at 'reg_addr0' is read.
*
**/
i40e_status i40e_aq_alternate_read(struct i40e_hw *hw,
u32 reg_addr0, u32 *reg_val0,
u32 reg_addr1, u32 *reg_val1)
static i40e_status i40e_aq_alternate_read(struct i40e_hw *hw,
u32 reg_addr0, u32 *reg_val0,
u32 reg_addr1, u32 *reg_val1)
{
struct i40e_aq_desc desc;
struct i40e_aqc_alternate_write *cmd_resp =
......
This diff is collapsed.
......@@ -1224,7 +1224,7 @@ static int i40e_get_sset_count(struct net_device *netdev, int sset)
case ETH_SS_TEST:
return I40E_TEST_LEN;
case ETH_SS_STATS:
if (vsi == pf->vsi[pf->lan_vsi]) {
if (vsi == pf->vsi[pf->lan_vsi] && pf->hw.partition_id == 1) {
int len = I40E_PF_STATS_LEN(netdev);
if (pf->lan_veb != I40E_NO_VEB)
......@@ -1297,7 +1297,7 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
i += 2;
}
rcu_read_unlock();
if (vsi != pf->vsi[pf->lan_vsi])
if (vsi != pf->vsi[pf->lan_vsi] || pf->hw.partition_id != 1)
return;
if (pf->lan_veb != I40E_NO_VEB) {
......@@ -1370,7 +1370,7 @@ static void i40e_get_strings(struct net_device *netdev, u32 stringset,
snprintf(p, ETH_GSTRING_LEN, "rx-%u.rx_bytes", i);
p += ETH_GSTRING_LEN;
}
if (vsi != pf->vsi[pf->lan_vsi])
if (vsi != pf->vsi[pf->lan_vsi] || pf->hw.partition_id != 1)
return;
if (pf->lan_veb != I40E_NO_VEB) {
......
This diff is collapsed.
......@@ -171,8 +171,8 @@ static i40e_status i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw)
*
* Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
**/
i40e_status i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset,
u16 *data)
static i40e_status i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset,
u16 *data)
{
i40e_status ret_code = I40E_ERR_TIMEOUT;
u32 sr_reg;
......@@ -200,7 +200,6 @@ i40e_status i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset,
*data = (u16)((sr_reg &
I40E_GLNVM_SRDATA_RDDATA_MASK)
>> I40E_GLNVM_SRDATA_RDDATA_SHIFT);
*data = le16_to_cpu(*data);
}
}
if (ret_code)
......@@ -237,8 +236,8 @@ i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
* method. The buffer read is preceded by the NVM ownership take
* and followed by the release.
**/
i40e_status i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset,
u16 *words, u16 *data)
static i40e_status i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset,
u16 *words, u16 *data)
{
i40e_status ret_code = 0;
u16 index, word;
......
......@@ -228,7 +228,7 @@ static int i40e_add_del_fdir_udpv4(struct i40e_vsi *vsi,
"PCTYPE:%d, Filter command send failed for fd_id:%d (ret = %d)\n",
fd_data->pctype, fd_data->fd_id, ret);
err = true;
} else {
} else if (I40E_DEBUG_FD & pf->hw.debug_mask) {
if (add)
dev_info(&pf->pdev->dev,
"Filter OK for PCTYPE %d loc = %d\n",
......@@ -303,7 +303,7 @@ static int i40e_add_del_fdir_tcpv4(struct i40e_vsi *vsi,
"PCTYPE:%d, Filter command send failed for fd_id:%d (ret = %d)\n",
fd_data->pctype, fd_data->fd_id, ret);
err = true;
} else {
} else if (I40E_DEBUG_FD & pf->hw.debug_mask) {
if (add)
dev_info(&pf->pdev->dev, "Filter OK for PCTYPE %d loc = %d)\n",
fd_data->pctype, fd_data->fd_id);
......@@ -376,7 +376,7 @@ static int i40e_add_del_fdir_ipv4(struct i40e_vsi *vsi,
"PCTYPE:%d, Filter command send failed for fd_id:%d (ret = %d)\n",
fd_data->pctype, fd_data->fd_id, ret);
err = true;
} else {
} else if (I40E_DEBUG_FD & pf->hw.debug_mask) {
if (add)
dev_info(&pf->pdev->dev,
"Filter OK for PCTYPE %d loc = %d\n",
......@@ -471,12 +471,27 @@ static void i40e_fd_handle_status(struct i40e_ring *rx_ring,
dev_warn(&pdev->dev, "ntuple filter loc = %d, could not be added\n",
rx_desc->wb.qword0.hi_dword.fd_id);
/* Check if the programming error is for ATR.
* If so, auto disable ATR and set a state for
* flush in progress. Next time we come here if flush is in
* progress do nothing, once flush is complete the state will
* be cleared.
*/
if (test_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state))
return;
pf->fd_add_err++;
/* store the current atr filter count */
pf->fd_atr_cnt = i40e_get_current_atr_cnt(pf);
if ((rx_desc->wb.qword0.hi_dword.fd_id == 0) &&
(pf->auto_disable_flags & I40E_FLAG_FD_SB_ENABLED)) {
pf->auto_disable_flags |= I40E_FLAG_FD_ATR_ENABLED;
set_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state);
}
/* filter programming failed most likely due to table full */
fcnt_prog = i40e_get_cur_guaranteed_fd_count(pf);
fcnt_prog = i40e_get_global_fd_count(pf);
fcnt_avail = pf->fdir_pf_filter_count;
/* If ATR is running fcnt_prog can quickly change,
* if we are very close to full, it makes sense to disable
......@@ -755,6 +770,8 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget)
tx_desc = I40E_TX_DESC(tx_ring, 0);
}
prefetch(tx_desc);
/* update budget accounting */
budget--;
} while (likely(budget));
......@@ -1044,7 +1061,7 @@ void i40e_clean_rx_ring(struct i40e_ring *rx_ring)
for (i = 0; i < rx_ring->count; i++) {
rx_bi = &rx_ring->rx_bi[i];
rx_bi->dma = 0;
rx_bi->hdr_buf = 0;
rx_bi->hdr_buf = NULL;
}
}
}
......@@ -1926,6 +1943,9 @@ static void i40e_atr(struct i40e_ring *tx_ring, struct sk_buff *skb,
if (!(pf->flags & I40E_FLAG_FD_ATR_ENABLED))
return;
if ((pf->auto_disable_flags & I40E_FLAG_FD_ATR_ENABLED))
return;
/* if sampling is disabled do nothing */
if (!tx_ring->atr_sample_rate)
return;
......@@ -2198,8 +2218,16 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 tx_flags,
struct iphdr *this_ip_hdr;
u32 network_hdr_len;
u8 l4_hdr = 0;
u32 l4_tunnel = 0;
if (skb->encapsulation) {
switch (ip_hdr(skb)->protocol) {
case IPPROTO_UDP:
l4_tunnel = I40E_TXD_CTX_UDP_TUNNELING;
break;
default:
return;
}
network_hdr_len = skb_inner_network_header_len(skb);
this_ip_hdr = inner_ip_hdr(skb);
this_ipv6_hdr = inner_ipv6_hdr(skb);
......@@ -2222,8 +2250,8 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 tx_flags,
/* Now set the ctx descriptor fields */
*cd_tunneling |= (skb_network_header_len(skb) >> 2) <<
I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT |
I40E_TXD_CTX_UDP_TUNNELING |
I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT |
l4_tunnel |
((skb_inner_network_offset(skb) -
skb_transport_offset(skb)) >> 1) <<
I40E_TXD_CTX_QW0_NATLEN_SHIFT;
......
......@@ -709,74 +709,6 @@ void i40e_reset_vf(struct i40e_vf *vf, bool flr)
clear_bit(__I40E_VF_DISABLE, &pf->state);
}
/**
* i40e_enable_pf_switch_lb
* @pf: pointer to the pf structure
*
* enable switch loop back or die - no point in a return value
**/
void i40e_enable_pf_switch_lb(struct i40e_pf *pf)
{
struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
struct i40e_vsi_context ctxt;
int aq_ret;
ctxt.seid = pf->main_vsi_seid;
ctxt.pf_num = pf->hw.pf_id;
ctxt.vf_num = 0;
aq_ret = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL);
if (aq_ret) {
dev_info(&pf->pdev->dev,
"%s couldn't get pf vsi config, err %d, aq_err %d\n",
__func__, aq_ret, pf->hw.aq.asq_last_status);
return;
}
ctxt.flags = I40E_AQ_VSI_TYPE_PF;
ctxt.info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID);
ctxt.info.switch_id |= cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
aq_ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
if (aq_ret) {
dev_info(&pf->pdev->dev,
"%s: update vsi switch failed, aq_err=%d\n",
__func__, vsi->back->hw.aq.asq_last_status);
}
}
/**
* i40e_disable_pf_switch_lb
* @pf: pointer to the pf structure
*
* disable switch loop back or die - no point in a return value
**/
void i40e_disable_pf_switch_lb(struct i40e_pf *pf)
{
struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
struct i40e_vsi_context ctxt;
int aq_ret;
ctxt.seid = pf->main_vsi_seid;
ctxt.pf_num = pf->hw.pf_id;
ctxt.vf_num = 0;
aq_ret = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL);
if (aq_ret) {
dev_info(&pf->pdev->dev,
"%s couldn't get pf vsi config, err %d, aq_err %d\n",
__func__, aq_ret, pf->hw.aq.asq_last_status);
return;
}
ctxt.flags = I40E_AQ_VSI_TYPE_PF;
ctxt.info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID);
ctxt.info.switch_id &= ~cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
aq_ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
if (aq_ret) {
dev_info(&pf->pdev->dev,
"%s: update vsi switch failed, aq_err=%d\n",
__func__, vsi->back->hw.aq.asq_last_status);
}
}
/**
* i40e_free_vfs
* @pf: pointer to the pf structure
......
......@@ -126,7 +126,5 @@ int i40e_ndo_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool enable);
void i40e_vc_notify_link_state(struct i40e_pf *pf);
void i40e_vc_notify_reset(struct i40e_pf *pf);
void i40e_enable_pf_switch_lb(struct i40e_pf *pf);
void i40e_disable_pf_switch_lb(struct i40e_pf *pf);
#endif /* _I40E_VIRTCHNL_PF_H_ */
......@@ -85,9 +85,8 @@ void i40evf_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
{
struct i40e_aq_desc *aq_desc = (struct i40e_aq_desc *)desc;
u16 len = le16_to_cpu(aq_desc->datalen);
u8 *aq_buffer = (u8 *)buffer;
u32 data[4];
u32 i = 0;
u8 *buf = (u8 *)buffer;
u16 i = 0;
if ((!(mask & hw->debug_mask)) || (desc == NULL))
return;
......@@ -109,29 +108,30 @@ void i40evf_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
le32_to_cpu(aq_desc->params.external.addr_low));
if ((buffer != NULL) && (aq_desc->datalen != 0)) {
memset(data, 0, sizeof(data));
i40e_debug(hw, mask, "AQ CMD Buffer:\n");
if (buf_len < len)
len = buf_len;
for (i = 0; i < len; i++) {
data[((i % 16) / 4)] |=
((u32)aq_buffer[i]) << (8 * (i % 4));
if ((i % 16) == 15) {
i40e_debug(hw, mask,
"\t0x%04X %08X %08X %08X %08X\n",
i - 15, le32_to_cpu(data[0]),
le32_to_cpu(data[1]),
le32_to_cpu(data[2]),
le32_to_cpu(data[3]));
memset(data, 0, sizeof(data));
}
/* write the full 16-byte chunks */
for (i = 0; i < (len - 16); i += 16)
i40e_debug(hw, mask,
"\t0x%04X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
i, buf[i], buf[i + 1], buf[i + 2],
buf[i + 3], buf[i + 4], buf[i + 5],
buf[i + 6], buf[i + 7], buf[i + 8],
buf[i + 9], buf[i + 10], buf[i + 11],
buf[i + 12], buf[i + 13], buf[i + 14],
buf[i + 15]);
/* write whatever's left over without overrunning the buffer */
if (i < len) {
char d_buf[80];
int j = 0;
memset(d_buf, 0, sizeof(d_buf));
j += sprintf(d_buf, "\t0x%04X ", i);
while (i < len)
j += sprintf(&d_buf[j], " %02X", buf[i++]);
i40e_debug(hw, mask, "%s\n", d_buf);
}
if ((i % 16) != 0)
i40e_debug(hw, mask, "\t0x%04X %08X %08X %08X %08X\n",
i - (i % 16), le32_to_cpu(data[0]),
le32_to_cpu(data[1]),
le32_to_cpu(data[2]),
le32_to_cpu(data[3]));
}
}
......
......@@ -289,6 +289,8 @@ static bool i40e_clean_tx_irq(struct i40e_ring *tx_ring, int budget)
tx_desc = I40E_TX_DESC(tx_ring, 0);
}
prefetch(tx_desc);
/* update budget accounting */
budget--;
} while (likely(budget));
......@@ -542,7 +544,7 @@ void i40evf_clean_rx_ring(struct i40e_ring *rx_ring)
for (i = 0; i < rx_ring->count; i++) {
rx_bi = &rx_ring->rx_bi[i];
rx_bi->dma = 0;
rx_bi->hdr_buf = 0;
rx_bi->hdr_buf = NULL;
}
}
}
......@@ -1461,8 +1463,16 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 tx_flags,
struct iphdr *this_ip_hdr;
u32 network_hdr_len;
u8 l4_hdr = 0;
u32 l4_tunnel = 0;
if (skb->encapsulation) {
switch (ip_hdr(skb)->protocol) {
case IPPROTO_UDP:
l4_tunnel = I40E_TXD_CTX_UDP_TUNNELING;
break;
default:
return;
}
network_hdr_len = skb_inner_network_header_len(skb);
this_ip_hdr = inner_ip_hdr(skb);
this_ipv6_hdr = inner_ipv6_hdr(skb);
......@@ -1485,8 +1495,8 @@ static void i40e_tx_enable_csum(struct sk_buff *skb, u32 tx_flags,
/* Now set the ctx descriptor fields */
*cd_tunneling |= (skb_network_header_len(skb) >> 2) <<
I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT |
I40E_TXD_CTX_UDP_TUNNELING |
I40E_TXD_CTX_QW0_EXT_IPLEN_SHIFT |
l4_tunnel |
((skb_inner_network_offset(skb) -
skb_transport_offset(skb)) >> 1) <<
I40E_TXD_CTX_QW0_NATLEN_SHIFT;
......
......@@ -36,7 +36,7 @@ char i40evf_driver_name[] = "i40evf";
static const char i40evf_driver_string[] =
"Intel(R) XL710/X710 Virtual Function Network Driver";
#define DRV_VERSION "1.2.5"
#define DRV_VERSION "1.2.6"
const char i40evf_driver_version[] = DRV_VERSION;
static const char i40evf_copyright[] =
"Copyright (c) 2013 - 2014 Intel Corporation.";
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment