Current release - regressions:
- core: avoid CFI problems with sock priv helpers - xsk: bring back busy polling support - netpoll: ensure skb_pool list is always initialized Current release - new code bugs: - core: make page_pool_ref_netmem work with net iovs - ipv4: route: fix drop reason being overridden in ip_route_input_slow - udp: make rehash4 independent in udp_lib_rehash() Previous releases - regressions: - bpf: fix bpf_sk_select_reuseport() memory leak - openvswitch: fix lockup on tx to unregistering netdev with carrier - mptcp: be sure to send ack when mptcp-level window re-opens - eth: bnxt: always recalculate features after XDP clearing, fix null-deref - eth: mlx5: fix sub-function add port error handling - eth: fec: handle page_pool_dev_alloc_pages error Previous releases - always broken: - vsock: some fixes due to transport de-assignment - eth: ice: fix E825 initialization - eth: mlx5e: fix inversion dependency warning while enabling IPsec tunnel - eth: gtp: destroy device along with udp socket's netns dismantle. - eth: xilinx: axienet: Fix IRQ coalescing packet count overflow Signed-off-by: Paolo Abeni <pabeni@redhat.com> -----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEEg1AjqC77wbdLX2LbKSR5jcyPE6QFAmeJGOISHHBhYmVuaUBy ZWRoYXQuY29tAAoJECkkeY3MjxOkfLwP/1XaeyEtSifDiF+bj7f3M6gd8RC2wkNq 8DvHadl+uPx1RWv0F2UH9fsVz17A3Gg3oF2Agl4tMP5p9F0e489pNjm2QXOl1zac hpJdV0VdNJHKEfWhKODRfLap6fNtPoEQP5r3scbFYuzkdMw6sYZujdQUmFNghPYe Y6GKZIrQ96vYLpSTrLCAQt/2EEt608b3ESFFhqTkvB8voB2cODNxxBoTJ5K+jMa0 +fVW46siGKc8HSaUJCWS5YkAW/Tu3AXJmYgKGQg9PaErVclwImsQFXggIki80P7W 747Gkuc3kZm3Mt91d6kK1s5Sxr/FAaaJlOOE2iHpZld6cN+Y6niJ+knFdkaX5rCE T/aLq8cdegwSdct6CIJ7YZp3v1AVv21erWf7OpbY9KGTWPV9d2yzh3fYin87tAzs YYo0H1OqqbxpnKThgGREpu+LqEkCbMzsKmwn/5wTAZZl28ySZWZin2ukzTMRqla0 Y8JJvBYvcHn/ekb4gJNaDhJF7ZBuLjrXlG1SXAyO+GS4TwToqrK/luPRf0tkbI/Z QVNBNCukdRTy/IeZQJsc1gtE1tlQmRXNlTbAILPIkWWdxgjdpd/wBbP8/qG9184l Ut4gu7AVF+LLH5nhgRVHAcfrO3i/kbRFC3ErQw06YLyqLInyss8GPULP7tWeFfE3 iM/DsTHjjr04 =EtnO -----END PGP SIGNATURE----- Merge tag 'net-6.13-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Paolo Abeni: "Notably this includes fixes for a few regressions spotted very recently. No known outstanding ones. Current release - regressions: - core: avoid CFI problems with sock priv helpers - xsk: bring back busy polling support - netpoll: ensure skb_pool list is always initialized Current release - new code bugs: - core: make page_pool_ref_netmem work with net iovs - ipv4: route: fix drop reason being overridden in ip_route_input_slow - udp: make rehash4 independent in udp_lib_rehash() Previous releases - regressions: - bpf: fix bpf_sk_select_reuseport() memory leak - openvswitch: fix lockup on tx to unregistering netdev with carrier - mptcp: be sure to send ack when mptcp-level window re-opens - eth: - bnxt: always recalculate features after XDP clearing, fix null-deref - mlx5: fix sub-function add port error handling - fec: handle page_pool_dev_alloc_pages error Previous releases - always broken: - vsock: some fixes due to transport de-assignment - eth: - ice: fix E825 initialization - mlx5e: fix inversion dependency warning while enabling IPsec tunnel - gtp: destroy device along with udp socket's netns dismantle. - xilinx: axienet: Fix IRQ coalescing packet count overflow" * tag 'net-6.13-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (44 commits) netdev: avoid CFI problems with sock priv helpers net/mlx5e: Always start IPsec sequence number from 1 net/mlx5e: Rely on reqid in IPsec tunnel mode net/mlx5e: Fix inversion dependency warning while enabling IPsec tunnel net/mlx5: Clear port select structure when fail to create net/mlx5: SF, Fix add port error handling net/mlx5: Fix a lockdep warning as part of the write combining test net/mlx5: Fix RDMA TX steering prio net: make page_pool_ref_netmem work with net iovs net: ethernet: xgbe: re-add aneg to supported features in PHY quirks net: pcs: xpcs: actively unset DW_VR_MII_DIG_CTRL1_2G5_EN for 1G SGMII net: pcs: xpcs: fix DW_VR_MII_DIG_CTRL1_2G5_EN bit being set for 1G SGMII w/o inband selftests: net: Adapt ethtool mq tests to fix in qdisc graft net: fec: handle page_pool_dev_alloc_pages error net: netpoll: ensure skb_pool list is always initialized net: xilinx: axienet: Fix IRQ coalescing packet count overflow nfp: bpf: prevent integer overflow in nfp_bpf_event_output() selftests: mptcp: avoid spurious errors on disconnect mptcp: fix spurious wake-up on under memory pressure mptcp: be sure to send ack when mptcp-level window re-opens ...
This commit is contained in:
commit
ce69b40190
54 changed files with 553 additions and 400 deletions
|
@ -923,7 +923,6 @@ static void xgbe_phy_free_phy_device(struct xgbe_prv_data *pdata)
|
||||||
|
|
||||||
static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata)
|
static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata)
|
||||||
{
|
{
|
||||||
__ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, };
|
|
||||||
struct xgbe_phy_data *phy_data = pdata->phy_data;
|
struct xgbe_phy_data *phy_data = pdata->phy_data;
|
||||||
unsigned int phy_id = phy_data->phydev->phy_id;
|
unsigned int phy_id = phy_data->phydev->phy_id;
|
||||||
|
|
||||||
|
@ -945,14 +944,7 @@ static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata)
|
||||||
phy_write(phy_data->phydev, 0x04, 0x0d01);
|
phy_write(phy_data->phydev, 0x04, 0x0d01);
|
||||||
phy_write(phy_data->phydev, 0x00, 0x9140);
|
phy_write(phy_data->phydev, 0x00, 0x9140);
|
||||||
|
|
||||||
linkmode_set_bit_array(phy_10_100_features_array,
|
linkmode_copy(phy_data->phydev->supported, PHY_GBIT_FEATURES);
|
||||||
ARRAY_SIZE(phy_10_100_features_array),
|
|
||||||
supported);
|
|
||||||
linkmode_set_bit_array(phy_gbit_features_array,
|
|
||||||
ARRAY_SIZE(phy_gbit_features_array),
|
|
||||||
supported);
|
|
||||||
|
|
||||||
linkmode_copy(phy_data->phydev->supported, supported);
|
|
||||||
|
|
||||||
phy_support_asym_pause(phy_data->phydev);
|
phy_support_asym_pause(phy_data->phydev);
|
||||||
|
|
||||||
|
@ -964,7 +956,6 @@ static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata)
|
||||||
|
|
||||||
static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata)
|
static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata)
|
||||||
{
|
{
|
||||||
__ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, };
|
|
||||||
struct xgbe_phy_data *phy_data = pdata->phy_data;
|
struct xgbe_phy_data *phy_data = pdata->phy_data;
|
||||||
struct xgbe_sfp_eeprom *sfp_eeprom = &phy_data->sfp_eeprom;
|
struct xgbe_sfp_eeprom *sfp_eeprom = &phy_data->sfp_eeprom;
|
||||||
unsigned int phy_id = phy_data->phydev->phy_id;
|
unsigned int phy_id = phy_data->phydev->phy_id;
|
||||||
|
@ -1028,13 +1019,7 @@ static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata)
|
||||||
reg = phy_read(phy_data->phydev, 0x00);
|
reg = phy_read(phy_data->phydev, 0x00);
|
||||||
phy_write(phy_data->phydev, 0x00, reg & ~0x00800);
|
phy_write(phy_data->phydev, 0x00, reg & ~0x00800);
|
||||||
|
|
||||||
linkmode_set_bit_array(phy_10_100_features_array,
|
linkmode_copy(phy_data->phydev->supported, PHY_GBIT_FEATURES);
|
||||||
ARRAY_SIZE(phy_10_100_features_array),
|
|
||||||
supported);
|
|
||||||
linkmode_set_bit_array(phy_gbit_features_array,
|
|
||||||
ARRAY_SIZE(phy_gbit_features_array),
|
|
||||||
supported);
|
|
||||||
linkmode_copy(phy_data->phydev->supported, supported);
|
|
||||||
phy_support_asym_pause(phy_data->phydev);
|
phy_support_asym_pause(phy_data->phydev);
|
||||||
|
|
||||||
netif_dbg(pdata, drv, pdata->netdev,
|
netif_dbg(pdata, drv, pdata->netdev,
|
||||||
|
|
|
@ -4708,7 +4708,7 @@ void bnxt_set_ring_params(struct bnxt *bp)
|
||||||
/* Changing allocation mode of RX rings.
|
/* Changing allocation mode of RX rings.
|
||||||
* TODO: Update when extending xdp_rxq_info to support allocation modes.
|
* TODO: Update when extending xdp_rxq_info to support allocation modes.
|
||||||
*/
|
*/
|
||||||
int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode)
|
static void __bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode)
|
||||||
{
|
{
|
||||||
struct net_device *dev = bp->dev;
|
struct net_device *dev = bp->dev;
|
||||||
|
|
||||||
|
@ -4729,15 +4729,30 @@ int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode)
|
||||||
bp->rx_skb_func = bnxt_rx_page_skb;
|
bp->rx_skb_func = bnxt_rx_page_skb;
|
||||||
}
|
}
|
||||||
bp->rx_dir = DMA_BIDIRECTIONAL;
|
bp->rx_dir = DMA_BIDIRECTIONAL;
|
||||||
/* Disable LRO or GRO_HW */
|
|
||||||
netdev_update_features(dev);
|
|
||||||
} else {
|
} else {
|
||||||
dev->max_mtu = bp->max_mtu;
|
dev->max_mtu = bp->max_mtu;
|
||||||
bp->flags &= ~BNXT_FLAG_RX_PAGE_MODE;
|
bp->flags &= ~BNXT_FLAG_RX_PAGE_MODE;
|
||||||
bp->rx_dir = DMA_FROM_DEVICE;
|
bp->rx_dir = DMA_FROM_DEVICE;
|
||||||
bp->rx_skb_func = bnxt_rx_skb;
|
bp->rx_skb_func = bnxt_rx_skb;
|
||||||
}
|
}
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
void bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode)
|
||||||
|
{
|
||||||
|
__bnxt_set_rx_skb_mode(bp, page_mode);
|
||||||
|
|
||||||
|
if (!page_mode) {
|
||||||
|
int rx, tx;
|
||||||
|
|
||||||
|
bnxt_get_max_rings(bp, &rx, &tx, true);
|
||||||
|
if (rx > 1) {
|
||||||
|
bp->flags &= ~BNXT_FLAG_NO_AGG_RINGS;
|
||||||
|
bp->dev->hw_features |= NETIF_F_LRO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update LRO and GRO_HW availability */
|
||||||
|
netdev_update_features(bp->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bnxt_free_vnic_attributes(struct bnxt *bp)
|
static void bnxt_free_vnic_attributes(struct bnxt *bp)
|
||||||
|
@ -16214,7 +16229,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
if (bp->max_fltr < BNXT_MAX_FLTR)
|
if (bp->max_fltr < BNXT_MAX_FLTR)
|
||||||
bp->max_fltr = BNXT_MAX_FLTR;
|
bp->max_fltr = BNXT_MAX_FLTR;
|
||||||
bnxt_init_l2_fltr_tbl(bp);
|
bnxt_init_l2_fltr_tbl(bp);
|
||||||
bnxt_set_rx_skb_mode(bp, false);
|
__bnxt_set_rx_skb_mode(bp, false);
|
||||||
bnxt_set_tpa_flags(bp);
|
bnxt_set_tpa_flags(bp);
|
||||||
bnxt_set_ring_params(bp);
|
bnxt_set_ring_params(bp);
|
||||||
bnxt_rdma_aux_device_init(bp);
|
bnxt_rdma_aux_device_init(bp);
|
||||||
|
|
|
@ -2846,7 +2846,7 @@ u32 bnxt_fw_health_readl(struct bnxt *bp, int reg_idx);
|
||||||
bool bnxt_bs_trace_avail(struct bnxt *bp, u16 type);
|
bool bnxt_bs_trace_avail(struct bnxt *bp, u16 type);
|
||||||
void bnxt_set_tpa_flags(struct bnxt *bp);
|
void bnxt_set_tpa_flags(struct bnxt *bp);
|
||||||
void bnxt_set_ring_params(struct bnxt *);
|
void bnxt_set_ring_params(struct bnxt *);
|
||||||
int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode);
|
void bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode);
|
||||||
void bnxt_insert_usr_fltr(struct bnxt *bp, struct bnxt_filter_base *fltr);
|
void bnxt_insert_usr_fltr(struct bnxt *bp, struct bnxt_filter_base *fltr);
|
||||||
void bnxt_del_one_usr_fltr(struct bnxt *bp, struct bnxt_filter_base *fltr);
|
void bnxt_del_one_usr_fltr(struct bnxt *bp, struct bnxt_filter_base *fltr);
|
||||||
int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp, unsigned long *bmap,
|
int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp, unsigned long *bmap,
|
||||||
|
|
|
@ -422,15 +422,8 @@ static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog)
|
||||||
bnxt_set_rx_skb_mode(bp, true);
|
bnxt_set_rx_skb_mode(bp, true);
|
||||||
xdp_features_set_redirect_target(dev, true);
|
xdp_features_set_redirect_target(dev, true);
|
||||||
} else {
|
} else {
|
||||||
int rx, tx;
|
|
||||||
|
|
||||||
xdp_features_clear_redirect_target(dev);
|
xdp_features_clear_redirect_target(dev);
|
||||||
bnxt_set_rx_skb_mode(bp, false);
|
bnxt_set_rx_skb_mode(bp, false);
|
||||||
bnxt_get_max_rings(bp, &rx, &tx, true);
|
|
||||||
if (rx > 1) {
|
|
||||||
bp->flags &= ~BNXT_FLAG_NO_AGG_RINGS;
|
|
||||||
bp->dev->hw_features |= NETIF_F_LRO;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
bp->tx_nr_rings_xdp = tx_xdp;
|
bp->tx_nr_rings_xdp = tx_xdp;
|
||||||
bp->tx_nr_rings = bp->tx_nr_rings_per_tc * tc + tx_xdp;
|
bp->tx_nr_rings = bp->tx_nr_rings_per_tc * tc + tx_xdp;
|
||||||
|
|
|
@ -1591,19 +1591,22 @@ static void fec_enet_tx(struct net_device *ndev, int budget)
|
||||||
fec_enet_tx_queue(ndev, i, budget);
|
fec_enet_tx_queue(ndev, i, budget);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fec_enet_update_cbd(struct fec_enet_priv_rx_q *rxq,
|
static int fec_enet_update_cbd(struct fec_enet_priv_rx_q *rxq,
|
||||||
struct bufdesc *bdp, int index)
|
struct bufdesc *bdp, int index)
|
||||||
{
|
{
|
||||||
struct page *new_page;
|
struct page *new_page;
|
||||||
dma_addr_t phys_addr;
|
dma_addr_t phys_addr;
|
||||||
|
|
||||||
new_page = page_pool_dev_alloc_pages(rxq->page_pool);
|
new_page = page_pool_dev_alloc_pages(rxq->page_pool);
|
||||||
WARN_ON(!new_page);
|
if (unlikely(!new_page))
|
||||||
rxq->rx_skb_info[index].page = new_page;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
rxq->rx_skb_info[index].page = new_page;
|
||||||
rxq->rx_skb_info[index].offset = FEC_ENET_XDP_HEADROOM;
|
rxq->rx_skb_info[index].offset = FEC_ENET_XDP_HEADROOM;
|
||||||
phys_addr = page_pool_get_dma_addr(new_page) + FEC_ENET_XDP_HEADROOM;
|
phys_addr = page_pool_get_dma_addr(new_page) + FEC_ENET_XDP_HEADROOM;
|
||||||
bdp->cbd_bufaddr = cpu_to_fec32(phys_addr);
|
bdp->cbd_bufaddr = cpu_to_fec32(phys_addr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32
|
static u32
|
||||||
|
@ -1698,6 +1701,7 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
|
||||||
int cpu = smp_processor_id();
|
int cpu = smp_processor_id();
|
||||||
struct xdp_buff xdp;
|
struct xdp_buff xdp;
|
||||||
struct page *page;
|
struct page *page;
|
||||||
|
__fec32 cbd_bufaddr;
|
||||||
u32 sub_len = 4;
|
u32 sub_len = 4;
|
||||||
|
|
||||||
#if !defined(CONFIG_M5272)
|
#if !defined(CONFIG_M5272)
|
||||||
|
@ -1766,12 +1770,17 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
|
||||||
|
|
||||||
index = fec_enet_get_bd_index(bdp, &rxq->bd);
|
index = fec_enet_get_bd_index(bdp, &rxq->bd);
|
||||||
page = rxq->rx_skb_info[index].page;
|
page = rxq->rx_skb_info[index].page;
|
||||||
|
cbd_bufaddr = bdp->cbd_bufaddr;
|
||||||
|
if (fec_enet_update_cbd(rxq, bdp, index)) {
|
||||||
|
ndev->stats.rx_dropped++;
|
||||||
|
goto rx_processing_done;
|
||||||
|
}
|
||||||
|
|
||||||
dma_sync_single_for_cpu(&fep->pdev->dev,
|
dma_sync_single_for_cpu(&fep->pdev->dev,
|
||||||
fec32_to_cpu(bdp->cbd_bufaddr),
|
fec32_to_cpu(cbd_bufaddr),
|
||||||
pkt_len,
|
pkt_len,
|
||||||
DMA_FROM_DEVICE);
|
DMA_FROM_DEVICE);
|
||||||
prefetch(page_address(page));
|
prefetch(page_address(page));
|
||||||
fec_enet_update_cbd(rxq, bdp, index);
|
|
||||||
|
|
||||||
if (xdp_prog) {
|
if (xdp_prog) {
|
||||||
xdp_buff_clear_frags_flag(&xdp);
|
xdp_buff_clear_frags_flag(&xdp);
|
||||||
|
|
|
@ -1665,6 +1665,7 @@ struct ice_aqc_get_port_options_elem {
|
||||||
#define ICE_AQC_PORT_OPT_MAX_LANE_25G 5
|
#define ICE_AQC_PORT_OPT_MAX_LANE_25G 5
|
||||||
#define ICE_AQC_PORT_OPT_MAX_LANE_50G 6
|
#define ICE_AQC_PORT_OPT_MAX_LANE_50G 6
|
||||||
#define ICE_AQC_PORT_OPT_MAX_LANE_100G 7
|
#define ICE_AQC_PORT_OPT_MAX_LANE_100G 7
|
||||||
|
#define ICE_AQC_PORT_OPT_MAX_LANE_200G 8
|
||||||
|
|
||||||
u8 global_scid[2];
|
u8 global_scid[2];
|
||||||
u8 phy_scid[2];
|
u8 phy_scid[2];
|
||||||
|
|
|
@ -4095,6 +4095,57 @@ ice_aq_set_port_option(struct ice_hw *hw, u8 lport, u8 lport_valid,
|
||||||
return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
|
return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_get_phy_lane_number - Get PHY lane number for current adapter
|
||||||
|
* @hw: pointer to the hw struct
|
||||||
|
*
|
||||||
|
* Return: PHY lane number on success, negative error code otherwise.
|
||||||
|
*/
|
||||||
|
int ice_get_phy_lane_number(struct ice_hw *hw)
|
||||||
|
{
|
||||||
|
struct ice_aqc_get_port_options_elem *options;
|
||||||
|
unsigned int lport = 0;
|
||||||
|
unsigned int lane;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
options = kcalloc(ICE_AQC_PORT_OPT_MAX, sizeof(*options), GFP_KERNEL);
|
||||||
|
if (!options)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
for (lane = 0; lane < ICE_MAX_PORT_PER_PCI_DEV; lane++) {
|
||||||
|
u8 options_count = ICE_AQC_PORT_OPT_MAX;
|
||||||
|
u8 speed, active_idx, pending_idx;
|
||||||
|
bool active_valid, pending_valid;
|
||||||
|
|
||||||
|
err = ice_aq_get_port_options(hw, options, &options_count, lane,
|
||||||
|
true, &active_idx, &active_valid,
|
||||||
|
&pending_idx, &pending_valid);
|
||||||
|
if (err)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (!active_valid)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
speed = options[active_idx].max_lane_speed;
|
||||||
|
/* If we don't get speed for this lane, it's unoccupied */
|
||||||
|
if (speed > ICE_AQC_PORT_OPT_MAX_LANE_200G)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (hw->pf_id == lport) {
|
||||||
|
kfree(options);
|
||||||
|
return lane;
|
||||||
|
}
|
||||||
|
|
||||||
|
lport++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PHY lane not found */
|
||||||
|
err = -ENXIO;
|
||||||
|
err:
|
||||||
|
kfree(options);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_aq_sff_eeprom
|
* ice_aq_sff_eeprom
|
||||||
* @hw: pointer to the HW struct
|
* @hw: pointer to the HW struct
|
||||||
|
|
|
@ -193,6 +193,7 @@ ice_aq_get_port_options(struct ice_hw *hw,
|
||||||
int
|
int
|
||||||
ice_aq_set_port_option(struct ice_hw *hw, u8 lport, u8 lport_valid,
|
ice_aq_set_port_option(struct ice_hw *hw, u8 lport, u8 lport_valid,
|
||||||
u8 new_option);
|
u8 new_option);
|
||||||
|
int ice_get_phy_lane_number(struct ice_hw *hw);
|
||||||
int
|
int
|
||||||
ice_aq_sff_eeprom(struct ice_hw *hw, u16 lport, u8 bus_addr,
|
ice_aq_sff_eeprom(struct ice_hw *hw, u16 lport, u8 bus_addr,
|
||||||
u16 mem_addr, u8 page, u8 set_page, u8 *data, u8 length,
|
u16 mem_addr, u8 page, u8 set_page, u8 *data, u8 length,
|
||||||
|
|
|
@ -1144,7 +1144,7 @@ ice_link_event(struct ice_pf *pf, struct ice_port_info *pi, bool link_up,
|
||||||
if (link_up == old_link && link_speed == old_link_speed)
|
if (link_up == old_link && link_speed == old_link_speed)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ice_ptp_link_change(pf, pf->hw.pf_id, link_up);
|
ice_ptp_link_change(pf, link_up);
|
||||||
|
|
||||||
if (ice_is_dcb_active(pf)) {
|
if (ice_is_dcb_active(pf)) {
|
||||||
if (test_bit(ICE_FLAG_DCB_ENA, pf->flags))
|
if (test_bit(ICE_FLAG_DCB_ENA, pf->flags))
|
||||||
|
@ -6790,7 +6790,7 @@ static int ice_up_complete(struct ice_vsi *vsi)
|
||||||
ice_print_link_msg(vsi, true);
|
ice_print_link_msg(vsi, true);
|
||||||
netif_tx_start_all_queues(vsi->netdev);
|
netif_tx_start_all_queues(vsi->netdev);
|
||||||
netif_carrier_on(vsi->netdev);
|
netif_carrier_on(vsi->netdev);
|
||||||
ice_ptp_link_change(pf, pf->hw.pf_id, true);
|
ice_ptp_link_change(pf, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform an initial read of the statistics registers now to
|
/* Perform an initial read of the statistics registers now to
|
||||||
|
@ -7260,7 +7260,7 @@ int ice_down(struct ice_vsi *vsi)
|
||||||
|
|
||||||
if (vsi->netdev) {
|
if (vsi->netdev) {
|
||||||
vlan_err = ice_vsi_del_vlan_zero(vsi);
|
vlan_err = ice_vsi_del_vlan_zero(vsi);
|
||||||
ice_ptp_link_change(vsi->back, vsi->back->hw.pf_id, false);
|
ice_ptp_link_change(vsi->back, false);
|
||||||
netif_carrier_off(vsi->netdev);
|
netif_carrier_off(vsi->netdev);
|
||||||
netif_tx_disable(vsi->netdev);
|
netif_tx_disable(vsi->netdev);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1388,10 +1388,9 @@ ice_ptp_port_phy_restart(struct ice_ptp_port *ptp_port)
|
||||||
/**
|
/**
|
||||||
* ice_ptp_link_change - Reconfigure PTP after link status change
|
* ice_ptp_link_change - Reconfigure PTP after link status change
|
||||||
* @pf: Board private structure
|
* @pf: Board private structure
|
||||||
* @port: Port for which the PHY start is set
|
|
||||||
* @linkup: Link is up or down
|
* @linkup: Link is up or down
|
||||||
*/
|
*/
|
||||||
void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
|
void ice_ptp_link_change(struct ice_pf *pf, bool linkup)
|
||||||
{
|
{
|
||||||
struct ice_ptp_port *ptp_port;
|
struct ice_ptp_port *ptp_port;
|
||||||
struct ice_hw *hw = &pf->hw;
|
struct ice_hw *hw = &pf->hw;
|
||||||
|
@ -1399,14 +1398,7 @@ void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
|
||||||
if (pf->ptp.state != ICE_PTP_READY)
|
if (pf->ptp.state != ICE_PTP_READY)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (WARN_ON_ONCE(port >= hw->ptp.num_lports))
|
|
||||||
return;
|
|
||||||
|
|
||||||
ptp_port = &pf->ptp.port;
|
ptp_port = &pf->ptp.port;
|
||||||
if (ice_is_e825c(hw) && hw->ptp.is_2x50g_muxed_topo)
|
|
||||||
port *= 2;
|
|
||||||
if (WARN_ON_ONCE(ptp_port->port_num != port))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Update cached link status for this port immediately */
|
/* Update cached link status for this port immediately */
|
||||||
ptp_port->link_up = linkup;
|
ptp_port->link_up = linkup;
|
||||||
|
@ -3164,10 +3156,17 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||||
{
|
{
|
||||||
struct ice_ptp *ptp = &pf->ptp;
|
struct ice_ptp *ptp = &pf->ptp;
|
||||||
struct ice_hw *hw = &pf->hw;
|
struct ice_hw *hw = &pf->hw;
|
||||||
int err;
|
int lane_num, err;
|
||||||
|
|
||||||
ptp->state = ICE_PTP_INITIALIZING;
|
ptp->state = ICE_PTP_INITIALIZING;
|
||||||
|
|
||||||
|
lane_num = ice_get_phy_lane_number(hw);
|
||||||
|
if (lane_num < 0) {
|
||||||
|
err = lane_num;
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptp->port.port_num = (u8)lane_num;
|
||||||
ice_ptp_init_hw(hw);
|
ice_ptp_init_hw(hw);
|
||||||
|
|
||||||
ice_ptp_init_tx_interrupt_mode(pf);
|
ice_ptp_init_tx_interrupt_mode(pf);
|
||||||
|
@ -3188,10 +3187,6 @@ void ice_ptp_init(struct ice_pf *pf)
|
||||||
if (err)
|
if (err)
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
|
|
||||||
ptp->port.port_num = hw->pf_id;
|
|
||||||
if (ice_is_e825c(hw) && hw->ptp.is_2x50g_muxed_topo)
|
|
||||||
ptp->port.port_num = hw->pf_id * 2;
|
|
||||||
|
|
||||||
err = ice_ptp_init_port(pf, &ptp->port);
|
err = ice_ptp_init_port(pf, &ptp->port);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
|
|
|
@ -310,7 +310,7 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf,
|
||||||
enum ice_reset_req reset_type);
|
enum ice_reset_req reset_type);
|
||||||
void ice_ptp_init(struct ice_pf *pf);
|
void ice_ptp_init(struct ice_pf *pf);
|
||||||
void ice_ptp_release(struct ice_pf *pf);
|
void ice_ptp_release(struct ice_pf *pf);
|
||||||
void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup);
|
void ice_ptp_link_change(struct ice_pf *pf, bool linkup);
|
||||||
#else /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */
|
#else /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */
|
||||||
static inline int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr)
|
static inline int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr)
|
||||||
{
|
{
|
||||||
|
@ -358,7 +358,7 @@ static inline void ice_ptp_prepare_for_reset(struct ice_pf *pf,
|
||||||
}
|
}
|
||||||
static inline void ice_ptp_init(struct ice_pf *pf) { }
|
static inline void ice_ptp_init(struct ice_pf *pf) { }
|
||||||
static inline void ice_ptp_release(struct ice_pf *pf) { }
|
static inline void ice_ptp_release(struct ice_pf *pf) { }
|
||||||
static inline void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup)
|
static inline void ice_ptp_link_change(struct ice_pf *pf, bool linkup)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,7 @@ struct ice_eth56g_mac_reg_cfg eth56g_mac_cfg[NUM_ICE_ETH56G_LNK_SPD] = {
|
||||||
.rx_offset = {
|
.rx_offset = {
|
||||||
.serdes = 0xffffeb27, /* -10.42424 */
|
.serdes = 0xffffeb27, /* -10.42424 */
|
||||||
.no_fec = 0xffffcccd, /* -25.6 */
|
.no_fec = 0xffffcccd, /* -25.6 */
|
||||||
.fc = 0xfffe0014, /* -255.96 */
|
.fc = 0xfffc557b, /* -469.26 */
|
||||||
.sfd = 0x4a4, /* 2.32 */
|
.sfd = 0x4a4, /* 2.32 */
|
||||||
.bs_ds = 0x32 /* 0.0969697 */
|
.bs_ds = 0x32 /* 0.0969697 */
|
||||||
}
|
}
|
||||||
|
|
|
@ -900,31 +900,46 @@ static void ice_ptp_exec_tmr_cmd(struct ice_hw *hw)
|
||||||
* The following functions operate on devices with the ETH 56G PHY.
|
* The following functions operate on devices with the ETH 56G PHY.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_ptp_get_dest_dev_e825 - get destination PHY for given port number
|
||||||
|
* @hw: pointer to the HW struct
|
||||||
|
* @port: destination port
|
||||||
|
*
|
||||||
|
* Return: destination sideband queue PHY device.
|
||||||
|
*/
|
||||||
|
static enum ice_sbq_msg_dev ice_ptp_get_dest_dev_e825(struct ice_hw *hw,
|
||||||
|
u8 port)
|
||||||
|
{
|
||||||
|
/* On a single complex E825, PHY 0 is always destination device phy_0
|
||||||
|
* and PHY 1 is phy_0_peer.
|
||||||
|
*/
|
||||||
|
if (port >= hw->ptp.ports_per_phy)
|
||||||
|
return eth56g_phy_1;
|
||||||
|
else
|
||||||
|
return eth56g_phy_0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_write_phy_eth56g - Write a PHY port register
|
* ice_write_phy_eth56g - Write a PHY port register
|
||||||
* @hw: pointer to the HW struct
|
* @hw: pointer to the HW struct
|
||||||
* @phy_idx: PHY index
|
* @port: destination port
|
||||||
* @addr: PHY register address
|
* @addr: PHY register address
|
||||||
* @val: Value to write
|
* @val: Value to write
|
||||||
*
|
*
|
||||||
* Return: 0 on success, other error codes when failed to write to PHY
|
* Return: 0 on success, other error codes when failed to write to PHY
|
||||||
*/
|
*/
|
||||||
static int ice_write_phy_eth56g(struct ice_hw *hw, u8 phy_idx, u32 addr,
|
static int ice_write_phy_eth56g(struct ice_hw *hw, u8 port, u32 addr, u32 val)
|
||||||
u32 val)
|
|
||||||
{
|
{
|
||||||
struct ice_sbq_msg_input phy_msg;
|
struct ice_sbq_msg_input msg = {
|
||||||
|
.dest_dev = ice_ptp_get_dest_dev_e825(hw, port),
|
||||||
|
.opcode = ice_sbq_msg_wr,
|
||||||
|
.msg_addr_low = lower_16_bits(addr),
|
||||||
|
.msg_addr_high = upper_16_bits(addr),
|
||||||
|
.data = val
|
||||||
|
};
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
phy_msg.opcode = ice_sbq_msg_wr;
|
err = ice_sbq_rw_reg(hw, &msg, ICE_AQ_FLAG_RD);
|
||||||
|
|
||||||
phy_msg.msg_addr_low = lower_16_bits(addr);
|
|
||||||
phy_msg.msg_addr_high = upper_16_bits(addr);
|
|
||||||
|
|
||||||
phy_msg.data = val;
|
|
||||||
phy_msg.dest_dev = hw->ptp.phy.eth56g.phy_addr[phy_idx];
|
|
||||||
|
|
||||||
err = ice_sbq_rw_reg(hw, &phy_msg, ICE_AQ_FLAG_RD);
|
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
ice_debug(hw, ICE_DBG_PTP, "PTP failed to send msg to phy %d\n",
|
ice_debug(hw, ICE_DBG_PTP, "PTP failed to send msg to phy %d\n",
|
||||||
err);
|
err);
|
||||||
|
@ -935,41 +950,36 @@ static int ice_write_phy_eth56g(struct ice_hw *hw, u8 phy_idx, u32 addr,
|
||||||
/**
|
/**
|
||||||
* ice_read_phy_eth56g - Read a PHY port register
|
* ice_read_phy_eth56g - Read a PHY port register
|
||||||
* @hw: pointer to the HW struct
|
* @hw: pointer to the HW struct
|
||||||
* @phy_idx: PHY index
|
* @port: destination port
|
||||||
* @addr: PHY register address
|
* @addr: PHY register address
|
||||||
* @val: Value to write
|
* @val: Value to write
|
||||||
*
|
*
|
||||||
* Return: 0 on success, other error codes when failed to read from PHY
|
* Return: 0 on success, other error codes when failed to read from PHY
|
||||||
*/
|
*/
|
||||||
static int ice_read_phy_eth56g(struct ice_hw *hw, u8 phy_idx, u32 addr,
|
static int ice_read_phy_eth56g(struct ice_hw *hw, u8 port, u32 addr, u32 *val)
|
||||||
u32 *val)
|
|
||||||
{
|
{
|
||||||
struct ice_sbq_msg_input phy_msg;
|
struct ice_sbq_msg_input msg = {
|
||||||
|
.dest_dev = ice_ptp_get_dest_dev_e825(hw, port),
|
||||||
|
.opcode = ice_sbq_msg_rd,
|
||||||
|
.msg_addr_low = lower_16_bits(addr),
|
||||||
|
.msg_addr_high = upper_16_bits(addr)
|
||||||
|
};
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
phy_msg.opcode = ice_sbq_msg_rd;
|
err = ice_sbq_rw_reg(hw, &msg, ICE_AQ_FLAG_RD);
|
||||||
|
if (err)
|
||||||
phy_msg.msg_addr_low = lower_16_bits(addr);
|
|
||||||
phy_msg.msg_addr_high = upper_16_bits(addr);
|
|
||||||
|
|
||||||
phy_msg.data = 0;
|
|
||||||
phy_msg.dest_dev = hw->ptp.phy.eth56g.phy_addr[phy_idx];
|
|
||||||
|
|
||||||
err = ice_sbq_rw_reg(hw, &phy_msg, ICE_AQ_FLAG_RD);
|
|
||||||
if (err) {
|
|
||||||
ice_debug(hw, ICE_DBG_PTP, "PTP failed to send msg to phy %d\n",
|
ice_debug(hw, ICE_DBG_PTP, "PTP failed to send msg to phy %d\n",
|
||||||
err);
|
err);
|
||||||
return err;
|
else
|
||||||
}
|
*val = msg.data;
|
||||||
|
|
||||||
*val = phy_msg.data;
|
return err;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_phy_res_address_eth56g - Calculate a PHY port register address
|
* ice_phy_res_address_eth56g - Calculate a PHY port register address
|
||||||
* @port: Port number to be written
|
* @hw: pointer to the HW struct
|
||||||
|
* @lane: Lane number to be written
|
||||||
* @res_type: resource type (register/memory)
|
* @res_type: resource type (register/memory)
|
||||||
* @offset: Offset from PHY port register base
|
* @offset: Offset from PHY port register base
|
||||||
* @addr: The result address
|
* @addr: The result address
|
||||||
|
@ -978,17 +988,19 @@ static int ice_read_phy_eth56g(struct ice_hw *hw, u8 phy_idx, u32 addr,
|
||||||
* * %0 - success
|
* * %0 - success
|
||||||
* * %EINVAL - invalid port number or resource type
|
* * %EINVAL - invalid port number or resource type
|
||||||
*/
|
*/
|
||||||
static int ice_phy_res_address_eth56g(u8 port, enum eth56g_res_type res_type,
|
static int ice_phy_res_address_eth56g(struct ice_hw *hw, u8 lane,
|
||||||
u32 offset, u32 *addr)
|
enum eth56g_res_type res_type,
|
||||||
|
u32 offset,
|
||||||
|
u32 *addr)
|
||||||
{
|
{
|
||||||
u8 lane = port % ICE_PORTS_PER_QUAD;
|
|
||||||
u8 phy = ICE_GET_QUAD_NUM(port);
|
|
||||||
|
|
||||||
if (res_type >= NUM_ETH56G_PHY_RES)
|
if (res_type >= NUM_ETH56G_PHY_RES)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
*addr = eth56g_phy_res[res_type].base[phy] +
|
/* Lanes 4..7 are in fact 0..3 on a second PHY */
|
||||||
|
lane %= hw->ptp.ports_per_phy;
|
||||||
|
*addr = eth56g_phy_res[res_type].base[0] +
|
||||||
lane * eth56g_phy_res[res_type].step + offset;
|
lane * eth56g_phy_res[res_type].step + offset;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1008,19 +1020,17 @@ static int ice_phy_res_address_eth56g(u8 port, enum eth56g_res_type res_type,
|
||||||
static int ice_write_port_eth56g(struct ice_hw *hw, u8 port, u32 offset,
|
static int ice_write_port_eth56g(struct ice_hw *hw, u8 port, u32 offset,
|
||||||
u32 val, enum eth56g_res_type res_type)
|
u32 val, enum eth56g_res_type res_type)
|
||||||
{
|
{
|
||||||
u8 phy_port = port % hw->ptp.ports_per_phy;
|
|
||||||
u8 phy_idx = port / hw->ptp.ports_per_phy;
|
|
||||||
u32 addr;
|
u32 addr;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (port >= hw->ptp.num_lports)
|
if (port >= hw->ptp.num_lports)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
err = ice_phy_res_address_eth56g(phy_port, res_type, offset, &addr);
|
err = ice_phy_res_address_eth56g(hw, port, res_type, offset, &addr);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
return ice_write_phy_eth56g(hw, phy_idx, addr, val);
|
return ice_write_phy_eth56g(hw, port, addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1039,19 +1049,17 @@ static int ice_write_port_eth56g(struct ice_hw *hw, u8 port, u32 offset,
|
||||||
static int ice_read_port_eth56g(struct ice_hw *hw, u8 port, u32 offset,
|
static int ice_read_port_eth56g(struct ice_hw *hw, u8 port, u32 offset,
|
||||||
u32 *val, enum eth56g_res_type res_type)
|
u32 *val, enum eth56g_res_type res_type)
|
||||||
{
|
{
|
||||||
u8 phy_port = port % hw->ptp.ports_per_phy;
|
|
||||||
u8 phy_idx = port / hw->ptp.ports_per_phy;
|
|
||||||
u32 addr;
|
u32 addr;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (port >= hw->ptp.num_lports)
|
if (port >= hw->ptp.num_lports)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
err = ice_phy_res_address_eth56g(phy_port, res_type, offset, &addr);
|
err = ice_phy_res_address_eth56g(hw, port, res_type, offset, &addr);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
return ice_read_phy_eth56g(hw, phy_idx, addr, val);
|
return ice_read_phy_eth56g(hw, port, addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1200,6 +1208,56 @@ static int ice_write_port_mem_eth56g(struct ice_hw *hw, u8 port, u16 offset,
|
||||||
return ice_write_port_eth56g(hw, port, offset, val, ETH56G_PHY_MEM_PTP);
|
return ice_write_port_eth56g(hw, port, offset, val, ETH56G_PHY_MEM_PTP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_write_quad_ptp_reg_eth56g - Write a PHY quad register
|
||||||
|
* @hw: pointer to the HW struct
|
||||||
|
* @offset: PHY register offset
|
||||||
|
* @port: Port number
|
||||||
|
* @val: Value to write
|
||||||
|
*
|
||||||
|
* Return:
|
||||||
|
* * %0 - success
|
||||||
|
* * %EIO - invalid port number or resource type
|
||||||
|
* * %other - failed to write to PHY
|
||||||
|
*/
|
||||||
|
static int ice_write_quad_ptp_reg_eth56g(struct ice_hw *hw, u8 port,
|
||||||
|
u32 offset, u32 val)
|
||||||
|
{
|
||||||
|
u32 addr;
|
||||||
|
|
||||||
|
if (port >= hw->ptp.num_lports)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
addr = eth56g_phy_res[ETH56G_PHY_REG_PTP].base[0] + offset;
|
||||||
|
|
||||||
|
return ice_write_phy_eth56g(hw, port, addr, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ice_read_quad_ptp_reg_eth56g - Read a PHY quad register
|
||||||
|
* @hw: pointer to the HW struct
|
||||||
|
* @offset: PHY register offset
|
||||||
|
* @port: Port number
|
||||||
|
* @val: Value to read
|
||||||
|
*
|
||||||
|
* Return:
|
||||||
|
* * %0 - success
|
||||||
|
* * %EIO - invalid port number or resource type
|
||||||
|
* * %other - failed to read from PHY
|
||||||
|
*/
|
||||||
|
static int ice_read_quad_ptp_reg_eth56g(struct ice_hw *hw, u8 port,
|
||||||
|
u32 offset, u32 *val)
|
||||||
|
{
|
||||||
|
u32 addr;
|
||||||
|
|
||||||
|
if (port >= hw->ptp.num_lports)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
addr = eth56g_phy_res[ETH56G_PHY_REG_PTP].base[0] + offset;
|
||||||
|
|
||||||
|
return ice_read_phy_eth56g(hw, port, addr, val);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_is_64b_phy_reg_eth56g - Check if this is a 64bit PHY register
|
* ice_is_64b_phy_reg_eth56g - Check if this is a 64bit PHY register
|
||||||
* @low_addr: the low address to check
|
* @low_addr: the low address to check
|
||||||
|
@ -1919,7 +1977,6 @@ ice_phy_get_speed_eth56g(struct ice_link_status *li)
|
||||||
*/
|
*/
|
||||||
static int ice_phy_cfg_parpcs_eth56g(struct ice_hw *hw, u8 port)
|
static int ice_phy_cfg_parpcs_eth56g(struct ice_hw *hw, u8 port)
|
||||||
{
|
{
|
||||||
u8 port_blk = port & ~(ICE_PORTS_PER_QUAD - 1);
|
|
||||||
u32 val;
|
u32 val;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -1934,8 +1991,8 @@ static int ice_phy_cfg_parpcs_eth56g(struct ice_hw *hw, u8 port)
|
||||||
switch (ice_phy_get_speed_eth56g(&hw->port_info->phy.link_info)) {
|
switch (ice_phy_get_speed_eth56g(&hw->port_info->phy.link_info)) {
|
||||||
case ICE_ETH56G_LNK_SPD_1G:
|
case ICE_ETH56G_LNK_SPD_1G:
|
||||||
case ICE_ETH56G_LNK_SPD_2_5G:
|
case ICE_ETH56G_LNK_SPD_2_5G:
|
||||||
err = ice_read_ptp_reg_eth56g(hw, port_blk,
|
err = ice_read_quad_ptp_reg_eth56g(hw, port,
|
||||||
PHY_GPCS_CONFIG_REG0, &val);
|
PHY_GPCS_CONFIG_REG0, &val);
|
||||||
if (err) {
|
if (err) {
|
||||||
ice_debug(hw, ICE_DBG_PTP, "Failed to read PHY_GPCS_CONFIG_REG0, status: %d",
|
ice_debug(hw, ICE_DBG_PTP, "Failed to read PHY_GPCS_CONFIG_REG0, status: %d",
|
||||||
err);
|
err);
|
||||||
|
@ -1946,8 +2003,8 @@ static int ice_phy_cfg_parpcs_eth56g(struct ice_hw *hw, u8 port)
|
||||||
val |= FIELD_PREP(PHY_GPCS_CONFIG_REG0_TX_THR_M,
|
val |= FIELD_PREP(PHY_GPCS_CONFIG_REG0_TX_THR_M,
|
||||||
ICE_ETH56G_NOMINAL_TX_THRESH);
|
ICE_ETH56G_NOMINAL_TX_THRESH);
|
||||||
|
|
||||||
err = ice_write_ptp_reg_eth56g(hw, port_blk,
|
err = ice_write_quad_ptp_reg_eth56g(hw, port,
|
||||||
PHY_GPCS_CONFIG_REG0, val);
|
PHY_GPCS_CONFIG_REG0, val);
|
||||||
if (err) {
|
if (err) {
|
||||||
ice_debug(hw, ICE_DBG_PTP, "Failed to write PHY_GPCS_CONFIG_REG0, status: %d",
|
ice_debug(hw, ICE_DBG_PTP, "Failed to write PHY_GPCS_CONFIG_REG0, status: %d",
|
||||||
err);
|
err);
|
||||||
|
@ -1988,50 +2045,47 @@ static int ice_phy_cfg_parpcs_eth56g(struct ice_hw *hw, u8 port)
|
||||||
*/
|
*/
|
||||||
int ice_phy_cfg_ptp_1step_eth56g(struct ice_hw *hw, u8 port)
|
int ice_phy_cfg_ptp_1step_eth56g(struct ice_hw *hw, u8 port)
|
||||||
{
|
{
|
||||||
u8 port_blk = port & ~(ICE_PORTS_PER_QUAD - 1);
|
u8 quad_lane = port % ICE_PORTS_PER_QUAD;
|
||||||
u8 blk_port = port & (ICE_PORTS_PER_QUAD - 1);
|
u32 addr, val, peer_delay;
|
||||||
bool enable, sfd_ena;
|
bool enable, sfd_ena;
|
||||||
u32 val, peer_delay;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
enable = hw->ptp.phy.eth56g.onestep_ena;
|
enable = hw->ptp.phy.eth56g.onestep_ena;
|
||||||
peer_delay = hw->ptp.phy.eth56g.peer_delay;
|
peer_delay = hw->ptp.phy.eth56g.peer_delay;
|
||||||
sfd_ena = hw->ptp.phy.eth56g.sfd_ena;
|
sfd_ena = hw->ptp.phy.eth56g.sfd_ena;
|
||||||
|
|
||||||
/* PHY_PTP_1STEP_CONFIG */
|
addr = PHY_PTP_1STEP_CONFIG;
|
||||||
err = ice_read_ptp_reg_eth56g(hw, port_blk, PHY_PTP_1STEP_CONFIG, &val);
|
err = ice_read_quad_ptp_reg_eth56g(hw, port, addr, &val);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
if (enable)
|
if (enable)
|
||||||
val |= blk_port;
|
val |= BIT(quad_lane);
|
||||||
else
|
else
|
||||||
val &= ~blk_port;
|
val &= ~BIT(quad_lane);
|
||||||
|
|
||||||
val &= ~(PHY_PTP_1STEP_T1S_UP64_M | PHY_PTP_1STEP_T1S_DELTA_M);
|
val &= ~(PHY_PTP_1STEP_T1S_UP64_M | PHY_PTP_1STEP_T1S_DELTA_M);
|
||||||
|
|
||||||
err = ice_write_ptp_reg_eth56g(hw, port_blk, PHY_PTP_1STEP_CONFIG, val);
|
err = ice_write_quad_ptp_reg_eth56g(hw, port, addr, val);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
/* PHY_PTP_1STEP_PEER_DELAY */
|
addr = PHY_PTP_1STEP_PEER_DELAY(quad_lane);
|
||||||
val = FIELD_PREP(PHY_PTP_1STEP_PD_DELAY_M, peer_delay);
|
val = FIELD_PREP(PHY_PTP_1STEP_PD_DELAY_M, peer_delay);
|
||||||
if (peer_delay)
|
if (peer_delay)
|
||||||
val |= PHY_PTP_1STEP_PD_ADD_PD_M;
|
val |= PHY_PTP_1STEP_PD_ADD_PD_M;
|
||||||
val |= PHY_PTP_1STEP_PD_DLY_V_M;
|
val |= PHY_PTP_1STEP_PD_DLY_V_M;
|
||||||
err = ice_write_ptp_reg_eth56g(hw, port_blk,
|
err = ice_write_quad_ptp_reg_eth56g(hw, port, addr, val);
|
||||||
PHY_PTP_1STEP_PEER_DELAY(blk_port), val);
|
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
val &= ~PHY_PTP_1STEP_PD_DLY_V_M;
|
val &= ~PHY_PTP_1STEP_PD_DLY_V_M;
|
||||||
err = ice_write_ptp_reg_eth56g(hw, port_blk,
|
err = ice_write_quad_ptp_reg_eth56g(hw, port, addr, val);
|
||||||
PHY_PTP_1STEP_PEER_DELAY(blk_port), val);
|
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
/* PHY_MAC_XIF_MODE */
|
addr = PHY_MAC_XIF_MODE;
|
||||||
err = ice_read_mac_reg_eth56g(hw, port, PHY_MAC_XIF_MODE, &val);
|
err = ice_read_mac_reg_eth56g(hw, port, addr, &val);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -2051,7 +2105,7 @@ int ice_phy_cfg_ptp_1step_eth56g(struct ice_hw *hw, u8 port)
|
||||||
FIELD_PREP(PHY_MAC_XIF_TS_BIN_MODE_M, enable) |
|
FIELD_PREP(PHY_MAC_XIF_TS_BIN_MODE_M, enable) |
|
||||||
FIELD_PREP(PHY_MAC_XIF_TS_SFD_ENA_M, sfd_ena);
|
FIELD_PREP(PHY_MAC_XIF_TS_SFD_ENA_M, sfd_ena);
|
||||||
|
|
||||||
return ice_write_mac_reg_eth56g(hw, port, PHY_MAC_XIF_MODE, val);
|
return ice_write_mac_reg_eth56g(hw, port, addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2093,21 +2147,22 @@ static u32 ice_ptp_calc_bitslip_eth56g(struct ice_hw *hw, u8 port, u32 bs,
|
||||||
bool fc, bool rs,
|
bool fc, bool rs,
|
||||||
enum ice_eth56g_link_spd spd)
|
enum ice_eth56g_link_spd spd)
|
||||||
{
|
{
|
||||||
u8 port_offset = port & (ICE_PORTS_PER_QUAD - 1);
|
|
||||||
u8 port_blk = port & ~(ICE_PORTS_PER_QUAD - 1);
|
|
||||||
u32 bitslip;
|
u32 bitslip;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!bs || rs)
|
if (!bs || rs)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (spd == ICE_ETH56G_LNK_SPD_1G || spd == ICE_ETH56G_LNK_SPD_2_5G)
|
if (spd == ICE_ETH56G_LNK_SPD_1G || spd == ICE_ETH56G_LNK_SPD_2_5G) {
|
||||||
err = ice_read_gpcs_reg_eth56g(hw, port, PHY_GPCS_BITSLIP,
|
err = ice_read_gpcs_reg_eth56g(hw, port, PHY_GPCS_BITSLIP,
|
||||||
&bitslip);
|
&bitslip);
|
||||||
else
|
} else {
|
||||||
err = ice_read_ptp_reg_eth56g(hw, port_blk,
|
u8 quad_lane = port % ICE_PORTS_PER_QUAD;
|
||||||
PHY_REG_SD_BIT_SLIP(port_offset),
|
u32 addr;
|
||||||
&bitslip);
|
|
||||||
|
addr = PHY_REG_SD_BIT_SLIP(quad_lane);
|
||||||
|
err = ice_read_quad_ptp_reg_eth56g(hw, port, addr, &bitslip);
|
||||||
|
}
|
||||||
if (err)
|
if (err)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -2667,59 +2722,29 @@ static int ice_get_phy_tx_tstamp_ready_eth56g(struct ice_hw *hw, u8 port,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ice_is_muxed_topo - detect breakout 2x50G topology for E825C
|
* ice_ptp_init_phy_e825 - initialize PHY parameters
|
||||||
* @hw: pointer to the HW struct
|
|
||||||
*
|
|
||||||
* Return: true if it's 2x50 breakout topology, false otherwise
|
|
||||||
*/
|
|
||||||
static bool ice_is_muxed_topo(struct ice_hw *hw)
|
|
||||||
{
|
|
||||||
u8 link_topo;
|
|
||||||
bool mux;
|
|
||||||
u32 val;
|
|
||||||
|
|
||||||
val = rd32(hw, GLGEN_SWITCH_MODE_CONFIG);
|
|
||||||
mux = FIELD_GET(GLGEN_SWITCH_MODE_CONFIG_25X4_QUAD_M, val);
|
|
||||||
val = rd32(hw, GLGEN_MAC_LINK_TOPO);
|
|
||||||
link_topo = FIELD_GET(GLGEN_MAC_LINK_TOPO_LINK_TOPO_M, val);
|
|
||||||
|
|
||||||
return (mux && link_topo == ICE_LINK_TOPO_UP_TO_2_LINKS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ice_ptp_init_phy_e825c - initialize PHY parameters
|
|
||||||
* @hw: pointer to the HW struct
|
* @hw: pointer to the HW struct
|
||||||
*/
|
*/
|
||||||
static void ice_ptp_init_phy_e825c(struct ice_hw *hw)
|
static void ice_ptp_init_phy_e825(struct ice_hw *hw)
|
||||||
{
|
{
|
||||||
struct ice_ptp_hw *ptp = &hw->ptp;
|
struct ice_ptp_hw *ptp = &hw->ptp;
|
||||||
struct ice_eth56g_params *params;
|
struct ice_eth56g_params *params;
|
||||||
u8 phy;
|
u32 phy_rev;
|
||||||
|
int err;
|
||||||
|
|
||||||
ptp->phy_model = ICE_PHY_ETH56G;
|
ptp->phy_model = ICE_PHY_ETH56G;
|
||||||
params = &ptp->phy.eth56g;
|
params = &ptp->phy.eth56g;
|
||||||
params->onestep_ena = false;
|
params->onestep_ena = false;
|
||||||
params->peer_delay = 0;
|
params->peer_delay = 0;
|
||||||
params->sfd_ena = false;
|
params->sfd_ena = false;
|
||||||
params->phy_addr[0] = eth56g_phy_0;
|
|
||||||
params->phy_addr[1] = eth56g_phy_1;
|
|
||||||
params->num_phys = 2;
|
params->num_phys = 2;
|
||||||
ptp->ports_per_phy = 4;
|
ptp->ports_per_phy = 4;
|
||||||
ptp->num_lports = params->num_phys * ptp->ports_per_phy;
|
ptp->num_lports = params->num_phys * ptp->ports_per_phy;
|
||||||
|
|
||||||
ice_sb_access_ena_eth56g(hw, true);
|
ice_sb_access_ena_eth56g(hw, true);
|
||||||
for (phy = 0; phy < params->num_phys; phy++) {
|
err = ice_read_phy_eth56g(hw, hw->pf_id, PHY_REG_REVISION, &phy_rev);
|
||||||
u32 phy_rev;
|
if (err || phy_rev != PHY_REVISION_ETH56G)
|
||||||
int err;
|
ptp->phy_model = ICE_PHY_UNSUP;
|
||||||
|
|
||||||
err = ice_read_phy_eth56g(hw, phy, PHY_REG_REVISION, &phy_rev);
|
|
||||||
if (err || phy_rev != PHY_REVISION_ETH56G) {
|
|
||||||
ptp->phy_model = ICE_PHY_UNSUP;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ptp->is_2x50g_muxed_topo = ice_is_muxed_topo(hw);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* E822 family functions
|
/* E822 family functions
|
||||||
|
@ -2738,10 +2763,9 @@ static void ice_fill_phy_msg_e82x(struct ice_hw *hw,
|
||||||
struct ice_sbq_msg_input *msg, u8 port,
|
struct ice_sbq_msg_input *msg, u8 port,
|
||||||
u16 offset)
|
u16 offset)
|
||||||
{
|
{
|
||||||
int phy_port, phy, quadtype;
|
int phy_port, quadtype;
|
||||||
|
|
||||||
phy_port = port % hw->ptp.ports_per_phy;
|
phy_port = port % hw->ptp.ports_per_phy;
|
||||||
phy = port / hw->ptp.ports_per_phy;
|
|
||||||
quadtype = ICE_GET_QUAD_NUM(port) %
|
quadtype = ICE_GET_QUAD_NUM(port) %
|
||||||
ICE_GET_QUAD_NUM(hw->ptp.ports_per_phy);
|
ICE_GET_QUAD_NUM(hw->ptp.ports_per_phy);
|
||||||
|
|
||||||
|
@ -2753,12 +2777,7 @@ static void ice_fill_phy_msg_e82x(struct ice_hw *hw,
|
||||||
msg->msg_addr_high = P_Q1_H(P_4_BASE + offset, phy_port);
|
msg->msg_addr_high = P_Q1_H(P_4_BASE + offset, phy_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (phy == 0)
|
msg->dest_dev = rmn_0;
|
||||||
msg->dest_dev = rmn_0;
|
|
||||||
else if (phy == 1)
|
|
||||||
msg->dest_dev = rmn_1;
|
|
||||||
else
|
|
||||||
msg->dest_dev = rmn_2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5478,7 +5497,7 @@ void ice_ptp_init_hw(struct ice_hw *hw)
|
||||||
else if (ice_is_e810(hw))
|
else if (ice_is_e810(hw))
|
||||||
ice_ptp_init_phy_e810(ptp);
|
ice_ptp_init_phy_e810(ptp);
|
||||||
else if (ice_is_e825c(hw))
|
else if (ice_is_e825c(hw))
|
||||||
ice_ptp_init_phy_e825c(hw);
|
ice_ptp_init_phy_e825(hw);
|
||||||
else
|
else
|
||||||
ptp->phy_model = ICE_PHY_UNSUP;
|
ptp->phy_model = ICE_PHY_UNSUP;
|
||||||
}
|
}
|
||||||
|
|
|
@ -850,7 +850,6 @@ struct ice_mbx_data {
|
||||||
|
|
||||||
struct ice_eth56g_params {
|
struct ice_eth56g_params {
|
||||||
u8 num_phys;
|
u8 num_phys;
|
||||||
u8 phy_addr[2];
|
|
||||||
bool onestep_ena;
|
bool onestep_ena;
|
||||||
bool sfd_ena;
|
bool sfd_ena;
|
||||||
u32 peer_delay;
|
u32 peer_delay;
|
||||||
|
@ -881,7 +880,6 @@ struct ice_ptp_hw {
|
||||||
union ice_phy_params phy;
|
union ice_phy_params phy;
|
||||||
u8 num_lports;
|
u8 num_lports;
|
||||||
u8 ports_per_phy;
|
u8 ports_per_phy;
|
||||||
bool is_2x50g_muxed_topo;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Port hardware description */
|
/* Port hardware description */
|
||||||
|
|
|
@ -724,6 +724,12 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x,
|
||||||
/* check esn */
|
/* check esn */
|
||||||
if (x->props.flags & XFRM_STATE_ESN)
|
if (x->props.flags & XFRM_STATE_ESN)
|
||||||
mlx5e_ipsec_update_esn_state(sa_entry);
|
mlx5e_ipsec_update_esn_state(sa_entry);
|
||||||
|
else
|
||||||
|
/* According to RFC4303, section "3.3.3. Sequence Number Generation",
|
||||||
|
* the first packet sent using a given SA will contain a sequence
|
||||||
|
* number of 1.
|
||||||
|
*/
|
||||||
|
sa_entry->esn_state.esn = 1;
|
||||||
|
|
||||||
mlx5e_ipsec_build_accel_xfrm_attrs(sa_entry, &sa_entry->attrs);
|
mlx5e_ipsec_build_accel_xfrm_attrs(sa_entry, &sa_entry->attrs);
|
||||||
|
|
||||||
|
@ -768,9 +774,12 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x,
|
||||||
MLX5_IPSEC_RESCHED);
|
MLX5_IPSEC_RESCHED);
|
||||||
|
|
||||||
if (x->xso.type == XFRM_DEV_OFFLOAD_PACKET &&
|
if (x->xso.type == XFRM_DEV_OFFLOAD_PACKET &&
|
||||||
x->props.mode == XFRM_MODE_TUNNEL)
|
x->props.mode == XFRM_MODE_TUNNEL) {
|
||||||
xa_set_mark(&ipsec->sadb, sa_entry->ipsec_obj_id,
|
xa_lock_bh(&ipsec->sadb);
|
||||||
MLX5E_IPSEC_TUNNEL_SA);
|
__xa_set_mark(&ipsec->sadb, sa_entry->ipsec_obj_id,
|
||||||
|
MLX5E_IPSEC_TUNNEL_SA);
|
||||||
|
xa_unlock_bh(&ipsec->sadb);
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
x->xso.offload_handle = (unsigned long)sa_entry;
|
x->xso.offload_handle = (unsigned long)sa_entry;
|
||||||
|
@ -797,7 +806,6 @@ err_xfrm:
|
||||||
static void mlx5e_xfrm_del_state(struct xfrm_state *x)
|
static void mlx5e_xfrm_del_state(struct xfrm_state *x)
|
||||||
{
|
{
|
||||||
struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x);
|
struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x);
|
||||||
struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs;
|
|
||||||
struct mlx5e_ipsec *ipsec = sa_entry->ipsec;
|
struct mlx5e_ipsec *ipsec = sa_entry->ipsec;
|
||||||
struct mlx5e_ipsec_sa_entry *old;
|
struct mlx5e_ipsec_sa_entry *old;
|
||||||
|
|
||||||
|
@ -806,12 +814,6 @@ static void mlx5e_xfrm_del_state(struct xfrm_state *x)
|
||||||
|
|
||||||
old = xa_erase_bh(&ipsec->sadb, sa_entry->ipsec_obj_id);
|
old = xa_erase_bh(&ipsec->sadb, sa_entry->ipsec_obj_id);
|
||||||
WARN_ON(old != sa_entry);
|
WARN_ON(old != sa_entry);
|
||||||
|
|
||||||
if (attrs->mode == XFRM_MODE_TUNNEL &&
|
|
||||||
attrs->type == XFRM_DEV_OFFLOAD_PACKET)
|
|
||||||
/* Make sure that no ARP requests are running in parallel */
|
|
||||||
flush_workqueue(ipsec->wq);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mlx5e_xfrm_free_state(struct xfrm_state *x)
|
static void mlx5e_xfrm_free_state(struct xfrm_state *x)
|
||||||
|
|
|
@ -1718,23 +1718,21 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
|
||||||
goto err_alloc;
|
goto err_alloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attrs->family == AF_INET)
|
|
||||||
setup_fte_addr4(spec, &attrs->saddr.a4, &attrs->daddr.a4);
|
|
||||||
else
|
|
||||||
setup_fte_addr6(spec, attrs->saddr.a6, attrs->daddr.a6);
|
|
||||||
|
|
||||||
setup_fte_no_frags(spec);
|
setup_fte_no_frags(spec);
|
||||||
setup_fte_upper_proto_match(spec, &attrs->upspec);
|
setup_fte_upper_proto_match(spec, &attrs->upspec);
|
||||||
|
|
||||||
switch (attrs->type) {
|
switch (attrs->type) {
|
||||||
case XFRM_DEV_OFFLOAD_CRYPTO:
|
case XFRM_DEV_OFFLOAD_CRYPTO:
|
||||||
|
if (attrs->family == AF_INET)
|
||||||
|
setup_fte_addr4(spec, &attrs->saddr.a4, &attrs->daddr.a4);
|
||||||
|
else
|
||||||
|
setup_fte_addr6(spec, attrs->saddr.a6, attrs->daddr.a6);
|
||||||
setup_fte_spi(spec, attrs->spi, false);
|
setup_fte_spi(spec, attrs->spi, false);
|
||||||
setup_fte_esp(spec);
|
setup_fte_esp(spec);
|
||||||
setup_fte_reg_a(spec);
|
setup_fte_reg_a(spec);
|
||||||
break;
|
break;
|
||||||
case XFRM_DEV_OFFLOAD_PACKET:
|
case XFRM_DEV_OFFLOAD_PACKET:
|
||||||
if (attrs->reqid)
|
setup_fte_reg_c4(spec, attrs->reqid);
|
||||||
setup_fte_reg_c4(spec, attrs->reqid);
|
|
||||||
err = setup_pkt_reformat(ipsec, attrs, &flow_act);
|
err = setup_pkt_reformat(ipsec, attrs, &flow_act);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_pkt_reformat;
|
goto err_pkt_reformat;
|
||||||
|
|
|
@ -91,8 +91,9 @@ u32 mlx5_ipsec_device_caps(struct mlx5_core_dev *mdev)
|
||||||
EXPORT_SYMBOL_GPL(mlx5_ipsec_device_caps);
|
EXPORT_SYMBOL_GPL(mlx5_ipsec_device_caps);
|
||||||
|
|
||||||
static void mlx5e_ipsec_packet_setup(void *obj, u32 pdn,
|
static void mlx5e_ipsec_packet_setup(void *obj, u32 pdn,
|
||||||
struct mlx5_accel_esp_xfrm_attrs *attrs)
|
struct mlx5e_ipsec_sa_entry *sa_entry)
|
||||||
{
|
{
|
||||||
|
struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs;
|
||||||
void *aso_ctx;
|
void *aso_ctx;
|
||||||
|
|
||||||
aso_ctx = MLX5_ADDR_OF(ipsec_obj, obj, ipsec_aso);
|
aso_ctx = MLX5_ADDR_OF(ipsec_obj, obj, ipsec_aso);
|
||||||
|
@ -120,8 +121,12 @@ static void mlx5e_ipsec_packet_setup(void *obj, u32 pdn,
|
||||||
* active.
|
* active.
|
||||||
*/
|
*/
|
||||||
MLX5_SET(ipsec_obj, obj, aso_return_reg, MLX5_IPSEC_ASO_REG_C_4_5);
|
MLX5_SET(ipsec_obj, obj, aso_return_reg, MLX5_IPSEC_ASO_REG_C_4_5);
|
||||||
if (attrs->dir == XFRM_DEV_OFFLOAD_OUT)
|
if (attrs->dir == XFRM_DEV_OFFLOAD_OUT) {
|
||||||
MLX5_SET(ipsec_aso, aso_ctx, mode, MLX5_IPSEC_ASO_INC_SN);
|
MLX5_SET(ipsec_aso, aso_ctx, mode, MLX5_IPSEC_ASO_INC_SN);
|
||||||
|
if (!attrs->replay_esn.trigger)
|
||||||
|
MLX5_SET(ipsec_aso, aso_ctx, mode_parameter,
|
||||||
|
sa_entry->esn_state.esn);
|
||||||
|
}
|
||||||
|
|
||||||
if (attrs->lft.hard_packet_limit != XFRM_INF) {
|
if (attrs->lft.hard_packet_limit != XFRM_INF) {
|
||||||
MLX5_SET(ipsec_aso, aso_ctx, remove_flow_pkt_cnt,
|
MLX5_SET(ipsec_aso, aso_ctx, remove_flow_pkt_cnt,
|
||||||
|
@ -175,7 +180,7 @@ static int mlx5_create_ipsec_obj(struct mlx5e_ipsec_sa_entry *sa_entry)
|
||||||
|
|
||||||
res = &mdev->mlx5e_res.hw_objs;
|
res = &mdev->mlx5e_res.hw_objs;
|
||||||
if (attrs->type == XFRM_DEV_OFFLOAD_PACKET)
|
if (attrs->type == XFRM_DEV_OFFLOAD_PACKET)
|
||||||
mlx5e_ipsec_packet_setup(obj, res->pdn, attrs);
|
mlx5e_ipsec_packet_setup(obj, res->pdn, sa_entry);
|
||||||
|
|
||||||
err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
|
err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
|
||||||
if (!err)
|
if (!err)
|
||||||
|
|
|
@ -2709,6 +2709,7 @@ struct mlx5_flow_namespace *mlx5_get_flow_namespace(struct mlx5_core_dev *dev,
|
||||||
break;
|
break;
|
||||||
case MLX5_FLOW_NAMESPACE_RDMA_TX:
|
case MLX5_FLOW_NAMESPACE_RDMA_TX:
|
||||||
root_ns = steering->rdma_tx_root_ns;
|
root_ns = steering->rdma_tx_root_ns;
|
||||||
|
prio = RDMA_TX_BYPASS_PRIO;
|
||||||
break;
|
break;
|
||||||
case MLX5_FLOW_NAMESPACE_RDMA_RX_COUNTERS:
|
case MLX5_FLOW_NAMESPACE_RDMA_RX_COUNTERS:
|
||||||
root_ns = steering->rdma_rx_root_ns;
|
root_ns = steering->rdma_rx_root_ns;
|
||||||
|
|
|
@ -530,7 +530,7 @@ int mlx5_lag_port_sel_create(struct mlx5_lag *ldev,
|
||||||
set_tt_map(port_sel, hash_type);
|
set_tt_map(port_sel, hash_type);
|
||||||
err = mlx5_lag_create_definers(ldev, hash_type, ports);
|
err = mlx5_lag_create_definers(ldev, hash_type, ports);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
goto clear_port_sel;
|
||||||
|
|
||||||
if (port_sel->tunnel) {
|
if (port_sel->tunnel) {
|
||||||
err = mlx5_lag_create_inner_ttc_table(ldev);
|
err = mlx5_lag_create_inner_ttc_table(ldev);
|
||||||
|
@ -549,6 +549,8 @@ destroy_inner:
|
||||||
mlx5_destroy_ttc_table(port_sel->inner.ttc);
|
mlx5_destroy_ttc_table(port_sel->inner.ttc);
|
||||||
destroy_definers:
|
destroy_definers:
|
||||||
mlx5_lag_destroy_definers(ldev);
|
mlx5_lag_destroy_definers(ldev);
|
||||||
|
clear_port_sel:
|
||||||
|
memset(port_sel, 0, sizeof(*port_sel));
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -257,6 +257,7 @@ static int mlx5_sf_add(struct mlx5_core_dev *dev, struct mlx5_sf_table *table,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
esw_err:
|
esw_err:
|
||||||
|
mlx5_sf_function_id_erase(table, sf);
|
||||||
mlx5_sf_free(table, sf);
|
mlx5_sf_free(table, sf);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -382,6 +382,7 @@ err_alloc_bfreg:
|
||||||
|
|
||||||
bool mlx5_wc_support_get(struct mlx5_core_dev *mdev)
|
bool mlx5_wc_support_get(struct mlx5_core_dev *mdev)
|
||||||
{
|
{
|
||||||
|
struct mutex *wc_state_lock = &mdev->wc_state_lock;
|
||||||
struct mlx5_core_dev *parent = NULL;
|
struct mlx5_core_dev *parent = NULL;
|
||||||
|
|
||||||
if (!MLX5_CAP_GEN(mdev, bf)) {
|
if (!MLX5_CAP_GEN(mdev, bf)) {
|
||||||
|
@ -400,32 +401,31 @@ bool mlx5_wc_support_get(struct mlx5_core_dev *mdev)
|
||||||
*/
|
*/
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
mutex_lock(&mdev->wc_state_lock);
|
#ifdef CONFIG_MLX5_SF
|
||||||
|
if (mlx5_core_is_sf(mdev)) {
|
||||||
|
parent = mdev->priv.parent_mdev;
|
||||||
|
wc_state_lock = &parent->wc_state_lock;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mutex_lock(wc_state_lock);
|
||||||
|
|
||||||
if (mdev->wc_state != MLX5_WC_STATE_UNINITIALIZED)
|
if (mdev->wc_state != MLX5_WC_STATE_UNINITIALIZED)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
#ifdef CONFIG_MLX5_SF
|
|
||||||
if (mlx5_core_is_sf(mdev))
|
|
||||||
parent = mdev->priv.parent_mdev;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
mutex_lock(&parent->wc_state_lock);
|
|
||||||
|
|
||||||
mlx5_core_test_wc(parent);
|
mlx5_core_test_wc(parent);
|
||||||
|
|
||||||
mlx5_core_dbg(mdev, "parent set wc_state=%d\n",
|
mlx5_core_dbg(mdev, "parent set wc_state=%d\n",
|
||||||
parent->wc_state);
|
parent->wc_state);
|
||||||
mdev->wc_state = parent->wc_state;
|
mdev->wc_state = parent->wc_state;
|
||||||
|
|
||||||
mutex_unlock(&parent->wc_state_lock);
|
} else {
|
||||||
|
mlx5_core_test_wc(mdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
mlx5_core_test_wc(mdev);
|
|
||||||
|
|
||||||
unlock:
|
unlock:
|
||||||
mutex_unlock(&mdev->wc_state_lock);
|
mutex_unlock(wc_state_lock);
|
||||||
out:
|
out:
|
||||||
mlx5_core_dbg(mdev, "wc_state=%d\n", mdev->wc_state);
|
mlx5_core_dbg(mdev, "wc_state=%d\n", mdev->wc_state);
|
||||||
|
|
||||||
|
|
|
@ -1656,9 +1656,9 @@ static int __init mana_driver_init(void)
|
||||||
|
|
||||||
static void __exit mana_driver_exit(void)
|
static void __exit mana_driver_exit(void)
|
||||||
{
|
{
|
||||||
debugfs_remove(mana_debugfs_root);
|
|
||||||
|
|
||||||
pci_unregister_driver(&mana_driver);
|
pci_unregister_driver(&mana_driver);
|
||||||
|
|
||||||
|
debugfs_remove(mana_debugfs_root);
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(mana_driver_init);
|
module_init(mana_driver_init);
|
||||||
|
|
|
@ -458,7 +458,8 @@ int nfp_bpf_event_output(struct nfp_app_bpf *bpf, const void *data,
|
||||||
map_id_full = be64_to_cpu(cbe->map_ptr);
|
map_id_full = be64_to_cpu(cbe->map_ptr);
|
||||||
map_id = map_id_full;
|
map_id = map_id_full;
|
||||||
|
|
||||||
if (len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size)
|
if (size_add(pkt_size, data_size) > INT_MAX ||
|
||||||
|
len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (cbe->hdr.ver != NFP_CCM_ABI_VERSION)
|
if (cbe->hdr.ver != NFP_CCM_ABI_VERSION)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/ethtool.h>
|
#include <linux/ethtool.h>
|
||||||
#include <linux/hwmon.h>
|
|
||||||
#include <linux/phy.h>
|
#include <linux/phy.h>
|
||||||
#include <linux/if_vlan.h>
|
#include <linux/if_vlan.h>
|
||||||
#include <linux/in.h>
|
#include <linux/in.h>
|
||||||
|
@ -5347,43 +5346,6 @@ static bool rtl_aspm_is_safe(struct rtl8169_private *tp)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static umode_t r8169_hwmon_is_visible(const void *drvdata,
|
|
||||||
enum hwmon_sensor_types type,
|
|
||||||
u32 attr, int channel)
|
|
||||||
{
|
|
||||||
return 0444;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int r8169_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
|
|
||||||
u32 attr, int channel, long *val)
|
|
||||||
{
|
|
||||||
struct rtl8169_private *tp = dev_get_drvdata(dev);
|
|
||||||
int val_raw;
|
|
||||||
|
|
||||||
val_raw = phy_read_paged(tp->phydev, 0xbd8, 0x12) & 0x3ff;
|
|
||||||
if (val_raw >= 512)
|
|
||||||
val_raw -= 1024;
|
|
||||||
|
|
||||||
*val = 1000 * val_raw / 2;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct hwmon_ops r8169_hwmon_ops = {
|
|
||||||
.is_visible = r8169_hwmon_is_visible,
|
|
||||||
.read = r8169_hwmon_read,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct hwmon_channel_info * const r8169_hwmon_info[] = {
|
|
||||||
HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct hwmon_chip_info r8169_hwmon_chip_info = {
|
|
||||||
.ops = &r8169_hwmon_ops,
|
|
||||||
.info = r8169_hwmon_info,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
{
|
{
|
||||||
struct rtl8169_private *tp;
|
struct rtl8169_private *tp;
|
||||||
|
@ -5563,12 +5525,6 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
/* The temperature sensor is available from RTl8125B */
|
|
||||||
if (IS_REACHABLE(CONFIG_HWMON) && tp->mac_version >= RTL_GIGA_MAC_VER_63)
|
|
||||||
/* ignore errors */
|
|
||||||
devm_hwmon_device_register_with_info(&pdev->dev, "nic_temp", tp,
|
|
||||||
&r8169_hwmon_chip_info,
|
|
||||||
NULL);
|
|
||||||
rc = register_netdev(dev);
|
rc = register_netdev(dev);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
@ -2763,6 +2763,7 @@ static const struct ravb_hw_info ravb_rzv2m_hw_info = {
|
||||||
.net_features = NETIF_F_RXCSUM,
|
.net_features = NETIF_F_RXCSUM,
|
||||||
.stats_len = ARRAY_SIZE(ravb_gstrings_stats),
|
.stats_len = ARRAY_SIZE(ravb_gstrings_stats),
|
||||||
.tccr_mask = TCCR_TSRQ0 | TCCR_TSRQ1 | TCCR_TSRQ2 | TCCR_TSRQ3,
|
.tccr_mask = TCCR_TSRQ0 | TCCR_TSRQ1 | TCCR_TSRQ2 | TCCR_TSRQ3,
|
||||||
|
.tx_max_frame_size = SZ_2K,
|
||||||
.rx_max_frame_size = SZ_2K,
|
.rx_max_frame_size = SZ_2K,
|
||||||
.rx_buffer_size = SZ_2K +
|
.rx_buffer_size = SZ_2K +
|
||||||
SKB_DATA_ALIGN(sizeof(struct skb_shared_info)),
|
SKB_DATA_ALIGN(sizeof(struct skb_shared_info)),
|
||||||
|
|
|
@ -127,15 +127,15 @@ struct cpsw_ale_dev_id {
|
||||||
|
|
||||||
static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
|
static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
|
||||||
{
|
{
|
||||||
int idx, idx2;
|
int idx, idx2, index;
|
||||||
u32 hi_val = 0;
|
u32 hi_val = 0;
|
||||||
|
|
||||||
idx = start / 32;
|
idx = start / 32;
|
||||||
idx2 = (start + bits - 1) / 32;
|
idx2 = (start + bits - 1) / 32;
|
||||||
/* Check if bits to be fetched exceed a word */
|
/* Check if bits to be fetched exceed a word */
|
||||||
if (idx != idx2) {
|
if (idx != idx2) {
|
||||||
idx2 = 2 - idx2; /* flip */
|
index = 2 - idx2; /* flip */
|
||||||
hi_val = ale_entry[idx2] << ((idx2 * 32) - start);
|
hi_val = ale_entry[index] << ((idx2 * 32) - start);
|
||||||
}
|
}
|
||||||
start -= idx * 32;
|
start -= idx * 32;
|
||||||
idx = 2 - idx; /* flip */
|
idx = 2 - idx; /* flip */
|
||||||
|
@ -145,16 +145,16 @@ static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
|
||||||
static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits,
|
static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits,
|
||||||
u32 value)
|
u32 value)
|
||||||
{
|
{
|
||||||
int idx, idx2;
|
int idx, idx2, index;
|
||||||
|
|
||||||
value &= BITMASK(bits);
|
value &= BITMASK(bits);
|
||||||
idx = start / 32;
|
idx = start / 32;
|
||||||
idx2 = (start + bits - 1) / 32;
|
idx2 = (start + bits - 1) / 32;
|
||||||
/* Check if bits to be set exceed a word */
|
/* Check if bits to be set exceed a word */
|
||||||
if (idx != idx2) {
|
if (idx != idx2) {
|
||||||
idx2 = 2 - idx2; /* flip */
|
index = 2 - idx2; /* flip */
|
||||||
ale_entry[idx2] &= ~(BITMASK(bits + start - (idx2 * 32)));
|
ale_entry[index] &= ~(BITMASK(bits + start - (idx2 * 32)));
|
||||||
ale_entry[idx2] |= (value >> ((idx2 * 32) - start));
|
ale_entry[index] |= (value >> ((idx2 * 32) - start));
|
||||||
}
|
}
|
||||||
start -= idx * 32;
|
start -= idx * 32;
|
||||||
idx = 2 - idx; /* flip */
|
idx = 2 - idx; /* flip */
|
||||||
|
|
|
@ -2056,6 +2056,12 @@ axienet_ethtools_set_coalesce(struct net_device *ndev,
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ecoalesce->rx_max_coalesced_frames > 255 ||
|
||||||
|
ecoalesce->tx_max_coalesced_frames > 255) {
|
||||||
|
NL_SET_ERR_MSG(extack, "frames must be less than 256");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (ecoalesce->rx_max_coalesced_frames)
|
if (ecoalesce->rx_max_coalesced_frames)
|
||||||
lp->coalesce_count_rx = ecoalesce->rx_max_coalesced_frames;
|
lp->coalesce_count_rx = ecoalesce->rx_max_coalesced_frames;
|
||||||
if (ecoalesce->rx_coalesce_usecs)
|
if (ecoalesce->rx_coalesce_usecs)
|
||||||
|
|
|
@ -1524,8 +1524,8 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev,
|
||||||
goto out_encap;
|
goto out_encap;
|
||||||
}
|
}
|
||||||
|
|
||||||
gn = net_generic(dev_net(dev), gtp_net_id);
|
gn = net_generic(src_net, gtp_net_id);
|
||||||
list_add_rcu(>p->list, &gn->gtp_dev_list);
|
list_add(>p->list, &gn->gtp_dev_list);
|
||||||
dev->priv_destructor = gtp_destructor;
|
dev->priv_destructor = gtp_destructor;
|
||||||
|
|
||||||
netdev_dbg(dev, "registered new GTP interface\n");
|
netdev_dbg(dev, "registered new GTP interface\n");
|
||||||
|
@ -1551,7 +1551,7 @@ static void gtp_dellink(struct net_device *dev, struct list_head *head)
|
||||||
hlist_for_each_entry_safe(pctx, next, >p->tid_hash[i], hlist_tid)
|
hlist_for_each_entry_safe(pctx, next, >p->tid_hash[i], hlist_tid)
|
||||||
pdp_context_delete(pctx);
|
pdp_context_delete(pctx);
|
||||||
|
|
||||||
list_del_rcu(>p->list);
|
list_del(>p->list);
|
||||||
unregister_netdevice_queue(dev, head);
|
unregister_netdevice_queue(dev, head);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2271,16 +2271,19 @@ static int gtp_genl_dump_pdp(struct sk_buff *skb,
|
||||||
struct gtp_dev *last_gtp = (struct gtp_dev *)cb->args[2], *gtp;
|
struct gtp_dev *last_gtp = (struct gtp_dev *)cb->args[2], *gtp;
|
||||||
int i, j, bucket = cb->args[0], skip = cb->args[1];
|
int i, j, bucket = cb->args[0], skip = cb->args[1];
|
||||||
struct net *net = sock_net(skb->sk);
|
struct net *net = sock_net(skb->sk);
|
||||||
|
struct net_device *dev;
|
||||||
struct pdp_ctx *pctx;
|
struct pdp_ctx *pctx;
|
||||||
struct gtp_net *gn;
|
|
||||||
|
|
||||||
gn = net_generic(net, gtp_net_id);
|
|
||||||
|
|
||||||
if (cb->args[4])
|
if (cb->args[4])
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
list_for_each_entry_rcu(gtp, &gn->gtp_dev_list, list) {
|
for_each_netdev_rcu(net, dev) {
|
||||||
|
if (dev->rtnl_link_ops != >p_link_ops)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
gtp = netdev_priv(dev);
|
||||||
|
|
||||||
if (last_gtp && last_gtp != gtp)
|
if (last_gtp && last_gtp != gtp)
|
||||||
continue;
|
continue;
|
||||||
else
|
else
|
||||||
|
@ -2475,9 +2478,14 @@ static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list,
|
||||||
|
|
||||||
list_for_each_entry(net, net_list, exit_list) {
|
list_for_each_entry(net, net_list, exit_list) {
|
||||||
struct gtp_net *gn = net_generic(net, gtp_net_id);
|
struct gtp_net *gn = net_generic(net, gtp_net_id);
|
||||||
struct gtp_dev *gtp;
|
struct gtp_dev *gtp, *gtp_next;
|
||||||
|
struct net_device *dev;
|
||||||
|
|
||||||
list_for_each_entry(gtp, &gn->gtp_dev_list, list)
|
for_each_netdev(net, dev)
|
||||||
|
if (dev->rtnl_link_ops == >p_link_ops)
|
||||||
|
gtp_dellink(dev, dev_to_kill);
|
||||||
|
|
||||||
|
list_for_each_entry_safe(gtp, gtp_next, &gn->gtp_dev_list, list)
|
||||||
gtp_dellink(gtp->dev, dev_to_kill);
|
gtp_dellink(gtp->dev, dev_to_kill);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -684,7 +684,9 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs,
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
mask = DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
|
val = 0;
|
||||||
|
mask = DW_VR_MII_DIG_CTRL1_2G5_EN | DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
|
||||||
|
|
||||||
if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
|
if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED)
|
||||||
val = DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
|
val = DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
|
||||||
|
|
||||||
|
|
|
@ -206,8 +206,8 @@ static int pfcp_newlink(struct net *net, struct net_device *dev,
|
||||||
goto exit_del_pfcp_sock;
|
goto exit_del_pfcp_sock;
|
||||||
}
|
}
|
||||||
|
|
||||||
pn = net_generic(dev_net(dev), pfcp_net_id);
|
pn = net_generic(net, pfcp_net_id);
|
||||||
list_add_rcu(&pfcp->list, &pn->pfcp_dev_list);
|
list_add(&pfcp->list, &pn->pfcp_dev_list);
|
||||||
|
|
||||||
netdev_dbg(dev, "registered new PFCP interface\n");
|
netdev_dbg(dev, "registered new PFCP interface\n");
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ static void pfcp_dellink(struct net_device *dev, struct list_head *head)
|
||||||
{
|
{
|
||||||
struct pfcp_dev *pfcp = netdev_priv(dev);
|
struct pfcp_dev *pfcp = netdev_priv(dev);
|
||||||
|
|
||||||
list_del_rcu(&pfcp->list);
|
list_del(&pfcp->list);
|
||||||
unregister_netdevice_queue(dev, head);
|
unregister_netdevice_queue(dev, head);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,11 +247,16 @@ static int __net_init pfcp_net_init(struct net *net)
|
||||||
static void __net_exit pfcp_net_exit(struct net *net)
|
static void __net_exit pfcp_net_exit(struct net *net)
|
||||||
{
|
{
|
||||||
struct pfcp_net *pn = net_generic(net, pfcp_net_id);
|
struct pfcp_net *pn = net_generic(net, pfcp_net_id);
|
||||||
struct pfcp_dev *pfcp;
|
struct pfcp_dev *pfcp, *pfcp_next;
|
||||||
|
struct net_device *dev;
|
||||||
LIST_HEAD(list);
|
LIST_HEAD(list);
|
||||||
|
|
||||||
rtnl_lock();
|
rtnl_lock();
|
||||||
list_for_each_entry(pfcp, &pn->pfcp_dev_list, list)
|
for_each_netdev(net, dev)
|
||||||
|
if (dev->rtnl_link_ops == &pfcp_link_ops)
|
||||||
|
pfcp_dellink(dev, &list);
|
||||||
|
|
||||||
|
list_for_each_entry_safe(pfcp, pfcp_next, &pn->pfcp_dev_list, list)
|
||||||
pfcp_dellink(pfcp->dev, &list);
|
pfcp_dellink(pfcp->dev, &list);
|
||||||
|
|
||||||
unregister_netdevice_many(&list);
|
unregister_netdevice_many(&list);
|
||||||
|
|
|
@ -174,12 +174,4 @@ static inline void sk_mark_napi_id_once(struct sock *sk,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sk_mark_napi_id_once_xdp(struct sock *sk,
|
|
||||||
const struct xdp_buff *xdp)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_NET_RX_BUSY_POLL
|
|
||||||
__sk_mark_napi_id_once(sk, xdp->rxq->napi_id);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* _LINUX_NET_BUSY_POLL_H */
|
#endif /* _LINUX_NET_BUSY_POLL_H */
|
||||||
|
|
|
@ -294,7 +294,7 @@ static inline long page_pool_unref_page(struct page *page, long nr)
|
||||||
|
|
||||||
static inline void page_pool_ref_netmem(netmem_ref netmem)
|
static inline void page_pool_ref_netmem(netmem_ref netmem)
|
||||||
{
|
{
|
||||||
atomic_long_inc(&netmem_to_page(netmem)->pp_ref_count);
|
atomic_long_inc(netmem_get_pp_ref_count_ref(netmem));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void page_pool_ref_page(struct page *page)
|
static inline void page_pool_ref_page(struct page *page)
|
||||||
|
|
|
@ -62,7 +62,6 @@ struct xdp_rxq_info {
|
||||||
u32 queue_index;
|
u32 queue_index;
|
||||||
u32 reg_state;
|
u32 reg_state;
|
||||||
struct xdp_mem_info mem;
|
struct xdp_mem_info mem;
|
||||||
unsigned int napi_id;
|
|
||||||
u32 frag_size;
|
u32 frag_size;
|
||||||
} ____cacheline_aligned; /* perf critical, avoid false-sharing */
|
} ____cacheline_aligned; /* perf critical, avoid false-sharing */
|
||||||
|
|
||||||
|
|
|
@ -59,15 +59,6 @@ static inline void xsk_pool_fill_cb(struct xsk_buff_pool *pool,
|
||||||
xp_fill_cb(pool, desc);
|
xp_fill_cb(pool, desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned int xsk_pool_get_napi_id(struct xsk_buff_pool *pool)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_NET_RX_BUSY_POLL
|
|
||||||
return pool->heads[0].xdp.rxq->napi_id;
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void xsk_pool_dma_unmap(struct xsk_buff_pool *pool,
|
static inline void xsk_pool_dma_unmap(struct xsk_buff_pool *pool,
|
||||||
unsigned long attrs)
|
unsigned long attrs)
|
||||||
{
|
{
|
||||||
|
@ -306,11 +297,6 @@ static inline void xsk_pool_fill_cb(struct xsk_buff_pool *pool,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned int xsk_pool_get_napi_id(struct xsk_buff_pool *pool)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void xsk_pool_dma_unmap(struct xsk_buff_pool *pool,
|
static inline void xsk_pool_dma_unmap(struct xsk_buff_pool *pool,
|
||||||
unsigned long attrs)
|
unsigned long attrs)
|
||||||
{
|
{
|
||||||
|
|
|
@ -11251,6 +11251,7 @@ BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern,
|
||||||
bool is_sockarray = map->map_type == BPF_MAP_TYPE_REUSEPORT_SOCKARRAY;
|
bool is_sockarray = map->map_type == BPF_MAP_TYPE_REUSEPORT_SOCKARRAY;
|
||||||
struct sock_reuseport *reuse;
|
struct sock_reuseport *reuse;
|
||||||
struct sock *selected_sk;
|
struct sock *selected_sk;
|
||||||
|
int err;
|
||||||
|
|
||||||
selected_sk = map->ops->map_lookup_elem(map, key);
|
selected_sk = map->ops->map_lookup_elem(map, key);
|
||||||
if (!selected_sk)
|
if (!selected_sk)
|
||||||
|
@ -11258,10 +11259,6 @@ BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern,
|
||||||
|
|
||||||
reuse = rcu_dereference(selected_sk->sk_reuseport_cb);
|
reuse = rcu_dereference(selected_sk->sk_reuseport_cb);
|
||||||
if (!reuse) {
|
if (!reuse) {
|
||||||
/* Lookup in sock_map can return TCP ESTABLISHED sockets. */
|
|
||||||
if (sk_is_refcounted(selected_sk))
|
|
||||||
sock_put(selected_sk);
|
|
||||||
|
|
||||||
/* reuseport_array has only sk with non NULL sk_reuseport_cb.
|
/* reuseport_array has only sk with non NULL sk_reuseport_cb.
|
||||||
* The only (!reuse) case here is - the sk has already been
|
* The only (!reuse) case here is - the sk has already been
|
||||||
* unhashed (e.g. by close()), so treat it as -ENOENT.
|
* unhashed (e.g. by close()), so treat it as -ENOENT.
|
||||||
|
@ -11269,24 +11266,33 @@ BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern,
|
||||||
* Other maps (e.g. sock_map) do not provide this guarantee and
|
* Other maps (e.g. sock_map) do not provide this guarantee and
|
||||||
* the sk may never be in the reuseport group to begin with.
|
* the sk may never be in the reuseport group to begin with.
|
||||||
*/
|
*/
|
||||||
return is_sockarray ? -ENOENT : -EINVAL;
|
err = is_sockarray ? -ENOENT : -EINVAL;
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(reuse->reuseport_id != reuse_kern->reuseport_id)) {
|
if (unlikely(reuse->reuseport_id != reuse_kern->reuseport_id)) {
|
||||||
struct sock *sk = reuse_kern->sk;
|
struct sock *sk = reuse_kern->sk;
|
||||||
|
|
||||||
if (sk->sk_protocol != selected_sk->sk_protocol)
|
if (sk->sk_protocol != selected_sk->sk_protocol) {
|
||||||
return -EPROTOTYPE;
|
err = -EPROTOTYPE;
|
||||||
else if (sk->sk_family != selected_sk->sk_family)
|
} else if (sk->sk_family != selected_sk->sk_family) {
|
||||||
return -EAFNOSUPPORT;
|
err = -EAFNOSUPPORT;
|
||||||
|
} else {
|
||||||
/* Catch all. Likely bound to a different sockaddr. */
|
/* Catch all. Likely bound to a different sockaddr. */
|
||||||
return -EBADFD;
|
err = -EBADFD;
|
||||||
|
}
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
reuse_kern->selected_sk = selected_sk;
|
reuse_kern->selected_sk = selected_sk;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
error:
|
||||||
|
/* Lookup in sock_map can return TCP ESTABLISHED sockets. */
|
||||||
|
if (sk_is_refcounted(selected_sk))
|
||||||
|
sock_put(selected_sk);
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct bpf_func_proto sk_select_reuseport_proto = {
|
static const struct bpf_func_proto sk_select_reuseport_proto = {
|
||||||
|
|
|
@ -197,6 +197,16 @@ static const struct genl_multicast_group netdev_nl_mcgrps[] = {
|
||||||
[NETDEV_NLGRP_PAGE_POOL] = { "page-pool", },
|
[NETDEV_NLGRP_PAGE_POOL] = { "page-pool", },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void __netdev_nl_sock_priv_init(void *priv)
|
||||||
|
{
|
||||||
|
netdev_nl_sock_priv_init(priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __netdev_nl_sock_priv_destroy(void *priv)
|
||||||
|
{
|
||||||
|
netdev_nl_sock_priv_destroy(priv);
|
||||||
|
}
|
||||||
|
|
||||||
struct genl_family netdev_nl_family __ro_after_init = {
|
struct genl_family netdev_nl_family __ro_after_init = {
|
||||||
.name = NETDEV_FAMILY_NAME,
|
.name = NETDEV_FAMILY_NAME,
|
||||||
.version = NETDEV_FAMILY_VERSION,
|
.version = NETDEV_FAMILY_VERSION,
|
||||||
|
@ -208,6 +218,6 @@ struct genl_family netdev_nl_family __ro_after_init = {
|
||||||
.mcgrps = netdev_nl_mcgrps,
|
.mcgrps = netdev_nl_mcgrps,
|
||||||
.n_mcgrps = ARRAY_SIZE(netdev_nl_mcgrps),
|
.n_mcgrps = ARRAY_SIZE(netdev_nl_mcgrps),
|
||||||
.sock_priv_size = sizeof(struct list_head),
|
.sock_priv_size = sizeof(struct list_head),
|
||||||
.sock_priv_init = (void *)netdev_nl_sock_priv_init,
|
.sock_priv_init = __netdev_nl_sock_priv_init,
|
||||||
.sock_priv_destroy = (void *)netdev_nl_sock_priv_destroy,
|
.sock_priv_destroy = __netdev_nl_sock_priv_destroy,
|
||||||
};
|
};
|
||||||
|
|
|
@ -627,6 +627,8 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev)
|
||||||
const struct net_device_ops *ops;
|
const struct net_device_ops *ops;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
skb_queue_head_init(&np->skb_pool);
|
||||||
|
|
||||||
if (ndev->priv_flags & IFF_DISABLE_NETPOLL) {
|
if (ndev->priv_flags & IFF_DISABLE_NETPOLL) {
|
||||||
np_err(np, "%s doesn't support polling, aborting\n",
|
np_err(np, "%s doesn't support polling, aborting\n",
|
||||||
ndev->name);
|
ndev->name);
|
||||||
|
@ -662,6 +664,9 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev)
|
||||||
strscpy(np->dev_name, ndev->name, IFNAMSIZ);
|
strscpy(np->dev_name, ndev->name, IFNAMSIZ);
|
||||||
npinfo->netpoll = np;
|
npinfo->netpoll = np;
|
||||||
|
|
||||||
|
/* fill up the skb queue */
|
||||||
|
refill_skbs(np);
|
||||||
|
|
||||||
/* last thing to do is link it to the net device structure */
|
/* last thing to do is link it to the net device structure */
|
||||||
rcu_assign_pointer(ndev->npinfo, npinfo);
|
rcu_assign_pointer(ndev->npinfo, npinfo);
|
||||||
|
|
||||||
|
@ -681,8 +686,6 @@ int netpoll_setup(struct netpoll *np)
|
||||||
struct in_device *in_dev;
|
struct in_device *in_dev;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
skb_queue_head_init(&np->skb_pool);
|
|
||||||
|
|
||||||
rtnl_lock();
|
rtnl_lock();
|
||||||
if (np->dev_name[0]) {
|
if (np->dev_name[0]) {
|
||||||
struct net *net = current->nsproxy->net_ns;
|
struct net *net = current->nsproxy->net_ns;
|
||||||
|
@ -782,9 +785,6 @@ put_noaddr:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fill up the skb queue */
|
|
||||||
refill_skbs(np);
|
|
||||||
|
|
||||||
err = __netpoll_setup(np, ndev);
|
err = __netpoll_setup(np, ndev);
|
||||||
if (err)
|
if (err)
|
||||||
goto flush;
|
goto flush;
|
||||||
|
|
|
@ -851,6 +851,9 @@ static ssize_t get_imix_entries(const char __user *buffer,
|
||||||
unsigned long weight;
|
unsigned long weight;
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
|
|
||||||
|
if (pkt_dev->n_imix_entries >= MAX_IMIX_ENTRIES)
|
||||||
|
return -E2BIG;
|
||||||
|
|
||||||
len = num_arg(&buffer[i], max_digits, &size);
|
len = num_arg(&buffer[i], max_digits, &size);
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
return len;
|
return len;
|
||||||
|
@ -880,9 +883,6 @@ static ssize_t get_imix_entries(const char __user *buffer,
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
pkt_dev->n_imix_entries++;
|
pkt_dev->n_imix_entries++;
|
||||||
|
|
||||||
if (pkt_dev->n_imix_entries > MAX_IMIX_ENTRIES)
|
|
||||||
return -E2BIG;
|
|
||||||
} while (c == ' ');
|
} while (c == ' ');
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
|
|
|
@ -186,7 +186,6 @@ int __xdp_rxq_info_reg(struct xdp_rxq_info *xdp_rxq,
|
||||||
xdp_rxq_info_init(xdp_rxq);
|
xdp_rxq_info_init(xdp_rxq);
|
||||||
xdp_rxq->dev = dev;
|
xdp_rxq->dev = dev;
|
||||||
xdp_rxq->queue_index = queue_index;
|
xdp_rxq->queue_index = queue_index;
|
||||||
xdp_rxq->napi_id = napi_id;
|
|
||||||
xdp_rxq->frag_size = frag_size;
|
xdp_rxq->frag_size = frag_size;
|
||||||
|
|
||||||
xdp_rxq->reg_state = REG_STATE_REGISTERED;
|
xdp_rxq->reg_state = REG_STATE_REGISTERED;
|
||||||
|
|
|
@ -2445,6 +2445,7 @@ martian_destination:
|
||||||
net_warn_ratelimited("martian destination %pI4 from %pI4, dev %s\n",
|
net_warn_ratelimited("martian destination %pI4 from %pI4, dev %s\n",
|
||||||
&daddr, &saddr, dev->name);
|
&daddr, &saddr, dev->name);
|
||||||
#endif
|
#endif
|
||||||
|
goto out;
|
||||||
|
|
||||||
e_nobufs:
|
e_nobufs:
|
||||||
reason = SKB_DROP_REASON_NOMEM;
|
reason = SKB_DROP_REASON_NOMEM;
|
||||||
|
|
|
@ -533,7 +533,7 @@ begin:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In hash4, rehash can happen in connect(), where hash4_cnt keeps unchanged. */
|
/* udp_rehash4() only checks hslot4, and hash4_cnt is not processed. */
|
||||||
static void udp_rehash4(struct udp_table *udptable, struct sock *sk,
|
static void udp_rehash4(struct udp_table *udptable, struct sock *sk,
|
||||||
u16 newhash4)
|
u16 newhash4)
|
||||||
{
|
{
|
||||||
|
@ -582,15 +582,13 @@ void udp_lib_hash4(struct sock *sk, u16 hash)
|
||||||
struct net *net = sock_net(sk);
|
struct net *net = sock_net(sk);
|
||||||
struct udp_table *udptable;
|
struct udp_table *udptable;
|
||||||
|
|
||||||
/* Connected udp socket can re-connect to another remote address,
|
/* Connected udp socket can re-connect to another remote address, which
|
||||||
* so rehash4 is needed.
|
* will be handled by rehash. Thus no need to redo hash4 here.
|
||||||
*/
|
*/
|
||||||
udptable = net->ipv4.udp_table;
|
if (udp_hashed4(sk))
|
||||||
if (udp_hashed4(sk)) {
|
|
||||||
udp_rehash4(udptable, sk, hash);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
|
udptable = net->ipv4.udp_table;
|
||||||
hslot = udp_hashslot(udptable, net, udp_sk(sk)->udp_port_hash);
|
hslot = udp_hashslot(udptable, net, udp_sk(sk)->udp_port_hash);
|
||||||
hslot2 = udp_hashslot2(udptable, udp_sk(sk)->udp_portaddr_hash);
|
hslot2 = udp_hashslot2(udptable, udp_sk(sk)->udp_portaddr_hash);
|
||||||
hslot4 = udp_hashslot4(udptable, hash);
|
hslot4 = udp_hashslot4(udptable, hash);
|
||||||
|
@ -2173,14 +2171,14 @@ void udp_lib_rehash(struct sock *sk, u16 newhash, u16 newhash4)
|
||||||
struct udp_table *udptable = udp_get_table_prot(sk);
|
struct udp_table *udptable = udp_get_table_prot(sk);
|
||||||
struct udp_hslot *hslot, *hslot2, *nhslot2;
|
struct udp_hslot *hslot, *hslot2, *nhslot2;
|
||||||
|
|
||||||
|
hslot = udp_hashslot(udptable, sock_net(sk),
|
||||||
|
udp_sk(sk)->udp_port_hash);
|
||||||
hslot2 = udp_hashslot2(udptable, udp_sk(sk)->udp_portaddr_hash);
|
hslot2 = udp_hashslot2(udptable, udp_sk(sk)->udp_portaddr_hash);
|
||||||
nhslot2 = udp_hashslot2(udptable, newhash);
|
nhslot2 = udp_hashslot2(udptable, newhash);
|
||||||
udp_sk(sk)->udp_portaddr_hash = newhash;
|
udp_sk(sk)->udp_portaddr_hash = newhash;
|
||||||
|
|
||||||
if (hslot2 != nhslot2 ||
|
if (hslot2 != nhslot2 ||
|
||||||
rcu_access_pointer(sk->sk_reuseport_cb)) {
|
rcu_access_pointer(sk->sk_reuseport_cb)) {
|
||||||
hslot = udp_hashslot(udptable, sock_net(sk),
|
|
||||||
udp_sk(sk)->udp_port_hash);
|
|
||||||
/* we must lock primary chain too */
|
/* we must lock primary chain too */
|
||||||
spin_lock_bh(&hslot->lock);
|
spin_lock_bh(&hslot->lock);
|
||||||
if (rcu_access_pointer(sk->sk_reuseport_cb))
|
if (rcu_access_pointer(sk->sk_reuseport_cb))
|
||||||
|
@ -2199,19 +2197,29 @@ void udp_lib_rehash(struct sock *sk, u16 newhash, u16 newhash4)
|
||||||
spin_unlock(&nhslot2->lock);
|
spin_unlock(&nhslot2->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (udp_hashed4(sk)) {
|
spin_unlock_bh(&hslot->lock);
|
||||||
udp_rehash4(udptable, sk, newhash4);
|
}
|
||||||
|
|
||||||
if (hslot2 != nhslot2) {
|
/* Now process hash4 if necessary:
|
||||||
spin_lock(&hslot2->lock);
|
* (1) update hslot4;
|
||||||
udp_hash4_dec(hslot2);
|
* (2) update hslot2->hash4_cnt.
|
||||||
spin_unlock(&hslot2->lock);
|
* Note that hslot2/hslot4 should be checked separately, as
|
||||||
|
* either of them may change with the other unchanged.
|
||||||
|
*/
|
||||||
|
if (udp_hashed4(sk)) {
|
||||||
|
spin_lock_bh(&hslot->lock);
|
||||||
|
|
||||||
spin_lock(&nhslot2->lock);
|
udp_rehash4(udptable, sk, newhash4);
|
||||||
udp_hash4_inc(nhslot2);
|
if (hslot2 != nhslot2) {
|
||||||
spin_unlock(&nhslot2->lock);
|
spin_lock(&hslot2->lock);
|
||||||
}
|
udp_hash4_dec(hslot2);
|
||||||
|
spin_unlock(&hslot2->lock);
|
||||||
|
|
||||||
|
spin_lock(&nhslot2->lock);
|
||||||
|
udp_hash4_inc(nhslot2);
|
||||||
|
spin_unlock(&nhslot2->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock_bh(&hslot->lock);
|
spin_unlock_bh(&hslot->lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -607,7 +607,6 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb,
|
||||||
}
|
}
|
||||||
opts->ext_copy.use_ack = 1;
|
opts->ext_copy.use_ack = 1;
|
||||||
opts->suboptions = OPTION_MPTCP_DSS;
|
opts->suboptions = OPTION_MPTCP_DSS;
|
||||||
WRITE_ONCE(msk->old_wspace, __mptcp_space((struct sock *)msk));
|
|
||||||
|
|
||||||
/* Add kind/length/subtype/flag overhead if mapping is not populated */
|
/* Add kind/length/subtype/flag overhead if mapping is not populated */
|
||||||
if (dss_size == 0)
|
if (dss_size == 0)
|
||||||
|
@ -1288,7 +1287,7 @@ static void mptcp_set_rwin(struct tcp_sock *tp, struct tcphdr *th)
|
||||||
}
|
}
|
||||||
MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_RCVWNDCONFLICT);
|
MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_RCVWNDCONFLICT);
|
||||||
}
|
}
|
||||||
return;
|
goto update_wspace;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rcv_wnd_new != rcv_wnd_old) {
|
if (rcv_wnd_new != rcv_wnd_old) {
|
||||||
|
@ -1313,6 +1312,9 @@ raise_win:
|
||||||
th->window = htons(new_win);
|
th->window = htons(new_win);
|
||||||
MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_RCVWNDSHARED);
|
MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_RCVWNDSHARED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_wspace:
|
||||||
|
WRITE_ONCE(msk->old_wspace, tp->rcv_wnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
__sum16 __mptcp_make_csum(u64 data_seq, u32 subflow_seq, u16 data_len, __wsum sum)
|
__sum16 __mptcp_make_csum(u64 data_seq, u32 subflow_seq, u16 data_len, __wsum sum)
|
||||||
|
|
|
@ -760,10 +760,15 @@ static inline u64 mptcp_data_avail(const struct mptcp_sock *msk)
|
||||||
|
|
||||||
static inline bool mptcp_epollin_ready(const struct sock *sk)
|
static inline bool mptcp_epollin_ready(const struct sock *sk)
|
||||||
{
|
{
|
||||||
|
u64 data_avail = mptcp_data_avail(mptcp_sk(sk));
|
||||||
|
|
||||||
|
if (!data_avail)
|
||||||
|
return false;
|
||||||
|
|
||||||
/* mptcp doesn't have to deal with small skbs in the receive queue,
|
/* mptcp doesn't have to deal with small skbs in the receive queue,
|
||||||
* at it can always coalesce them
|
* as it can always coalesce them
|
||||||
*/
|
*/
|
||||||
return (mptcp_data_avail(mptcp_sk(sk)) >= sk->sk_rcvlowat) ||
|
return (data_avail >= sk->sk_rcvlowat) ||
|
||||||
(mem_cgroup_sockets_enabled && sk->sk_memcg &&
|
(mem_cgroup_sockets_enabled && sk->sk_memcg &&
|
||||||
mem_cgroup_under_socket_pressure(sk->sk_memcg)) ||
|
mem_cgroup_under_socket_pressure(sk->sk_memcg)) ||
|
||||||
READ_ONCE(tcp_memory_pressure);
|
READ_ONCE(tcp_memory_pressure);
|
||||||
|
|
|
@ -289,6 +289,7 @@ enum {
|
||||||
ncsi_dev_state_config_sp = 0x0301,
|
ncsi_dev_state_config_sp = 0x0301,
|
||||||
ncsi_dev_state_config_cis,
|
ncsi_dev_state_config_cis,
|
||||||
ncsi_dev_state_config_oem_gma,
|
ncsi_dev_state_config_oem_gma,
|
||||||
|
ncsi_dev_state_config_apply_mac,
|
||||||
ncsi_dev_state_config_clear_vids,
|
ncsi_dev_state_config_clear_vids,
|
||||||
ncsi_dev_state_config_svf,
|
ncsi_dev_state_config_svf,
|
||||||
ncsi_dev_state_config_ev,
|
ncsi_dev_state_config_ev,
|
||||||
|
@ -322,6 +323,7 @@ struct ncsi_dev_priv {
|
||||||
#define NCSI_DEV_RESHUFFLE 4
|
#define NCSI_DEV_RESHUFFLE 4
|
||||||
#define NCSI_DEV_RESET 8 /* Reset state of NC */
|
#define NCSI_DEV_RESET 8 /* Reset state of NC */
|
||||||
unsigned int gma_flag; /* OEM GMA flag */
|
unsigned int gma_flag; /* OEM GMA flag */
|
||||||
|
struct sockaddr pending_mac; /* MAC address received from GMA */
|
||||||
spinlock_t lock; /* Protect the NCSI device */
|
spinlock_t lock; /* Protect the NCSI device */
|
||||||
unsigned int package_probe_id;/* Current ID during probe */
|
unsigned int package_probe_id;/* Current ID during probe */
|
||||||
unsigned int package_num; /* Number of packages */
|
unsigned int package_num; /* Number of packages */
|
||||||
|
|
|
@ -1038,7 +1038,7 @@ static void ncsi_configure_channel(struct ncsi_dev_priv *ndp)
|
||||||
: ncsi_dev_state_config_clear_vids;
|
: ncsi_dev_state_config_clear_vids;
|
||||||
break;
|
break;
|
||||||
case ncsi_dev_state_config_oem_gma:
|
case ncsi_dev_state_config_oem_gma:
|
||||||
nd->state = ncsi_dev_state_config_clear_vids;
|
nd->state = ncsi_dev_state_config_apply_mac;
|
||||||
|
|
||||||
nca.package = np->id;
|
nca.package = np->id;
|
||||||
nca.channel = nc->id;
|
nca.channel = nc->id;
|
||||||
|
@ -1050,10 +1050,22 @@ static void ncsi_configure_channel(struct ncsi_dev_priv *ndp)
|
||||||
nca.type = NCSI_PKT_CMD_OEM;
|
nca.type = NCSI_PKT_CMD_OEM;
|
||||||
ret = ncsi_gma_handler(&nca, nc->version.mf_id);
|
ret = ncsi_gma_handler(&nca, nc->version.mf_id);
|
||||||
}
|
}
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
|
nd->state = ncsi_dev_state_config_clear_vids;
|
||||||
schedule_work(&ndp->work);
|
schedule_work(&ndp->work);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
case ncsi_dev_state_config_apply_mac:
|
||||||
|
rtnl_lock();
|
||||||
|
ret = dev_set_mac_address(dev, &ndp->pending_mac, NULL);
|
||||||
|
rtnl_unlock();
|
||||||
|
if (ret < 0)
|
||||||
|
netdev_warn(dev, "NCSI: 'Writing MAC address to device failed\n");
|
||||||
|
|
||||||
|
nd->state = ncsi_dev_state_config_clear_vids;
|
||||||
|
|
||||||
|
fallthrough;
|
||||||
case ncsi_dev_state_config_clear_vids:
|
case ncsi_dev_state_config_clear_vids:
|
||||||
case ncsi_dev_state_config_svf:
|
case ncsi_dev_state_config_svf:
|
||||||
case ncsi_dev_state_config_ev:
|
case ncsi_dev_state_config_ev:
|
||||||
|
|
|
@ -628,16 +628,14 @@ static int ncsi_rsp_handler_snfc(struct ncsi_request *nr)
|
||||||
static int ncsi_rsp_handler_oem_gma(struct ncsi_request *nr, int mfr_id)
|
static int ncsi_rsp_handler_oem_gma(struct ncsi_request *nr, int mfr_id)
|
||||||
{
|
{
|
||||||
struct ncsi_dev_priv *ndp = nr->ndp;
|
struct ncsi_dev_priv *ndp = nr->ndp;
|
||||||
|
struct sockaddr *saddr = &ndp->pending_mac;
|
||||||
struct net_device *ndev = ndp->ndev.dev;
|
struct net_device *ndev = ndp->ndev.dev;
|
||||||
struct ncsi_rsp_oem_pkt *rsp;
|
struct ncsi_rsp_oem_pkt *rsp;
|
||||||
struct sockaddr saddr;
|
|
||||||
u32 mac_addr_off = 0;
|
u32 mac_addr_off = 0;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
/* Get the response header */
|
/* Get the response header */
|
||||||
rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
|
rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
|
||||||
|
|
||||||
saddr.sa_family = ndev->type;
|
|
||||||
ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
|
ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
|
||||||
if (mfr_id == NCSI_OEM_MFR_BCM_ID)
|
if (mfr_id == NCSI_OEM_MFR_BCM_ID)
|
||||||
mac_addr_off = BCM_MAC_ADDR_OFFSET;
|
mac_addr_off = BCM_MAC_ADDR_OFFSET;
|
||||||
|
@ -646,22 +644,17 @@ static int ncsi_rsp_handler_oem_gma(struct ncsi_request *nr, int mfr_id)
|
||||||
else if (mfr_id == NCSI_OEM_MFR_INTEL_ID)
|
else if (mfr_id == NCSI_OEM_MFR_INTEL_ID)
|
||||||
mac_addr_off = INTEL_MAC_ADDR_OFFSET;
|
mac_addr_off = INTEL_MAC_ADDR_OFFSET;
|
||||||
|
|
||||||
memcpy(saddr.sa_data, &rsp->data[mac_addr_off], ETH_ALEN);
|
saddr->sa_family = ndev->type;
|
||||||
|
memcpy(saddr->sa_data, &rsp->data[mac_addr_off], ETH_ALEN);
|
||||||
if (mfr_id == NCSI_OEM_MFR_BCM_ID || mfr_id == NCSI_OEM_MFR_INTEL_ID)
|
if (mfr_id == NCSI_OEM_MFR_BCM_ID || mfr_id == NCSI_OEM_MFR_INTEL_ID)
|
||||||
eth_addr_inc((u8 *)saddr.sa_data);
|
eth_addr_inc((u8 *)saddr->sa_data);
|
||||||
if (!is_valid_ether_addr((const u8 *)saddr.sa_data))
|
if (!is_valid_ether_addr((const u8 *)saddr->sa_data))
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
||||||
/* Set the flag for GMA command which should only be called once */
|
/* Set the flag for GMA command which should only be called once */
|
||||||
ndp->gma_flag = 1;
|
ndp->gma_flag = 1;
|
||||||
|
|
||||||
rtnl_lock();
|
return 0;
|
||||||
ret = dev_set_mac_address(ndev, &saddr, NULL);
|
|
||||||
rtnl_unlock();
|
|
||||||
if (ret < 0)
|
|
||||||
netdev_warn(ndev, "NCSI: 'Writing mac address to device failed\n");
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Response handler for Mellanox card */
|
/* Response handler for Mellanox card */
|
||||||
|
|
|
@ -934,7 +934,9 @@ static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port,
|
||||||
{
|
{
|
||||||
struct vport *vport = ovs_vport_rcu(dp, out_port);
|
struct vport *vport = ovs_vport_rcu(dp, out_port);
|
||||||
|
|
||||||
if (likely(vport && netif_carrier_ok(vport->dev))) {
|
if (likely(vport &&
|
||||||
|
netif_running(vport->dev) &&
|
||||||
|
netif_carrier_ok(vport->dev))) {
|
||||||
u16 mru = OVS_CB(skb)->mru;
|
u16 mru = OVS_CB(skb)->mru;
|
||||||
u32 cutlen = OVS_CB(skb)->cutlen;
|
u32 cutlen = OVS_CB(skb)->cutlen;
|
||||||
|
|
||||||
|
|
|
@ -491,6 +491,15 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk)
|
||||||
*/
|
*/
|
||||||
vsk->transport->release(vsk);
|
vsk->transport->release(vsk);
|
||||||
vsock_deassign_transport(vsk);
|
vsock_deassign_transport(vsk);
|
||||||
|
|
||||||
|
/* transport's release() and destruct() can touch some socket
|
||||||
|
* state, since we are reassigning the socket to a new transport
|
||||||
|
* during vsock_connect(), let's reset these fields to have a
|
||||||
|
* clean state.
|
||||||
|
*/
|
||||||
|
sock_reset_flag(sk, SOCK_DONE);
|
||||||
|
sk->sk_state = TCP_CLOSE;
|
||||||
|
vsk->peer_shutdown = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We increase the module refcnt to prevent the transport unloading
|
/* We increase the module refcnt to prevent the transport unloading
|
||||||
|
@ -870,6 +879,9 @@ EXPORT_SYMBOL_GPL(vsock_create_connected);
|
||||||
|
|
||||||
s64 vsock_stream_has_data(struct vsock_sock *vsk)
|
s64 vsock_stream_has_data(struct vsock_sock *vsk)
|
||||||
{
|
{
|
||||||
|
if (WARN_ON(!vsk->transport))
|
||||||
|
return 0;
|
||||||
|
|
||||||
return vsk->transport->stream_has_data(vsk);
|
return vsk->transport->stream_has_data(vsk);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(vsock_stream_has_data);
|
EXPORT_SYMBOL_GPL(vsock_stream_has_data);
|
||||||
|
@ -878,6 +890,9 @@ s64 vsock_connectible_has_data(struct vsock_sock *vsk)
|
||||||
{
|
{
|
||||||
struct sock *sk = sk_vsock(vsk);
|
struct sock *sk = sk_vsock(vsk);
|
||||||
|
|
||||||
|
if (WARN_ON(!vsk->transport))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (sk->sk_type == SOCK_SEQPACKET)
|
if (sk->sk_type == SOCK_SEQPACKET)
|
||||||
return vsk->transport->seqpacket_has_data(vsk);
|
return vsk->transport->seqpacket_has_data(vsk);
|
||||||
else
|
else
|
||||||
|
@ -887,6 +902,9 @@ EXPORT_SYMBOL_GPL(vsock_connectible_has_data);
|
||||||
|
|
||||||
s64 vsock_stream_has_space(struct vsock_sock *vsk)
|
s64 vsock_stream_has_space(struct vsock_sock *vsk)
|
||||||
{
|
{
|
||||||
|
if (WARN_ON(!vsk->transport))
|
||||||
|
return 0;
|
||||||
|
|
||||||
return vsk->transport->stream_has_space(vsk);
|
return vsk->transport->stream_has_space(vsk);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(vsock_stream_has_space);
|
EXPORT_SYMBOL_GPL(vsock_stream_has_space);
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
/* Threshold for detecting small packets to copy */
|
/* Threshold for detecting small packets to copy */
|
||||||
#define GOOD_COPY_LEN 128
|
#define GOOD_COPY_LEN 128
|
||||||
|
|
||||||
|
static void virtio_transport_cancel_close_work(struct vsock_sock *vsk,
|
||||||
|
bool cancel_timeout);
|
||||||
|
|
||||||
static const struct virtio_transport *
|
static const struct virtio_transport *
|
||||||
virtio_transport_get_ops(struct vsock_sock *vsk)
|
virtio_transport_get_ops(struct vsock_sock *vsk)
|
||||||
{
|
{
|
||||||
|
@ -1109,6 +1112,8 @@ void virtio_transport_destruct(struct vsock_sock *vsk)
|
||||||
{
|
{
|
||||||
struct virtio_vsock_sock *vvs = vsk->trans;
|
struct virtio_vsock_sock *vvs = vsk->trans;
|
||||||
|
|
||||||
|
virtio_transport_cancel_close_work(vsk, true);
|
||||||
|
|
||||||
kfree(vvs);
|
kfree(vvs);
|
||||||
vsk->trans = NULL;
|
vsk->trans = NULL;
|
||||||
}
|
}
|
||||||
|
@ -1204,6 +1209,22 @@ static void virtio_transport_wait_close(struct sock *sk, long timeout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void virtio_transport_cancel_close_work(struct vsock_sock *vsk,
|
||||||
|
bool cancel_timeout)
|
||||||
|
{
|
||||||
|
struct sock *sk = sk_vsock(vsk);
|
||||||
|
|
||||||
|
if (vsk->close_work_scheduled &&
|
||||||
|
(!cancel_timeout || cancel_delayed_work(&vsk->close_work))) {
|
||||||
|
vsk->close_work_scheduled = false;
|
||||||
|
|
||||||
|
virtio_transport_remove_sock(vsk);
|
||||||
|
|
||||||
|
/* Release refcnt obtained when we scheduled the timeout */
|
||||||
|
sock_put(sk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void virtio_transport_do_close(struct vsock_sock *vsk,
|
static void virtio_transport_do_close(struct vsock_sock *vsk,
|
||||||
bool cancel_timeout)
|
bool cancel_timeout)
|
||||||
{
|
{
|
||||||
|
@ -1215,15 +1236,7 @@ static void virtio_transport_do_close(struct vsock_sock *vsk,
|
||||||
sk->sk_state = TCP_CLOSING;
|
sk->sk_state = TCP_CLOSING;
|
||||||
sk->sk_state_change(sk);
|
sk->sk_state_change(sk);
|
||||||
|
|
||||||
if (vsk->close_work_scheduled &&
|
virtio_transport_cancel_close_work(vsk, cancel_timeout);
|
||||||
(!cancel_timeout || cancel_delayed_work(&vsk->close_work))) {
|
|
||||||
vsk->close_work_scheduled = false;
|
|
||||||
|
|
||||||
virtio_transport_remove_sock(vsk);
|
|
||||||
|
|
||||||
/* Release refcnt obtained when we scheduled the timeout */
|
|
||||||
sock_put(sk);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void virtio_transport_close_timeout(struct work_struct *work)
|
static void virtio_transport_close_timeout(struct work_struct *work)
|
||||||
|
@ -1628,8 +1641,11 @@ void virtio_transport_recv_pkt(struct virtio_transport *t,
|
||||||
|
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
|
|
||||||
/* Check if sk has been closed before lock_sock */
|
/* Check if sk has been closed or assigned to another transport before
|
||||||
if (sock_flag(sk, SOCK_DONE)) {
|
* lock_sock (note: listener sockets are not assigned to any transport)
|
||||||
|
*/
|
||||||
|
if (sock_flag(sk, SOCK_DONE) ||
|
||||||
|
(sk->sk_state != TCP_LISTEN && vsk->transport != &t->transport)) {
|
||||||
(void)virtio_transport_reset_no_sock(t, skb);
|
(void)virtio_transport_reset_no_sock(t, skb);
|
||||||
release_sock(sk);
|
release_sock(sk);
|
||||||
sock_put(sk);
|
sock_put(sk);
|
||||||
|
|
|
@ -77,6 +77,7 @@ static int vsock_bpf_recvmsg(struct sock *sk, struct msghdr *msg,
|
||||||
size_t len, int flags, int *addr_len)
|
size_t len, int flags, int *addr_len)
|
||||||
{
|
{
|
||||||
struct sk_psock *psock;
|
struct sk_psock *psock;
|
||||||
|
struct vsock_sock *vsk;
|
||||||
int copied;
|
int copied;
|
||||||
|
|
||||||
psock = sk_psock_get(sk);
|
psock = sk_psock_get(sk);
|
||||||
|
@ -84,6 +85,13 @@ static int vsock_bpf_recvmsg(struct sock *sk, struct msghdr *msg,
|
||||||
return __vsock_recvmsg(sk, msg, len, flags);
|
return __vsock_recvmsg(sk, msg, len, flags);
|
||||||
|
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
|
vsk = vsock_sk(sk);
|
||||||
|
|
||||||
|
if (!vsk->transport) {
|
||||||
|
copied = -ENODEV;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (vsock_has_data(sk, psock) && sk_psock_queue_empty(psock)) {
|
if (vsock_has_data(sk, psock) && sk_psock_queue_empty(psock)) {
|
||||||
release_sock(sk);
|
release_sock(sk);
|
||||||
sk_psock_put(sk, psock);
|
sk_psock_put(sk, psock);
|
||||||
|
@ -108,6 +116,7 @@ static int vsock_bpf_recvmsg(struct sock *sk, struct msghdr *msg,
|
||||||
copied = sk_msg_recvmsg(sk, psock, msg, len, flags);
|
copied = sk_msg_recvmsg(sk, psock, msg, len, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
release_sock(sk);
|
release_sock(sk);
|
||||||
sk_psock_put(sk, psock);
|
sk_psock_put(sk, psock);
|
||||||
|
|
||||||
|
|
|
@ -322,7 +322,6 @@ static int xsk_rcv_check(struct xdp_sock *xs, struct xdp_buff *xdp, u32 len)
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
}
|
}
|
||||||
|
|
||||||
sk_mark_napi_id_once_xdp(&xs->sk, xdp);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -908,11 +907,8 @@ static int __xsk_sendmsg(struct socket *sock, struct msghdr *m, size_t total_len
|
||||||
if (unlikely(!xs->tx))
|
if (unlikely(!xs->tx))
|
||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
|
|
||||||
if (sk_can_busy_loop(sk)) {
|
if (sk_can_busy_loop(sk))
|
||||||
if (xs->zc)
|
|
||||||
__sk_mark_napi_id_once(sk, xsk_pool_get_napi_id(xs->pool));
|
|
||||||
sk_busy_loop(sk, 1); /* only support non-blocking sockets */
|
sk_busy_loop(sk, 1); /* only support non-blocking sockets */
|
||||||
}
|
|
||||||
|
|
||||||
if (xs->zc && xsk_no_wakeup(sk))
|
if (xs->zc && xsk_no_wakeup(sk))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1298,6 +1294,14 @@ static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
|
||||||
xs->queue_id = qid;
|
xs->queue_id = qid;
|
||||||
xp_add_xsk(xs->pool, xs);
|
xp_add_xsk(xs->pool, xs);
|
||||||
|
|
||||||
|
if (xs->zc && qid < dev->real_num_rx_queues) {
|
||||||
|
struct netdev_rx_queue *rxq;
|
||||||
|
|
||||||
|
rxq = __netif_get_rx_queue(dev, qid);
|
||||||
|
if (rxq->napi)
|
||||||
|
__sk_mark_napi_id_once(sk, rxq->napi->napi_id);
|
||||||
|
}
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_put(dev);
|
dev_put(dev);
|
||||||
|
|
|
@ -2384,6 +2384,17 @@ def print_kernel_family_struct_src(family, cw):
|
||||||
if not kernel_can_gen_family_struct(family):
|
if not kernel_can_gen_family_struct(family):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if 'sock-priv' in family.kernel_family:
|
||||||
|
# Generate "trampolines" to make CFI happy
|
||||||
|
cw.write_func("static void", f"__{family.c_name}_nl_sock_priv_init",
|
||||||
|
[f"{family.c_name}_nl_sock_priv_init(priv);"],
|
||||||
|
["void *priv"])
|
||||||
|
cw.nl()
|
||||||
|
cw.write_func("static void", f"__{family.c_name}_nl_sock_priv_destroy",
|
||||||
|
[f"{family.c_name}_nl_sock_priv_destroy(priv);"],
|
||||||
|
["void *priv"])
|
||||||
|
cw.nl()
|
||||||
|
|
||||||
cw.block_start(f"struct genl_family {family.ident_name}_nl_family __ro_after_init =")
|
cw.block_start(f"struct genl_family {family.ident_name}_nl_family __ro_after_init =")
|
||||||
cw.p('.name\t\t= ' + family.fam_key + ',')
|
cw.p('.name\t\t= ' + family.fam_key + ',')
|
||||||
cw.p('.version\t= ' + family.ver_key + ',')
|
cw.p('.version\t= ' + family.ver_key + ',')
|
||||||
|
@ -2401,9 +2412,8 @@ def print_kernel_family_struct_src(family, cw):
|
||||||
cw.p(f'.n_mcgrps\t= ARRAY_SIZE({family.c_name}_nl_mcgrps),')
|
cw.p(f'.n_mcgrps\t= ARRAY_SIZE({family.c_name}_nl_mcgrps),')
|
||||||
if 'sock-priv' in family.kernel_family:
|
if 'sock-priv' in family.kernel_family:
|
||||||
cw.p(f'.sock_priv_size\t= sizeof({family.kernel_family["sock-priv"]}),')
|
cw.p(f'.sock_priv_size\t= sizeof({family.kernel_family["sock-priv"]}),')
|
||||||
# Force cast here, actual helpers take pointer to the real type.
|
cw.p(f'.sock_priv_init\t= __{family.c_name}_nl_sock_priv_init,')
|
||||||
cw.p(f'.sock_priv_init\t= (void *){family.c_name}_nl_sock_priv_init,')
|
cw.p(f'.sock_priv_destroy = __{family.c_name}_nl_sock_priv_destroy,')
|
||||||
cw.p(f'.sock_priv_destroy = (void *){family.c_name}_nl_sock_priv_destroy,')
|
|
||||||
cw.block_end(';')
|
cw.block_end(';')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -58,9 +58,12 @@ for root in mq mqprio; do
|
||||||
ethtool -L $NDEV combined 4
|
ethtool -L $NDEV combined 4
|
||||||
n_child_assert 4 "One real queue, rest default"
|
n_child_assert 4 "One real queue, rest default"
|
||||||
|
|
||||||
# Graft some
|
# Remove real one
|
||||||
tcq replace parent 100:1 handle 204:
|
tcq del parent 100:4 handle 204:
|
||||||
n_child_assert 3 "Grafted"
|
|
||||||
|
# Replace default with pfifo
|
||||||
|
tcq replace parent 100:1 handle 205: pfifo limit 1000
|
||||||
|
n_child_assert 3 "Deleting real one, replacing default one with pfifo"
|
||||||
|
|
||||||
ethtool -L $NDEV combined 1
|
ethtool -L $NDEV combined 1
|
||||||
n_child_assert 1 "Grafted, one"
|
n_child_assert 1 "Grafted, one"
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
@ -1211,23 +1213,42 @@ static void parse_setsock_options(const char *name)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void xdisconnect(int fd, int addrlen)
|
void xdisconnect(int fd)
|
||||||
{
|
{
|
||||||
struct sockaddr_storage empty;
|
socklen_t addrlen = sizeof(struct sockaddr_storage);
|
||||||
|
struct sockaddr_storage addr, empty;
|
||||||
int msec_sleep = 10;
|
int msec_sleep = 10;
|
||||||
int queued = 1;
|
void *raw_addr;
|
||||||
int i;
|
int i, cmdlen;
|
||||||
|
char cmd[128];
|
||||||
|
|
||||||
|
/* get the local address and convert it to string */
|
||||||
|
if (getsockname(fd, (struct sockaddr *)&addr, &addrlen) < 0)
|
||||||
|
xerror("getsockname");
|
||||||
|
|
||||||
|
if (addr.ss_family == AF_INET)
|
||||||
|
raw_addr = &(((struct sockaddr_in *)&addr)->sin_addr);
|
||||||
|
else if (addr.ss_family == AF_INET6)
|
||||||
|
raw_addr = &(((struct sockaddr_in6 *)&addr)->sin6_addr);
|
||||||
|
else
|
||||||
|
xerror("bad family");
|
||||||
|
|
||||||
|
strcpy(cmd, "ss -M | grep -q ");
|
||||||
|
cmdlen = strlen(cmd);
|
||||||
|
if (!inet_ntop(addr.ss_family, raw_addr, &cmd[cmdlen],
|
||||||
|
sizeof(cmd) - cmdlen))
|
||||||
|
xerror("inet_ntop");
|
||||||
|
|
||||||
shutdown(fd, SHUT_WR);
|
shutdown(fd, SHUT_WR);
|
||||||
|
|
||||||
/* while until the pending data is completely flushed, the later
|
/*
|
||||||
|
* wait until the pending data is completely flushed and all
|
||||||
|
* the MPTCP sockets reached the closed status.
|
||||||
* disconnect will bypass/ignore/drop any pending data.
|
* disconnect will bypass/ignore/drop any pending data.
|
||||||
*/
|
*/
|
||||||
for (i = 0; ; i += msec_sleep) {
|
for (i = 0; ; i += msec_sleep) {
|
||||||
if (ioctl(fd, SIOCOUTQ, &queued) < 0)
|
/* closed socket are not listed by 'ss' */
|
||||||
xerror("can't query out socket queue: %d", errno);
|
if (system(cmd) != 0)
|
||||||
|
|
||||||
if (!queued)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (i > poll_timeout)
|
if (i > poll_timeout)
|
||||||
|
@ -1281,9 +1302,9 @@ again:
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (cfg_truncate > 0) {
|
if (cfg_truncate > 0) {
|
||||||
xdisconnect(fd, peer->ai_addrlen);
|
xdisconnect(fd);
|
||||||
} else if (--cfg_repeat > 0) {
|
} else if (--cfg_repeat > 0) {
|
||||||
xdisconnect(fd, peer->ai_addrlen);
|
xdisconnect(fd);
|
||||||
|
|
||||||
/* the socket could be unblocking at this point, we need the
|
/* the socket could be unblocking at this point, we need the
|
||||||
* connect to be blocking
|
* connect to be blocking
|
||||||
|
|
Loading…
Add table
Reference in a new issue