From 7a4ea5da4d02c6087db8643fd5940974fabbaea3 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Fri, 1 Nov 2024 15:00:22 -0700 Subject: [PATCH 01/16] net: hisilicon: hns: use ethtool string helpers The latter is the preferred way to copy ethtool strings. Avoids manually incrementing the pointer. Cleans up the code quite well. Signed-off-by: Rosen Penev Reviewed-by: Jijie Shao Link: https://patch.msgid.link/20241101220023.290926-1-rosenp@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/hisilicon/hns/hnae.h | 2 +- .../net/ethernet/hisilicon/hns/hns_ae_adapt.c | 20 ++---- .../ethernet/hisilicon/hns/hns_dsaf_gmac.c | 5 +- .../net/ethernet/hisilicon/hns/hns_dsaf_mac.c | 3 +- .../net/ethernet/hisilicon/hns/hns_dsaf_mac.h | 4 +- .../ethernet/hisilicon/hns/hns_dsaf_main.c | 70 +++++++------------ .../ethernet/hisilicon/hns/hns_dsaf_main.h | 2 +- .../net/ethernet/hisilicon/hns/hns_dsaf_ppe.c | 31 ++++---- .../net/ethernet/hisilicon/hns/hns_dsaf_ppe.h | 2 +- .../net/ethernet/hisilicon/hns/hns_dsaf_rcb.c | 66 +++++++++-------- .../net/ethernet/hisilicon/hns/hns_dsaf_rcb.h | 2 +- .../ethernet/hisilicon/hns/hns_dsaf_xgmac.c | 5 +- .../net/ethernet/hisilicon/hns/hns_ethtool.c | 67 +++++++++--------- 13 files changed, 122 insertions(+), 157 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.h b/drivers/net/ethernet/hisilicon/hns/hnae.h index d72657444ef3..2ae34d01fd36 100644 --- a/drivers/net/ethernet/hisilicon/hns/hnae.h +++ b/drivers/net/ethernet/hisilicon/hns/hnae.h @@ -512,7 +512,7 @@ struct hnae_ae_ops { struct net_device_stats *net_stats); void (*get_stats)(struct hnae_handle *handle, u64 *data); void (*get_strings)(struct hnae_handle *handle, - u32 stringset, u8 *data); + u32 stringset, u8 **data); int (*get_sset_count)(struct hnae_handle *handle, int stringset); void (*update_led_status)(struct hnae_handle *handle); int (*set_led_id)(struct hnae_handle *handle, diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c index bc3e406f0139..8ce910f8d0cc 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c @@ -730,15 +730,14 @@ static void hns_ae_get_stats(struct hnae_handle *handle, u64 *data) hns_dsaf_get_stats(vf_cb->dsaf_dev, p, vf_cb->port_index); } -static void hns_ae_get_strings(struct hnae_handle *handle, - u32 stringset, u8 *data) +static void hns_ae_get_strings(struct hnae_handle *handle, u32 stringset, + u8 **data) { int port; int idx; struct hns_mac_cb *mac_cb; struct hns_ppe_cb *ppe_cb; struct dsaf_device *dsaf_dev = hns_ae_get_dsaf_dev(handle->dev); - u8 *p = data; struct hnae_vf_cb *vf_cb; assert(handle); @@ -748,19 +747,14 @@ static void hns_ae_get_strings(struct hnae_handle *handle, mac_cb = hns_get_mac_cb(handle); ppe_cb = hns_get_ppe_cb(handle); - for (idx = 0; idx < handle->q_num; idx++) { - hns_rcb_get_strings(stringset, p, idx); - p += ETH_GSTRING_LEN * hns_rcb_get_ring_sset_count(stringset); - } - - hns_ppe_get_strings(ppe_cb, stringset, p); - p += ETH_GSTRING_LEN * hns_ppe_get_sset_count(stringset); + for (idx = 0; idx < handle->q_num; idx++) + hns_rcb_get_strings(stringset, data, idx); - hns_mac_get_strings(mac_cb, stringset, p); - p += ETH_GSTRING_LEN * hns_mac_get_sset_count(mac_cb, stringset); + hns_ppe_get_strings(ppe_cb, stringset, data); + hns_mac_get_strings(mac_cb, stringset, data); if (mac_cb->mac_type == HNAE_PORT_SERVICE) - hns_dsaf_get_strings(stringset, p, port, dsaf_dev); + hns_dsaf_get_strings(stringset, data, port, dsaf_dev); } static int hns_ae_get_sset_count(struct hnae_handle *handle, int stringset) diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c index bdb7afaabdd0..400933ca1a29 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c @@ -669,16 +669,15 @@ static void hns_gmac_get_stats(void *mac_drv, u64 *data) } } -static void hns_gmac_get_strings(u32 stringset, u8 *data) +static void hns_gmac_get_strings(u32 stringset, u8 **data) { - u8 *buff = data; u32 i; if (stringset != ETH_SS_STATS) return; for (i = 0; i < ARRAY_SIZE(g_gmac_stats_string); i++) - ethtool_puts(&buff, g_gmac_stats_string[i].desc); + ethtool_puts(data, g_gmac_stats_string[i].desc); } static int hns_gmac_get_sset_count(int stringset) diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c index 5fa9b2eeb929..bc6b269be299 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c @@ -1190,8 +1190,7 @@ void hns_mac_get_stats(struct hns_mac_cb *mac_cb, u64 *data) mac_ctrl_drv->get_ethtool_stats(mac_ctrl_drv, data); } -void hns_mac_get_strings(struct hns_mac_cb *mac_cb, - int stringset, u8 *data) +void hns_mac_get_strings(struct hns_mac_cb *mac_cb, int stringset, u8 **data) { struct mac_driver *mac_ctrl_drv = hns_mac_get_drv(mac_cb); diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h index edf0bcf76ac9..630f01cf7a71 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h @@ -378,7 +378,7 @@ struct mac_driver { void (*get_regs)(void *mac_drv, void *data); int (*get_regs_count)(void); /* get strings name for ethtool statistic */ - void (*get_strings)(u32 stringset, u8 *data); + void (*get_strings)(u32 stringset, u8 **data); /* get the number of strings*/ int (*get_sset_count)(int stringset); @@ -445,7 +445,7 @@ int hns_mac_config_mac_loopback(struct hns_mac_cb *mac_cb, enum hnae_loop loop, int en); void hns_mac_update_stats(struct hns_mac_cb *mac_cb); void hns_mac_get_stats(struct hns_mac_cb *mac_cb, u64 *data); -void hns_mac_get_strings(struct hns_mac_cb *mac_cb, int stringset, u8 *data); +void hns_mac_get_strings(struct hns_mac_cb *mac_cb, int stringset, u8 **data); int hns_mac_get_sset_count(struct hns_mac_cb *mac_cb, int stringset); void hns_mac_get_regs(struct hns_mac_cb *mac_cb, void *data); int hns_mac_get_regs_count(struct hns_mac_cb *mac_cb); diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c index eb60f45a3460..851490346261 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c @@ -2590,55 +2590,34 @@ void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data) p[i] = 0xdddddddd; } -static char *hns_dsaf_get_node_stats_strings(char *data, int node, - struct dsaf_device *dsaf_dev) +static void hns_dsaf_get_node_stats_strings(u8 **data, int node, + struct dsaf_device *dsaf_dev) { - char *buff = data; - int i; bool is_ver1 = AE_IS_VER1(dsaf_dev->dsaf_ver); + int i; - snprintf(buff, ETH_GSTRING_LEN, "innod%d_pad_drop_pkts", node); - buff += ETH_GSTRING_LEN; - snprintf(buff, ETH_GSTRING_LEN, "innod%d_manage_pkts", node); - buff += ETH_GSTRING_LEN; - snprintf(buff, ETH_GSTRING_LEN, "innod%d_rx_pkts", node); - buff += ETH_GSTRING_LEN; - snprintf(buff, ETH_GSTRING_LEN, "innod%d_rx_pkt_id", node); - buff += ETH_GSTRING_LEN; - snprintf(buff, ETH_GSTRING_LEN, "innod%d_rx_pause_frame", node); - buff += ETH_GSTRING_LEN; - snprintf(buff, ETH_GSTRING_LEN, "innod%d_release_buf_num", node); - buff += ETH_GSTRING_LEN; - snprintf(buff, ETH_GSTRING_LEN, "innod%d_sbm_drop_pkts", node); - buff += ETH_GSTRING_LEN; - snprintf(buff, ETH_GSTRING_LEN, "innod%d_crc_false_pkts", node); - buff += ETH_GSTRING_LEN; - snprintf(buff, ETH_GSTRING_LEN, "innod%d_bp_drop_pkts", node); - buff += ETH_GSTRING_LEN; - snprintf(buff, ETH_GSTRING_LEN, "innod%d_lookup_rslt_drop_pkts", node); - buff += ETH_GSTRING_LEN; - snprintf(buff, ETH_GSTRING_LEN, "innod%d_local_rslt_fail_pkts", node); - buff += ETH_GSTRING_LEN; - snprintf(buff, ETH_GSTRING_LEN, "innod%d_vlan_drop_pkts", node); - buff += ETH_GSTRING_LEN; - snprintf(buff, ETH_GSTRING_LEN, "innod%d_stp_drop_pkts", node); - buff += ETH_GSTRING_LEN; + ethtool_sprintf(data, "innod%d_pad_drop_pkts", node); + ethtool_sprintf(data, "innod%d_manage_pkts", node); + ethtool_sprintf(data, "innod%d_rx_pkts", node); + ethtool_sprintf(data, "innod%d_rx_pkt_id", node); + ethtool_sprintf(data, "innod%d_rx_pause_frame", node); + ethtool_sprintf(data, "innod%d_release_buf_num", node); + ethtool_sprintf(data, "innod%d_sbm_drop_pkts", node); + ethtool_sprintf(data, "innod%d_crc_false_pkts", node); + ethtool_sprintf(data, "innod%d_bp_drop_pkts", node); + ethtool_sprintf(data, "innod%d_lookup_rslt_drop_pkts", node); + ethtool_sprintf(data, "innod%d_local_rslt_fail_pkts", node); + ethtool_sprintf(data, "innod%d_vlan_drop_pkts", node); + ethtool_sprintf(data, "innod%d_stp_drop_pkts", node); if (node < DSAF_SERVICE_NW_NUM && !is_ver1) { for (i = 0; i < DSAF_PRIO_NR; i++) { - snprintf(buff + 0 * ETH_GSTRING_LEN * DSAF_PRIO_NR, - ETH_GSTRING_LEN, "inod%d_pfc_prio%d_pkts", - node, i); - snprintf(buff + 1 * ETH_GSTRING_LEN * DSAF_PRIO_NR, - ETH_GSTRING_LEN, "onod%d_pfc_prio%d_pkts", - node, i); - buff += ETH_GSTRING_LEN; + ethtool_sprintf(data, "inod%d_pfc_prio%d_pkts", node, + i); + ethtool_sprintf(data, "onod%d_pfc_prio%d_pkts", node, + i); } - buff += 1 * DSAF_PRIO_NR * ETH_GSTRING_LEN; } - snprintf(buff, ETH_GSTRING_LEN, "onnod%d_tx_pkts", node); - buff += ETH_GSTRING_LEN; - - return buff; + ethtool_sprintf(data, "onnod%d_tx_pkts", node); } static u64 *hns_dsaf_get_node_stats(struct dsaf_device *ddev, u64 *data, @@ -2720,21 +2699,20 @@ int hns_dsaf_get_sset_count(struct dsaf_device *dsaf_dev, int stringset) *@port:port index *@dsaf_dev: dsaf device */ -void hns_dsaf_get_strings(int stringset, u8 *data, int port, +void hns_dsaf_get_strings(int stringset, u8 **data, int port, struct dsaf_device *dsaf_dev) { - char *buff = (char *)data; int node = port; if (stringset != ETH_SS_STATS) return; /* for ge/xge node info */ - buff = hns_dsaf_get_node_stats_strings(buff, node, dsaf_dev); + hns_dsaf_get_node_stats_strings(data, node, dsaf_dev); /* for ppe node info */ node = port + DSAF_PPE_INODE_BASE; - (void)hns_dsaf_get_node_stats_strings(buff, node, dsaf_dev); + hns_dsaf_get_node_stats_strings(data, node, dsaf_dev); } /** diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h index 5526a10caac5..0eb03dff1a8b 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h @@ -442,7 +442,7 @@ void hns_dsaf_update_stats(struct dsaf_device *dsaf_dev, u32 inode_num); int hns_dsaf_get_sset_count(struct dsaf_device *dsaf_dev, int stringset); void hns_dsaf_get_stats(struct dsaf_device *ddev, u64 *data, int port); -void hns_dsaf_get_strings(int stringset, u8 *data, int port, +void hns_dsaf_get_strings(int stringset, u8 **data, int port, struct dsaf_device *dsaf_dev); void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data); diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c index a08d1f0a5a16..5013beb4d282 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c @@ -457,24 +457,23 @@ int hns_ppe_get_regs_count(void) * @stringset: string set type * @data: output string */ -void hns_ppe_get_strings(struct hns_ppe_cb *ppe_cb, int stringset, u8 *data) +void hns_ppe_get_strings(struct hns_ppe_cb *ppe_cb, int stringset, u8 **data) { int index = ppe_cb->index; - u8 *buff = data; - - ethtool_sprintf(&buff, "ppe%d_rx_sw_pkt", index); - ethtool_sprintf(&buff, "ppe%d_rx_pkt_ok", index); - ethtool_sprintf(&buff, "ppe%d_rx_drop_pkt_no_bd", index); - ethtool_sprintf(&buff, "ppe%d_rx_alloc_buf_fail", index); - ethtool_sprintf(&buff, "ppe%d_rx_alloc_buf_wait", index); - ethtool_sprintf(&buff, "ppe%d_rx_pkt_drop_no_buf", index); - ethtool_sprintf(&buff, "ppe%d_rx_pkt_err_fifo_full", index); - - ethtool_sprintf(&buff, "ppe%d_tx_bd", index); - ethtool_sprintf(&buff, "ppe%d_tx_pkt", index); - ethtool_sprintf(&buff, "ppe%d_tx_pkt_ok", index); - ethtool_sprintf(&buff, "ppe%d_tx_pkt_err_fifo_empty", index); - ethtool_sprintf(&buff, "ppe%d_tx_pkt_err_csum_fail", index); + + ethtool_sprintf(data, "ppe%d_rx_sw_pkt", index); + ethtool_sprintf(data, "ppe%d_rx_pkt_ok", index); + ethtool_sprintf(data, "ppe%d_rx_drop_pkt_no_bd", index); + ethtool_sprintf(data, "ppe%d_rx_alloc_buf_fail", index); + ethtool_sprintf(data, "ppe%d_rx_alloc_buf_wait", index); + ethtool_sprintf(data, "ppe%d_rx_pkt_drop_no_buf", index); + ethtool_sprintf(data, "ppe%d_rx_pkt_err_fifo_full", index); + + ethtool_sprintf(data, "ppe%d_tx_bd", index); + ethtool_sprintf(data, "ppe%d_tx_pkt", index); + ethtool_sprintf(data, "ppe%d_tx_pkt_ok", index); + ethtool_sprintf(data, "ppe%d_tx_pkt_err_fifo_empty", index); + ethtool_sprintf(data, "ppe%d_tx_pkt_err_csum_fail", index); } void hns_ppe_get_stats(struct hns_ppe_cb *ppe_cb, u64 *data) diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.h index 7e00231c1acf..602c8e971fe4 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.h @@ -109,7 +109,7 @@ int hns_ppe_get_sset_count(int stringset); int hns_ppe_get_regs_count(void); void hns_ppe_get_regs(struct hns_ppe_cb *ppe_cb, void *data); -void hns_ppe_get_strings(struct hns_ppe_cb *ppe_cb, int stringset, u8 *data); +void hns_ppe_get_strings(struct hns_ppe_cb *ppe_cb, int stringset, u8 **data); void hns_ppe_get_stats(struct hns_ppe_cb *ppe_cb, u64 *data); void hns_ppe_set_tso_enable(struct hns_ppe_cb *ppe_cb, u32 value); void hns_ppe_set_rss_key(struct hns_ppe_cb *ppe_cb, diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c index 93344563a259..46af467aa596 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c @@ -923,44 +923,42 @@ int hns_rcb_get_ring_regs_count(void) *@data:strings name value *@index:queue index */ -void hns_rcb_get_strings(int stringset, u8 *data, int index) +void hns_rcb_get_strings(int stringset, u8 **data, int index) { - u8 *buff = data; - if (stringset != ETH_SS_STATS) return; - ethtool_sprintf(&buff, "tx_ring%d_rcb_pkt_num", index); - ethtool_sprintf(&buff, "tx_ring%d_ppe_tx_pkt_num", index); - ethtool_sprintf(&buff, "tx_ring%d_ppe_drop_pkt_num", index); - ethtool_sprintf(&buff, "tx_ring%d_fbd_num", index); - - ethtool_sprintf(&buff, "tx_ring%d_pkt_num", index); - ethtool_sprintf(&buff, "tx_ring%d_bytes", index); - ethtool_sprintf(&buff, "tx_ring%d_err_cnt", index); - ethtool_sprintf(&buff, "tx_ring%d_io_err", index); - ethtool_sprintf(&buff, "tx_ring%d_sw_err", index); - ethtool_sprintf(&buff, "tx_ring%d_seg_pkt", index); - ethtool_sprintf(&buff, "tx_ring%d_restart_queue", index); - ethtool_sprintf(&buff, "tx_ring%d_tx_busy", index); - - ethtool_sprintf(&buff, "rx_ring%d_rcb_pkt_num", index); - ethtool_sprintf(&buff, "rx_ring%d_ppe_pkt_num", index); - ethtool_sprintf(&buff, "rx_ring%d_ppe_drop_pkt_num", index); - ethtool_sprintf(&buff, "rx_ring%d_fbd_num", index); - - ethtool_sprintf(&buff, "rx_ring%d_pkt_num", index); - ethtool_sprintf(&buff, "rx_ring%d_bytes", index); - ethtool_sprintf(&buff, "rx_ring%d_err_cnt", index); - ethtool_sprintf(&buff, "rx_ring%d_io_err", index); - ethtool_sprintf(&buff, "rx_ring%d_sw_err", index); - ethtool_sprintf(&buff, "rx_ring%d_seg_pkt", index); - ethtool_sprintf(&buff, "rx_ring%d_reuse_pg", index); - ethtool_sprintf(&buff, "rx_ring%d_len_err", index); - ethtool_sprintf(&buff, "rx_ring%d_non_vld_desc_err", index); - ethtool_sprintf(&buff, "rx_ring%d_bd_num_err", index); - ethtool_sprintf(&buff, "rx_ring%d_l2_err", index); - ethtool_sprintf(&buff, "rx_ring%d_l3l4csum_err", index); + ethtool_sprintf(data, "tx_ring%d_rcb_pkt_num", index); + ethtool_sprintf(data, "tx_ring%d_ppe_tx_pkt_num", index); + ethtool_sprintf(data, "tx_ring%d_ppe_drop_pkt_num", index); + ethtool_sprintf(data, "tx_ring%d_fbd_num", index); + + ethtool_sprintf(data, "tx_ring%d_pkt_num", index); + ethtool_sprintf(data, "tx_ring%d_bytes", index); + ethtool_sprintf(data, "tx_ring%d_err_cnt", index); + ethtool_sprintf(data, "tx_ring%d_io_err", index); + ethtool_sprintf(data, "tx_ring%d_sw_err", index); + ethtool_sprintf(data, "tx_ring%d_seg_pkt", index); + ethtool_sprintf(data, "tx_ring%d_restart_queue", index); + ethtool_sprintf(data, "tx_ring%d_tx_busy", index); + + ethtool_sprintf(data, "rx_ring%d_rcb_pkt_num", index); + ethtool_sprintf(data, "rx_ring%d_ppe_pkt_num", index); + ethtool_sprintf(data, "rx_ring%d_ppe_drop_pkt_num", index); + ethtool_sprintf(data, "rx_ring%d_fbd_num", index); + + ethtool_sprintf(data, "rx_ring%d_pkt_num", index); + ethtool_sprintf(data, "rx_ring%d_bytes", index); + ethtool_sprintf(data, "rx_ring%d_err_cnt", index); + ethtool_sprintf(data, "rx_ring%d_io_err", index); + ethtool_sprintf(data, "rx_ring%d_sw_err", index); + ethtool_sprintf(data, "rx_ring%d_seg_pkt", index); + ethtool_sprintf(data, "rx_ring%d_reuse_pg", index); + ethtool_sprintf(data, "rx_ring%d_len_err", index); + ethtool_sprintf(data, "rx_ring%d_non_vld_desc_err", index); + ethtool_sprintf(data, "rx_ring%d_bd_num_err", index); + ethtool_sprintf(data, "rx_ring%d_l2_err", index); + ethtool_sprintf(data, "rx_ring%d_l3l4csum_err", index); } void hns_rcb_get_common_regs(struct rcb_common_cb *rcb_com, void *data) diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h index c1e9b6997853..0f4cc184ef39 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h @@ -157,7 +157,7 @@ int hns_rcb_get_ring_regs_count(void); void hns_rcb_get_ring_regs(struct hnae_queue *queue, void *data); -void hns_rcb_get_strings(int stringset, u8 *data, int index); +void hns_rcb_get_strings(int stringset, u8 **data, int index); void hns_rcb_set_rx_ring_bs(struct hnae_queue *q, u32 buf_size); void hns_rcb_set_tx_ring_bs(struct hnae_queue *q, u32 buf_size); diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c index c58833eb4830..dbc44c2c26c2 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c @@ -743,16 +743,15 @@ static void hns_xgmac_get_stats(void *mac_drv, u64 *data) *@stringset: type of values in data *@data:data for value of string name */ -static void hns_xgmac_get_strings(u32 stringset, u8 *data) +static void hns_xgmac_get_strings(u32 stringset, u8 **data) { - u8 *buff = data; u32 i; if (stringset != ETH_SS_STATS) return; for (i = 0; i < ARRAY_SIZE(g_xgmac_stats_string); i++) - ethtool_puts(&buff, g_xgmac_stats_string[i].desc); + ethtool_puts(data, g_xgmac_stats_string[i].desc); } /** diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c index a5bb306b2cf1..6c458f037262 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c @@ -903,7 +903,6 @@ static void hns_get_strings(struct net_device *netdev, u32 stringset, u8 *data) { struct hns_nic_priv *priv = netdev_priv(netdev); struct hnae_handle *h = priv->ae_handle; - u8 *buff = data; if (!h->dev->ops->get_strings) { netdev_err(netdev, "h->dev->ops->get_strings is null!\n"); @@ -912,43 +911,43 @@ static void hns_get_strings(struct net_device *netdev, u32 stringset, u8 *data) if (stringset == ETH_SS_TEST) { if (priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII) - ethtool_puts(&buff, + ethtool_puts(&data, hns_nic_test_strs[MAC_INTERNALLOOP_MAC]); - ethtool_puts(&buff, hns_nic_test_strs[MAC_INTERNALLOOP_SERDES]); + ethtool_puts(&data, hns_nic_test_strs[MAC_INTERNALLOOP_SERDES]); if ((netdev->phydev) && (!netdev->phydev->is_c45)) - ethtool_puts(&buff, + ethtool_puts(&data, hns_nic_test_strs[MAC_INTERNALLOOP_PHY]); } else { - ethtool_puts(&buff, "rx_packets"); - ethtool_puts(&buff, "tx_packets"); - ethtool_puts(&buff, "rx_bytes"); - ethtool_puts(&buff, "tx_bytes"); - ethtool_puts(&buff, "rx_errors"); - ethtool_puts(&buff, "tx_errors"); - ethtool_puts(&buff, "rx_dropped"); - ethtool_puts(&buff, "tx_dropped"); - ethtool_puts(&buff, "multicast"); - ethtool_puts(&buff, "collisions"); - ethtool_puts(&buff, "rx_over_errors"); - ethtool_puts(&buff, "rx_crc_errors"); - ethtool_puts(&buff, "rx_frame_errors"); - ethtool_puts(&buff, "rx_fifo_errors"); - ethtool_puts(&buff, "rx_missed_errors"); - ethtool_puts(&buff, "tx_aborted_errors"); - ethtool_puts(&buff, "tx_carrier_errors"); - ethtool_puts(&buff, "tx_fifo_errors"); - ethtool_puts(&buff, "tx_heartbeat_errors"); - ethtool_puts(&buff, "rx_length_errors"); - ethtool_puts(&buff, "tx_window_errors"); - ethtool_puts(&buff, "rx_compressed"); - ethtool_puts(&buff, "tx_compressed"); - ethtool_puts(&buff, "netdev_rx_dropped"); - ethtool_puts(&buff, "netdev_tx_dropped"); - - ethtool_puts(&buff, "netdev_tx_timeout"); - - h->dev->ops->get_strings(h, stringset, buff); + ethtool_puts(&data, "rx_packets"); + ethtool_puts(&data, "tx_packets"); + ethtool_puts(&data, "rx_bytes"); + ethtool_puts(&data, "tx_bytes"); + ethtool_puts(&data, "rx_errors"); + ethtool_puts(&data, "tx_errors"); + ethtool_puts(&data, "rx_dropped"); + ethtool_puts(&data, "tx_dropped"); + ethtool_puts(&data, "multicast"); + ethtool_puts(&data, "collisions"); + ethtool_puts(&data, "rx_over_errors"); + ethtool_puts(&data, "rx_crc_errors"); + ethtool_puts(&data, "rx_frame_errors"); + ethtool_puts(&data, "rx_fifo_errors"); + ethtool_puts(&data, "rx_missed_errors"); + ethtool_puts(&data, "tx_aborted_errors"); + ethtool_puts(&data, "tx_carrier_errors"); + ethtool_puts(&data, "tx_fifo_errors"); + ethtool_puts(&data, "tx_heartbeat_errors"); + ethtool_puts(&data, "rx_length_errors"); + ethtool_puts(&data, "tx_window_errors"); + ethtool_puts(&data, "rx_compressed"); + ethtool_puts(&data, "tx_compressed"); + ethtool_puts(&data, "netdev_rx_dropped"); + ethtool_puts(&data, "netdev_tx_dropped"); + + ethtool_puts(&data, "netdev_tx_timeout"); + + h->dev->ops->get_strings(h, stringset, &data); } } @@ -970,7 +969,7 @@ static int hns_get_sset_count(struct net_device *netdev, int stringset) return -EOPNOTSUPP; } if (stringset == ETH_SS_TEST) { - u32 cnt = (sizeof(hns_nic_test_strs) / ETH_GSTRING_LEN); + u32 cnt = ARRAY_SIZE(hns_nic_test_strs); if (priv->ae_handle->phy_if == PHY_INTERFACE_MODE_XGMII) cnt--; -- 2.50.1 From ffda5c62878fcd86ec9f1d0122027e7710f9566b Mon Sep 17 00:00:00 2001 From: Lothar Rubusch Date: Sat, 2 Nov 2024 11:41:21 +0000 Subject: [PATCH 02/16] net: stmmac: add support for dwmac 3.72a The dwmac 3.72a is an ip version that can be found on Intel/Altera Arria10 SoCs. Going by the hardware features "snps,multicast-filter-bins" and "snps,perfect-filter-entries" shall be supported. Thus add a compatibility flag, and extend coverage of the driver for the 3.72a. Signed-off-by: Lothar Rubusch Reviewed-by: Andrew Lunn Link: https://patch.msgid.link/20241102114122.4631-2-l.rubusch@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c | 1 + drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c index 598eff926815..b9218c07eb6b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c @@ -56,6 +56,7 @@ static const struct of_device_id dwmac_generic_match[] = { { .compatible = "snps,dwmac-3.610"}, { .compatible = "snps,dwmac-3.70a"}, { .compatible = "snps,dwmac-3.710"}, + { .compatible = "snps,dwmac-3.72a"}, { .compatible = "snps,dwmac-4.00"}, { .compatible = "snps,dwmac-4.10a"}, { .compatible = "snps,dwmac"}, diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index ad868e8d195d..3ac32444e492 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -522,6 +522,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) if (of_device_is_compatible(np, "st,spear600-gmac") || of_device_is_compatible(np, "snps,dwmac-3.50a") || of_device_is_compatible(np, "snps,dwmac-3.70a") || + of_device_is_compatible(np, "snps,dwmac-3.72a") || of_device_is_compatible(np, "snps,dwmac")) { /* Note that the max-frame-size parameter as defined in the * ePAPR v1.1 spec is defined as max-frame-size, it's -- 2.50.1 From 8bed89232a8cb7bd4363e010650da7cdc5cc2e7d Mon Sep 17 00:00:00 2001 From: Lothar Rubusch Date: Sat, 2 Nov 2024 11:41:22 +0000 Subject: [PATCH 03/16] dt-bindings: net: snps,dwmac: add support for Arria10 The hard processor system (HPS) on the Intel/Altera Arria10 provides three Ethernet Media Access Controller (EMAC) peripherals. Each EMAC can be used to transmit and receive data at 10/100/1000 Mbps over ethernet connections in compliance with the IEEE 802.3 specification. The EMACs on the Arria10 are instances of the Synopsis DesignWare Universal 10/100/1000 Ethernet MAC, version 3.72a. Support the Synopsis DesignWare version 3.72a, which is used in Intel's Arria10 SoC, since it was missing. Signed-off-by: Lothar Rubusch Acked-by: Rob Herring (Arm) Link: https://patch.msgid.link/20241102114122.4631-3-l.rubusch@gmail.com Signed-off-by: Jakub Kicinski --- Documentation/devicetree/bindings/net/snps,dwmac.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/net/snps,dwmac.yaml b/Documentation/devicetree/bindings/net/snps,dwmac.yaml index f48a0f44cf2d..1ae6bf51742d 100644 --- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml +++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml @@ -26,6 +26,7 @@ select: - snps,dwmac-3.610 - snps,dwmac-3.70a - snps,dwmac-3.710 + - snps,dwmac-3.72a - snps,dwmac-4.00 - snps,dwmac-4.10a - snps,dwmac-4.20a @@ -90,6 +91,7 @@ properties: - snps,dwmac-3.610 - snps,dwmac-3.70a - snps,dwmac-3.710 + - snps,dwmac-3.72a - snps,dwmac-4.00 - snps,dwmac-4.10a - snps,dwmac-4.20a -- 2.50.1 From 83cb4b470c66b37b19a347a35cea01e0cbdd258d Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Mon, 4 Nov 2024 23:16:20 +0100 Subject: [PATCH 04/16] r8169: remove leftover locks after reverted change After e31a9fedc7d8 ("Revert "r8169: disable ASPM during NAPI poll"") these locks aren't needed any longer. Signed-off-by: Heiner Kallweit Link: https://patch.msgid.link/680f2606-ac7d-4ced-8694-e5033855da9b@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/realtek/r8169_main.c | 29 ++--------------------- 1 file changed, 2 insertions(+), 27 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index e83c4841bd3b..c7dc8b539b3e 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -662,13 +662,9 @@ struct rtl8169_private { struct work_struct work; } wk; - raw_spinlock_t config25_lock; raw_spinlock_t mac_ocp_lock; struct mutex led_lock; /* serialize LED ctrl RMW access */ - raw_spinlock_t cfg9346_usage_lock; - int cfg9346_usage_count; - unsigned supports_gmii:1; unsigned aspm_manageable:1; unsigned dash_enabled:1; @@ -722,22 +718,12 @@ static inline struct device *tp_to_dev(struct rtl8169_private *tp) static void rtl_lock_config_regs(struct rtl8169_private *tp) { - unsigned long flags; - - raw_spin_lock_irqsave(&tp->cfg9346_usage_lock, flags); - if (!--tp->cfg9346_usage_count) - RTL_W8(tp, Cfg9346, Cfg9346_Lock); - raw_spin_unlock_irqrestore(&tp->cfg9346_usage_lock, flags); + RTL_W8(tp, Cfg9346, Cfg9346_Lock); } static void rtl_unlock_config_regs(struct rtl8169_private *tp) { - unsigned long flags; - - raw_spin_lock_irqsave(&tp->cfg9346_usage_lock, flags); - if (!tp->cfg9346_usage_count++) - RTL_W8(tp, Cfg9346, Cfg9346_Unlock); - raw_spin_unlock_irqrestore(&tp->cfg9346_usage_lock, flags); + RTL_W8(tp, Cfg9346, Cfg9346_Unlock); } static void rtl_pci_commit(struct rtl8169_private *tp) @@ -748,24 +734,18 @@ static void rtl_pci_commit(struct rtl8169_private *tp) static void rtl_mod_config2(struct rtl8169_private *tp, u8 clear, u8 set) { - unsigned long flags; u8 val; - raw_spin_lock_irqsave(&tp->config25_lock, flags); val = RTL_R8(tp, Config2); RTL_W8(tp, Config2, (val & ~clear) | set); - raw_spin_unlock_irqrestore(&tp->config25_lock, flags); } static void rtl_mod_config5(struct rtl8169_private *tp, u8 clear, u8 set) { - unsigned long flags; u8 val; - raw_spin_lock_irqsave(&tp->config25_lock, flags); val = RTL_R8(tp, Config5); RTL_W8(tp, Config5, (val & ~clear) | set); - raw_spin_unlock_irqrestore(&tp->config25_lock, flags); } static bool rtl_is_8125(struct rtl8169_private *tp) @@ -1571,7 +1551,6 @@ static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts) { WAKE_MAGIC, Config3, MagicPacket } }; unsigned int i, tmp = ARRAY_SIZE(cfg); - unsigned long flags; u8 options; rtl_unlock_config_regs(tp); @@ -1590,14 +1569,12 @@ static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts) r8168_mac_ocp_modify(tp, 0xc0b6, BIT(0), 0); } - raw_spin_lock_irqsave(&tp->config25_lock, flags); for (i = 0; i < tmp; i++) { options = RTL_R8(tp, cfg[i].reg) & ~cfg[i].mask; if (wolopts & cfg[i].opt) options |= cfg[i].mask; RTL_W8(tp, cfg[i].reg, options); } - raw_spin_unlock_irqrestore(&tp->config25_lock, flags); switch (tp->mac_version) { case RTL_GIGA_MAC_VER_02 ... RTL_GIGA_MAC_VER_06: @@ -5489,8 +5466,6 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) tp->supports_gmii = ent->driver_data == RTL_CFG_NO_GBIT ? 0 : 1; tp->ocp_base = OCP_STD_PHY_BASE; - raw_spin_lock_init(&tp->cfg9346_usage_lock); - raw_spin_lock_init(&tp->config25_lock); raw_spin_lock_init(&tp->mac_ocp_lock); mutex_init(&tp->led_lock); -- 2.50.1 From f920ce04c39983d3fb181a77590b05bedfd25f98 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Sun, 3 Nov 2024 08:57:59 -0800 Subject: [PATCH 05/16] dt-bindings: net: Add T-HEAD dwmac support Add documentation to describe the DesginWare-based GMAC controllers in the T-HEAD TH1520 SoC. Reviewed-by: Andrew Lunn Reviewed-by: Krzysztof Kozlowski Signed-off-by: Jisheng Zhang Signed-off-by: Emil Renner Berthing Signed-off-by: Drew Fustini Link: https://patch.msgid.link/20241103-th1520-gmac-v7-1-ef094a30169c@tenstorrent.com Signed-off-by: Jakub Kicinski --- .../devicetree/bindings/net/snps,dwmac.yaml | 1 + .../bindings/net/thead,th1520-gmac.yaml | 110 ++++++++++++++++++ MAINTAINERS | 1 + 3 files changed, 112 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/thead,th1520-gmac.yaml diff --git a/Documentation/devicetree/bindings/net/snps,dwmac.yaml b/Documentation/devicetree/bindings/net/snps,dwmac.yaml index 1ae6bf51742d..eb1f3ae41ab9 100644 --- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml +++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml @@ -101,6 +101,7 @@ properties: - snps,dwxgmac-2.10 - starfive,jh7100-dwmac - starfive,jh7110-dwmac + - thead,th1520-gmac reg: minItems: 1 diff --git a/Documentation/devicetree/bindings/net/thead,th1520-gmac.yaml b/Documentation/devicetree/bindings/net/thead,th1520-gmac.yaml new file mode 100644 index 000000000000..6d9de3303762 --- /dev/null +++ b/Documentation/devicetree/bindings/net/thead,th1520-gmac.yaml @@ -0,0 +1,110 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/thead,th1520-gmac.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: T-HEAD TH1520 GMAC Ethernet controller + +maintainers: + - Drew Fustini + +description: | + The TH1520 GMAC is described in the TH1520 Peripheral Interface User Manual + https://git.beagleboard.org/beaglev-ahead/beaglev-ahead/-/tree/main/docs + + Features include + - Compliant with IEEE802.3 Specification + - IEEE 1588-2008 standard for precision networked clock synchronization + - Supports 10/100/1000Mbps data transfer rate + - Supports RGMII/MII interface + - Preamble and start of frame data (SFD) insertion in Transmit path + - Preamble and SFD deletion in the Receive path + - Automatic CRC and pad generation options for receive frames + - MDIO master interface for PHY device configuration and management + + The GMAC Registers consists of two parts + - APB registers are used to configure clock frequency/clock enable/clock + direction/PHY interface type. + - AHB registers are use to configure GMAC core (DesignWare Core part). + GMAC core register consists of DMA registers and GMAC registers. + +select: + properties: + compatible: + contains: + enum: + - thead,th1520-gmac + required: + - compatible + +allOf: + - $ref: snps,dwmac.yaml# + +properties: + compatible: + items: + - enum: + - thead,th1520-gmac + - const: snps,dwmac-3.70a + + reg: + items: + - description: DesignWare GMAC IP core registers + - description: GMAC APB registers + + reg-names: + items: + - const: dwmac + - const: apb + + clocks: + items: + - description: GMAC main clock + - description: Peripheral registers interface clock + + clock-names: + items: + - const: stmmaceth + - const: pclk + + interrupts: + items: + - description: Combined signal for various interrupt events + + interrupt-names: + items: + - const: macirq + +required: + - clocks + - clock-names + +unevaluatedProperties: false + +examples: + - | + gmac0: ethernet@e7070000 { + compatible = "thead,th1520-gmac", "snps,dwmac-3.70a"; + reg = <0xe7070000 0x2000>, <0xec003000 0x1000>; + reg-names = "dwmac", "apb"; + clocks = <&clk 1>, <&clk 2>; + clock-names = "stmmaceth", "pclk"; + interrupts = <66>; + interrupt-names = "macirq"; + phy-mode = "rgmii-id"; + snps,fixed-burst; + snps,axi-config = <&stmmac_axi_setup>; + snps,pbl = <32>; + phy-handle = <&phy0>; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dwmac-mdio"; + + phy0: ethernet-phy@0 { + reg = <0>; + }; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 7a5a8a49ce32..c0725ed591de 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19845,6 +19845,7 @@ L: linux-riscv@lists.infradead.org S: Maintained T: git https://github.com/pdp7/linux.git F: Documentation/devicetree/bindings/clock/thead,th1520-clk-ap.yaml +F: Documentation/devicetree/bindings/net/thead,th1520-gmac.yaml F: arch/riscv/boot/dts/thead/ F: drivers/clk/thead/clk-th1520-ap.c F: include/dt-bindings/clock/thead,th1520-clk-ap.h -- 2.50.1 From 33a1a01e3afa724c5f0014548008fe12426f6357 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Sun, 3 Nov 2024 08:58:00 -0800 Subject: [PATCH 06/16] net: stmmac: Add glue layer for T-HEAD TH1520 SoC Add dwmac glue driver to support the DesignWare-based GMAC controllers on the T-HEAD TH1520 SoC. Reviewed-by: Andrew Lunn Signed-off-by: Jisheng Zhang Signed-off-by: Emil Renner Berthing Signed-off-by: Drew Fustini Link: https://patch.msgid.link/20241103-th1520-gmac-v7-2-ef094a30169c@tenstorrent.com Signed-off-by: Jakub Kicinski --- MAINTAINERS | 1 + drivers/net/ethernet/stmicro/stmmac/Kconfig | 10 + drivers/net/ethernet/stmicro/stmmac/Makefile | 1 + .../net/ethernet/stmicro/stmmac/dwmac-thead.c | 273 ++++++++++++++++++ 4 files changed, 285 insertions(+) create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c diff --git a/MAINTAINERS b/MAINTAINERS index c0725ed591de..c51fd742cbc8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19848,6 +19848,7 @@ F: Documentation/devicetree/bindings/clock/thead,th1520-clk-ap.yaml F: Documentation/devicetree/bindings/net/thead,th1520-gmac.yaml F: arch/riscv/boot/dts/thead/ F: drivers/clk/thead/clk-th1520-ap.c +F: drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c F: include/dt-bindings/clock/thead,th1520-clk-ap.h RNBD BLOCK DRIVERS diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig index 05cc07b8f48c..6658536a4e17 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig @@ -228,6 +228,16 @@ config DWMAC_SUN8I stmmac device driver. This driver is used for H3/A83T/A64 EMAC ethernet controller. +config DWMAC_THEAD + tristate "T-HEAD dwmac support" + depends on OF && (ARCH_THEAD || COMPILE_TEST) + help + Support for ethernet controllers on T-HEAD RISC-V SoCs + + This selects the T-HEAD platform specific glue layer support for + the stmmac device driver. This driver is used for T-HEAD TH1520 + ethernet controller. + config DWMAC_IMX8 tristate "NXP IMX8 DWMAC support" default ARCH_MXC diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile index 7e46dca90628..2389fd261344 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o obj-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o obj-$(CONFIG_DWMAC_SUN8I) += dwmac-sun8i.o +obj-$(CONFIG_DWMAC_THEAD) += dwmac-thead.o obj-$(CONFIG_DWMAC_DWC_QOS_ETH) += dwmac-dwc-qos-eth.o obj-$(CONFIG_DWMAC_INTEL_PLAT) += dwmac-intel-plat.o obj-$(CONFIG_DWMAC_LOONGSON1) += dwmac-loongson1.o diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c new file mode 100644 index 000000000000..dce84ed184e9 --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c @@ -0,0 +1,273 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * T-HEAD DWMAC platform driver + * + * Copyright (C) 2021 Alibaba Group Holding Limited. + * Copyright (C) 2023 Jisheng Zhang + * + */ + +#include +#include +#include +#include +#include +#include + +#include "stmmac_platform.h" + +#define GMAC_CLK_EN 0x00 +#define GMAC_TX_CLK_EN BIT(1) +#define GMAC_TX_CLK_N_EN BIT(2) +#define GMAC_TX_CLK_OUT_EN BIT(3) +#define GMAC_RX_CLK_EN BIT(4) +#define GMAC_RX_CLK_N_EN BIT(5) +#define GMAC_EPHY_REF_CLK_EN BIT(6) +#define GMAC_RXCLK_DELAY_CTRL 0x04 +#define GMAC_RXCLK_BYPASS BIT(15) +#define GMAC_RXCLK_INVERT BIT(14) +#define GMAC_RXCLK_DELAY GENMASK(4, 0) +#define GMAC_TXCLK_DELAY_CTRL 0x08 +#define GMAC_TXCLK_BYPASS BIT(15) +#define GMAC_TXCLK_INVERT BIT(14) +#define GMAC_TXCLK_DELAY GENMASK(4, 0) +#define GMAC_PLLCLK_DIV 0x0c +#define GMAC_PLLCLK_DIV_EN BIT(31) +#define GMAC_PLLCLK_DIV_NUM GENMASK(7, 0) +#define GMAC_GTXCLK_SEL 0x18 +#define GMAC_GTXCLK_SEL_PLL BIT(0) +#define GMAC_INTF_CTRL 0x1c +#define PHY_INTF_MASK BIT(0) +#define PHY_INTF_RGMII FIELD_PREP(PHY_INTF_MASK, 1) +#define PHY_INTF_MII_GMII FIELD_PREP(PHY_INTF_MASK, 0) +#define GMAC_TXCLK_OEN 0x20 +#define TXCLK_DIR_MASK BIT(0) +#define TXCLK_DIR_OUTPUT FIELD_PREP(TXCLK_DIR_MASK, 0) +#define TXCLK_DIR_INPUT FIELD_PREP(TXCLK_DIR_MASK, 1) + +#define GMAC_GMII_RGMII_RATE 125000000 +#define GMAC_MII_RATE 25000000 + +struct thead_dwmac { + struct plat_stmmacenet_data *plat; + void __iomem *apb_base; + struct device *dev; +}; + +static int thead_dwmac_set_phy_if(struct plat_stmmacenet_data *plat) +{ + struct thead_dwmac *dwmac = plat->bsp_priv; + u32 phyif; + + switch (plat->mac_interface) { + case PHY_INTERFACE_MODE_MII: + phyif = PHY_INTF_MII_GMII; + break; + case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_ID: + case PHY_INTERFACE_MODE_RGMII_TXID: + case PHY_INTERFACE_MODE_RGMII_RXID: + phyif = PHY_INTF_RGMII; + break; + default: + dev_err(dwmac->dev, "unsupported phy interface %d\n", + plat->mac_interface); + return -EINVAL; + } + + writel(phyif, dwmac->apb_base + GMAC_INTF_CTRL); + return 0; +} + +static int thead_dwmac_set_txclk_dir(struct plat_stmmacenet_data *plat) +{ + struct thead_dwmac *dwmac = plat->bsp_priv; + u32 txclk_dir; + + switch (plat->mac_interface) { + case PHY_INTERFACE_MODE_MII: + txclk_dir = TXCLK_DIR_INPUT; + break; + case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_ID: + case PHY_INTERFACE_MODE_RGMII_TXID: + case PHY_INTERFACE_MODE_RGMII_RXID: + txclk_dir = TXCLK_DIR_OUTPUT; + break; + default: + dev_err(dwmac->dev, "unsupported phy interface %d\n", + plat->mac_interface); + return -EINVAL; + } + + writel(txclk_dir, dwmac->apb_base + GMAC_TXCLK_OEN); + return 0; +} + +static void thead_dwmac_fix_speed(void *priv, unsigned int speed, unsigned int mode) +{ + struct plat_stmmacenet_data *plat; + struct thead_dwmac *dwmac = priv; + unsigned long rate; + u32 div, reg; + + plat = dwmac->plat; + + switch (plat->mac_interface) { + /* For MII, rxc/txc is provided by phy */ + case PHY_INTERFACE_MODE_MII: + return; + + case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_ID: + case PHY_INTERFACE_MODE_RGMII_RXID: + case PHY_INTERFACE_MODE_RGMII_TXID: + rate = clk_get_rate(plat->stmmac_clk); + if (!rate || rate % GMAC_GMII_RGMII_RATE != 0 || + rate % GMAC_MII_RATE != 0) { + dev_err(dwmac->dev, "invalid gmac rate %ld\n", rate); + return; + } + + writel(0, dwmac->apb_base + GMAC_PLLCLK_DIV); + + switch (speed) { + case SPEED_1000: + div = rate / GMAC_GMII_RGMII_RATE; + break; + case SPEED_100: + div = rate / GMAC_MII_RATE; + break; + case SPEED_10: + div = rate * 10 / GMAC_MII_RATE; + break; + default: + dev_err(dwmac->dev, "invalid speed %u\n", speed); + return; + } + + reg = FIELD_PREP(GMAC_PLLCLK_DIV_EN, 1) | + FIELD_PREP(GMAC_PLLCLK_DIV_NUM, div); + writel(reg, dwmac->apb_base + GMAC_PLLCLK_DIV); + break; + default: + dev_err(dwmac->dev, "unsupported phy interface %d\n", + plat->mac_interface); + return; + } +} + +static int thead_dwmac_enable_clk(struct plat_stmmacenet_data *plat) +{ + struct thead_dwmac *dwmac = plat->bsp_priv; + u32 reg; + + switch (plat->mac_interface) { + case PHY_INTERFACE_MODE_MII: + reg = GMAC_RX_CLK_EN | GMAC_TX_CLK_EN; + break; + + case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_ID: + case PHY_INTERFACE_MODE_RGMII_RXID: + case PHY_INTERFACE_MODE_RGMII_TXID: + /* use pll */ + writel(GMAC_GTXCLK_SEL_PLL, dwmac->apb_base + GMAC_GTXCLK_SEL); + reg = GMAC_TX_CLK_EN | GMAC_TX_CLK_N_EN | GMAC_TX_CLK_OUT_EN | + GMAC_RX_CLK_EN | GMAC_RX_CLK_N_EN; + break; + + default: + dev_err(dwmac->dev, "unsupported phy interface %d\n", + plat->mac_interface); + return -EINVAL; + } + + writel(reg, dwmac->apb_base + GMAC_CLK_EN); + return 0; +} + +static int thead_dwmac_init(struct platform_device *pdev, void *priv) +{ + struct thead_dwmac *dwmac = priv; + unsigned int reg; + int ret; + + ret = thead_dwmac_set_phy_if(dwmac->plat); + if (ret) + return ret; + + ret = thead_dwmac_set_txclk_dir(dwmac->plat); + if (ret) + return ret; + + reg = readl(dwmac->apb_base + GMAC_RXCLK_DELAY_CTRL); + reg &= ~(GMAC_RXCLK_DELAY); + reg |= FIELD_PREP(GMAC_RXCLK_DELAY, 0); + writel(reg, dwmac->apb_base + GMAC_RXCLK_DELAY_CTRL); + + reg = readl(dwmac->apb_base + GMAC_TXCLK_DELAY_CTRL); + reg &= ~(GMAC_TXCLK_DELAY); + reg |= FIELD_PREP(GMAC_TXCLK_DELAY, 0); + writel(reg, dwmac->apb_base + GMAC_TXCLK_DELAY_CTRL); + + return thead_dwmac_enable_clk(dwmac->plat); +} + +static int thead_dwmac_probe(struct platform_device *pdev) +{ + struct stmmac_resources stmmac_res; + struct plat_stmmacenet_data *plat; + struct thead_dwmac *dwmac; + void __iomem *apb; + int ret; + + ret = stmmac_get_platform_resources(pdev, &stmmac_res); + if (ret) + return dev_err_probe(&pdev->dev, ret, + "failed to get resources\n"); + + plat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac); + if (IS_ERR(plat)) + return dev_err_probe(&pdev->dev, PTR_ERR(plat), + "dt configuration failed\n"); + + dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL); + if (!dwmac) + return -ENOMEM; + + apb = devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(apb)) + return dev_err_probe(&pdev->dev, PTR_ERR(apb), + "failed to remap gmac apb registers\n"); + + dwmac->dev = &pdev->dev; + dwmac->plat = plat; + dwmac->apb_base = apb; + plat->bsp_priv = dwmac; + plat->fix_mac_speed = thead_dwmac_fix_speed; + plat->init = thead_dwmac_init; + + return devm_stmmac_pltfr_probe(pdev, plat, &stmmac_res); +} + +static const struct of_device_id thead_dwmac_match[] = { + { .compatible = "thead,th1520-gmac" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, thead_dwmac_match); + +static struct platform_driver thead_dwmac_driver = { + .probe = thead_dwmac_probe, + .driver = { + .name = "thead-dwmac", + .pm = &stmmac_pltfr_pm_ops, + .of_match_table = thead_dwmac_match, + }, +}; +module_platform_driver(thead_dwmac_driver); + +MODULE_AUTHOR("Jisheng Zhang "); +MODULE_AUTHOR("Drew Fustini "); +MODULE_DESCRIPTION("T-HEAD DWMAC platform driver"); +MODULE_LICENSE("GPL"); -- 2.50.1 From f2c71c49da8f8941e3e465605fc41939eee9210a Mon Sep 17 00:00:00 2001 From: "Matthieu Baerts (NGI0)" Date: Mon, 4 Nov 2024 13:43:47 +0100 Subject: [PATCH 07/16] mptcp: remove unneeded lock when listing scheds mptcp_get_available_schedulers() needs to iterate over the schedulers' list only to read the names: it doesn't modify anything there. In this case, it is enough to hold the RCU read lock, no need to combine this with the associated spin lock as it was done since its introduction in commit 73c900aa3660 ("mptcp: add net.mptcp.available_schedulers"). Suggested-by: Paolo Abeni Reviewed-by: Geliang Tang Reviewed-by: Simon Horman Signed-off-by: Matthieu Baerts (NGI0) Link: https://patch.msgid.link/20241104-net-next-mptcp-sched-unneeded-lock-v2-1-2ccc1e0c750c@kernel.org Signed-off-by: Jakub Kicinski --- net/mptcp/sched.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/mptcp/sched.c b/net/mptcp/sched.c index 78ed508ebc1b..df7dbcfa3b71 100644 --- a/net/mptcp/sched.c +++ b/net/mptcp/sched.c @@ -60,7 +60,6 @@ void mptcp_get_available_schedulers(char *buf, size_t maxlen) size_t offs = 0; rcu_read_lock(); - spin_lock(&mptcp_sched_list_lock); list_for_each_entry_rcu(sched, &mptcp_sched_list, list) { offs += snprintf(buf + offs, maxlen - offs, "%s%s", @@ -69,7 +68,6 @@ void mptcp_get_available_schedulers(char *buf, size_t maxlen) if (WARN_ON_ONCE(offs >= maxlen)) break; } - spin_unlock(&mptcp_sched_list_lock); rcu_read_unlock(); } -- 2.50.1 From fc49b804967e5b1cc1665efd4de112945e1ab4c6 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Mon, 4 Nov 2024 15:25:24 +0100 Subject: [PATCH 08/16] selftests: netfilter: run conntrack_dump_flush in netns This test will fail if the initial namespace has conntrack active due to unexpected number of flows returned on dump: conntrack_dump_flush.c:451:test_flush_by_zone:Expected ret (7) == 2 (2) test_flush_by_zone: Test failed FAIL conntrack_dump_flush.test_flush_by_zone not ok 2 conntrack_dump_flush.test_flush_by_zone Add a wrapper that unshares this program to avoid this problem. Signed-off-by: Florian Westphal Link: https://patch.msgid.link/20241104142529.2352-1-fw@strlen.de Signed-off-by: Jakub Kicinski --- tools/testing/selftests/net/netfilter/Makefile | 4 ++-- tools/testing/selftests/net/netfilter/conntrack_dump_flush.sh | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100755 tools/testing/selftests/net/netfilter/conntrack_dump_flush.sh diff --git a/tools/testing/selftests/net/netfilter/Makefile b/tools/testing/selftests/net/netfilter/Makefile index 9d009f74cfc2..ffe161fac8b5 100644 --- a/tools/testing/selftests/net/netfilter/Makefile +++ b/tools/testing/selftests/net/netfilter/Makefile @@ -8,6 +8,7 @@ MNL_LDLIBS := $(shell $(HOSTPKG_CONFIG) --libs libmnl 2>/dev/null || echo -lmnl) TEST_PROGS := br_netfilter.sh bridge_brouter.sh TEST_PROGS += br_netfilter_queue.sh +TEST_PROGS += conntrack_dump_flush.sh TEST_PROGS += conntrack_icmp_related.sh TEST_PROGS += conntrack_ipip_mtu.sh TEST_PROGS += conntrack_tcp_unreplied.sh @@ -36,10 +37,9 @@ TEST_PROGS += xt_string.sh TEST_PROGS_EXTENDED = nft_concat_range_perf.sh -TEST_GEN_PROGS = conntrack_dump_flush - TEST_GEN_FILES = audit_logread TEST_GEN_FILES += connect_close nf_queue +TEST_GEN_FILES += conntrack_dump_flush TEST_GEN_FILES += conntrack_reverse_clash TEST_GEN_FILES += sctp_collision diff --git a/tools/testing/selftests/net/netfilter/conntrack_dump_flush.sh b/tools/testing/selftests/net/netfilter/conntrack_dump_flush.sh new file mode 100755 index 000000000000..8b0935385849 --- /dev/null +++ b/tools/testing/selftests/net/netfilter/conntrack_dump_flush.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +exec unshare -n ./conntrack_dump_flush -- 2.50.1 From a84e8c05f58305dfa808bc5465c5175c29d7c9b6 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Mon, 4 Nov 2024 15:28:18 +0100 Subject: [PATCH 09/16] selftests: netfilter: nft_queue.sh: fix warnings with socat 1.8.0.0 Updated to a more recent socat release and saw this: socat E xioopen_ipdgram_listen(): unknown address family 0 socat W address is opened in read-write mode but only supports read-only First error is avoided via pf=ipv4 option, second one via -u (unidirectional) mode. Signed-off-by: Florian Westphal Link: https://patch.msgid.link/20241104142821.2608-1-fw@strlen.de Signed-off-by: Jakub Kicinski --- tools/testing/selftests/net/netfilter/nft_queue.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/net/netfilter/nft_queue.sh b/tools/testing/selftests/net/netfilter/nft_queue.sh index a9d109fcc15c..785e3875a6da 100755 --- a/tools/testing/selftests/net/netfilter/nft_queue.sh +++ b/tools/testing/selftests/net/netfilter/nft_queue.sh @@ -512,10 +512,10 @@ EOF :> "$TMPFILE1" :> "$TMPFILE2" - timeout 10 ip netns exec "$ns2" socat UDP-LISTEN:12345,fork OPEN:"$TMPFILE1",trunc & + timeout 10 ip netns exec "$ns2" socat UDP-LISTEN:12345,fork,pf=ipv4 OPEN:"$TMPFILE1",trunc & local rpid1=$! - timeout 10 ip netns exec "$ns3" socat UDP-LISTEN:12345,fork OPEN:"$TMPFILE2",trunc & + timeout 10 ip netns exec "$ns3" socat UDP-LISTEN:12345,fork,pf=ipv4 OPEN:"$TMPFILE2",trunc & local rpid2=$! ip netns exec "$nsrouter" ./nf_queue -q 12 -d 1000 & @@ -528,8 +528,8 @@ EOF # Send two packets, one should end up in ns1, other in ns2. # This is because nfqueue will delay packet for long enough so that # second packet will not find existing conntrack entry. - echo "Packet 1" | ip netns exec "$ns1" socat STDIN UDP-DATAGRAM:10.6.6.6:12345,bind=0.0.0.0:55221 - echo "Packet 2" | ip netns exec "$ns1" socat STDIN UDP-DATAGRAM:10.6.6.6:12345,bind=0.0.0.0:55221 + echo "Packet 1" | ip netns exec "$ns1" socat -u STDIN UDP-DATAGRAM:10.6.6.6:12345,bind=0.0.0.0:55221 + echo "Packet 2" | ip netns exec "$ns1" socat -u STDIN UDP-DATAGRAM:10.6.6.6:12345,bind=0.0.0.0:55221 busywait 10000 output_files_written "$TMPFILE1" "$TMPFILE2" -- 2.50.1 From eb02688c5c45c3e7af7e71f036a7144f5639cbfe Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Tue, 5 Nov 2024 19:23:50 +0100 Subject: [PATCH 10/16] ipv6: release nexthop on device removal The CI is hitting some aperiodic hangup at device removal time in the pmtu.sh self-test: unregister_netdevice: waiting for veth_A-R1 to become free. Usage count = 6 ref_tracker: veth_A-R1@ffff888013df15d8 has 1/5 users at dst_init+0x84/0x4a0 dst_alloc+0x97/0x150 ip6_dst_alloc+0x23/0x90 ip6_rt_pcpu_alloc+0x1e6/0x520 ip6_pol_route+0x56f/0x840 fib6_rule_lookup+0x334/0x630 ip6_route_output_flags+0x259/0x480 ip6_dst_lookup_tail.constprop.0+0x5c2/0x940 ip6_dst_lookup_flow+0x88/0x190 udp_tunnel6_dst_lookup+0x2a7/0x4c0 vxlan_xmit_one+0xbde/0x4a50 [vxlan] vxlan_xmit+0x9ad/0xf20 [vxlan] dev_hard_start_xmit+0x10e/0x360 __dev_queue_xmit+0xf95/0x18c0 arp_solicit+0x4a2/0xe00 neigh_probe+0xaa/0xf0 While the first suspect is the dst_cache, explicitly tracking the dst owing the last device reference via probes proved such dst is held by the nexthop in the originating fib6_info. Similar to commit f5b51fe804ec ("ipv6: route: purge exception on removal"), we need to explicitly release the originating fib info when disconnecting a to-be-removed device from a live ipv6 dst: move the fib6_info cleanup into ip6_dst_ifdown(). Tested running: ./pmtu.sh cleanup_ipv6_exception in a tight loop for more than 400 iterations with no spat, running an unpatched kernel I observed a splat every ~10 iterations. Fixes: f88d8ea67fbd ("ipv6: Plumb support for nexthop object in a fib6_info") Signed-off-by: Paolo Abeni Reviewed-by: Eric Dumazet Reviewed-by: David Ahern Link: https://patch.msgid.link/604c45c188c609b732286b47ac2a451a40f6cf6d.1730828007.git.pabeni@redhat.com Signed-off-by: Jakub Kicinski --- net/ipv6/route.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index d7ce5cf2017a..038c1eeef0be 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -374,6 +374,7 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev) { struct rt6_info *rt = dst_rt6_info(dst); struct inet6_dev *idev = rt->rt6i_idev; + struct fib6_info *from; if (idev && idev->dev != blackhole_netdev) { struct inet6_dev *blackhole_idev = in6_dev_get(blackhole_netdev); @@ -383,6 +384,8 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev) in6_dev_put(idev); } } + from = unrcu_pointer(xchg(&rt->from, NULL)); + fib6_info_release(from); } static bool __rt6_check_expired(const struct rt6_info *rt) @@ -1455,7 +1458,6 @@ static DEFINE_SPINLOCK(rt6_exception_lock); static void rt6_remove_exception(struct rt6_exception_bucket *bucket, struct rt6_exception *rt6_ex) { - struct fib6_info *from; struct net *net; if (!bucket || !rt6_ex) @@ -1467,8 +1469,6 @@ static void rt6_remove_exception(struct rt6_exception_bucket *bucket, /* purge completely the exception to allow releasing the held resources: * some [sk] cache may keep the dst around for unlimited time */ - from = unrcu_pointer(xchg(&rt6_ex->rt6i->from, NULL)); - fib6_info_release(from); dst_dev_put(&rt6_ex->rt6i->dst); hlist_del_rcu(&rt6_ex->hlist); -- 2.50.1 From 52ed077aa6336dbef83a2d6d21c52d1706fb7f16 Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Tue, 5 Nov 2024 19:23:51 +0100 Subject: [PATCH 11/16] selftests: net: really check for bg process completion A recent refactor transformed the check for process completion in a true statement, due to a typo. As a result, the relevant test-case is unable to catch the regression it was supposed to detect. Restore the correct condition. Fixes: 691bb4e49c98 ("selftests: net: avoid just another constant wait") Signed-off-by: Paolo Abeni Reviewed-by: David Ahern Link: https://patch.msgid.link/0e6f213811f8e93a235307e683af8225cc6277ae.1730828007.git.pabeni@redhat.com Signed-off-by: Jakub Kicinski --- tools/testing/selftests/net/pmtu.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh index 569bce8b6383..6c651c880fe8 100755 --- a/tools/testing/selftests/net/pmtu.sh +++ b/tools/testing/selftests/net/pmtu.sh @@ -2056,7 +2056,7 @@ check_running() { pid=${1} cmd=${2} - [ "$(cat /proc/${pid}/cmdline 2>/dev/null | tr -d '\0')" = "{cmd}" ] + [ "$(cat /proc/${pid}/cmdline 2>/dev/null | tr -d '\0')" = "${cmd}" ] } test_cleanup_vxlanX_exception() { -- 2.50.1 From 1e4033b53db48cc77c436feac9c6d7d63db87b87 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 5 Nov 2024 17:43:57 +0000 Subject: [PATCH 12/16] net: skb_reset_mac_len() must check if mac_header was set Recent discussions show that skb_reset_mac_len() should be more careful. We expect the MAC header being set. If not, clear skb->mac_len and fire a warning for CONFIG_DEBUG_NET=y builds. If after investigations we find that not having a MAC header was okay, we can remove the warning. Signed-off-by: Eric Dumazet Link: https://lore.kernel.org/netdev/CANn89iJZGH+yEfJxfPWa3Hm7jxb-aeY2Up4HufmLMnVuQXt38A@mail.gmail.com/T/ Cc: En-Wei Wu Reviewed-by: Joe Damato Reviewed-by: Xuan Zhuo Link: https://patch.msgid.link/20241105174403.850330-2-edumazet@google.com Signed-off-by: Jakub Kicinski --- include/linux/skbuff.h | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 48f1e0fa2a13..5d8fefa71cac 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2909,9 +2909,19 @@ static inline void skb_reset_inner_headers(struct sk_buff *skb) skb->inner_transport_header = skb->transport_header; } +static inline int skb_mac_header_was_set(const struct sk_buff *skb) +{ + return skb->mac_header != (typeof(skb->mac_header))~0U; +} + static inline void skb_reset_mac_len(struct sk_buff *skb) { - skb->mac_len = skb->network_header - skb->mac_header; + if (!skb_mac_header_was_set(skb)) { + DEBUG_NET_WARN_ON_ONCE(1); + skb->mac_len = 0; + } else { + skb->mac_len = skb->network_header - skb->mac_header; + } } static inline unsigned char *skb_inner_transport_header(const struct sk_buff @@ -3014,11 +3024,6 @@ static inline void skb_set_network_header(struct sk_buff *skb, const int offset) skb->network_header += offset; } -static inline int skb_mac_header_was_set(const struct sk_buff *skb) -{ - return skb->mac_header != (typeof(skb->mac_header))~0U; -} - static inline unsigned char *skb_mac_header(const struct sk_buff *skb) { DEBUG_NET_WARN_ON_ONCE(!skb_mac_header_was_set(skb)); -- 2.50.1 From cfe8394e06f22847ecae0312bdd0b633b471b3f0 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 5 Nov 2024 17:43:58 +0000 Subject: [PATCH 13/16] net: add debug check in skb_reset_inner_transport_header() Make sure (skb->data - skb->head) can fit in skb->inner_transport_header This needs CONFIG_DEBUG_NET=y. Signed-off-by: Eric Dumazet Reviewed-by: Joe Damato Reviewed-by: Xuan Zhuo Link: https://patch.msgid.link/20241105174403.850330-3-edumazet@google.com Signed-off-by: Jakub Kicinski --- include/linux/skbuff.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 5d8fefa71cac..75795568803c 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2937,7 +2937,10 @@ static inline int skb_inner_transport_offset(const struct sk_buff *skb) static inline void skb_reset_inner_transport_header(struct sk_buff *skb) { - skb->inner_transport_header = skb->data - skb->head; + long offset = skb->data - skb->head; + + DEBUG_NET_WARN_ON_ONCE(offset != (typeof(skb->inner_transport_header))offset); + skb->inner_transport_header = offset; } static inline void skb_set_inner_transport_header(struct sk_buff *skb, -- 2.50.1 From 1732e4bedb3e29986da6ea315e8bf8caf74e1e38 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 5 Nov 2024 17:43:59 +0000 Subject: [PATCH 14/16] net: add debug check in skb_reset_inner_network_header() Make sure (skb->data - skb->head) can fit in skb->inner_network_header This needs CONFIG_DEBUG_NET=y. Signed-off-by: Eric Dumazet Reviewed-by: Joe Damato Reviewed-by: Xuan Zhuo Link: https://patch.msgid.link/20241105174403.850330-4-edumazet@google.com Signed-off-by: Jakub Kicinski --- include/linux/skbuff.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 75795568803c..8dafd1295a6e 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2957,7 +2957,10 @@ static inline unsigned char *skb_inner_network_header(const struct sk_buff *skb) static inline void skb_reset_inner_network_header(struct sk_buff *skb) { - skb->inner_network_header = skb->data - skb->head; + long offset = skb->data - skb->head; + + DEBUG_NET_WARN_ON_ONCE(offset != (typeof(skb->inner_network_header))offset); + skb->inner_network_header = offset; } static inline void skb_set_inner_network_header(struct sk_buff *skb, -- 2.50.1 From 78a0cb2f45dc9327f26956c242f7f4b450efff49 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 5 Nov 2024 17:44:00 +0000 Subject: [PATCH 15/16] net: add debug check in skb_reset_inner_mac_header() Make sure (skb->data - skb->head) can fit in skb->inner_mac_header This needs CONFIG_DEBUG_NET=y. Signed-off-by: Eric Dumazet Reviewed-by: Joe Damato Reviewed-by: Xuan Zhuo Link: https://patch.msgid.link/20241105174403.850330-5-edumazet@google.com Signed-off-by: Jakub Kicinski --- include/linux/skbuff.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 8dafd1295a6e..32a7d8a65b9f 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2982,7 +2982,10 @@ static inline unsigned char *skb_inner_mac_header(const struct sk_buff *skb) static inline void skb_reset_inner_mac_header(struct sk_buff *skb) { - skb->inner_mac_header = skb->data - skb->head; + long offset = skb->data - skb->head; + + DEBUG_NET_WARN_ON_ONCE(offset != (typeof(skb->inner_mac_header))offset); + skb->inner_mac_header = offset; } static inline void skb_set_inner_mac_header(struct sk_buff *skb, -- 2.50.1 From ae50ea52bdd77eabd8f3c4630c1b03c3373f61a5 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 5 Nov 2024 17:44:01 +0000 Subject: [PATCH 16/16] net: add debug check in skb_reset_transport_header() Make sure (skb->data - skb->head) can fit in skb->transport_header This needs CONFIG_DEBUG_NET=y. Signed-off-by: Eric Dumazet Reviewed-by: Joe Damato Reviewed-by: Xuan Zhuo Link: https://patch.msgid.link/20241105174403.850330-6-edumazet@google.com Signed-off-by: Jakub Kicinski --- include/linux/skbuff.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 32a7d8a65b9f..f76524844e7e 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -3007,7 +3007,10 @@ static inline unsigned char *skb_transport_header(const struct sk_buff *skb) static inline void skb_reset_transport_header(struct sk_buff *skb) { - skb->transport_header = skb->data - skb->head; + long offset = skb->data - skb->head; + + DEBUG_NET_WARN_ON_ONCE(offset != (typeof(skb->transport_header))offset); + skb->transport_header = offset; } static inline void skb_set_transport_header(struct sk_buff *skb, -- 2.50.1