Skip to content

Commit 0506c93

Browse files
committed
Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue
Tony Nguyen says: ==================== Intel Wired LAN Driver Updates 2021-07-23 This series contains updates to i40e driver only. Arkadiusz corrects the order of calls for disabling queues to resolve a false error message and adds a better message to the user when transitioning FW LLDP back on while the firmware is still processing the off request. Lukasz adds additional information regarding possible incorrect cable use when a PHY type error occurs. Jedrzej adds ndo_select_queue support to resolve incorrect queue selection when SW DCB is used and adds a warning when there are not enough queues for desired TC configuration. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 1f22cf1 + ea52faa commit 0506c93

File tree

4 files changed

+94
-25
lines changed

4 files changed

+94
-25
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -980,7 +980,7 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw,
980980
default:
981981
/* if we got here and link is up something bad is afoot */
982982
netdev_info(netdev,
983-
"WARNING: Link is up but PHY type 0x%x is not recognized.\n",
983+
"WARNING: Link is up but PHY type 0x%x is not recognized, or incorrect cable is in use\n",
984984
hw_link_info->phy_type);
985985
}
986986

@@ -5294,6 +5294,10 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
52945294
dev_warn(&pf->pdev->dev,
52955295
"Device configuration forbids SW from starting the LLDP agent.\n");
52965296
return -EINVAL;
5297+
case I40E_AQ_RC_EAGAIN:
5298+
dev_warn(&pf->pdev->dev,
5299+
"Stop FW LLDP agent command is still being processed, please try again in a second.\n");
5300+
return -EBUSY;
52975301
default:
52985302
dev_warn(&pf->pdev->dev,
52995303
"Starting FW LLDP agent failed: error: %s, %s\n",

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

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4454,11 +4454,10 @@ int i40e_control_wait_tx_q(int seid, struct i40e_pf *pf, int pf_q,
44544454
}
44554455

44564456
/**
4457-
* i40e_vsi_control_tx - Start or stop a VSI's rings
4457+
* i40e_vsi_enable_tx - Start a VSI's rings
44584458
* @vsi: the VSI being configured
4459-
* @enable: start or stop the rings
44604459
**/
4461-
static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable)
4460+
static int i40e_vsi_enable_tx(struct i40e_vsi *vsi)
44624461
{
44634462
struct i40e_pf *pf = vsi->back;
44644463
int i, pf_q, ret = 0;
@@ -4467,7 +4466,7 @@ static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable)
44674466
for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) {
44684467
ret = i40e_control_wait_tx_q(vsi->seid, pf,
44694468
pf_q,
4470-
false /*is xdp*/, enable);
4469+
false /*is xdp*/, true);
44714470
if (ret)
44724471
break;
44734472

@@ -4476,7 +4475,7 @@ static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable)
44764475

44774476
ret = i40e_control_wait_tx_q(vsi->seid, pf,
44784477
pf_q + vsi->alloc_queue_pairs,
4479-
true /*is xdp*/, enable);
4478+
true /*is xdp*/, true);
44804479
if (ret)
44814480
break;
44824481
}
@@ -4574,32 +4573,25 @@ int i40e_control_wait_rx_q(struct i40e_pf *pf, int pf_q, bool enable)
45744573
}
45754574

45764575
/**
4577-
* i40e_vsi_control_rx - Start or stop a VSI's rings
4576+
* i40e_vsi_enable_rx - Start a VSI's rings
45784577
* @vsi: the VSI being configured
4579-
* @enable: start or stop the rings
45804578
**/
4581-
static int i40e_vsi_control_rx(struct i40e_vsi *vsi, bool enable)
4579+
static int i40e_vsi_enable_rx(struct i40e_vsi *vsi)
45824580
{
45834581
struct i40e_pf *pf = vsi->back;
45844582
int i, pf_q, ret = 0;
45854583

45864584
pf_q = vsi->base_queue;
45874585
for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) {
4588-
ret = i40e_control_wait_rx_q(pf, pf_q, enable);
4586+
ret = i40e_control_wait_rx_q(pf, pf_q, true);
45894587
if (ret) {
45904588
dev_info(&pf->pdev->dev,
4591-
"VSI seid %d Rx ring %d %sable timeout\n",
4592-
vsi->seid, pf_q, (enable ? "en" : "dis"));
4589+
"VSI seid %d Rx ring %d enable timeout\n",
4590+
vsi->seid, pf_q);
45934591
break;
45944592
}
45954593
}
45964594

4597-
/* Due to HW errata, on Rx disable only, the register can indicate done
4598-
* before it really is. Needs 50ms to be sure
4599-
*/
4600-
if (!enable)
4601-
mdelay(50);
4602-
46034595
return ret;
46044596
}
46054597

@@ -4612,29 +4604,47 @@ int i40e_vsi_start_rings(struct i40e_vsi *vsi)
46124604
int ret = 0;
46134605

46144606
/* do rx first for enable and last for disable */
4615-
ret = i40e_vsi_control_rx(vsi, true);
4607+
ret = i40e_vsi_enable_rx(vsi);
46164608
if (ret)
46174609
return ret;
4618-
ret = i40e_vsi_control_tx(vsi, true);
4610+
ret = i40e_vsi_enable_tx(vsi);
46194611

46204612
return ret;
46214613
}
46224614

4615+
#define I40E_DISABLE_TX_GAP_MSEC 50
4616+
46234617
/**
46244618
* i40e_vsi_stop_rings - Stop a VSI's rings
46254619
* @vsi: the VSI being configured
46264620
**/
46274621
void i40e_vsi_stop_rings(struct i40e_vsi *vsi)
46284622
{
4623+
struct i40e_pf *pf = vsi->back;
4624+
int pf_q, err, q_end;
4625+
46294626
/* When port TX is suspended, don't wait */
46304627
if (test_bit(__I40E_PORT_SUSPENDED, vsi->back->state))
46314628
return i40e_vsi_stop_rings_no_wait(vsi);
46324629

4633-
/* do rx first for enable and last for disable
4634-
* Ignore return value, we need to shutdown whatever we can
4635-
*/
4636-
i40e_vsi_control_tx(vsi, false);
4637-
i40e_vsi_control_rx(vsi, false);
4630+
q_end = vsi->base_queue + vsi->num_queue_pairs;
4631+
for (pf_q = vsi->base_queue; pf_q < q_end; pf_q++)
4632+
i40e_pre_tx_queue_cfg(&pf->hw, (u32)pf_q, false);
4633+
4634+
for (pf_q = vsi->base_queue; pf_q < q_end; pf_q++) {
4635+
err = i40e_control_wait_rx_q(pf, pf_q, false);
4636+
if (err)
4637+
dev_info(&pf->pdev->dev,
4638+
"VSI seid %d Rx ring %d dissable timeout\n",
4639+
vsi->seid, pf_q);
4640+
}
4641+
4642+
msleep(I40E_DISABLE_TX_GAP_MSEC);
4643+
pf_q = vsi->base_queue;
4644+
for (pf_q = vsi->base_queue; pf_q < q_end; pf_q++)
4645+
wr32(&pf->hw, I40E_QTX_ENA(pf_q), 0);
4646+
4647+
i40e_vsi_wait_queues_disabled(vsi);
46384648
}
46394649

46404650
/**
@@ -7280,6 +7290,8 @@ static int i40e_validate_mqprio_qopt(struct i40e_vsi *vsi,
72807290
}
72817291
if (vsi->num_queue_pairs <
72827292
(mqprio_qopt->qopt.offset[i] + mqprio_qopt->qopt.count[i])) {
7293+
dev_err(&vsi->back->pdev->dev,
7294+
"Failed to create traffic channel, insufficient number of queues.\n");
72837295
return -EINVAL;
72847296
}
72857297
if (sum_max_rate > i40e_get_link_speed(vsi)) {
@@ -13261,6 +13273,7 @@ static const struct net_device_ops i40e_netdev_ops = {
1326113273
.ndo_poll_controller = i40e_netpoll,
1326213274
#endif
1326313275
.ndo_setup_tc = __i40e_setup_tc,
13276+
.ndo_select_queue = i40e_lan_select_queue,
1326413277
.ndo_set_features = i40e_set_features,
1326513278
.ndo_set_vf_mac = i40e_ndo_set_vf_mac,
1326613279
.ndo_set_vf_vlan = i40e_ndo_set_vf_port_vlan,

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

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3631,6 +3631,56 @@ static inline int i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb,
36313631
return -1;
36323632
}
36333633

3634+
static u16 i40e_swdcb_skb_tx_hash(struct net_device *dev,
3635+
const struct sk_buff *skb,
3636+
u16 num_tx_queues)
3637+
{
3638+
u32 jhash_initval_salt = 0xd631614b;
3639+
u32 hash;
3640+
3641+
if (skb->sk && skb->sk->sk_hash)
3642+
hash = skb->sk->sk_hash;
3643+
else
3644+
hash = (__force u16)skb->protocol ^ skb->hash;
3645+
3646+
hash = jhash_1word(hash, jhash_initval_salt);
3647+
3648+
return (u16)(((u64)hash * num_tx_queues) >> 32);
3649+
}
3650+
3651+
u16 i40e_lan_select_queue(struct net_device *netdev,
3652+
struct sk_buff *skb,
3653+
struct net_device __always_unused *sb_dev)
3654+
{
3655+
struct i40e_netdev_priv *np = netdev_priv(netdev);
3656+
struct i40e_vsi *vsi = np->vsi;
3657+
struct i40e_hw *hw;
3658+
u16 qoffset;
3659+
u16 qcount;
3660+
u8 tclass;
3661+
u16 hash;
3662+
u8 prio;
3663+
3664+
/* is DCB enabled at all? */
3665+
if (vsi->tc_config.numtc == 1)
3666+
return i40e_swdcb_skb_tx_hash(netdev, skb,
3667+
netdev->real_num_tx_queues);
3668+
3669+
prio = skb->priority;
3670+
hw = &vsi->back->hw;
3671+
tclass = hw->local_dcbx_config.etscfg.prioritytable[prio];
3672+
/* sanity check */
3673+
if (unlikely(!(vsi->tc_config.enabled_tc & BIT(tclass))))
3674+
tclass = 0;
3675+
3676+
/* select a queue assigned for the given TC */
3677+
qcount = vsi->tc_config.tc_info[tclass].qcount;
3678+
hash = i40e_swdcb_skb_tx_hash(netdev, skb, qcount);
3679+
3680+
qoffset = vsi->tc_config.tc_info[tclass].qoffset;
3681+
return qoffset + hash;
3682+
}
3683+
36343684
/**
36353685
* i40e_xmit_xdp_ring - transmits an XDP buffer to an XDP Tx ring
36363686
* @xdpf: data to transmit

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,8 @@ static inline unsigned int i40e_rx_pg_order(struct i40e_ring *ring)
451451

452452
bool i40e_alloc_rx_buffers(struct i40e_ring *rxr, u16 cleaned_count);
453453
netdev_tx_t i40e_lan_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
454+
u16 i40e_lan_select_queue(struct net_device *netdev, struct sk_buff *skb,
455+
struct net_device *sb_dev);
454456
void i40e_clean_tx_ring(struct i40e_ring *tx_ring);
455457
void i40e_clean_rx_ring(struct i40e_ring *rx_ring);
456458
int i40e_setup_tx_descriptors(struct i40e_ring *tx_ring);

0 commit comments

Comments
 (0)