Skip to content

Commit 397df70

Browse files
committed
Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue
Jeff Kirsher says: ==================== 40GbE Intel Wired LAN Driver Updates 2017-03-29 This series contains updates to i40e and i40evf only. Preethi changes the default driver mode of operation to descriptor write-back for VF. Alex cleans up and addresses several issues in the way that i40e handles private flags. Modifies the driver to use the length of the packet instead of the DD status bit to determine if a new descriptor is ready to be processed. Refactors the driver by pulling the code responsible for fetching the receive buffer and synchronizing DMA into a single function. Also pulled the code responsible for handling buffer recycling and page counting and distributed it through several functions, so we can commonize the bits that handle either freeing or recycling the buffers. Cleans up the code in preparation for us adding support for build_skb(). Changed the way we handle the maximum frame size for the receive path so it is more consistent with other drivers. Paul enables XL722 to use the direct read/write method since it does not support the AQ command to read/write the control register. Christopher fixes a case where we miss an arq element if a new one is added before we enable interrupts and exit the loop. Jake cleans up a pointless goto statement. Also cleaned up a flag that was not being used. Carolyn does round 2 for adding a delay to the receive queue to accommodate the hardware needs. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 14a98e6 + d08a9f6 commit 397df70

File tree

13 files changed

+559
-428
lines changed

13 files changed

+559
-428
lines changed

drivers/net/ethernet/intel/i40e/i40e.h

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,6 @@
9191
#define I40E_QUEUE_WAIT_RETRY_LIMIT 10
9292
#define I40E_INT_NAME_STR_LEN (IFNAMSIZ + 16)
9393

94-
/* Ethtool Private Flags */
95-
#define I40E_PRIV_FLAGS_MFP_FLAG BIT(0)
96-
#define I40E_PRIV_FLAGS_LINKPOLL_FLAG BIT(1)
97-
#define I40E_PRIV_FLAGS_FD_ATR BIT(2)
98-
#define I40E_PRIV_FLAGS_VEB_STATS BIT(3)
99-
#define I40E_PRIV_FLAGS_HW_ATR_EVICT BIT(4)
100-
#define I40E_PRIV_FLAGS_TRUE_PROMISC_SUPPORT BIT(5)
101-
10294
#define I40E_NVM_VERSION_LO_SHIFT 0
10395
#define I40E_NVM_VERSION_LO_MASK (0xff << I40E_NVM_VERSION_LO_SHIFT)
10496
#define I40E_NVM_VERSION_HI_SHIFT 12
@@ -397,7 +389,6 @@ struct i40e_pf {
397389
#define I40E_FLAG_MSIX_ENABLED BIT_ULL(3)
398390
#define I40E_FLAG_RSS_ENABLED BIT_ULL(6)
399391
#define I40E_FLAG_VMDQ_ENABLED BIT_ULL(7)
400-
#define I40E_FLAG_FDIR_REQUIRES_REINIT BIT_ULL(8)
401392
#define I40E_FLAG_NEED_LINK_UPDATE BIT_ULL(9)
402393
#define I40E_FLAG_IWARP_ENABLED BIT_ULL(10)
403394
#define I40E_FLAG_CLEAN_ADMINQ BIT_ULL(14)
@@ -439,6 +430,7 @@ struct i40e_pf {
439430
#define I40E_FLAG_TEMP_LINK_POLLING BIT_ULL(55)
440431
#define I40E_FLAG_CLIENT_L2_CHANGE BIT_ULL(56)
441432
#define I40E_FLAG_WOL_MC_MAGIC_PKT_WAKE BIT_ULL(57)
433+
#define I40E_FLAG_LEGACY_RX BIT_ULL(58)
442434

443435
/* Tracks features that are disabled due to hw limitations.
444436
* If a bit is set here, it means that the corresponding

drivers/net/ethernet/intel/i40e/i40e_common.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4963,7 +4963,9 @@ u32 i40e_read_rx_ctl(struct i40e_hw *hw, u32 reg_addr)
49634963
int retry = 5;
49644964
u32 val = 0;
49654965

4966-
use_register = (hw->aq.api_maj_ver == 1) && (hw->aq.api_min_ver < 5);
4966+
use_register = (((hw->aq.api_maj_ver == 1) &&
4967+
(hw->aq.api_min_ver < 5)) ||
4968+
(hw->mac.type == I40E_MAC_X722));
49674969
if (!use_register) {
49684970
do_retry:
49694971
status = i40e_aq_rx_ctl_read_register(hw, reg_addr, &val, NULL);
@@ -5022,7 +5024,9 @@ void i40e_write_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val)
50225024
bool use_register;
50235025
int retry = 5;
50245026

5025-
use_register = (hw->aq.api_maj_ver == 1) && (hw->aq.api_min_ver < 5);
5027+
use_register = (((hw->aq.api_maj_ver == 1) &&
5028+
(hw->aq.api_min_ver < 5)) ||
5029+
(hw->mac.type == I40E_MAC_X722));
50265030
if (!use_register) {
50275031
do_retry:
50285032
status = i40e_aq_rx_ctl_write_register(hw, reg_addr,

drivers/net/ethernet/intel/i40e/i40e_ethtool.c

Lines changed: 115 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -207,22 +207,37 @@ static const char i40e_gstrings_test[][ETH_GSTRING_LEN] = {
207207

208208
#define I40E_TEST_LEN (sizeof(i40e_gstrings_test) / ETH_GSTRING_LEN)
209209

210-
static const char i40e_priv_flags_strings[][ETH_GSTRING_LEN] = {
211-
"MFP",
212-
"LinkPolling",
213-
"flow-director-atr",
214-
"veb-stats",
215-
"hw-atr-eviction",
210+
struct i40e_priv_flags {
211+
char flag_string[ETH_GSTRING_LEN];
212+
u64 flag;
213+
bool read_only;
216214
};
217215

218-
#define I40E_PRIV_FLAGS_STR_LEN ARRAY_SIZE(i40e_priv_flags_strings)
216+
#define I40E_PRIV_FLAG(_name, _flag, _read_only) { \
217+
.flag_string = _name, \
218+
.flag = _flag, \
219+
.read_only = _read_only, \
220+
}
221+
222+
static const struct i40e_priv_flags i40e_gstrings_priv_flags[] = {
223+
/* NOTE: MFP setting cannot be changed */
224+
I40E_PRIV_FLAG("MFP", I40E_FLAG_MFP_ENABLED, 1),
225+
I40E_PRIV_FLAG("LinkPolling", I40E_FLAG_LINK_POLLING_ENABLED, 0),
226+
I40E_PRIV_FLAG("flow-director-atr", I40E_FLAG_FD_ATR_ENABLED, 0),
227+
I40E_PRIV_FLAG("veb-stats", I40E_FLAG_VEB_STATS_ENABLED, 0),
228+
I40E_PRIV_FLAG("hw-atr-eviction", I40E_FLAG_HW_ATR_EVICT_CAPABLE, 0),
229+
I40E_PRIV_FLAG("legacy-rx", I40E_FLAG_LEGACY_RX, 0),
230+
};
231+
232+
#define I40E_PRIV_FLAGS_STR_LEN ARRAY_SIZE(i40e_gstrings_priv_flags)
219233

220234
/* Private flags with a global effect, restricted to PF 0 */
221-
static const char i40e_gl_priv_flags_strings[][ETH_GSTRING_LEN] = {
222-
"vf-true-promisc-support",
235+
static const struct i40e_priv_flags i40e_gl_gstrings_priv_flags[] = {
236+
I40E_PRIV_FLAG("vf-true-promisc-support",
237+
I40E_FLAG_TRUE_PROMISC_SUPPORT, 0),
223238
};
224239

225-
#define I40E_GL_PRIV_FLAGS_STR_LEN ARRAY_SIZE(i40e_gl_priv_flags_strings)
240+
#define I40E_GL_PRIV_FLAGS_STR_LEN ARRAY_SIZE(i40e_gl_gstrings_priv_flags)
226241

227242
/**
228243
* i40e_partition_setting_complaint - generic complaint for MFP restriction
@@ -1660,12 +1675,18 @@ static void i40e_get_strings(struct net_device *netdev, u32 stringset,
16601675
/* BUG_ON(p - data != I40E_STATS_LEN * ETH_GSTRING_LEN); */
16611676
break;
16621677
case ETH_SS_PRIV_FLAGS:
1663-
memcpy(data, i40e_priv_flags_strings,
1664-
I40E_PRIV_FLAGS_STR_LEN * ETH_GSTRING_LEN);
1665-
data += I40E_PRIV_FLAGS_STR_LEN * ETH_GSTRING_LEN;
1666-
if (pf->hw.pf_id == 0)
1667-
memcpy(data, i40e_gl_priv_flags_strings,
1668-
I40E_GL_PRIV_FLAGS_STR_LEN * ETH_GSTRING_LEN);
1678+
for (i = 0; i < I40E_PRIV_FLAGS_STR_LEN; i++) {
1679+
snprintf(p, ETH_GSTRING_LEN, "%s",
1680+
i40e_gstrings_priv_flags[i].flag_string);
1681+
p += ETH_GSTRING_LEN;
1682+
}
1683+
if (pf->hw.pf_id != 0)
1684+
break;
1685+
for (i = 0; i < I40E_GL_PRIV_FLAGS_STR_LEN; i++) {
1686+
snprintf(p, ETH_GSTRING_LEN, "%s",
1687+
i40e_gl_gstrings_priv_flags[i].flag_string);
1688+
p += ETH_GSTRING_LEN;
1689+
}
16691690
break;
16701691
default:
16711692
break;
@@ -3952,7 +3973,7 @@ static int i40e_set_rxfh(struct net_device *netdev, const u32 *indir,
39523973
* @dev: network interface device structure
39533974
*
39543975
* The get string set count and the string set should be matched for each
3955-
* flag returned. Add new strings for each flag to the i40e_priv_flags_strings
3976+
* flag returned. Add new strings for each flag to the i40e_gstrings_priv_flags
39563977
* array.
39573978
*
39583979
* Returns a u32 bitmap of flags.
@@ -3962,19 +3983,27 @@ static u32 i40e_get_priv_flags(struct net_device *dev)
39623983
struct i40e_netdev_priv *np = netdev_priv(dev);
39633984
struct i40e_vsi *vsi = np->vsi;
39643985
struct i40e_pf *pf = vsi->back;
3965-
u32 ret_flags = 0;
3966-
3967-
ret_flags |= pf->flags & I40E_FLAG_LINK_POLLING_ENABLED ?
3968-
I40E_PRIV_FLAGS_LINKPOLL_FLAG : 0;
3969-
ret_flags |= pf->flags & I40E_FLAG_FD_ATR_ENABLED ?
3970-
I40E_PRIV_FLAGS_FD_ATR : 0;
3971-
ret_flags |= pf->flags & I40E_FLAG_VEB_STATS_ENABLED ?
3972-
I40E_PRIV_FLAGS_VEB_STATS : 0;
3973-
ret_flags |= pf->hw_disabled_flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE ?
3974-
0 : I40E_PRIV_FLAGS_HW_ATR_EVICT;
3975-
if (pf->hw.pf_id == 0) {
3976-
ret_flags |= pf->flags & I40E_FLAG_TRUE_PROMISC_SUPPORT ?
3977-
I40E_PRIV_FLAGS_TRUE_PROMISC_SUPPORT : 0;
3986+
u32 i, j, ret_flags = 0;
3987+
3988+
for (i = 0; i < I40E_PRIV_FLAGS_STR_LEN; i++) {
3989+
const struct i40e_priv_flags *priv_flags;
3990+
3991+
priv_flags = &i40e_gstrings_priv_flags[i];
3992+
3993+
if (priv_flags->flag & pf->flags)
3994+
ret_flags |= BIT(i);
3995+
}
3996+
3997+
if (pf->hw.pf_id != 0)
3998+
return ret_flags;
3999+
4000+
for (j = 0; j < I40E_GL_PRIV_FLAGS_STR_LEN; j++) {
4001+
const struct i40e_priv_flags *priv_flags;
4002+
4003+
priv_flags = &i40e_gl_gstrings_priv_flags[j];
4004+
4005+
if (priv_flags->flag & pf->flags)
4006+
ret_flags |= BIT(i + j);
39784007
}
39794008

39804009
return ret_flags;
@@ -3990,54 +4019,66 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
39904019
struct i40e_netdev_priv *np = netdev_priv(dev);
39914020
struct i40e_vsi *vsi = np->vsi;
39924021
struct i40e_pf *pf = vsi->back;
3993-
u16 sw_flags = 0, valid_flags = 0;
3994-
bool reset_required = false;
3995-
bool promisc_change = false;
3996-
int ret;
4022+
u64 changed_flags;
4023+
u32 i, j;
39974024

3998-
/* NOTE: MFP is not settable */
4025+
changed_flags = pf->flags;
39994026

4000-
if (flags & I40E_PRIV_FLAGS_LINKPOLL_FLAG)
4001-
pf->flags |= I40E_FLAG_LINK_POLLING_ENABLED;
4002-
else
4003-
pf->flags &= ~I40E_FLAG_LINK_POLLING_ENABLED;
4027+
for (i = 0; i < I40E_PRIV_FLAGS_STR_LEN; i++) {
4028+
const struct i40e_priv_flags *priv_flags;
40044029

4005-
/* allow the user to control the state of the Flow
4006-
* Director ATR (Application Targeted Routing) feature
4007-
* of the driver
4008-
*/
4009-
if (flags & I40E_PRIV_FLAGS_FD_ATR) {
4010-
pf->flags |= I40E_FLAG_FD_ATR_ENABLED;
4011-
} else {
4012-
pf->flags &= ~I40E_FLAG_FD_ATR_ENABLED;
4013-
pf->hw_disabled_flags |= I40E_FLAG_FD_ATR_ENABLED;
4030+
priv_flags = &i40e_gstrings_priv_flags[i];
40144031

4015-
/* flush current ATR settings */
4016-
set_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state);
4032+
if (priv_flags->read_only)
4033+
continue;
4034+
4035+
if (flags & BIT(i))
4036+
pf->flags |= priv_flags->flag;
4037+
else
4038+
pf->flags &= ~(priv_flags->flag);
40174039
}
40184040

4019-
if ((flags & I40E_PRIV_FLAGS_VEB_STATS) &&
4020-
!(pf->flags & I40E_FLAG_VEB_STATS_ENABLED)) {
4021-
pf->flags |= I40E_FLAG_VEB_STATS_ENABLED;
4022-
reset_required = true;
4023-
} else if (!(flags & I40E_PRIV_FLAGS_VEB_STATS) &&
4024-
(pf->flags & I40E_FLAG_VEB_STATS_ENABLED)) {
4025-
pf->flags &= ~I40E_FLAG_VEB_STATS_ENABLED;
4026-
reset_required = true;
4041+
if (pf->hw.pf_id != 0)
4042+
goto flags_complete;
4043+
4044+
for (j = 0; j < I40E_GL_PRIV_FLAGS_STR_LEN; j++) {
4045+
const struct i40e_priv_flags *priv_flags;
4046+
4047+
priv_flags = &i40e_gl_gstrings_priv_flags[j];
4048+
4049+
if (priv_flags->read_only)
4050+
continue;
4051+
4052+
if (flags & BIT(i + j))
4053+
pf->flags |= priv_flags->flag;
4054+
else
4055+
pf->flags &= ~(priv_flags->flag);
40274056
}
40284057

4029-
if (pf->hw.pf_id == 0) {
4030-
if ((flags & I40E_PRIV_FLAGS_TRUE_PROMISC_SUPPORT) &&
4031-
!(pf->flags & I40E_FLAG_TRUE_PROMISC_SUPPORT)) {
4032-
pf->flags |= I40E_FLAG_TRUE_PROMISC_SUPPORT;
4033-
promisc_change = true;
4034-
} else if (!(flags & I40E_PRIV_FLAGS_TRUE_PROMISC_SUPPORT) &&
4035-
(pf->flags & I40E_FLAG_TRUE_PROMISC_SUPPORT)) {
4036-
pf->flags &= ~I40E_FLAG_TRUE_PROMISC_SUPPORT;
4037-
promisc_change = true;
4038-
}
4058+
flags_complete:
4059+
/* check for flags that changed */
4060+
changed_flags ^= pf->flags;
4061+
4062+
/* Process any additional changes needed as a result of flag changes.
4063+
* The changed_flags value reflects the list of bits that were
4064+
* changed in the code above.
4065+
*/
4066+
4067+
/* Flush current ATR settings if ATR was disabled */
4068+
if ((changed_flags & I40E_FLAG_FD_ATR_ENABLED) &&
4069+
!(pf->flags & I40E_FLAG_FD_ATR_ENABLED)) {
4070+
pf->hw_disabled_flags |= I40E_FLAG_FD_ATR_ENABLED;
4071+
set_bit(__I40E_FD_FLUSH_REQUESTED, &pf->state);
40394072
}
4040-
if (promisc_change) {
4073+
4074+
/* Only allow ATR evict on hardware that is capable of handling it */
4075+
if (pf->hw_disabled_flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE)
4076+
pf->flags &= ~I40E_FLAG_HW_ATR_EVICT_CAPABLE;
4077+
4078+
if (changed_flags & I40E_FLAG_TRUE_PROMISC_SUPPORT) {
4079+
u16 sw_flags = 0, valid_flags = 0;
4080+
int ret;
4081+
40414082
if (!(pf->flags & I40E_FLAG_TRUE_PROMISC_SUPPORT))
40424083
sw_flags = I40E_AQ_SET_SWITCH_CFG_PROMISC;
40434084
valid_flags = I40E_AQ_SET_SWITCH_CFG_PROMISC;
@@ -4053,14 +4094,11 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
40534094
}
40544095
}
40554096

4056-
if ((flags & I40E_PRIV_FLAGS_HW_ATR_EVICT) &&
4057-
(pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE))
4058-
pf->hw_disabled_flags &= ~I40E_FLAG_HW_ATR_EVICT_CAPABLE;
4059-
else
4060-
pf->hw_disabled_flags |= I40E_FLAG_HW_ATR_EVICT_CAPABLE;
4061-
4062-
/* if needed, issue reset to cause things to take effect */
4063-
if (reset_required)
4097+
/* Issue reset to cause things to take effect, as additional bits
4098+
* are added we will need to create a mask of bits requiring reset
4099+
*/
4100+
if ((changed_flags & I40E_FLAG_VEB_STATS_ENABLED) ||
4101+
((changed_flags & I40E_FLAG_LEGACY_RX) && netif_running(dev)))
40644102
i40e_do_reset(pf, BIT(__I40E_PF_RESET_REQUESTED));
40654103

40664104
return 0;

drivers/net/ethernet/intel/i40e/i40e_main.c

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2995,7 +2995,8 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)
29952995

29962996
ring->rx_buf_len = vsi->rx_buf_len;
29972997

2998-
rx_ctx.dbuff = ring->rx_buf_len >> I40E_RXQ_CTX_DBUFF_SHIFT;
2998+
rx_ctx.dbuff = DIV_ROUND_UP(ring->rx_buf_len,
2999+
BIT_ULL(I40E_RXQ_CTX_DBUFF_SHIFT));
29993000

30003001
rx_ctx.base = (ring->dma / 128);
30013002
rx_ctx.qlen = ring->count;
@@ -3075,17 +3076,18 @@ static int i40e_vsi_configure_rx(struct i40e_vsi *vsi)
30753076
int err = 0;
30763077
u16 i;
30773078

3078-
if (vsi->netdev && (vsi->netdev->mtu > ETH_DATA_LEN))
3079-
vsi->max_frame = vsi->netdev->mtu + ETH_HLEN
3080-
+ ETH_FCS_LEN + VLAN_HLEN;
3081-
else
3082-
vsi->max_frame = I40E_RXBUFFER_2048;
3083-
3084-
vsi->rx_buf_len = I40E_RXBUFFER_2048;
3085-
3086-
/* round up for the chip's needs */
3087-
vsi->rx_buf_len = ALIGN(vsi->rx_buf_len,
3088-
BIT_ULL(I40E_RXQ_CTX_DBUFF_SHIFT));
3079+
if (!vsi->netdev || (vsi->back->flags & I40E_FLAG_LEGACY_RX)) {
3080+
vsi->max_frame = I40E_MAX_RXBUFFER;
3081+
vsi->rx_buf_len = I40E_RXBUFFER_2048;
3082+
#if (PAGE_SIZE < 8192)
3083+
} else if (vsi->netdev->mtu <= ETH_DATA_LEN) {
3084+
vsi->max_frame = I40E_RXBUFFER_1536 - NET_IP_ALIGN;
3085+
vsi->rx_buf_len = I40E_RXBUFFER_1536 - NET_IP_ALIGN;
3086+
#endif
3087+
} else {
3088+
vsi->max_frame = I40E_MAX_RXBUFFER;
3089+
vsi->rx_buf_len = I40E_RXBUFFER_2048;
3090+
}
30893091

30903092
/* set up individual rings */
30913093
for (i = 0; i < vsi->num_queue_pairs && !err; i++)
@@ -4065,6 +4067,12 @@ static int i40e_vsi_control_rx(struct i40e_vsi *vsi, bool enable)
40654067
}
40664068
}
40674069

4070+
/* Due to HW errata, on Rx disable only, the register can indicate done
4071+
* before it really is. Needs 50ms to be sure
4072+
*/
4073+
if (!enable)
4074+
mdelay(50);
4075+
40684076
return ret;
40694077
}
40704078

@@ -5167,10 +5175,6 @@ static int i40e_init_pf_dcb(struct i40e_pf *pf)
51675175
(hw->dcbx_status == I40E_DCBX_STATUS_DISABLED)) {
51685176
dev_info(&pf->pdev->dev,
51695177
"DCBX offload is not supported or is disabled for this PF.\n");
5170-
5171-
if (pf->flags & I40E_FLAG_MFP_ENABLED)
5172-
goto out;
5173-
51745178
} else {
51755179
/* When status is not DISABLED then DCBX in FW */
51765180
pf->dcbx_cap = DCB_CAP_DCBX_LLD_MANAGED |
@@ -6519,9 +6523,11 @@ static void i40e_clean_adminq_subtask(struct i40e_pf *pf)
65196523
opcode);
65206524
break;
65216525
}
6522-
} while (pending && (i++ < pf->adminq_work_limit));
6526+
} while (i++ < pf->adminq_work_limit);
6527+
6528+
if (i < pf->adminq_work_limit)
6529+
clear_bit(__I40E_ADMINQ_EVENT_PENDING, &pf->state);
65236530

6524-
clear_bit(__I40E_ADMINQ_EVENT_PENDING, &pf->state);
65256531
/* re-enable Admin queue interrupt cause */
65266532
val = rd32(hw, I40E_PFINT_ICR0_ENA);
65276533
val |= I40E_PFINT_ICR0_ENA_ADMINQ_MASK;

0 commit comments

Comments
 (0)