Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'mlxsw-move-tx-header-handling-to-pci-driver'

Petr Machata says:

====================
mlxsw: Move Tx header handling to PCI driver

Amit Cohen writes:

Tx header should be added to all packets transmitted from the CPU to
Spectrum ASICs. Historically, handling this header was added as a driver
function, as Tx header is different between Spectrum and Switch-X.

From May 2021, there is no support for SwitchX-2 ASIC, and all the relevant
code was removed.

For now, there is no justification to handle Tx header as part of
spectrum.c, we can handle this as part of PCI, in skb_transmit().

This change will also be useful when XDP support will be added to mlxsw,
as for XDP_TX and XDP_REDIRECT actions, Tx header should be added before
transmitting the packet.

Patch set overview:
Patches #1-#2 add structure to store Tx header info and initialize it
Patch #3 moves definitions of Tx header fields to txheader.h
Patch #4 moves Tx header handling to PCI driver
Patch #5 removes unnecessary attribute
====================

Link: https://patch.msgid.link/cover.1737044384.git.petrm@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+176 -259
+10 -11
drivers/net/ethernet/mellanox/mlxsw/core.c
··· 35 35 #include "reg.h" 36 36 #include "resources.h" 37 37 #include "../mlxfw/mlxfw.h" 38 + #include "txheader.h" 38 39 39 40 static LIST_HEAD(mlxsw_core_driver_list); 40 41 static DEFINE_SPINLOCK(mlxsw_core_driver_list_lock); ··· 678 677 struct list_head bulk_list; 679 678 struct mlxsw_core *core; 680 679 struct sk_buff *tx_skb; 681 - struct mlxsw_tx_info tx_info; 680 + struct mlxsw_txhdr_info txhdr_info; 682 681 struct delayed_work timeout_dw; 683 682 unsigned int retries; 684 683 u64 tid; ··· 738 737 if (!skb) 739 738 return -ENOMEM; 740 739 741 - trace_devlink_hwmsg(priv_to_devlink(mlxsw_core), false, 0, 742 - skb->data + mlxsw_core->driver->txhdr_len, 743 - skb->len - mlxsw_core->driver->txhdr_len); 740 + trace_devlink_hwmsg(priv_to_devlink(mlxsw_core), false, 0, skb->data, 741 + skb->len); 744 742 745 743 atomic_set(&trans->active, 1); 746 - err = mlxsw_core_skb_transmit(mlxsw_core, skb, &trans->tx_info); 744 + err = mlxsw_core_skb_transmit(mlxsw_core, skb, &trans->txhdr_info); 747 745 if (err) { 748 746 dev_kfree_skb(skb); 749 747 return err; ··· 944 944 945 945 emad_len = (reg_len + sizeof(u32) + MLXSW_EMAD_ETH_HDR_LEN + 946 946 (MLXSW_EMAD_OP_TLV_LEN + MLXSW_EMAD_END_TLV_LEN) * 947 - sizeof(u32) + mlxsw_core->driver->txhdr_len); 947 + sizeof(u32) + MLXSW_TXHDR_LEN); 948 948 if (mlxsw_core->emad.enable_string_tlv) 949 949 emad_len += MLXSW_EMAD_STRING_TLV_LEN * sizeof(u32); 950 950 if (mlxsw_core->emad.enable_latency_tlv) ··· 984 984 list_add_tail(&trans->bulk_list, bulk_list); 985 985 trans->core = mlxsw_core; 986 986 trans->tx_skb = skb; 987 - trans->tx_info.local_port = MLXSW_PORT_CPU_PORT; 988 - trans->tx_info.is_emad = true; 987 + trans->txhdr_info.tx_info.local_port = MLXSW_PORT_CPU_PORT; 988 + trans->txhdr_info.tx_info.is_emad = true; 989 989 INIT_DELAYED_WORK(&trans->timeout_dw, mlxsw_emad_trans_timeout_work); 990 990 trans->tid = tid; 991 991 init_completion(&trans->completion); ··· 995 995 trans->type = type; 996 996 997 997 mlxsw_emad_construct(mlxsw_core, skb, reg, payload, type, trans->tid); 998 - mlxsw_core->driver->txhdr_construct(skb, &trans->tx_info); 999 998 1000 999 spin_lock_bh(&mlxsw_core->emad.trans_list_lock); 1001 1000 list_add_tail_rcu(&trans->list, &mlxsw_core->emad.trans_list); ··· 2329 2330 EXPORT_SYMBOL(mlxsw_core_skb_transmit_busy); 2330 2331 2331 2332 int mlxsw_core_skb_transmit(struct mlxsw_core *mlxsw_core, struct sk_buff *skb, 2332 - const struct mlxsw_tx_info *tx_info) 2333 + const struct mlxsw_txhdr_info *txhdr_info) 2333 2334 { 2334 2335 return mlxsw_core->bus->skb_transmit(mlxsw_core->bus_priv, skb, 2335 - tx_info); 2336 + txhdr_info); 2336 2337 } 2337 2338 EXPORT_SYMBOL(mlxsw_core_skb_transmit); 2338 2339
+8 -5
drivers/net/ethernet/mellanox/mlxsw/core.h
··· 72 72 bool is_emad; 73 73 }; 74 74 75 + struct mlxsw_txhdr_info { 76 + struct mlxsw_tx_info tx_info; 77 + bool data; 78 + u16 max_fid; /* Used for PTP packets which are sent as data. */ 79 + }; 80 + 75 81 struct mlxsw_rx_md_info { 76 82 struct napi_struct *napi; 77 83 u32 cookie_index; ··· 101 95 bool mlxsw_core_skb_transmit_busy(struct mlxsw_core *mlxsw_core, 102 96 const struct mlxsw_tx_info *tx_info); 103 97 int mlxsw_core_skb_transmit(struct mlxsw_core *mlxsw_core, struct sk_buff *skb, 104 - const struct mlxsw_tx_info *tx_info); 98 + const struct mlxsw_txhdr_info *txhdr_info); 105 99 void mlxsw_core_ptp_transmitted(struct mlxsw_core *mlxsw_core, 106 100 struct sk_buff *skb, u16 local_port); 107 101 ··· 432 426 int (*trap_policer_counter_get)(struct mlxsw_core *mlxsw_core, 433 427 const struct devlink_trap_policer *policer, 434 428 u64 *p_drops); 435 - void (*txhdr_construct)(struct sk_buff *skb, 436 - const struct mlxsw_tx_info *tx_info); 437 429 int (*resources_register)(struct mlxsw_core *mlxsw_core); 438 430 int (*kvd_sizes_get)(struct mlxsw_core *mlxsw_core, 439 431 const struct mlxsw_config_profile *profile, ··· 444 440 void (*ptp_transmitted)(struct mlxsw_core *mlxsw_core, 445 441 struct sk_buff *skb, u16 local_port); 446 442 447 - u8 txhdr_len; 448 443 const struct mlxsw_config_profile *profile; 449 444 bool sdq_supports_cqe_v2; 450 445 }; ··· 490 487 bool (*skb_transmit_busy)(void *bus_priv, 491 488 const struct mlxsw_tx_info *tx_info); 492 489 int (*skb_transmit)(void *bus_priv, struct sk_buff *skb, 493 - const struct mlxsw_tx_info *tx_info); 490 + const struct mlxsw_txhdr_info *txhdr_info); 494 491 int (*cmd_exec)(void *bus_priv, u16 opcode, u8 opcode_mod, 495 492 u32 in_mod, bool out_mbox_direct, 496 493 char *in_mbox, size_t in_mbox_size,
+1 -1
drivers/net/ethernet/mellanox/mlxsw/i2c.c
··· 516 516 } 517 517 518 518 static int mlxsw_i2c_skb_transmit(void *bus_priv, struct sk_buff *skb, 519 - const struct mlxsw_tx_info *tx_info) 519 + const struct mlxsw_txhdr_info *txhdr_info) 520 520 { 521 521 return 0; 522 522 }
+41 -3
drivers/net/ethernet/mellanox/mlxsw/pci.c
··· 21 21 #include "cmd.h" 22 22 #include "port.h" 23 23 #include "resources.h" 24 + #include "txheader.h" 24 25 25 26 #define mlxsw_pci_write32(mlxsw_pci, reg, val) \ 26 27 iowrite32be(val, (mlxsw_pci)->hw_addr + (MLXSW_PCI_ ## reg)) ··· 2096 2095 mlxsw_pci_free_irq_vectors(mlxsw_pci); 2097 2096 } 2098 2097 2098 + static int mlxsw_pci_txhdr_construct(struct sk_buff *skb, 2099 + const struct mlxsw_txhdr_info *txhdr_info) 2100 + { 2101 + const struct mlxsw_tx_info tx_info = txhdr_info->tx_info; 2102 + char *txhdr; 2103 + 2104 + if (skb_cow_head(skb, MLXSW_TXHDR_LEN)) 2105 + return -ENOMEM; 2106 + 2107 + txhdr = skb_push(skb, MLXSW_TXHDR_LEN); 2108 + memset(txhdr, 0, MLXSW_TXHDR_LEN); 2109 + 2110 + mlxsw_tx_hdr_version_set(txhdr, MLXSW_TXHDR_VERSION_1); 2111 + mlxsw_tx_hdr_proto_set(txhdr, MLXSW_TXHDR_PROTO_ETH); 2112 + mlxsw_tx_hdr_swid_set(txhdr, 0); 2113 + 2114 + if (unlikely(txhdr_info->data)) { 2115 + u16 fid = txhdr_info->max_fid + tx_info.local_port - 1; 2116 + 2117 + mlxsw_tx_hdr_rx_is_router_set(txhdr, true); 2118 + mlxsw_tx_hdr_fid_valid_set(txhdr, true); 2119 + mlxsw_tx_hdr_fid_set(txhdr, fid); 2120 + mlxsw_tx_hdr_type_set(txhdr, MLXSW_TXHDR_TYPE_DATA); 2121 + } else { 2122 + mlxsw_tx_hdr_ctl_set(txhdr, MLXSW_TXHDR_ETH_CTL); 2123 + mlxsw_tx_hdr_control_tclass_set(txhdr, 1); 2124 + mlxsw_tx_hdr_port_mid_set(txhdr, tx_info.local_port); 2125 + mlxsw_tx_hdr_type_set(txhdr, MLXSW_TXHDR_TYPE_CONTROL); 2126 + } 2127 + 2128 + return 0; 2129 + } 2130 + 2099 2131 static struct mlxsw_pci_queue * 2100 2132 mlxsw_pci_sdq_pick(struct mlxsw_pci *mlxsw_pci, 2101 2133 const struct mlxsw_tx_info *tx_info) ··· 2156 2122 } 2157 2123 2158 2124 static int mlxsw_pci_skb_transmit(void *bus_priv, struct sk_buff *skb, 2159 - const struct mlxsw_tx_info *tx_info) 2125 + const struct mlxsw_txhdr_info *txhdr_info) 2160 2126 { 2161 2127 struct mlxsw_pci *mlxsw_pci = bus_priv; 2162 2128 struct mlxsw_pci_queue *q; ··· 2165 2131 int i; 2166 2132 int err; 2167 2133 2134 + err = mlxsw_pci_txhdr_construct(skb, txhdr_info); 2135 + if (err) 2136 + return err; 2137 + 2168 2138 if (skb_shinfo(skb)->nr_frags > MLXSW_PCI_WQE_SG_ENTRIES - 1) { 2169 2139 err = skb_linearize(skb); 2170 2140 if (err) 2171 2141 return err; 2172 2142 } 2173 2143 2174 - q = mlxsw_pci_sdq_pick(mlxsw_pci, tx_info); 2144 + q = mlxsw_pci_sdq_pick(mlxsw_pci, &txhdr_info->tx_info); 2175 2145 spin_lock_bh(&q->lock); 2176 2146 elem_info = mlxsw_pci_queue_elem_info_producer_get(q); 2177 2147 if (!elem_info) { ··· 2183 2145 err = -EAGAIN; 2184 2146 goto unlock; 2185 2147 } 2186 - mlxsw_skb_cb(skb)->tx_info = *tx_info; 2148 + mlxsw_skb_cb(skb)->tx_info = txhdr_info->tx_info; 2187 2149 elem_info->sdq.skb = skb; 2188 2150 2189 2151 wqe = elem_info->elem;
+48 -161
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
··· 107 107 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00 108 108 }; 109 109 110 - /* tx_hdr_version 111 - * Tx header version. 112 - * Must be set to 1. 113 - */ 114 - MLXSW_ITEM32(tx, hdr, version, 0x00, 28, 4); 115 - 116 - /* tx_hdr_ctl 117 - * Packet control type. 118 - * 0 - Ethernet control (e.g. EMADs, LACP) 119 - * 1 - Ethernet data 120 - */ 121 - MLXSW_ITEM32(tx, hdr, ctl, 0x00, 26, 2); 122 - 123 - /* tx_hdr_proto 124 - * Packet protocol type. Must be set to 1 (Ethernet). 125 - */ 126 - MLXSW_ITEM32(tx, hdr, proto, 0x00, 21, 3); 127 - 128 - /* tx_hdr_rx_is_router 129 - * Packet is sent from the router. Valid for data packets only. 130 - */ 131 - MLXSW_ITEM32(tx, hdr, rx_is_router, 0x00, 19, 1); 132 - 133 - /* tx_hdr_fid_valid 134 - * Indicates if the 'fid' field is valid and should be used for 135 - * forwarding lookup. Valid for data packets only. 136 - */ 137 - MLXSW_ITEM32(tx, hdr, fid_valid, 0x00, 16, 1); 138 - 139 - /* tx_hdr_swid 140 - * Switch partition ID. Must be set to 0. 141 - */ 142 - MLXSW_ITEM32(tx, hdr, swid, 0x00, 12, 3); 143 - 144 - /* tx_hdr_control_tclass 145 - * Indicates if the packet should use the control TClass and not one 146 - * of the data TClasses. 147 - */ 148 - MLXSW_ITEM32(tx, hdr, control_tclass, 0x00, 6, 1); 149 - 150 - /* tx_hdr_etclass 151 - * Egress TClass to be used on the egress device on the egress port. 152 - */ 153 - MLXSW_ITEM32(tx, hdr, etclass, 0x00, 0, 4); 154 - 155 - /* tx_hdr_port_mid 156 - * Destination local port for unicast packets. 157 - * Destination multicast ID for multicast packets. 158 - * 159 - * Control packets are directed to a specific egress port, while data 160 - * packets are transmitted through the CPU port (0) into the switch partition, 161 - * where forwarding rules are applied. 162 - */ 163 - MLXSW_ITEM32(tx, hdr, port_mid, 0x04, 16, 16); 164 - 165 - /* tx_hdr_fid 166 - * Forwarding ID used for L2 forwarding lookup. Valid only if 'fid_valid' is 167 - * set, otherwise calculated based on the packet's VID using VID to FID mapping. 168 - * Valid for data packets only. 169 - */ 170 - MLXSW_ITEM32(tx, hdr, fid, 0x08, 16, 16); 171 - 172 - /* tx_hdr_type 173 - * 0 - Data packets 174 - * 6 - Control packets 175 - */ 176 - MLXSW_ITEM32(tx, hdr, type, 0x0C, 0, 4); 177 - 178 110 int mlxsw_sp_flow_counter_get(struct mlxsw_sp *mlxsw_sp, 179 111 unsigned int counter_index, bool clear, 180 112 u64 *packets, u64 *bytes) ··· 165 233 counter_index); 166 234 } 167 235 168 - void mlxsw_sp_txhdr_construct(struct sk_buff *skb, 169 - const struct mlxsw_tx_info *tx_info) 170 - { 171 - char *txhdr = skb_push(skb, MLXSW_TXHDR_LEN); 172 - 173 - memset(txhdr, 0, MLXSW_TXHDR_LEN); 174 - 175 - mlxsw_tx_hdr_version_set(txhdr, MLXSW_TXHDR_VERSION_1); 176 - mlxsw_tx_hdr_ctl_set(txhdr, MLXSW_TXHDR_ETH_CTL); 177 - mlxsw_tx_hdr_proto_set(txhdr, MLXSW_TXHDR_PROTO_ETH); 178 - mlxsw_tx_hdr_swid_set(txhdr, 0); 179 - mlxsw_tx_hdr_control_tclass_set(txhdr, 1); 180 - mlxsw_tx_hdr_port_mid_set(txhdr, tx_info->local_port); 181 - mlxsw_tx_hdr_type_set(txhdr, MLXSW_TXHDR_TYPE_CONTROL); 182 - } 183 - 184 - int 185 - mlxsw_sp_txhdr_ptp_data_construct(struct mlxsw_core *mlxsw_core, 186 - struct mlxsw_sp_port *mlxsw_sp_port, 187 - struct sk_buff *skb, 188 - const struct mlxsw_tx_info *tx_info) 189 - { 190 - char *txhdr; 191 - u16 max_fid; 192 - int err; 193 - 194 - if (skb_cow_head(skb, MLXSW_TXHDR_LEN)) { 195 - err = -ENOMEM; 196 - goto err_skb_cow_head; 197 - } 198 - 199 - if (!MLXSW_CORE_RES_VALID(mlxsw_core, FID)) { 200 - err = -EIO; 201 - goto err_res_valid; 202 - } 203 - max_fid = MLXSW_CORE_RES_GET(mlxsw_core, FID); 204 - 205 - txhdr = skb_push(skb, MLXSW_TXHDR_LEN); 206 - memset(txhdr, 0, MLXSW_TXHDR_LEN); 207 - 208 - mlxsw_tx_hdr_version_set(txhdr, MLXSW_TXHDR_VERSION_1); 209 - mlxsw_tx_hdr_proto_set(txhdr, MLXSW_TXHDR_PROTO_ETH); 210 - mlxsw_tx_hdr_rx_is_router_set(txhdr, true); 211 - mlxsw_tx_hdr_fid_valid_set(txhdr, true); 212 - mlxsw_tx_hdr_fid_set(txhdr, max_fid + tx_info->local_port - 1); 213 - mlxsw_tx_hdr_type_set(txhdr, MLXSW_TXHDR_TYPE_DATA); 214 - return 0; 215 - 216 - err_res_valid: 217 - err_skb_cow_head: 218 - this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped); 219 - dev_kfree_skb_any(skb); 220 - return err; 221 - } 222 - 223 236 static bool mlxsw_sp_skb_requires_ts(struct sk_buff *skb) 224 237 { 225 238 unsigned int type; ··· 176 299 return !!ptp_parse_header(skb, type); 177 300 } 178 301 179 - static int mlxsw_sp_txhdr_handle(struct mlxsw_core *mlxsw_core, 180 - struct mlxsw_sp_port *mlxsw_sp_port, 181 - struct sk_buff *skb, 182 - const struct mlxsw_tx_info *tx_info) 302 + static void mlxsw_sp_txhdr_info_data_init(struct mlxsw_core *mlxsw_core, 303 + struct sk_buff *skb, 304 + struct mlxsw_txhdr_info *txhdr_info) 183 305 { 184 - struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); 306 + /* Resource validation was done as part of PTP init. */ 307 + u16 max_fid = MLXSW_CORE_RES_GET(mlxsw_core, FID); 185 308 186 - /* In Spectrum-2 and Spectrum-3, PTP events that require a time stamp 187 - * need special handling and cannot be transmitted as regular control 188 - * packets. 309 + txhdr_info->data = true; 310 + txhdr_info->max_fid = max_fid; 311 + } 312 + 313 + static struct sk_buff * 314 + mlxsw_sp_vlan_tag_push(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb) 315 + { 316 + /* In some Spectrum ASICs, in order for PTP event packets to have their 317 + * correction field correctly set on the egress port they must be 318 + * transmitted as data packets. Such packets ingress the ASIC via the 319 + * CPU port and must have a VLAN tag, as the CPU port is not configured 320 + * with a PVID. Push the default VLAN (4095), which is configured as 321 + * egress untagged on all the ports. 189 322 */ 190 - if (unlikely(mlxsw_sp_skb_requires_ts(skb))) 191 - return mlxsw_sp->ptp_ops->txhdr_construct(mlxsw_core, 192 - mlxsw_sp_port, skb, 193 - tx_info); 323 + if (skb_vlan_tagged(skb)) 324 + return skb; 194 325 195 - if (skb_cow_head(skb, MLXSW_TXHDR_LEN)) { 196 - this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped); 197 - dev_kfree_skb_any(skb); 198 - return -ENOMEM; 199 - } 326 + return vlan_insert_tag_set_proto(skb, htons(ETH_P_8021Q), 327 + MLXSW_SP_DEFAULT_VID); 328 + } 200 329 201 - mlxsw_sp_txhdr_construct(skb, tx_info); 202 - return 0; 330 + static struct sk_buff * 331 + mlxsw_sp_txhdr_preparations(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb, 332 + struct mlxsw_txhdr_info *txhdr_info) 333 + { 334 + if (likely(!mlxsw_sp_skb_requires_ts(skb))) 335 + return skb; 336 + 337 + if (!mlxsw_sp->ptp_ops->tx_as_data) 338 + return skb; 339 + 340 + /* Special handling for PTP events that require a time stamp and cannot 341 + * be transmitted as regular control packets. 342 + */ 343 + mlxsw_sp_txhdr_info_data_init(mlxsw_sp->core, skb, txhdr_info); 344 + return mlxsw_sp_vlan_tag_push(mlxsw_sp, skb); 203 345 } 204 346 205 347 enum mlxsw_reg_spms_state mlxsw_sp_stp_spms_state(u8 state) ··· 617 721 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); 618 722 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; 619 723 struct mlxsw_sp_port_pcpu_stats *pcpu_stats; 620 - const struct mlxsw_tx_info tx_info = { 621 - .local_port = mlxsw_sp_port->local_port, 622 - .is_emad = false, 724 + struct mlxsw_txhdr_info txhdr_info = { 725 + .tx_info.local_port = mlxsw_sp_port->local_port, 726 + .tx_info.is_emad = false, 623 727 }; 624 728 u64 len; 625 729 int err; 626 730 627 731 memset(skb->cb, 0, sizeof(struct mlxsw_skb_cb)); 628 732 629 - if (mlxsw_core_skb_transmit_busy(mlxsw_sp->core, &tx_info)) 733 + if (mlxsw_core_skb_transmit_busy(mlxsw_sp->core, &txhdr_info.tx_info)) 630 734 return NETDEV_TX_BUSY; 631 735 632 736 if (eth_skb_pad(skb)) { ··· 634 738 return NETDEV_TX_OK; 635 739 } 636 740 637 - err = mlxsw_sp_txhdr_handle(mlxsw_sp->core, mlxsw_sp_port, skb, 638 - &tx_info); 639 - if (err) 741 + skb = mlxsw_sp_txhdr_preparations(mlxsw_sp, skb, &txhdr_info); 742 + if (!skb) { 743 + this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped); 640 744 return NETDEV_TX_OK; 745 + } 641 746 642 747 /* TX header is consumed by HW on the way so we shouldn't count its 643 748 * bytes as being sent. ··· 648 751 /* Due to a race we might fail here because of a full queue. In that 649 752 * unlikely case we simply drop the packet. 650 753 */ 651 - err = mlxsw_core_skb_transmit(mlxsw_sp->core, skb, &tx_info); 754 + err = mlxsw_core_skb_transmit(mlxsw_sp->core, skb, &txhdr_info); 652 755 653 756 if (!err) { 654 757 pcpu_stats = this_cpu_ptr(mlxsw_sp_port->pcpu_stats); ··· 2689 2792 .get_stats_count = mlxsw_sp1_get_stats_count, 2690 2793 .get_stats_strings = mlxsw_sp1_get_stats_strings, 2691 2794 .get_stats = mlxsw_sp1_get_stats, 2692 - .txhdr_construct = mlxsw_sp_ptp_txhdr_construct, 2693 2795 }; 2694 2796 2695 2797 static const struct mlxsw_sp_ptp_ops mlxsw_sp2_ptp_ops = { ··· 2707 2811 .get_stats_count = mlxsw_sp2_get_stats_count, 2708 2812 .get_stats_strings = mlxsw_sp2_get_stats_strings, 2709 2813 .get_stats = mlxsw_sp2_get_stats, 2710 - .txhdr_construct = mlxsw_sp2_ptp_txhdr_construct, 2814 + .tx_as_data = true, 2711 2815 }; 2712 2816 2713 2817 static const struct mlxsw_sp_ptp_ops mlxsw_sp4_ptp_ops = { ··· 2726 2830 .get_stats_count = mlxsw_sp2_get_stats_count, 2727 2831 .get_stats_strings = mlxsw_sp2_get_stats_strings, 2728 2832 .get_stats = mlxsw_sp2_get_stats, 2729 - .txhdr_construct = mlxsw_sp_ptp_txhdr_construct, 2730 2833 }; 2731 2834 2732 2835 struct mlxsw_sp_sample_trigger_node { ··· 3887 3992 .trap_policer_fini = mlxsw_sp_trap_policer_fini, 3888 3993 .trap_policer_set = mlxsw_sp_trap_policer_set, 3889 3994 .trap_policer_counter_get = mlxsw_sp_trap_policer_counter_get, 3890 - .txhdr_construct = mlxsw_sp_txhdr_construct, 3891 3995 .resources_register = mlxsw_sp1_resources_register, 3892 3996 .kvd_sizes_get = mlxsw_sp_kvd_sizes_get, 3893 3997 .ptp_transmitted = mlxsw_sp_ptp_transmitted, 3894 - .txhdr_len = MLXSW_TXHDR_LEN, 3895 3998 .profile = &mlxsw_sp1_config_profile, 3896 3999 .sdq_supports_cqe_v2 = false, 3897 4000 }; ··· 3923 4030 .trap_policer_fini = mlxsw_sp_trap_policer_fini, 3924 4031 .trap_policer_set = mlxsw_sp_trap_policer_set, 3925 4032 .trap_policer_counter_get = mlxsw_sp_trap_policer_counter_get, 3926 - .txhdr_construct = mlxsw_sp_txhdr_construct, 3927 4033 .resources_register = mlxsw_sp2_resources_register, 3928 4034 .ptp_transmitted = mlxsw_sp_ptp_transmitted, 3929 - .txhdr_len = MLXSW_TXHDR_LEN, 3930 4035 .profile = &mlxsw_sp2_config_profile, 3931 4036 .sdq_supports_cqe_v2 = true, 3932 4037 }; ··· 3958 4067 .trap_policer_fini = mlxsw_sp_trap_policer_fini, 3959 4068 .trap_policer_set = mlxsw_sp_trap_policer_set, 3960 4069 .trap_policer_counter_get = mlxsw_sp_trap_policer_counter_get, 3961 - .txhdr_construct = mlxsw_sp_txhdr_construct, 3962 4070 .resources_register = mlxsw_sp2_resources_register, 3963 4071 .ptp_transmitted = mlxsw_sp_ptp_transmitted, 3964 - .txhdr_len = MLXSW_TXHDR_LEN, 3965 4072 .profile = &mlxsw_sp2_config_profile, 3966 4073 .sdq_supports_cqe_v2 = true, 3967 4074 }; ··· 3991 4102 .trap_policer_fini = mlxsw_sp_trap_policer_fini, 3992 4103 .trap_policer_set = mlxsw_sp_trap_policer_set, 3993 4104 .trap_policer_counter_get = mlxsw_sp_trap_policer_counter_get, 3994 - .txhdr_construct = mlxsw_sp_txhdr_construct, 3995 4105 .resources_register = mlxsw_sp2_resources_register, 3996 4106 .ptp_transmitted = mlxsw_sp_ptp_transmitted, 3997 - .txhdr_len = MLXSW_TXHDR_LEN, 3998 4107 .profile = &mlxsw_sp4_config_profile, 3999 4108 .sdq_supports_cqe_v2 = true, 4000 4109 };
+1 -10
drivers/net/ethernet/mellanox/mlxsw/spectrum.h
··· 243 243 void (*get_stats_strings)(u8 **p); 244 244 void (*get_stats)(struct mlxsw_sp_port *mlxsw_sp_port, 245 245 u64 *data, int data_index); 246 - int (*txhdr_construct)(struct mlxsw_core *mlxsw_core, 247 - struct mlxsw_sp_port *mlxsw_sp_port, 248 - struct sk_buff *skb, 249 - const struct mlxsw_tx_info *tx_info); 246 + bool tx_as_data; 250 247 }; 251 248 252 249 struct mlxsw_sp_fid_core_ops { ··· 708 711 unsigned int *p_counter_index); 709 712 void mlxsw_sp_flow_counter_free(struct mlxsw_sp *mlxsw_sp, 710 713 unsigned int counter_index); 711 - void mlxsw_sp_txhdr_construct(struct sk_buff *skb, 712 - const struct mlxsw_tx_info *tx_info); 713 - int mlxsw_sp_txhdr_ptp_data_construct(struct mlxsw_core *mlxsw_core, 714 - struct mlxsw_sp_port *mlxsw_sp_port, 715 - struct sk_buff *skb, 716 - const struct mlxsw_tx_info *tx_info); 717 714 bool mlxsw_sp_port_dev_check(const struct net_device *dev); 718 715 struct mlxsw_sp *mlxsw_sp_lower_get(struct net_device *dev); 719 716 struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find(struct net_device *dev);
+4 -40
drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
··· 1353 1353 struct mlxsw_sp2_ptp_state *ptp_state; 1354 1354 int err; 1355 1355 1356 + /* Max FID will be used in data path, check validity as part of init. */ 1357 + if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, FID)) 1358 + return ERR_PTR(-EIO); 1359 + 1356 1360 ptp_state = kzalloc(sizeof(*ptp_state), GFP_KERNEL); 1357 1361 if (!ptp_state) 1358 1362 return ERR_PTR(-ENOMEM); ··· 1682 1678 BIT(HWTSTAMP_FILTER_PTP_V2_EVENT); 1683 1679 1684 1680 return 0; 1685 - } 1686 - 1687 - int mlxsw_sp_ptp_txhdr_construct(struct mlxsw_core *mlxsw_core, 1688 - struct mlxsw_sp_port *mlxsw_sp_port, 1689 - struct sk_buff *skb, 1690 - const struct mlxsw_tx_info *tx_info) 1691 - { 1692 - if (skb_cow_head(skb, MLXSW_TXHDR_LEN)) { 1693 - this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped); 1694 - dev_kfree_skb_any(skb); 1695 - return -ENOMEM; 1696 - } 1697 - 1698 - mlxsw_sp_txhdr_construct(skb, tx_info); 1699 - return 0; 1700 - } 1701 - 1702 - int mlxsw_sp2_ptp_txhdr_construct(struct mlxsw_core *mlxsw_core, 1703 - struct mlxsw_sp_port *mlxsw_sp_port, 1704 - struct sk_buff *skb, 1705 - const struct mlxsw_tx_info *tx_info) 1706 - { 1707 - /* In Spectrum-2 and Spectrum-3, in order for PTP event packets to have 1708 - * their correction field correctly set on the egress port they must be 1709 - * transmitted as data packets. Such packets ingress the ASIC via the 1710 - * CPU port and must have a VLAN tag, as the CPU port is not configured 1711 - * with a PVID. Push the default VLAN (4095), which is configured as 1712 - * egress untagged on all the ports. 1713 - */ 1714 - if (!skb_vlan_tagged(skb)) { 1715 - skb = vlan_insert_tag_set_proto(skb, htons(ETH_P_8021Q), 1716 - MLXSW_SP_DEFAULT_VID); 1717 - if (!skb) { 1718 - this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped); 1719 - return -ENOMEM; 1720 - } 1721 - } 1722 - 1723 - return mlxsw_sp_txhdr_ptp_data_construct(mlxsw_core, mlxsw_sp_port, skb, 1724 - tx_info); 1725 1681 }
-28
drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.h
··· 49 49 void mlxsw_sp1_get_stats(struct mlxsw_sp_port *mlxsw_sp_port, 50 50 u64 *data, int data_index); 51 51 52 - int mlxsw_sp_ptp_txhdr_construct(struct mlxsw_core *mlxsw_core, 53 - struct mlxsw_sp_port *mlxsw_sp_port, 54 - struct sk_buff *skb, 55 - const struct mlxsw_tx_info *tx_info); 56 - 57 52 struct mlxsw_sp_ptp_clock * 58 53 mlxsw_sp2_ptp_clock_init(struct mlxsw_sp *mlxsw_sp, struct device *dev); 59 54 ··· 72 77 73 78 int mlxsw_sp2_ptp_get_ts_info(struct mlxsw_sp *mlxsw_sp, 74 79 struct kernel_ethtool_ts_info *info); 75 - 76 - int mlxsw_sp2_ptp_txhdr_construct(struct mlxsw_core *mlxsw_core, 77 - struct mlxsw_sp_port *mlxsw_sp_port, 78 - struct sk_buff *skb, 79 - const struct mlxsw_tx_info *tx_info); 80 80 81 81 #else 82 82 ··· 147 157 { 148 158 } 149 159 150 - static inline int 151 - mlxsw_sp_ptp_txhdr_construct(struct mlxsw_core *mlxsw_core, 152 - struct mlxsw_sp_port *mlxsw_sp_port, 153 - struct sk_buff *skb, 154 - const struct mlxsw_tx_info *tx_info) 155 - { 156 - return -EOPNOTSUPP; 157 - } 158 - 159 160 static inline struct mlxsw_sp_ptp_clock * 160 161 mlxsw_sp2_ptp_clock_init(struct mlxsw_sp *mlxsw_sp, struct device *dev) 161 162 { ··· 189 208 static inline int 190 209 mlxsw_sp2_ptp_hwtstamp_set(struct mlxsw_sp_port *mlxsw_sp_port, 191 210 struct hwtstamp_config *config) 192 - { 193 - return -EOPNOTSUPP; 194 - } 195 - 196 - static inline int 197 - mlxsw_sp2_ptp_txhdr_construct(struct mlxsw_core *mlxsw_core, 198 - struct mlxsw_sp_port *mlxsw_sp_port, 199 - struct sk_buff *skb, 200 - const struct mlxsw_tx_info *tx_info) 201 211 { 202 212 return -EOPNOTSUPP; 203 213 }
+63
drivers/net/ethernet/mellanox/mlxsw/txheader.h
··· 4 4 #ifndef _MLXSW_TXHEADER_H 5 5 #define _MLXSW_TXHEADER_H 6 6 7 + /* tx_hdr_version 8 + * Tx header version. 9 + * Must be set to 1. 10 + */ 11 + MLXSW_ITEM32(tx, hdr, version, 0x00, 28, 4); 12 + 13 + /* tx_hdr_ctl 14 + * Packet control type. 15 + * 0 - Ethernet control (e.g. EMADs, LACP) 16 + * 1 - Ethernet data 17 + */ 18 + MLXSW_ITEM32(tx, hdr, ctl, 0x00, 26, 2); 19 + 20 + /* tx_hdr_proto 21 + * Packet protocol type. Must be set to 1 (Ethernet). 22 + */ 23 + MLXSW_ITEM32(tx, hdr, proto, 0x00, 21, 3); 24 + 25 + /* tx_hdr_rx_is_router 26 + * Packet is sent from the router. Valid for data packets only. 27 + */ 28 + MLXSW_ITEM32(tx, hdr, rx_is_router, 0x00, 19, 1); 29 + 30 + /* tx_hdr_fid_valid 31 + * Indicates if the 'fid' field is valid and should be used for 32 + * forwarding lookup. Valid for data packets only. 33 + */ 34 + MLXSW_ITEM32(tx, hdr, fid_valid, 0x00, 16, 1); 35 + 36 + /* tx_hdr_swid 37 + * Switch partition ID. Must be set to 0. 38 + */ 39 + MLXSW_ITEM32(tx, hdr, swid, 0x00, 12, 3); 40 + 41 + /* tx_hdr_control_tclass 42 + * Indicates if the packet should use the control TClass and not one 43 + * of the data TClasses. 44 + */ 45 + MLXSW_ITEM32(tx, hdr, control_tclass, 0x00, 6, 1); 46 + 47 + /* tx_hdr_port_mid 48 + * Destination local port for unicast packets. 49 + * Destination multicast ID for multicast packets. 50 + * 51 + * Control packets are directed to a specific egress port, while data 52 + * packets are transmitted through the CPU port (0) into the switch partition, 53 + * where forwarding rules are applied. 54 + */ 55 + MLXSW_ITEM32(tx, hdr, port_mid, 0x04, 16, 16); 56 + 57 + /* tx_hdr_fid 58 + * Forwarding ID used for L2 forwarding lookup. Valid only if 'fid_valid' is 59 + * set, otherwise calculated based on the packet's VID using VID to FID mapping. 60 + * Valid for data packets only. 61 + */ 62 + MLXSW_ITEM32(tx, hdr, fid, 0x08, 16, 16); 63 + 64 + /* tx_hdr_type 65 + * 0 - Data packets 66 + * 6 - Control packets 67 + */ 68 + MLXSW_ITEM32(tx, hdr, type, 0x0C, 0, 4); 69 + 7 70 #define MLXSW_TXHDR_LEN 0x10 8 71 #define MLXSW_TXHDR_VERSION_0 0 9 72 #define MLXSW_TXHDR_VERSION_1 1