mirror of
https://github.com/torvalds/linux.git
synced 2026-05-22 14:12:07 +02:00
Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue
Tony Nguyen says: ==================== 40GbE Intel Wired LAN Driver Updates 2022-06-21 This series contains updates to i40e driver only. Mateusz adds support for using the speed option in ethtool. Minghao Chi removes unneeded synchronize_irq() calls. Bernard Zhao removes unneeded NULL check. * '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue: intel/i40e: delete if NULL check before dev_kfree_skb i40e: Remove unnecessary synchronize_irq() before free_irq() i40e: Add support for ethtool -s <interface> speed <speed in Mb> ==================== Link: https://lore.kernel.org/r/20220621225930.632741-1-anthony.l.nguyen@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
85763435d5
|
|
@ -1143,6 +1143,71 @@ static int i40e_get_link_ksettings(struct net_device *netdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define I40E_LBIT_SIZE 8
|
||||
/**
|
||||
* i40e_speed_to_link_speed - Translate decimal speed to i40e_aq_link_speed
|
||||
* @speed: speed in decimal
|
||||
* @ks: ethtool ksettings
|
||||
*
|
||||
* Return i40e_aq_link_speed based on speed
|
||||
**/
|
||||
static enum i40e_aq_link_speed
|
||||
i40e_speed_to_link_speed(__u32 speed, const struct ethtool_link_ksettings *ks)
|
||||
{
|
||||
enum i40e_aq_link_speed link_speed = I40E_LINK_SPEED_UNKNOWN;
|
||||
bool speed_changed = false;
|
||||
int i, j;
|
||||
|
||||
static const struct {
|
||||
__u32 speed;
|
||||
enum i40e_aq_link_speed link_speed;
|
||||
__u8 bit[I40E_LBIT_SIZE];
|
||||
} i40e_speed_lut[] = {
|
||||
#define I40E_LBIT(mode) ETHTOOL_LINK_MODE_ ## mode ##_Full_BIT
|
||||
{SPEED_100, I40E_LINK_SPEED_100MB, {I40E_LBIT(100baseT)} },
|
||||
{SPEED_1000, I40E_LINK_SPEED_1GB,
|
||||
{I40E_LBIT(1000baseT), I40E_LBIT(1000baseX),
|
||||
I40E_LBIT(1000baseKX)} },
|
||||
{SPEED_10000, I40E_LINK_SPEED_10GB,
|
||||
{I40E_LBIT(10000baseT), I40E_LBIT(10000baseKR),
|
||||
I40E_LBIT(10000baseLR), I40E_LBIT(10000baseCR),
|
||||
I40E_LBIT(10000baseSR), I40E_LBIT(10000baseKX4)} },
|
||||
|
||||
{SPEED_25000, I40E_LINK_SPEED_25GB,
|
||||
{I40E_LBIT(25000baseCR), I40E_LBIT(25000baseKR),
|
||||
I40E_LBIT(25000baseSR)} },
|
||||
{SPEED_40000, I40E_LINK_SPEED_40GB,
|
||||
{I40E_LBIT(40000baseKR4), I40E_LBIT(40000baseCR4),
|
||||
I40E_LBIT(40000baseSR4), I40E_LBIT(40000baseLR4)} },
|
||||
{SPEED_20000, I40E_LINK_SPEED_20GB,
|
||||
{I40E_LBIT(20000baseKR2)} },
|
||||
{SPEED_2500, I40E_LINK_SPEED_2_5GB, {I40E_LBIT(2500baseT)} },
|
||||
{SPEED_5000, I40E_LINK_SPEED_5GB, {I40E_LBIT(2500baseT)} }
|
||||
#undef I40E_LBIT
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(i40e_speed_lut); i++) {
|
||||
if (i40e_speed_lut[i].speed == speed) {
|
||||
for (j = 0; j < I40E_LBIT_SIZE; j++) {
|
||||
if (test_bit(i40e_speed_lut[i].bit[j],
|
||||
ks->link_modes.supported)) {
|
||||
speed_changed = true;
|
||||
break;
|
||||
}
|
||||
if (!i40e_speed_lut[i].bit[j])
|
||||
break;
|
||||
}
|
||||
if (speed_changed) {
|
||||
link_speed = i40e_speed_lut[i].link_speed;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return link_speed;
|
||||
}
|
||||
|
||||
#undef I40E_LBIT_SIZE
|
||||
|
||||
/**
|
||||
* i40e_set_link_ksettings - Set Speed and Duplex
|
||||
* @netdev: network interface device structure
|
||||
|
|
@ -1159,12 +1224,14 @@ static int i40e_set_link_ksettings(struct net_device *netdev,
|
|||
struct ethtool_link_ksettings copy_ks;
|
||||
struct i40e_aq_set_phy_config config;
|
||||
struct i40e_pf *pf = np->vsi->back;
|
||||
enum i40e_aq_link_speed link_speed;
|
||||
struct i40e_vsi *vsi = np->vsi;
|
||||
struct i40e_hw *hw = &pf->hw;
|
||||
bool autoneg_changed = false;
|
||||
i40e_status status = 0;
|
||||
int timeout = 50;
|
||||
int err = 0;
|
||||
__u32 speed;
|
||||
u8 autoneg;
|
||||
|
||||
/* Changing port settings is not supported if this isn't the
|
||||
|
|
@ -1197,6 +1264,7 @@ static int i40e_set_link_ksettings(struct net_device *netdev,
|
|||
|
||||
/* save autoneg out of ksettings */
|
||||
autoneg = copy_ks.base.autoneg;
|
||||
speed = copy_ks.base.speed;
|
||||
|
||||
/* get our own copy of the bits to check against */
|
||||
memset(&safe_ks, 0, sizeof(struct ethtool_link_ksettings));
|
||||
|
|
@ -1215,6 +1283,7 @@ static int i40e_set_link_ksettings(struct net_device *netdev,
|
|||
|
||||
/* set autoneg back to what it currently is */
|
||||
copy_ks.base.autoneg = safe_ks.base.autoneg;
|
||||
copy_ks.base.speed = safe_ks.base.speed;
|
||||
|
||||
/* If copy_ks.base and safe_ks.base are not the same now, then they are
|
||||
* trying to set something that we do not support.
|
||||
|
|
@ -1331,6 +1400,27 @@ static int i40e_set_link_ksettings(struct net_device *netdev,
|
|||
40000baseLR4_Full))
|
||||
config.link_speed |= I40E_LINK_SPEED_40GB;
|
||||
|
||||
/* Autonegotiation must be disabled to change speed */
|
||||
if ((speed != SPEED_UNKNOWN && safe_ks.base.speed != speed) &&
|
||||
(autoneg == AUTONEG_DISABLE ||
|
||||
(safe_ks.base.autoneg == AUTONEG_DISABLE && !autoneg_changed))) {
|
||||
link_speed = i40e_speed_to_link_speed(speed, ks);
|
||||
if (link_speed == I40E_LINK_SPEED_UNKNOWN) {
|
||||
netdev_info(netdev, "Given speed is not supported\n");
|
||||
err = -EOPNOTSUPP;
|
||||
goto done;
|
||||
} else {
|
||||
config.link_speed = link_speed;
|
||||
}
|
||||
} else {
|
||||
if (safe_ks.base.speed != speed) {
|
||||
netdev_info(netdev,
|
||||
"Unable to set speed, disable autoneg\n");
|
||||
err = -EOPNOTSUPP;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* If speed didn't get set, set it to what it currently is.
|
||||
* This is needed because if advertise is 0 (as it is when autoneg
|
||||
* is disabled) then speed won't get set.
|
||||
|
|
|
|||
|
|
@ -4162,7 +4162,6 @@ static void i40e_free_misc_vector(struct i40e_pf *pf)
|
|||
i40e_flush(&pf->hw);
|
||||
|
||||
if (pf->flags & I40E_FLAG_MSIX_ENABLED && pf->msix_entries) {
|
||||
synchronize_irq(pf->msix_entries[0].vector);
|
||||
free_irq(pf->msix_entries[0].vector, pf);
|
||||
clear_bit(__I40E_MISC_IRQ_REQUESTED, pf->state);
|
||||
}
|
||||
|
|
@ -4901,7 +4900,6 @@ static void i40e_vsi_free_irq(struct i40e_vsi *vsi)
|
|||
irq_set_affinity_notifier(irq_num, NULL);
|
||||
/* remove our suggested affinity mask for this IRQ */
|
||||
irq_update_affinity_hint(irq_num, NULL);
|
||||
synchronize_irq(irq_num);
|
||||
free_irq(irq_num, vsi->q_vectors[i]);
|
||||
|
||||
/* Tear down the interrupt queue link list
|
||||
|
|
|
|||
|
|
@ -1483,10 +1483,8 @@ void i40e_clean_rx_ring(struct i40e_ring *rx_ring)
|
|||
if (!rx_ring->rx_bi)
|
||||
return;
|
||||
|
||||
if (rx_ring->skb) {
|
||||
dev_kfree_skb(rx_ring->skb);
|
||||
rx_ring->skb = NULL;
|
||||
}
|
||||
dev_kfree_skb(rx_ring->skb);
|
||||
rx_ring->skb = NULL;
|
||||
|
||||
if (rx_ring->xsk_pool) {
|
||||
i40e_xsk_clean_rx_ring(rx_ring);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user