Merge c31bd5b6ff ("Merge branch 'rtl8226b-serdes-switching'") into android-mainline

Steps on the way to 6.10-rc1

Change-Id: I9072485af6d838d26eb2e3b7a76c09555481efc9
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2024-07-30 13:26:15 +00:00
39 changed files with 674 additions and 247 deletions
+39 -24
View File
@@ -861,24 +861,27 @@ static void mv88e6xxx_get_caps(struct dsa_switch *ds, int port,
}
}
static struct phylink_pcs *mv88e6xxx_mac_select_pcs(struct dsa_switch *ds,
int port,
phy_interface_t interface)
static struct phylink_pcs *
mv88e6xxx_mac_select_pcs(struct phylink_config *config,
phy_interface_t interface)
{
struct mv88e6xxx_chip *chip = ds->priv;
struct dsa_port *dp = dsa_phylink_to_port(config);
struct mv88e6xxx_chip *chip = dp->ds->priv;
struct phylink_pcs *pcs = ERR_PTR(-EOPNOTSUPP);
if (chip->info->ops->pcs_ops)
pcs = chip->info->ops->pcs_ops->pcs_select(chip, port,
pcs = chip->info->ops->pcs_ops->pcs_select(chip, dp->index,
interface);
return pcs;
}
static int mv88e6xxx_mac_prepare(struct dsa_switch *ds, int port,
static int mv88e6xxx_mac_prepare(struct phylink_config *config,
unsigned int mode, phy_interface_t interface)
{
struct mv88e6xxx_chip *chip = ds->priv;
struct dsa_port *dp = dsa_phylink_to_port(config);
struct mv88e6xxx_chip *chip = dp->ds->priv;
int port = dp->index;
int err = 0;
/* In inband mode, the link may come up at any time while the link
@@ -897,11 +900,13 @@ static int mv88e6xxx_mac_prepare(struct dsa_switch *ds, int port,
return err;
}
static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,
static void mv88e6xxx_mac_config(struct phylink_config *config,
unsigned int mode,
const struct phylink_link_state *state)
{
struct mv88e6xxx_chip *chip = ds->priv;
struct dsa_port *dp = dsa_phylink_to_port(config);
struct mv88e6xxx_chip *chip = dp->ds->priv;
int port = dp->index;
int err = 0;
mv88e6xxx_reg_lock(chip);
@@ -917,13 +922,15 @@ err_unlock:
mv88e6xxx_reg_unlock(chip);
if (err && err != -EOPNOTSUPP)
dev_err(ds->dev, "p%d: failed to configure MAC/PCS\n", port);
dev_err(chip->dev, "p%d: failed to configure MAC/PCS\n", port);
}
static int mv88e6xxx_mac_finish(struct dsa_switch *ds, int port,
static int mv88e6xxx_mac_finish(struct phylink_config *config,
unsigned int mode, phy_interface_t interface)
{
struct mv88e6xxx_chip *chip = ds->priv;
struct dsa_port *dp = dsa_phylink_to_port(config);
struct mv88e6xxx_chip *chip = dp->ds->priv;
int port = dp->index;
int err = 0;
/* Undo the forced down state above after completing configuration
@@ -947,12 +954,14 @@ static int mv88e6xxx_mac_finish(struct dsa_switch *ds, int port,
return err;
}
static void mv88e6xxx_mac_link_down(struct dsa_switch *ds, int port,
static void mv88e6xxx_mac_link_down(struct phylink_config *config,
unsigned int mode,
phy_interface_t interface)
{
struct mv88e6xxx_chip *chip = ds->priv;
struct dsa_port *dp = dsa_phylink_to_port(config);
struct mv88e6xxx_chip *chip = dp->ds->priv;
const struct mv88e6xxx_ops *ops;
int port = dp->index;
int err = 0;
ops = chip->info->ops;
@@ -975,14 +984,16 @@ static void mv88e6xxx_mac_link_down(struct dsa_switch *ds, int port,
"p%d: failed to force MAC link down\n", port);
}
static void mv88e6xxx_mac_link_up(struct dsa_switch *ds, int port,
unsigned int mode, phy_interface_t interface,
static void mv88e6xxx_mac_link_up(struct phylink_config *config,
struct phy_device *phydev,
unsigned int mode, phy_interface_t interface,
int speed, int duplex,
bool tx_pause, bool rx_pause)
{
struct mv88e6xxx_chip *chip = ds->priv;
struct dsa_port *dp = dsa_phylink_to_port(config);
struct mv88e6xxx_chip *chip = dp->ds->priv;
const struct mv88e6xxx_ops *ops;
int port = dp->index;
int err = 0;
ops = chip->info->ops;
@@ -1008,7 +1019,7 @@ error:
mv88e6xxx_reg_unlock(chip);
if (err && err != -EOPNOTSUPP)
dev_err(ds->dev,
dev_err(chip->dev,
"p%d: failed to configure MAC link up\n", port);
}
@@ -6993,6 +7004,15 @@ static int mv88e6xxx_crosschip_lag_leave(struct dsa_switch *ds, int sw_index,
return err_sync ? : err_pvt;
}
static const struct phylink_mac_ops mv88e6xxx_phylink_mac_ops = {
.mac_select_pcs = mv88e6xxx_mac_select_pcs,
.mac_prepare = mv88e6xxx_mac_prepare,
.mac_config = mv88e6xxx_mac_config,
.mac_finish = mv88e6xxx_mac_finish,
.mac_link_down = mv88e6xxx_mac_link_down,
.mac_link_up = mv88e6xxx_mac_link_up,
};
static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
.get_tag_protocol = mv88e6xxx_get_tag_protocol,
.change_tag_protocol = mv88e6xxx_change_tag_protocol,
@@ -7001,12 +7021,6 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
.port_setup = mv88e6xxx_port_setup,
.port_teardown = mv88e6xxx_port_teardown,
.phylink_get_caps = mv88e6xxx_get_caps,
.phylink_mac_select_pcs = mv88e6xxx_mac_select_pcs,
.phylink_mac_prepare = mv88e6xxx_mac_prepare,
.phylink_mac_config = mv88e6xxx_mac_config,
.phylink_mac_finish = mv88e6xxx_mac_finish,
.phylink_mac_link_down = mv88e6xxx_mac_link_down,
.phylink_mac_link_up = mv88e6xxx_mac_link_up,
.get_strings = mv88e6xxx_get_strings,
.get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
.get_eth_mac_stats = mv88e6xxx_get_eth_mac_stats,
@@ -7075,6 +7089,7 @@ static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip)
ds->priv = chip;
ds->dev = dev;
ds->ops = &mv88e6xxx_switch_ops;
ds->phylink_mac_ops = &mv88e6xxx_phylink_mac_ops;
ds->ageing_time_min = chip->info->age_time_coeff;
ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX;
@@ -10,6 +10,7 @@
#include <net/ipv6.h>
#include <linux/netdevice.h>
#include <crypto/aes.h>
#include <linux/skbuff_ref.h>
#include "chcr_ktls.h"
static LIST_HEAD(uld_ctx_list);
@@ -1658,7 +1659,7 @@ static void chcr_ktls_copy_record_in_skb(struct sk_buff *nskb,
for (i = 0; i < record->num_frags; i++) {
skb_shinfo(nskb)->frags[i] = record->frags[i];
/* increase the frag ref count */
__skb_frag_ref(&skb_shinfo(nskb)->frags[i]);
__skb_frag_ref(&skb_shinfo(nskb)->frags[i], nskb->pp_recycle);
}
skb_shinfo(nskb)->nr_frags = record->num_frags;
+1
View File
@@ -34,6 +34,7 @@
#include <linux/mii.h>
#include <linux/of_net.h>
#include <linux/dmi.h>
#include <linux/skbuff_ref.h>
#include <asm/irq.h>
@@ -42,6 +42,7 @@
#include <linux/if_vlan.h>
#include <linux/vmalloc.h>
#include <linux/irq.h>
#include <linux/skbuff_ref.h>
#include <net/ip.h>
#if IS_ENABLED(CONFIG_IPV6)
@@ -273,6 +273,40 @@ out:
kvfree(out);
}
static int mlx5e_rep_query_aggr_q_counter(struct mlx5_core_dev *dev, int vport, void *out)
{
u32 in[MLX5_ST_SZ_DW(query_q_counter_in)] = {};
MLX5_SET(query_q_counter_in, in, opcode, MLX5_CMD_OP_QUERY_Q_COUNTER);
MLX5_SET(query_q_counter_in, in, other_vport, 1);
MLX5_SET(query_q_counter_in, in, vport_number, vport);
MLX5_SET(query_q_counter_in, in, aggregate, 1);
return mlx5_cmd_exec_inout(dev, query_q_counter, in, out);
}
static void mlx5e_rep_update_vport_q_counter(struct mlx5e_priv *priv)
{
struct mlx5e_rep_stats *rep_stats = &priv->stats.rep_stats;
u32 out[MLX5_ST_SZ_DW(query_q_counter_out)] = {};
struct mlx5e_rep_priv *rpriv = priv->ppriv;
struct mlx5_eswitch_rep *rep = rpriv->rep;
int err;
if (!MLX5_CAP_GEN(priv->mdev, q_counter_other_vport) ||
!MLX5_CAP_GEN(priv->mdev, q_counter_aggregation))
return;
err = mlx5e_rep_query_aggr_q_counter(priv->mdev, rep->vport, out);
if (err) {
netdev_warn(priv->netdev, "failed reading stats on vport %d, error %d\n",
rep->vport, err);
return;
}
rep_stats->rx_vport_out_of_buffer = MLX5_GET(query_q_counter_out, out, out_of_buffer);
}
static void mlx5e_rep_get_strings(struct net_device *dev,
u32 stringset, u8 *data)
{
@@ -1229,6 +1263,12 @@ static int mlx5e_update_rep_rx(struct mlx5e_priv *priv)
return 0;
}
static void mlx5e_rep_stats_update_ndo_stats(struct mlx5e_priv *priv)
{
mlx5e_stats_update_ndo_stats(priv);
mlx5e_rep_update_vport_q_counter(priv);
}
static int mlx5e_rep_event_mpesw(struct mlx5e_priv *priv)
{
struct mlx5e_rep_priv *rpriv = priv->ppriv;
@@ -1421,7 +1461,7 @@ static const struct mlx5e_profile mlx5e_rep_profile = {
.enable = mlx5e_rep_enable,
.disable = mlx5e_rep_disable,
.update_rx = mlx5e_update_rep_rx,
.update_stats = mlx5e_stats_update_ndo_stats,
.update_stats = mlx5e_rep_stats_update_ndo_stats,
.rx_handlers = &mlx5e_rx_handlers_rep,
.max_tc = 1,
.stats_grps = mlx5e_rep_stats_grps,
@@ -484,6 +484,7 @@ struct mlx5e_rep_stats {
u64 tx_vport_rdma_multicast_bytes;
u64 vport_loopback_packets;
u64 vport_loopback_bytes;
u64 rx_vport_out_of_buffer;
};
struct mlx5e_stats {
@@ -504,6 +505,7 @@ static inline void mlx5e_stats_copy_rep_stats(struct rtnl_link_stats64 *vf_vport
vf_vport->tx_packets = rep_stats->vport_tx_packets;
vf_vport->rx_bytes = rep_stats->vport_rx_bytes;
vf_vport->tx_bytes = rep_stats->vport_tx_bytes;
vf_vport->rx_missed_errors = rep_stats->rx_vport_out_of_buffer;
}
extern mlx5e_stats_grp_t mlx5e_nic_stats_grps[];
+3 -2
View File
@@ -73,6 +73,7 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/skbuff_ref.h>
#include <linux/ethtool.h>
#include <linux/crc32.h>
#include <linux/random.h>
@@ -1999,7 +2000,7 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc,
skb->len += hlen - swivel;
skb_frag_fill_page_desc(frag, page->buffer, off, hlen - swivel);
__skb_frag_ref(frag);
__skb_frag_ref(frag, skb->pp_recycle);
/* any more data? */
if ((words[0] & RX_COMP1_SPLIT_PKT) && ((dlen -= hlen) > 0)) {
@@ -2023,7 +2024,7 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc,
frag++;
skb_frag_fill_page_desc(frag, page->buffer, 0, hlen);
__skb_frag_ref(frag);
__skb_frag_ref(frag, skb->pp_recycle);
RX_USED_ADD(page, hlen + cp->crc_size);
}
+298 -26
View File
@@ -54,6 +54,25 @@
RTL8201F_ISR_LINK)
#define RTL8201F_IER 0x13
#define RTL822X_VND1_SERDES_OPTION 0x697a
#define RTL822X_VND1_SERDES_OPTION_MODE_MASK GENMASK(5, 0)
#define RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX_SGMII 0
#define RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX 2
#define RTL822X_VND1_SERDES_CTRL3 0x7580
#define RTL822X_VND1_SERDES_CTRL3_MODE_MASK GENMASK(5, 0)
#define RTL822X_VND1_SERDES_CTRL3_MODE_SGMII 0x02
#define RTL822X_VND1_SERDES_CTRL3_MODE_2500BASEX 0x16
/* RTL822X_VND2_XXXXX registers are only accessible when phydev->is_c45
* is set, they cannot be accessed by C45-over-C22.
*/
#define RTL822X_VND2_GBCR 0xa412
#define RTL822X_VND2_GANLPAR 0xa414
#define RTL822X_VND2_PHYSR 0xa434
#define RTL8366RB_POWER_SAVE 0x15
#define RTL8366RB_POWER_SAVE_ON BIT(12)
@@ -64,6 +83,9 @@
#define RTL_GENERIC_PHYID 0x001cc800
#define RTL_8211FVD_PHYID 0x001cc878
#define RTL_8221B_VB_CG 0x001cc849
#define RTL_8221B_VN_CG 0x001cc84a
#define RTL_8251B 0x001cc862
MODULE_DESCRIPTION("Realtek PHY driver");
MODULE_AUTHOR("Johnson Leung");
@@ -531,17 +553,8 @@ static int rtl8366rb_config_init(struct phy_device *phydev)
}
/* get actual speed to cover the downshift case */
static int rtlgen_get_speed(struct phy_device *phydev)
static void rtlgen_decode_speed(struct phy_device *phydev, int val)
{
int val;
if (!phydev->link)
return 0;
val = phy_read_paged(phydev, 0xa43, 0x12);
if (val < 0)
return val;
switch (val & RTLGEN_SPEED_MASK) {
case 0x0000:
phydev->speed = SPEED_10;
@@ -564,19 +577,26 @@ static int rtlgen_get_speed(struct phy_device *phydev)
default:
break;
}
return 0;
}
static int rtlgen_read_status(struct phy_device *phydev)
{
int ret;
int ret, val;
ret = genphy_read_status(phydev);
if (ret < 0)
return ret;
return rtlgen_get_speed(phydev);
if (!phydev->link)
return 0;
val = phy_read_paged(phydev, 0xa43, 0x12);
if (val < 0)
return val;
rtlgen_decode_speed(phydev, val);
return 0;
}
static int rtlgen_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
@@ -659,6 +679,84 @@ static int rtl822x_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
return ret;
}
static int rtl822xb_config_init(struct phy_device *phydev)
{
bool has_2500, has_sgmii;
u16 mode;
int ret;
has_2500 = test_bit(PHY_INTERFACE_MODE_2500BASEX,
phydev->host_interfaces) ||
phydev->interface == PHY_INTERFACE_MODE_2500BASEX;
has_sgmii = test_bit(PHY_INTERFACE_MODE_SGMII,
phydev->host_interfaces) ||
phydev->interface == PHY_INTERFACE_MODE_SGMII;
/* fill in possible interfaces */
__assign_bit(PHY_INTERFACE_MODE_2500BASEX, phydev->possible_interfaces,
has_2500);
__assign_bit(PHY_INTERFACE_MODE_SGMII, phydev->possible_interfaces,
has_sgmii);
if (!has_2500 && !has_sgmii)
return 0;
/* determine SerDes option mode */
if (has_2500 && !has_sgmii) {
mode = RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX;
phydev->rate_matching = RATE_MATCH_PAUSE;
} else {
mode = RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX_SGMII;
phydev->rate_matching = RATE_MATCH_NONE;
}
/* the following sequence with magic numbers sets up the SerDes
* option mode
*/
ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x75f3, 0);
if (ret < 0)
return ret;
ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND1,
RTL822X_VND1_SERDES_OPTION,
RTL822X_VND1_SERDES_OPTION_MODE_MASK,
mode);
if (ret < 0)
return ret;
ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6a04, 0x0503);
if (ret < 0)
return ret;
ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f10, 0xd455);
if (ret < 0)
return ret;
return phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x6f11, 0x8020);
}
static int rtl822xb_get_rate_matching(struct phy_device *phydev,
phy_interface_t iface)
{
int val;
/* Only rate matching at 2500base-x */
if (iface != PHY_INTERFACE_MODE_2500BASEX)
return RATE_MATCH_NONE;
val = phy_read_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_OPTION);
if (val < 0)
return val;
if ((val & RTL822X_VND1_SERDES_OPTION_MODE_MASK) ==
RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX)
return RATE_MATCH_PAUSE;
/* RTL822X_VND1_SERDES_OPTION_MODE_2500BASEX_SGMII */
return RATE_MATCH_NONE;
}
static int rtl822x_get_features(struct phy_device *phydev)
{
int val;
@@ -695,10 +793,30 @@ static int rtl822x_config_aneg(struct phy_device *phydev)
return __genphy_config_aneg(phydev, ret);
}
static void rtl822xb_update_interface(struct phy_device *phydev)
{
int val;
if (!phydev->link)
return;
/* Change interface according to serdes mode */
val = phy_read_mmd(phydev, MDIO_MMD_VEND1, RTL822X_VND1_SERDES_CTRL3);
if (val < 0)
return;
switch (val & RTL822X_VND1_SERDES_CTRL3_MODE_MASK) {
case RTL822X_VND1_SERDES_CTRL3_MODE_2500BASEX:
phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
break;
case RTL822X_VND1_SERDES_CTRL3_MODE_SGMII:
phydev->interface = PHY_INTERFACE_MODE_SGMII;
break;
}
}
static int rtl822x_read_status(struct phy_device *phydev)
{
int ret;
if (phydev->autoneg == AUTONEG_ENABLE) {
int lpadv = phy_read_paged(phydev, 0xa5d, 0x13);
@@ -709,11 +827,99 @@ static int rtl822x_read_status(struct phy_device *phydev)
lpadv);
}
ret = genphy_read_status(phydev);
return rtlgen_read_status(phydev);
}
static int rtl822xb_read_status(struct phy_device *phydev)
{
int ret;
ret = rtl822x_read_status(phydev);
if (ret < 0)
return ret;
return rtlgen_get_speed(phydev);
rtl822xb_update_interface(phydev);
return 0;
}
static int rtl822x_c45_get_features(struct phy_device *phydev)
{
linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT,
phydev->supported);
return genphy_c45_pma_read_abilities(phydev);
}
static int rtl822x_c45_config_aneg(struct phy_device *phydev)
{
bool changed = false;
int ret, val;
if (phydev->autoneg == AUTONEG_DISABLE)
return genphy_c45_pma_setup_forced(phydev);
ret = genphy_c45_an_config_aneg(phydev);
if (ret < 0)
return ret;
if (ret > 0)
changed = true;
val = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
/* Vendor register as C45 has no standardized support for 1000BaseT */
ret = phy_modify_mmd_changed(phydev, MDIO_MMD_VEND2, RTL822X_VND2_GBCR,
ADVERTISE_1000FULL, val);
if (ret < 0)
return ret;
if (ret > 0)
changed = true;
return genphy_c45_check_and_restart_aneg(phydev, changed);
}
static int rtl822x_c45_read_status(struct phy_device *phydev)
{
int ret, val;
ret = genphy_c45_read_status(phydev);
if (ret < 0)
return ret;
/* Vendor register as C45 has no standardized support for 1000BaseT */
if (phydev->autoneg == AUTONEG_ENABLE) {
val = phy_read_mmd(phydev, MDIO_MMD_VEND2,
RTL822X_VND2_GANLPAR);
if (val < 0)
return val;
mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val);
}
if (!phydev->link)
return 0;
/* Read actual speed from vendor register. */
val = phy_read_mmd(phydev, MDIO_MMD_VEND2, RTL822X_VND2_PHYSR);
if (val < 0)
return val;
rtlgen_decode_speed(phydev, val);
return 0;
}
static int rtl822xb_c45_read_status(struct phy_device *phydev)
{
int ret;
ret = rtl822x_c45_read_status(phydev);
if (ret < 0)
return ret;
rtl822xb_update_interface(phydev);
return 0;
}
static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
@@ -739,6 +945,35 @@ static int rtl8226_match_phy_device(struct phy_device *phydev)
rtlgen_supports_2_5gbps(phydev);
}
static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id,
bool is_c45)
{
if (phydev->is_c45)
return is_c45 && (id == phydev->c45_ids.device_ids[1]);
else
return !is_c45 && (id == phydev->phy_id);
}
static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev)
{
return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false);
}
static int rtl8221b_vb_cg_c45_match_phy_device(struct phy_device *phydev)
{
return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, true);
}
static int rtl8221b_vn_cg_c22_match_phy_device(struct phy_device *phydev)
{
return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, false);
}
static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev)
{
return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true);
}
static int rtlgen_resume(struct phy_device *phydev)
{
int ret = genphy_resume(phydev);
@@ -749,6 +984,15 @@ static int rtlgen_resume(struct phy_device *phydev)
return ret;
}
static int rtlgen_c45_resume(struct phy_device *phydev)
{
int ret = genphy_c45_pma_resume(phydev);
msleep(20);
return ret;
}
static int rtl9000a_config_init(struct phy_device *phydev)
{
phydev->autoneg = AUTONEG_DISABLE;
@@ -988,7 +1232,9 @@ static struct phy_driver realtek_drvs[] = {
.name = "RTL8226B_RTL8221B 2.5Gbps PHY",
.get_features = rtl822x_get_features,
.config_aneg = rtl822x_config_aneg,
.read_status = rtl822x_read_status,
.config_init = rtl822xb_config_init,
.get_rate_matching = rtl822xb_get_rate_matching,
.read_status = rtl822xb_read_status,
.suspend = genphy_suspend,
.resume = rtlgen_resume,
.read_page = rtl821x_read_page,
@@ -1010,31 +1256,57 @@ static struct phy_driver realtek_drvs[] = {
.name = "RTL8226B-CG_RTL8221B-CG 2.5Gbps PHY",
.get_features = rtl822x_get_features,
.config_aneg = rtl822x_config_aneg,
.read_status = rtl822x_read_status,
.config_init = rtl822xb_config_init,
.get_rate_matching = rtl822xb_get_rate_matching,
.read_status = rtl822xb_read_status,
.suspend = genphy_suspend,
.resume = rtlgen_resume,
.read_page = rtl821x_read_page,
.write_page = rtl821x_write_page,
}, {
PHY_ID_MATCH_EXACT(0x001cc849),
.name = "RTL8221B-VB-CG 2.5Gbps PHY",
.match_phy_device = rtl8221b_vb_cg_c22_match_phy_device,
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C22)",
.get_features = rtl822x_get_features,
.config_aneg = rtl822x_config_aneg,
.read_status = rtl822x_read_status,
.config_init = rtl822xb_config_init,
.get_rate_matching = rtl822xb_get_rate_matching,
.read_status = rtl822xb_read_status,
.suspend = genphy_suspend,
.resume = rtlgen_resume,
.read_page = rtl821x_read_page,
.write_page = rtl821x_write_page,
}, {
PHY_ID_MATCH_EXACT(0x001cc84a),
.name = "RTL8221B-VM-CG 2.5Gbps PHY",
.match_phy_device = rtl8221b_vb_cg_c45_match_phy_device,
.name = "RTL8221B-VB-CG 2.5Gbps PHY (C45)",
.config_init = rtl822xb_config_init,
.get_rate_matching = rtl822xb_get_rate_matching,
.get_features = rtl822x_c45_get_features,
.config_aneg = rtl822x_c45_config_aneg,
.read_status = rtl822xb_c45_read_status,
.suspend = genphy_c45_pma_suspend,
.resume = rtlgen_c45_resume,
}, {
.match_phy_device = rtl8221b_vn_cg_c22_match_phy_device,
.name = "RTL8221B-VM-CG 2.5Gbps PHY (C22)",
.get_features = rtl822x_get_features,
.config_aneg = rtl822x_config_aneg,
.read_status = rtl822x_read_status,
.config_init = rtl822xb_config_init,
.get_rate_matching = rtl822xb_get_rate_matching,
.read_status = rtl822xb_read_status,
.suspend = genphy_suspend,
.resume = rtlgen_resume,
.read_page = rtl821x_read_page,
.write_page = rtl821x_write_page,
}, {
.match_phy_device = rtl8221b_vn_cg_c45_match_phy_device,
.name = "RTL8221B-VN-CG 2.5Gbps PHY (C45)",
.config_init = rtl822xb_config_init,
.get_rate_matching = rtl822xb_get_rate_matching,
.get_features = rtl822x_c45_get_features,
.config_aneg = rtl822x_c45_config_aneg,
.read_status = rtl822xb_c45_read_status,
.suspend = genphy_c45_pma_suspend,
.resume = rtlgen_c45_resume,
}, {
PHY_ID_MATCH_EXACT(0x001cc862),
.name = "RTL8251B 5Gbps PHY",
+1
View File
@@ -506,6 +506,7 @@ static const struct sfp_quirk sfp_quirks[] = {
SFP_QUIRK_M("OEM", "SFP-2.5G-T", sfp_quirk_oem_2_5g),
SFP_QUIRK_F("OEM", "RTSFP-10", sfp_fixup_rollball_cc),
SFP_QUIRK_F("OEM", "RTSFP-10G", sfp_fixup_rollball_cc),
SFP_QUIRK_F("Turris", "RTSFP-2.5G", sfp_fixup_rollball),
SFP_QUIRK_F("Turris", "RTSFP-10", sfp_fixup_rollball),
SFP_QUIRK_F("Turris", "RTSFP-10G", sfp_fixup_rollball),
};
+1 -9
View File
@@ -121,7 +121,6 @@ static const struct net_device_ops qmimux_netdev_ops = {
.ndo_open = qmimux_open,
.ndo_stop = qmimux_stop,
.ndo_start_xmit = qmimux_start_xmit,
.ndo_get_stats64 = dev_get_tstats64,
};
static void qmimux_setup(struct net_device *dev)
@@ -133,6 +132,7 @@ static void qmimux_setup(struct net_device *dev)
dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
dev->netdev_ops = &qmimux_netdev_ops;
dev->mtu = 1500;
dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;
dev->needs_free_netdev = true;
}
@@ -257,12 +257,6 @@ static int qmimux_register_device(struct net_device *real_dev, u8 mux_id)
priv->mux_id = mux_id;
priv->real_dev = real_dev;
new_dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
if (!new_dev->tstats) {
err = -ENOBUFS;
goto out_free_newdev;
}
new_dev->sysfs_groups[0] = &qmi_wwan_sysfs_qmimux_attr_group;
err = register_netdevice(new_dev);
@@ -295,7 +289,6 @@ static void qmimux_unregister_device(struct net_device *dev,
struct qmimux_priv *priv = netdev_priv(dev);
struct net_device *real_dev = priv->real_dev;
free_percpu(dev->tstats);
netdev_upper_dev_unlink(real_dev, dev);
unregister_netdevice_queue(dev, head);
@@ -644,7 +637,6 @@ static const struct net_device_ops qmi_wwan_netdev_ops = {
.ndo_start_xmit = usbnet_start_xmit,
.ndo_tx_timeout = usbnet_tx_timeout,
.ndo_change_mtu = usbnet_change_mtu,
.ndo_get_stats64 = dev_get_tstats64,
.ndo_set_mac_address = qmi_wwan_mac_addr,
.ndo_validate_addr = eth_validate_addr,
};
+1
View File
@@ -1733,6 +1733,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
dev->hard_mtu = net->mtu + net->hard_header_len;
net->min_mtu = 0;
net->max_mtu = ETH_MAX_MTU;
net->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;
net->netdev_ops = &usbnet_netdev_ops;
net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
+2 -1
View File
@@ -26,6 +26,7 @@
#include <linux/ptr_ring.h>
#include <linux/bpf_trace.h>
#include <linux/net_tstamp.h>
#include <linux/skbuff_ref.h>
#include <net/page_pool/helpers.h>
#define DRV_NAME "veth"
@@ -716,7 +717,7 @@ static void veth_xdp_get(struct xdp_buff *xdp)
return;
for (i = 0; i < sinfo->nr_frags; i++)
__skb_frag_ref(&sinfo->frags[i]);
__skb_frag_ref(&sinfo->frags[i], false);
}
static int veth_convert_skb_to_xdp_buff(struct veth_rq *rq,
+1
View File
@@ -38,6 +38,7 @@
#include <linux/if_vlan.h>
#include <linux/udp.h>
#include <linux/highmem.h>
#include <linux/skbuff_ref.h>
#include <net/tcp.h>
-63
View File
@@ -3512,73 +3512,10 @@ static inline struct page *skb_frag_page(const skb_frag_t *frag)
return netmem_to_page(frag->netmem);
}
/**
* __skb_frag_ref - take an addition reference on a paged fragment.
* @frag: the paged fragment
*
* Takes an additional reference on the paged fragment @frag.
*/
static inline void __skb_frag_ref(skb_frag_t *frag)
{
get_page(skb_frag_page(frag));
}
/**
* skb_frag_ref - take an addition reference on a paged fragment of an skb.
* @skb: the buffer
* @f: the fragment offset.
*
* Takes an additional reference on the @f'th paged fragment of @skb.
*/
static inline void skb_frag_ref(struct sk_buff *skb, int f)
{
__skb_frag_ref(&skb_shinfo(skb)->frags[f]);
}
int skb_pp_cow_data(struct page_pool *pool, struct sk_buff **pskb,
unsigned int headroom);
int skb_cow_data_for_xdp(struct page_pool *pool, struct sk_buff **pskb,
struct bpf_prog *prog);
bool napi_pp_put_page(struct page *page);
static inline void
skb_page_unref(struct page *page, bool recycle)
{
#ifdef CONFIG_PAGE_POOL
if (recycle && napi_pp_put_page(page))
return;
#endif
put_page(page);
}
/**
* __skb_frag_unref - release a reference on a paged fragment.
* @frag: the paged fragment
* @recycle: recycle the page if allocated via page_pool
*
* Releases a reference on the paged fragment @frag
* or recycles the page via the page_pool API.
*/
static inline void __skb_frag_unref(skb_frag_t *frag, bool recycle)
{
skb_page_unref(skb_frag_page(frag), recycle);
}
/**
* skb_frag_unref - release a reference on a paged fragment of an skb.
* @skb: the buffer
* @f: the fragment offset
*
* Releases a reference on the @f'th paged fragment of @skb.
*/
static inline void skb_frag_unref(struct sk_buff *skb, int f)
{
struct skb_shared_info *shinfo = skb_shinfo(skb);
if (!skb_zcopy_managed(skb))
__skb_frag_unref(&shinfo->frags[f], skb->pp_recycle);
}
/**
* skb_frag_address - gets the address of the data contained in a paged fragment
* @frag: the paged fragment buffer
+106
View File
@@ -0,0 +1,106 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Skb ref helpers.
*
*/
#ifndef _LINUX_SKBUFF_REF_H
#define _LINUX_SKBUFF_REF_H
#include <linux/skbuff.h>
#include <net/page_pool/helpers.h>
#ifdef CONFIG_PAGE_POOL
static inline bool is_pp_page(struct page *page)
{
return (page->pp_magic & ~0x3UL) == PP_SIGNATURE;
}
static inline bool napi_pp_get_page(struct page *page)
{
page = compound_head(page);
if (!is_pp_page(page))
return false;
page_pool_ref_page(page);
return true;
}
#endif
static inline void skb_page_ref(struct page *page, bool recycle)
{
#ifdef CONFIG_PAGE_POOL
if (recycle && napi_pp_get_page(page))
return;
#endif
get_page(page);
}
/**
* __skb_frag_ref - take an addition reference on a paged fragment.
* @frag: the paged fragment
* @recycle: skb->pp_recycle param of the parent skb. False if no parent skb.
*
* Takes an additional reference on the paged fragment @frag. Obtains the
* correct reference count depending on whether skb->pp_recycle is set and
* whether the frag is a page pool frag.
*/
static inline void __skb_frag_ref(skb_frag_t *frag, bool recycle)
{
skb_page_ref(skb_frag_page(frag), recycle);
}
/**
* skb_frag_ref - take an addition reference on a paged fragment of an skb.
* @skb: the buffer
* @f: the fragment offset.
*
* Takes an additional reference on the @f'th paged fragment of @skb.
*/
static inline void skb_frag_ref(struct sk_buff *skb, int f)
{
__skb_frag_ref(&skb_shinfo(skb)->frags[f], skb->pp_recycle);
}
bool napi_pp_put_page(struct page *page);
static inline void
skb_page_unref(struct page *page, bool recycle)
{
#ifdef CONFIG_PAGE_POOL
if (recycle && napi_pp_put_page(page))
return;
#endif
put_page(page);
}
/**
* __skb_frag_unref - release a reference on a paged fragment.
* @frag: the paged fragment
* @recycle: recycle the page if allocated via page_pool
*
* Releases a reference on the paged fragment @frag
* or recycles the page via the page_pool API.
*/
static inline void __skb_frag_unref(skb_frag_t *frag, bool recycle)
{
skb_page_unref(skb_frag_page(frag), recycle);
}
/**
* skb_frag_unref - release a reference on a paged fragment of an skb.
* @skb: the buffer
* @f: the fragment offset
*
* Releases a reference on the @f'th paged fragment of @skb.
*/
static inline void skb_frag_unref(struct sk_buff *skb, int f)
{
struct skb_shared_info *shinfo = skb_shinfo(skb);
if (!skb_zcopy_managed(skb))
__skb_frag_unref(&shinfo->frags[f], skb->pp_recycle);
}
#endif /* _LINUX_SKBUFF_REF_H */
+11
View File
@@ -327,6 +327,12 @@ struct dsa_port {
};
};
static inline struct dsa_port *
dsa_phylink_to_port(struct phylink_config *config)
{
return container_of(config, struct dsa_port, pl_config);
}
/* TODO: ideally DSA ports would have a single dp->link_dp member,
* and no dst->rtable nor this struct dsa_link would be needed,
* but this would require some more complex tree walking,
@@ -451,6 +457,11 @@ struct dsa_switch {
*/
const struct dsa_switch_ops *ops;
/*
* Allow a DSA switch driver to override the phylink MAC ops
*/
const struct phylink_mac_ops *phylink_mac_ops;
/*
* User mii_bus and devices for the individual ports.
*/
+1 -1
View File
@@ -345,7 +345,7 @@ static inline bool flow_action_has_entries(const struct flow_action *action)
* flow_offload_has_one_action() - check if exactly one action is present
* @action: tc filter flow offload action
*
* Returns true if exactly one action is present.
* Return: true if exactly one action is present.
*/
static inline bool flow_offload_has_one_action(const struct flow_action *action)
{
-2
View File
@@ -35,8 +35,6 @@
#include <linux/cache.h>
#include <linux/security.h>
#define RTO_ONLINK 0x01
static inline __u8 ip_sock_rt_scope(const struct sock *sk)
{
if (sock_flag(sk, SOCK_LOCALROUTE))
+4
View File
@@ -58,6 +58,10 @@ struct mptcp_info {
__u64 mptcpi_bytes_received;
__u64 mptcpi_bytes_acked;
__u8 mptcpi_subflows_total;
__u8 reserved[3];
__u32 mptcpi_last_data_sent;
__u32 mptcpi_last_data_recv;
__u32 mptcpi_last_ack_recv;
};
/* MPTCP Reset reason codes, rfc8684 */
+1
View File
@@ -3,6 +3,7 @@
#include <net/dst_metadata.h>
#include <net/busy_poll.h>
#include <trace/events/net.h>
#include <linux/skbuff_ref.h>
#define MAX_GRO_SKBS 8
+5 -42
View File
@@ -51,6 +51,7 @@
#endif
#include <linux/string.h>
#include <linux/skbuff.h>
#include <linux/skbuff_ref.h>
#include <linux/splice.h>
#include <linux/cache.h>
#include <linux/rtnetlink.h>
@@ -906,11 +907,6 @@ static void skb_clone_fraglist(struct sk_buff *skb)
skb_get(list);
}
static bool is_pp_page(struct page *page)
{
return (page->pp_magic & ~0x3UL) == PP_SIGNATURE;
}
int skb_pp_cow_data(struct page_pool *pool, struct sk_buff **pskb,
unsigned int headroom)
{
@@ -1032,37 +1028,6 @@ static bool skb_pp_recycle(struct sk_buff *skb, void *data)
return napi_pp_put_page(virt_to_page(data));
}
/**
* skb_pp_frag_ref() - Increase fragment references of a page pool aware skb
* @skb: page pool aware skb
*
* Increase the fragment reference count (pp_ref_count) of a skb. This is
* intended to gain fragment references only for page pool aware skbs,
* i.e. when skb->pp_recycle is true, and not for fragments in a
* non-pp-recycling skb. It has a fallback to increase references on normal
* pages, as page pool aware skbs may also have normal page fragments.
*/
static int skb_pp_frag_ref(struct sk_buff *skb)
{
struct skb_shared_info *shinfo;
struct page *head_page;
int i;
if (!skb->pp_recycle)
return -EINVAL;
shinfo = skb_shinfo(skb);
for (i = 0; i < shinfo->nr_frags; i++) {
head_page = compound_head(skb_frag_page(&shinfo->frags[i]));
if (likely(is_pp_page(head_page)))
page_pool_ref_page(head_page);
else
page_ref_inc(head_page);
}
return 0;
}
static void skb_kfree_head(void *head, unsigned int end_offset)
{
if (end_offset == SKB_SMALL_HEAD_HEADROOM)
@@ -4198,7 +4163,7 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen)
to++;
} else {
__skb_frag_ref(fragfrom);
__skb_frag_ref(fragfrom, skb->pp_recycle);
skb_frag_page_copy(fragto, fragfrom);
skb_frag_off_copy(fragto, fragfrom);
skb_frag_size_set(fragto, todo);
@@ -4848,7 +4813,7 @@ normal:
}
*nskb_frag = (i < 0) ? skb_head_frag_to_page_desc(frag_skb) : *frag;
__skb_frag_ref(nskb_frag);
__skb_frag_ref(nskb_frag, nskb->pp_recycle);
size = skb_frag_size(nskb_frag);
if (pos < offset) {
@@ -5979,10 +5944,8 @@ bool skb_try_coalesce(struct sk_buff *to, struct sk_buff *from,
/* if the skb is not cloned this does nothing
* since we set nr_frags to 0.
*/
if (skb_pp_frag_ref(from)) {
for (i = 0; i < from_shinfo->nr_frags; i++)
__skb_frag_ref(&from_shinfo->frags[i]);
}
for (i = 0; i < from_shinfo->nr_frags; i++)
__skb_frag_ref(&from_shinfo->frags[i], from->pp_recycle);
to->truesize += delta;
to->len += len;
+11
View File
@@ -1505,6 +1505,17 @@ static int dsa_switch_probe(struct dsa_switch *ds)
if (!ds->num_ports)
return -EINVAL;
if (ds->phylink_mac_ops) {
if (ds->ops->phylink_mac_select_pcs ||
ds->ops->phylink_mac_prepare ||
ds->ops->phylink_mac_config ||
ds->ops->phylink_mac_finish ||
ds->ops->phylink_mac_link_down ||
ds->ops->phylink_mac_link_up ||
ds->ops->adjust_link)
return -EINVAL;
}
if (np) {
err = dsa_switch_parse_of(ds, np);
if (err)
+26 -12
View File
@@ -1558,7 +1558,7 @@ static struct phylink_pcs *
dsa_port_phylink_mac_select_pcs(struct phylink_config *config,
phy_interface_t interface)
{
struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
struct dsa_port *dp = dsa_phylink_to_port(config);
struct phylink_pcs *pcs = ERR_PTR(-EOPNOTSUPP);
struct dsa_switch *ds = dp->ds;
@@ -1572,7 +1572,7 @@ static int dsa_port_phylink_mac_prepare(struct phylink_config *config,
unsigned int mode,
phy_interface_t interface)
{
struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
struct dsa_port *dp = dsa_phylink_to_port(config);
struct dsa_switch *ds = dp->ds;
int err = 0;
@@ -1587,7 +1587,7 @@ static void dsa_port_phylink_mac_config(struct phylink_config *config,
unsigned int mode,
const struct phylink_link_state *state)
{
struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
struct dsa_port *dp = dsa_phylink_to_port(config);
struct dsa_switch *ds = dp->ds;
if (!ds->ops->phylink_mac_config)
@@ -1600,7 +1600,7 @@ static int dsa_port_phylink_mac_finish(struct phylink_config *config,
unsigned int mode,
phy_interface_t interface)
{
struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
struct dsa_port *dp = dsa_phylink_to_port(config);
struct dsa_switch *ds = dp->ds;
int err = 0;
@@ -1615,7 +1615,7 @@ static void dsa_port_phylink_mac_link_down(struct phylink_config *config,
unsigned int mode,
phy_interface_t interface)
{
struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
struct dsa_port *dp = dsa_phylink_to_port(config);
struct phy_device *phydev = NULL;
struct dsa_switch *ds = dp->ds;
@@ -1638,7 +1638,7 @@ static void dsa_port_phylink_mac_link_up(struct phylink_config *config,
int speed, int duplex,
bool tx_pause, bool rx_pause)
{
struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
struct dsa_port *dp = dsa_phylink_to_port(config);
struct dsa_switch *ds = dp->ds;
if (!ds->ops->phylink_mac_link_up) {
@@ -1662,6 +1662,7 @@ static const struct phylink_mac_ops dsa_port_phylink_mac_ops = {
int dsa_port_phylink_create(struct dsa_port *dp)
{
const struct phylink_mac_ops *mac_ops;
struct dsa_switch *ds = dp->ds;
phy_interface_t mode;
struct phylink *pl;
@@ -1685,8 +1686,12 @@ int dsa_port_phylink_create(struct dsa_port *dp)
}
}
pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn),
mode, &dsa_port_phylink_mac_ops);
mac_ops = &dsa_port_phylink_mac_ops;
if (ds->phylink_mac_ops)
mac_ops = ds->phylink_mac_ops;
pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn), mode,
mac_ops);
if (IS_ERR(pl)) {
pr_err("error creating PHYLINK: %ld\n", PTR_ERR(pl));
return PTR_ERR(pl);
@@ -1952,12 +1957,23 @@ static void dsa_shared_port_validate_of(struct dsa_port *dp,
dn, dsa_port_is_cpu(dp) ? "CPU" : "DSA", dp->index);
}
static void dsa_shared_port_link_down(struct dsa_port *dp)
{
struct dsa_switch *ds = dp->ds;
if (ds->phylink_mac_ops && ds->phylink_mac_ops->mac_link_down)
ds->phylink_mac_ops->mac_link_down(&dp->pl_config, MLO_AN_FIXED,
PHY_INTERFACE_MODE_NA);
else if (ds->ops->phylink_mac_link_down)
ds->ops->phylink_mac_link_down(ds, dp->index, MLO_AN_FIXED,
PHY_INTERFACE_MODE_NA);
}
int dsa_shared_port_link_register_of(struct dsa_port *dp)
{
struct dsa_switch *ds = dp->ds;
bool missing_link_description;
bool missing_phy_mode;
int port = dp->index;
dsa_shared_port_validate_of(dp, &missing_phy_mode,
&missing_link_description);
@@ -1973,9 +1989,7 @@ int dsa_shared_port_link_register_of(struct dsa_port *dp)
"Skipping phylink registration for %s port %d\n",
dsa_port_is_cpu(dp) ? "CPU" : "DSA", dp->index);
} else {
if (ds->ops->phylink_mac_link_down)
ds->ops->phylink_mac_link_down(ds, port,
MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
dsa_shared_port_link_down(dp);
return dsa_shared_port_phylink_register(dp);
}
+1
View File
@@ -1072,6 +1072,7 @@ const struct proto_ops inet_stream_ops = {
#endif
.splice_eof = inet_splice_eof,
.splice_read = tcp_splice_read,
.set_peek_off = sk_set_peek_off,
.read_sock = tcp_read_sock,
.read_skb = tcp_read_skb,
.sendmsg_locked = tcp_sendmsg_locked,
+1
View File
@@ -20,6 +20,7 @@
#include <net/udp.h>
#include <net/tcp.h>
#include <net/espintcp.h>
#include <linux/skbuff_ref.h>
#include <linux/highmem.h>
+1 -13
View File
@@ -106,9 +106,6 @@
#include "fib_lookup.h"
#define RT_FL_TOS(oldflp4) \
((oldflp4)->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK))
#define RT_GC_TIMEOUT (300*HZ)
#define DEFAULT_MIN_PMTU (512 + 20 + 20)
@@ -498,15 +495,6 @@ void __ip_select_ident(struct net *net, struct iphdr *iph, int segs)
}
EXPORT_SYMBOL(__ip_select_ident);
static void ip_rt_fix_tos(struct flowi4 *fl4)
{
__u8 tos = RT_FL_TOS(fl4);
fl4->flowi4_tos = tos & IPTOS_RT_MASK;
if (tos & RTO_ONLINK)
fl4->flowi4_scope = RT_SCOPE_LINK;
}
static void __build_flow_key(const struct net *net, struct flowi4 *fl4,
const struct sock *sk, const struct iphdr *iph,
int oif, __u8 tos, u8 prot, u32 mark,
@@ -2639,7 +2627,7 @@ struct rtable *ip_route_output_key_hash(struct net *net, struct flowi4 *fl4,
struct rtable *rth;
fl4->flowi4_iif = LOOPBACK_IFINDEX;
ip_rt_fix_tos(fl4);
fl4->flowi4_tos &= IPTOS_RT_MASK;
rcu_read_lock();
rth = ip_route_output_key_hash_rcu(net, fl4, &res, skb);
+10 -6
View File
@@ -1419,8 +1419,6 @@ static int tcp_peek_sndq(struct sock *sk, struct msghdr *msg, int len)
struct sk_buff *skb;
int copied = 0, err = 0;
/* XXX -- need to support SO_PEEK_OFF */
skb_rbtree_walk(skb, &sk->tcp_rtx_queue) {
err = skb_copy_datagram_msg(skb, 0, msg, skb->len);
if (err)
@@ -2331,6 +2329,7 @@ static int tcp_recvmsg_locked(struct sock *sk, struct msghdr *msg, size_t len,
int target; /* Read at least this many bytes */
long timeo;
struct sk_buff *skb, *last;
u32 peek_offset = 0;
u32 urg_hole = 0;
err = -ENOTCONN;
@@ -2364,7 +2363,8 @@ static int tcp_recvmsg_locked(struct sock *sk, struct msghdr *msg, size_t len,
seq = &tp->copied_seq;
if (flags & MSG_PEEK) {
peek_seq = tp->copied_seq;
peek_offset = max(sk_peek_offset(sk, flags), 0);
peek_seq = tp->copied_seq + peek_offset;
seq = &peek_seq;
}
@@ -2467,11 +2467,11 @@ static int tcp_recvmsg_locked(struct sock *sk, struct msghdr *msg, size_t len,
}
if ((flags & MSG_PEEK) &&
(peek_seq - copied - urg_hole != tp->copied_seq)) {
(peek_seq - peek_offset - copied - urg_hole != tp->copied_seq)) {
net_dbg_ratelimited("TCP(%s:%d): Application bug, race in MSG_PEEK\n",
current->comm,
task_pid_nr(current));
peek_seq = tp->copied_seq;
peek_seq = tp->copied_seq + peek_offset;
}
continue;
@@ -2512,7 +2512,10 @@ found_ok_skb:
WRITE_ONCE(*seq, *seq + used);
copied += used;
len -= used;
if (flags & MSG_PEEK)
sk_peek_offset_fwd(sk, used);
else
sk_peek_offset_bwd(sk, used);
tcp_rcv_space_adjust(sk);
skip_copy:
@@ -3013,6 +3016,7 @@ int tcp_disconnect(struct sock *sk, int flags)
__skb_queue_purge(&sk->sk_receive_queue);
WRITE_ONCE(tp->copied_seq, tp->rcv_nxt);
WRITE_ONCE(tp->urg_data, 0);
sk_set_peek_off(sk, -1);
tcp_write_queue_purge(sk);
tcp_fastopen_active_disable_ofo_check(sk);
skb_rbtree_purge(&tp->out_of_order_queue);
+1
View File
@@ -44,6 +44,7 @@
#include <linux/gfp.h>
#include <linux/module.h>
#include <linux/static_key.h>
#include <linux/skbuff_ref.h>
#include <trace/events/tcp.h>
+1
View File
@@ -36,6 +36,7 @@
#include <net/tcp.h>
#include <net/espintcp.h>
#include <net/inet6_hashtables.h>
#include <linux/skbuff_ref.h>
#include <linux/highmem.h>
+22 -37
View File
@@ -1154,7 +1154,7 @@ static int mpls_netconf_fill_devconf(struct sk_buff *skb, struct mpls_dev *mdev,
if ((all || type == NETCONFA_INPUT) &&
nla_put_s32(skb, NETCONFA_INPUT,
mdev->input_enabled) < 0)
READ_ONCE(mdev->input_enabled)) < 0)
goto nla_put_failure;
nlmsg_end(skb, nlh);
@@ -1303,11 +1303,12 @@ static int mpls_netconf_dump_devconf(struct sk_buff *skb,
{
const struct nlmsghdr *nlh = cb->nlh;
struct net *net = sock_net(skb->sk);
struct hlist_head *head;
struct {
unsigned long ifindex;
} *ctx = (void *)cb->ctx;
struct net_device *dev;
struct mpls_dev *mdev;
int idx, s_idx;
int h, s_h;
int err = 0;
if (cb->strict_check) {
struct netlink_ext_ack *extack = cb->extack;
@@ -1324,40 +1325,23 @@ static int mpls_netconf_dump_devconf(struct sk_buff *skb,
}
}
s_h = cb->args[0];
s_idx = idx = cb->args[1];
for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
idx = 0;
head = &net->dev_index_head[h];
rcu_read_lock();
cb->seq = net->dev_base_seq;
hlist_for_each_entry_rcu(dev, head, index_hlist) {
if (idx < s_idx)
goto cont;
mdev = mpls_dev_get(dev);
if (!mdev)
goto cont;
if (mpls_netconf_fill_devconf(skb, mdev,
NETLINK_CB(cb->skb).portid,
nlh->nlmsg_seq,
RTM_NEWNETCONF,
NLM_F_MULTI,
NETCONFA_ALL) < 0) {
rcu_read_unlock();
goto done;
}
nl_dump_check_consistent(cb, nlmsg_hdr(skb));
cont:
idx++;
}
rcu_read_unlock();
rcu_read_lock();
for_each_netdev_dump(net, dev, ctx->ifindex) {
mdev = mpls_dev_get(dev);
if (!mdev)
continue;
err = mpls_netconf_fill_devconf(skb, mdev,
NETLINK_CB(cb->skb).portid,
nlh->nlmsg_seq,
RTM_NEWNETCONF,
NLM_F_MULTI,
NETCONFA_ALL);
if (err < 0)
break;
}
done:
cb->args[0] = h;
cb->args[1] = idx;
rcu_read_unlock();
return skb->len;
return err;
}
#define MPLS_PERDEV_SYSCTL_OFFSET(field) \
@@ -2773,7 +2757,8 @@ static int __init mpls_init(void)
mpls_getroute, mpls_dump_routes, 0);
rtnl_register_module(THIS_MODULE, PF_MPLS, RTM_GETNETCONF,
mpls_netconf_get_devconf,
mpls_netconf_dump_devconf, 0);
mpls_netconf_dump_devconf,
RTNL_FLAG_DUMP_UNLOCKED);
err = ipgre_tunnel_encap_add_mpls_ops();
if (err)
pr_err("Can't add mpls over gre tunnel ops\n");
+1
View File
@@ -1068,6 +1068,7 @@ static void ack_update_msk(struct mptcp_sock *msk,
__mptcp_snd_una_update(msk, new_snd_una);
__mptcp_data_acked(sk);
}
msk->last_ack_recv = tcp_jiffies32;
mptcp_data_unlock(sk);
trace_ack_update_msk(mp_opt->data_ack,
+7
View File
@@ -706,6 +706,8 @@ static bool __mptcp_move_skbs_from_subflow(struct mptcp_sock *msk,
}
} while (more_data_avail);
if (moved > 0)
msk->last_data_recv = tcp_jiffies32;
*bytes += moved;
return done;
}
@@ -1556,6 +1558,8 @@ static int __subflow_push_pending(struct sock *sk, struct sock *ssk,
err = copied;
out:
if (err > 0)
msk->last_data_sent = tcp_jiffies32;
return err;
}
@@ -2793,6 +2797,9 @@ static void __mptcp_init_sock(struct sock *sk)
WRITE_ONCE(msk->allow_infinite_fallback, true);
msk->recovery = false;
msk->subflow_id = 1;
msk->last_data_sent = tcp_jiffies32;
msk->last_data_recv = tcp_jiffies32;
msk->last_ack_recv = tcp_jiffies32;
mptcp_pm_data_init(msk);
+3
View File
@@ -282,6 +282,9 @@ struct mptcp_sock {
u64 bytes_acked;
u64 snd_una;
u64 wnd_end;
u32 last_data_sent;
u32 last_data_recv;
u32 last_ack_recv;
unsigned long timer_ival;
u32 token;
int rmem_released;
+11 -5
View File
@@ -898,6 +898,7 @@ void mptcp_diag_fill_info(struct mptcp_sock *msk, struct mptcp_info *info)
struct sock *sk = (struct sock *)msk;
u32 flags = 0;
bool slow;
u32 now;
memset(info, 0, sizeof(*info));
@@ -926,11 +927,6 @@ void mptcp_diag_fill_info(struct mptcp_sock *msk, struct mptcp_info *info)
if (READ_ONCE(msk->can_ack))
flags |= MPTCP_INFO_FLAG_REMOTE_KEY_RECEIVED;
info->mptcpi_flags = flags;
mptcp_data_lock(sk);
info->mptcpi_snd_una = msk->snd_una;
info->mptcpi_rcv_nxt = msk->ack_seq;
info->mptcpi_bytes_acked = msk->bytes_acked;
mptcp_data_unlock(sk);
slow = lock_sock_fast(sk);
info->mptcpi_csum_enabled = READ_ONCE(msk->csum_enabled);
@@ -942,7 +938,17 @@ void mptcp_diag_fill_info(struct mptcp_sock *msk, struct mptcp_info *info)
info->mptcpi_bytes_retrans = msk->bytes_retrans;
info->mptcpi_subflows_total = info->mptcpi_subflows +
__mptcp_has_initial_subflow(msk);
now = tcp_jiffies32;
info->mptcpi_last_data_sent = jiffies_to_msecs(now - msk->last_data_sent);
info->mptcpi_last_data_recv = jiffies_to_msecs(now - msk->last_data_recv);
unlock_sock_fast(sk, slow);
mptcp_data_lock(sk);
info->mptcpi_last_ack_recv = jiffies_to_msecs(now - msk->last_ack_recv);
info->mptcpi_snd_una = msk->snd_una;
info->mptcpi_rcv_nxt = msk->ack_seq;
info->mptcpi_bytes_acked = msk->bytes_acked;
mptcp_data_unlock(sk);
}
EXPORT_SYMBOL_GPL(mptcp_diag_fill_info);
+1
View File
@@ -37,6 +37,7 @@
#include <net/inet_connection_sock.h>
#include <net/tcp.h>
#include <net/tls.h>
#include <linux/skbuff_ref.h>
#include "tls.h"
#include "trace.h"
+2 -1
View File
@@ -33,6 +33,7 @@
#include <crypto/aead.h>
#include <crypto/scatterwalk.h>
#include <net/ip6_checksum.h>
#include <linux/skbuff_ref.h>
#include "tls.h"
@@ -277,7 +278,7 @@ static int fill_sg_in(struct scatterlist *sg_in,
for (i = 0; remaining > 0; i++) {
skb_frag_t *frag = &record->frags[i];
__skb_frag_ref(frag);
__skb_frag_ref(frag, false);
sg_set_page(sg_in + i, skb_frag_page(frag),
skb_frag_size(frag), skb_frag_off(frag));
+1
View File
@@ -2,6 +2,7 @@
/* Copyright (c) 2016 Tom Herbert <tom@herbertland.com> */
#include <linux/skbuff.h>
#include <linux/skbuff_ref.h>
#include <linux/workqueue.h>
#include <net/strparser.h>
#include <net/tcp.h>
-1
View File
@@ -2147,7 +2147,6 @@ recv_end:
if (ret) {
if (err >= 0 || err == -EINPROGRESS)
err = ret;
decrypted = 0;
goto end;
}
+53
View File
@@ -200,6 +200,58 @@ chk_msk_cestab()
"${expected}" "${msg}" ""
}
msk_info_get_value()
{
local port="${1}"
local info="${2}"
ss -N "${ns}" -inHM dport "${port}" | \
mptcp_lib_get_info_value "${info}" "${info}"
}
chk_msk_info()
{
local port="${1}"
local info="${2}"
local cnt="${3}"
local msg="....chk ${info}"
local delta_ms=250 # half what we waited before, just to be sure
local now
now=$(msk_info_get_value "${port}" "${info}")
mptcp_lib_print_title "${msg}"
if { [ -z "${cnt}" ] || [ -z "${now}" ]; } &&
! mptcp_lib_expect_all_features; then
mptcp_lib_pr_skip "Feature probably not supported"
mptcp_lib_result_skip "${msg}"
elif [ "$((cnt + delta_ms))" -lt "${now}" ]; then
mptcp_lib_pr_ok
mptcp_lib_result_pass "${msg}"
else
mptcp_lib_pr_fail "value of ${info} changed by $((now - cnt))ms," \
"expected at least ${delta_ms}ms"
mptcp_lib_result_fail "${msg}"
ret=${KSFT_FAIL}
fi
}
chk_last_time_info()
{
local port="${1}"
local data_sent data_recv ack_recv
data_sent=$(msk_info_get_value "${port}" "last_data_sent")
data_recv=$(msk_info_get_value "${port}" "last_data_recv")
ack_recv=$(msk_info_get_value "${port}" "last_ack_recv")
sleep 0.5 # wait to check after if the timestamps difference
chk_msk_info "${port}" "last_data_sent" "${data_sent}"
chk_msk_info "${port}" "last_data_recv" "${data_recv}"
chk_msk_info "${port}" "last_ack_recv" "${ack_recv}"
}
wait_connected()
{
local listener_ns="${1}"
@@ -233,6 +285,7 @@ echo "b" | \
127.0.0.1 >/dev/null &
wait_connected $ns 10000
chk_msk_nr 2 "after MPC handshake "
chk_last_time_info 10000
chk_msk_remote_key_nr 2 "....chk remote_key"
chk_msk_fallback_nr 0 "....chk no fallback"
chk_msk_inuse 2