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 'net-sparx5-add-support-for-lan969x-switch-device'

Daniel Machon says:

====================
net: sparx5: add support for lan969x switch device

== Description:

This series is the second of a multi-part series, that prepares and adds
support for the new lan969x switch driver.

The upstreaming efforts is split into multiple series (might change a
bit as we go along):

1) Prepare the Sparx5 driver for lan969x (merged)

--> 2) add support lan969x (same basic features as Sparx5
provides excl. FDMA and VCAP).

3) Add support for lan969x VCAP, FDMA and RGMII

== Lan969x in short:

The lan969x Ethernet switch family [1] provides a rich set of
switching features and port configurations (up to 30 ports) from 10Mbps
to 10Gbps, with support for RGMII, SGMII, QSGMII, USGMII, and USXGMII,
ideal for industrial & process automation infrastructure applications,
transport, grid automation, power substation automation, and ring &
intra-ring topologies. The LAN969x family is hardware and software
compatible and scalable supporting 46Gbps to 102Gbps switch bandwidths.

== Preparing Sparx5 for lan969x:

The main preparation work for lan969x has already been merged [1].

After this series is applied, lan969x will have the same functionality
as Sparx5, except for VCAP and FDMA support. QoS features that requires
the VCAP (e.g. PSFP, port mirroring) will obviously not work until VCAP
support is added later.

== Patch breakdown:

Patch #1-#4 do some preparation work for lan969x

Patch #5 adds new registers required by lan969x

Patch #6 adds initial match data for all lan969x targets

Patch #7 defines the lan969x register differences

Patch #8 adds lan969x constants to match data

Patch #9 adds some lan969x ops in bulk

Patch #10 adds PTP function to ops

Patch #11 adds lan969x_calendar.c for calculating the calendar

Patch #12 makes additional use of the is_sparx5() macro to branch out
in certain places.

Patch #13 documents lan969x in the dt-bindings

Patch #14 adds lan969x compatible string to sparx5 driver

Patch #15 introduces new concept of per-target features

[1] https://lore.kernel.org/netdev/20241004-b4-sparx5-lan969x-switch-driver-v2-0-d3290f581663@microchip.com/

v1: https://lore.kernel.org/20241021-sparx5-lan969x-switch-driver-2-v1-0-c8c49ef21e0f@microchip.com
====================

Link: https://patch.msgid.link/20241024-sparx5-lan969x-switch-driver-2-v2-0-a0b5fae88a0f@microchip.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+1286 -84
+19 -1
Documentation/devicetree/bindings/net/microchip,sparx5-switch.yaml
··· 9 9 maintainers: 10 10 - Steen Hegelund <steen.hegelund@microchip.com> 11 11 - Lars Povlsen <lars.povlsen@microchip.com> 12 + - Daniel Machon <daniel.machon@microchip.com> 12 13 13 14 description: | 14 15 The SparX-5 Enterprise Ethernet switch family provides a rich set of ··· 35 34 pattern: "^switch@[0-9a-f]+$" 36 35 37 36 compatible: 38 - const: microchip,sparx5-switch 37 + oneOf: 38 + - enum: 39 + - microchip,lan9691-switch 40 + - microchip,sparx5-switch 41 + - items: 42 + - enum: 43 + - microchip,lan969c-switch 44 + - microchip,lan969b-switch 45 + - microchip,lan969a-switch 46 + - microchip,lan9699-switch 47 + - microchip,lan9698-switch 48 + - microchip,lan9697-switch 49 + - microchip,lan9696-switch 50 + - microchip,lan9695-switch 51 + - microchip,lan9694-switch 52 + - microchip,lan9693-switch 53 + - microchip,lan9692-switch 54 + - const: microchip,lan9691-switch 39 55 40 56 reg: 41 57 items:
+7
MAINTAINERS
··· 15091 15091 F: Documentation/devicetree/bindings/interrupt-controller/microchip,lan966x-oic.yaml 15092 15092 F: drivers/irqchip/irq-lan966x-oic.c 15093 15093 15094 + MICROCHIP LAN969X ETHERNET DRIVER 15095 + M: Daniel Machon <daniel.machon@microchip.com> 15096 + M: UNGLinuxDriver@microchip.com 15097 + L: netdev@vger.kernel.org 15098 + S: Maintained 15099 + F: drivers/net/ethernet/microchip/lan969x/* 15100 + 15094 15101 MICROCHIP LCDFB DRIVER 15095 15102 M: Nicolas Ferre <nicolas.ferre@microchip.com> 15096 15103 L: linux-fbdev@vger.kernel.org
+1
drivers/net/ethernet/microchip/Kconfig
··· 59 59 60 60 source "drivers/net/ethernet/microchip/lan865x/Kconfig" 61 61 source "drivers/net/ethernet/microchip/lan966x/Kconfig" 62 + source "drivers/net/ethernet/microchip/lan969x/Kconfig" 62 63 source "drivers/net/ethernet/microchip/sparx5/Kconfig" 63 64 source "drivers/net/ethernet/microchip/vcap/Kconfig" 64 65 source "drivers/net/ethernet/microchip/fdma/Kconfig"
+1
drivers/net/ethernet/microchip/Makefile
··· 11 11 12 12 obj-$(CONFIG_LAN865X) += lan865x/ 13 13 obj-$(CONFIG_LAN966X_SWITCH) += lan966x/ 14 + obj-$(CONFIG_LAN969X_SWITCH) += lan969x/ 14 15 obj-$(CONFIG_SPARX5_SWITCH) += sparx5/ 15 16 obj-$(CONFIG_VCAP) += vcap/ 16 17 obj-$(CONFIG_FDMA) += fdma/
+5
drivers/net/ethernet/microchip/lan969x/Kconfig
··· 1 + config LAN969X_SWITCH 2 + tristate "Lan969x switch driver" 3 + depends on SPARX5_SWITCH 4 + help 5 + This driver supports the lan969x family of network switch devices.
+12
drivers/net/ethernet/microchip/lan969x/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + # 3 + # Makefile for the Microchip lan969x network device drivers. 4 + # 5 + 6 + obj-$(CONFIG_LAN969X_SWITCH) += lan969x-switch.o 7 + 8 + lan969x-switch-y := lan969x_regs.o lan969x.o lan969x_calendar.o 9 + 10 + # Provide include files 11 + ccflags-y += -I$(srctree)/drivers/net/ethernet/microchip/fdma 12 + ccflags-y += -I$(srctree)/drivers/net/ethernet/microchip/vcap
+350
drivers/net/ethernet/microchip/lan969x/lan969x.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* Microchip lan969x Switch driver 3 + * 4 + * Copyright (c) 2024 Microchip Technology Inc. and its subsidiaries. 5 + */ 6 + 7 + #include "lan969x.h" 8 + 9 + #define LAN969X_SDLB_GRP_CNT 5 10 + #define LAN969X_HSCH_LEAK_GRP_CNT 4 11 + 12 + static const struct sparx5_main_io_resource lan969x_main_iomap[] = { 13 + { TARGET_CPU, 0xc0000, 0 }, /* 0xe00c0000 */ 14 + { TARGET_FDMA, 0xc0400, 0 }, /* 0xe00c0400 */ 15 + { TARGET_GCB, 0x2010000, 1 }, /* 0xe2010000 */ 16 + { TARGET_QS, 0x2030000, 1 }, /* 0xe2030000 */ 17 + { TARGET_PTP, 0x2040000, 1 }, /* 0xe2040000 */ 18 + { TARGET_ANA_ACL, 0x2050000, 1 }, /* 0xe2050000 */ 19 + { TARGET_LRN, 0x2060000, 1 }, /* 0xe2060000 */ 20 + { TARGET_VCAP_SUPER, 0x2080000, 1 }, /* 0xe2080000 */ 21 + { TARGET_QSYS, 0x20a0000, 1 }, /* 0xe20a0000 */ 22 + { TARGET_QFWD, 0x20b0000, 1 }, /* 0xe20b0000 */ 23 + { TARGET_XQS, 0x20c0000, 1 }, /* 0xe20c0000 */ 24 + { TARGET_VCAP_ES2, 0x20d0000, 1 }, /* 0xe20d0000 */ 25 + { TARGET_VCAP_ES0, 0x20e0000, 1 }, /* 0xe20e0000 */ 26 + { TARGET_ANA_AC_POL, 0x2200000, 1 }, /* 0xe2200000 */ 27 + { TARGET_QRES, 0x2280000, 1 }, /* 0xe2280000 */ 28 + { TARGET_EACL, 0x22c0000, 1 }, /* 0xe22c0000 */ 29 + { TARGET_ANA_CL, 0x2400000, 1 }, /* 0xe2400000 */ 30 + { TARGET_ANA_L3, 0x2480000, 1 }, /* 0xe2480000 */ 31 + { TARGET_ANA_AC_SDLB, 0x2500000, 1 }, /* 0xe2500000 */ 32 + { TARGET_HSCH, 0x2580000, 1 }, /* 0xe2580000 */ 33 + { TARGET_REW, 0x2600000, 1 }, /* 0xe2600000 */ 34 + { TARGET_ANA_L2, 0x2800000, 1 }, /* 0xe2800000 */ 35 + { TARGET_ANA_AC, 0x2900000, 1 }, /* 0xe2900000 */ 36 + { TARGET_VOP, 0x2a00000, 1 }, /* 0xe2a00000 */ 37 + { TARGET_DEV2G5, 0x3004000, 1 }, /* 0xe3004000 */ 38 + { TARGET_DEV10G, 0x3008000, 1 }, /* 0xe3008000 */ 39 + { TARGET_PCS10G_BR, 0x300c000, 1 }, /* 0xe300c000 */ 40 + { TARGET_DEV2G5 + 1, 0x3010000, 1 }, /* 0xe3010000 */ 41 + { TARGET_DEV2G5 + 2, 0x3014000, 1 }, /* 0xe3014000 */ 42 + { TARGET_DEV2G5 + 3, 0x3018000, 1 }, /* 0xe3018000 */ 43 + { TARGET_DEV2G5 + 4, 0x301c000, 1 }, /* 0xe301c000 */ 44 + { TARGET_DEV10G + 1, 0x3020000, 1 }, /* 0xe3020000 */ 45 + { TARGET_PCS10G_BR + 1, 0x3024000, 1 }, /* 0xe3024000 */ 46 + { TARGET_DEV2G5 + 5, 0x3028000, 1 }, /* 0xe3028000 */ 47 + { TARGET_DEV2G5 + 6, 0x302c000, 1 }, /* 0xe302c000 */ 48 + { TARGET_DEV2G5 + 7, 0x3030000, 1 }, /* 0xe3030000 */ 49 + { TARGET_DEV2G5 + 8, 0x3034000, 1 }, /* 0xe3034000 */ 50 + { TARGET_DEV10G + 2, 0x3038000, 1 }, /* 0xe3038000 */ 51 + { TARGET_PCS10G_BR + 2, 0x303c000, 1 }, /* 0xe303c000 */ 52 + { TARGET_DEV2G5 + 9, 0x3040000, 1 }, /* 0xe3040000 */ 53 + { TARGET_DEV5G, 0x3044000, 1 }, /* 0xe3044000 */ 54 + { TARGET_PCS5G_BR, 0x3048000, 1 }, /* 0xe3048000 */ 55 + { TARGET_DEV2G5 + 10, 0x304c000, 1 }, /* 0xe304c000 */ 56 + { TARGET_DEV2G5 + 11, 0x3050000, 1 }, /* 0xe3050000 */ 57 + { TARGET_DEV2G5 + 12, 0x3054000, 1 }, /* 0xe3054000 */ 58 + { TARGET_DEV10G + 3, 0x3058000, 1 }, /* 0xe3058000 */ 59 + { TARGET_PCS10G_BR + 3, 0x305c000, 1 }, /* 0xe305c000 */ 60 + { TARGET_DEV2G5 + 13, 0x3060000, 1 }, /* 0xe3060000 */ 61 + { TARGET_DEV5G + 1, 0x3064000, 1 }, /* 0xe3064000 */ 62 + { TARGET_PCS5G_BR + 1, 0x3068000, 1 }, /* 0xe3068000 */ 63 + { TARGET_DEV2G5 + 14, 0x306c000, 1 }, /* 0xe306c000 */ 64 + { TARGET_DEV2G5 + 15, 0x3070000, 1 }, /* 0xe3070000 */ 65 + { TARGET_DEV2G5 + 16, 0x3074000, 1 }, /* 0xe3074000 */ 66 + { TARGET_DEV10G + 4, 0x3078000, 1 }, /* 0xe3078000 */ 67 + { TARGET_PCS10G_BR + 4, 0x307c000, 1 }, /* 0xe307c000 */ 68 + { TARGET_DEV2G5 + 17, 0x3080000, 1 }, /* 0xe3080000 */ 69 + { TARGET_DEV5G + 2, 0x3084000, 1 }, /* 0xe3084000 */ 70 + { TARGET_PCS5G_BR + 2, 0x3088000, 1 }, /* 0xe3088000 */ 71 + { TARGET_DEV2G5 + 18, 0x308c000, 1 }, /* 0xe308c000 */ 72 + { TARGET_DEV2G5 + 19, 0x3090000, 1 }, /* 0xe3090000 */ 73 + { TARGET_DEV2G5 + 20, 0x3094000, 1 }, /* 0xe3094000 */ 74 + { TARGET_DEV10G + 5, 0x3098000, 1 }, /* 0xe3098000 */ 75 + { TARGET_PCS10G_BR + 5, 0x309c000, 1 }, /* 0xe309c000 */ 76 + { TARGET_DEV2G5 + 21, 0x30a0000, 1 }, /* 0xe30a0000 */ 77 + { TARGET_DEV5G + 3, 0x30a4000, 1 }, /* 0xe30a4000 */ 78 + { TARGET_PCS5G_BR + 3, 0x30a8000, 1 }, /* 0xe30a8000 */ 79 + { TARGET_DEV2G5 + 22, 0x30ac000, 1 }, /* 0xe30ac000 */ 80 + { TARGET_DEV2G5 + 23, 0x30b0000, 1 }, /* 0xe30b0000 */ 81 + { TARGET_DEV2G5 + 24, 0x30b4000, 1 }, /* 0xe30b4000 */ 82 + { TARGET_DEV10G + 6, 0x30b8000, 1 }, /* 0xe30b8000 */ 83 + { TARGET_PCS10G_BR + 6, 0x30bc000, 1 }, /* 0xe30bc000 */ 84 + { TARGET_DEV2G5 + 25, 0x30c0000, 1 }, /* 0xe30c0000 */ 85 + { TARGET_DEV10G + 7, 0x30c4000, 1 }, /* 0xe30c4000 */ 86 + { TARGET_PCS10G_BR + 7, 0x30c8000, 1 }, /* 0xe30c8000 */ 87 + { TARGET_DEV2G5 + 26, 0x30cc000, 1 }, /* 0xe30cc000 */ 88 + { TARGET_DEV10G + 8, 0x30d0000, 1 }, /* 0xe30d0000 */ 89 + { TARGET_PCS10G_BR + 8, 0x30d4000, 1 }, /* 0xe30d4000 */ 90 + { TARGET_DEV2G5 + 27, 0x30d8000, 1 }, /* 0xe30d8000 */ 91 + { TARGET_DEV10G + 9, 0x30dc000, 1 }, /* 0xe30dc000 */ 92 + { TARGET_PCS10G_BR + 9, 0x30e0000, 1 }, /* 0xe30e0000 */ 93 + { TARGET_DSM, 0x30ec000, 1 }, /* 0xe30ec000 */ 94 + { TARGET_PORT_CONF, 0x30f0000, 1 }, /* 0xe30f0000 */ 95 + { TARGET_ASM, 0x3200000, 1 }, /* 0xe3200000 */ 96 + }; 97 + 98 + static struct sparx5_sdlb_group lan969x_sdlb_groups[LAN969X_SDLB_GRP_CNT] = { 99 + { 1000000000, 8192 / 2, 64 }, /* 1 G */ 100 + { 500000000, 8192 / 2, 64 }, /* 500 M */ 101 + { 100000000, 8192 / 4, 64 }, /* 100 M */ 102 + { 50000000, 8192 / 4, 64 }, /* 50 M */ 103 + { 5000000, 8192 / 8, 64 }, /* 10 M */ 104 + }; 105 + 106 + static u32 lan969x_hsch_max_group_rate[LAN969X_HSCH_LEAK_GRP_CNT] = { 107 + 655355, 1048568, 6553550, 10485680 108 + }; 109 + 110 + static struct sparx5_sdlb_group *lan969x_get_sdlb_group(int idx) 111 + { 112 + return &lan969x_sdlb_groups[idx]; 113 + } 114 + 115 + static u32 lan969x_get_hsch_max_group_rate(int grp) 116 + { 117 + return lan969x_hsch_max_group_rate[grp]; 118 + } 119 + 120 + static u32 lan969x_get_dev_mode_bit(struct sparx5 *sparx5, int port) 121 + { 122 + if (lan969x_port_is_2g5(port) || lan969x_port_is_5g(port)) 123 + return port; 124 + 125 + /* 10G */ 126 + switch (port) { 127 + case 0: 128 + return 12; 129 + case 4: 130 + return 13; 131 + case 8: 132 + return 14; 133 + case 12: 134 + return 0; 135 + default: 136 + return port; 137 + } 138 + } 139 + 140 + static u32 lan969x_port_dev_mapping(struct sparx5 *sparx5, int port) 141 + { 142 + if (lan969x_port_is_5g(port)) { 143 + switch (port) { 144 + case 9: 145 + return 0; 146 + case 13: 147 + return 1; 148 + case 17: 149 + return 2; 150 + case 21: 151 + return 3; 152 + } 153 + } 154 + 155 + if (lan969x_port_is_10g(port)) { 156 + switch (port) { 157 + case 0: 158 + return 0; 159 + case 4: 160 + return 1; 161 + case 8: 162 + return 2; 163 + case 12: 164 + return 3; 165 + case 16: 166 + return 4; 167 + case 20: 168 + return 5; 169 + case 24: 170 + return 6; 171 + case 25: 172 + return 7; 173 + case 26: 174 + return 8; 175 + case 27: 176 + return 9; 177 + } 178 + } 179 + 180 + /* 2g5 port */ 181 + return port; 182 + } 183 + 184 + static int lan969x_port_mux_set(struct sparx5 *sparx5, struct sparx5_port *port, 185 + struct sparx5_port_config *conf) 186 + { 187 + u32 portno = port->portno; 188 + u32 inst; 189 + 190 + if (port->conf.portmode == conf->portmode) 191 + return 0; /* Nothing to do */ 192 + 193 + switch (conf->portmode) { 194 + case PHY_INTERFACE_MODE_QSGMII: /* QSGMII: 4x2G5 devices. Mode Q' */ 195 + inst = (portno - portno % 4) / 4; 196 + spx5_rmw(BIT(inst), BIT(inst), sparx5, PORT_CONF_QSGMII_ENA); 197 + break; 198 + default: 199 + break; 200 + } 201 + return 0; 202 + } 203 + 204 + static irqreturn_t lan969x_ptp_irq_handler(int irq, void *args) 205 + { 206 + int budget = SPARX5_MAX_PTP_ID; 207 + struct sparx5 *sparx5 = args; 208 + 209 + while (budget--) { 210 + struct sk_buff *skb, *skb_tmp, *skb_match = NULL; 211 + struct skb_shared_hwtstamps shhwtstamps; 212 + struct sparx5_port *port; 213 + struct timespec64 ts; 214 + unsigned long flags; 215 + u32 val, id, txport; 216 + u32 delay; 217 + 218 + val = spx5_rd(sparx5, PTP_TWOSTEP_CTRL); 219 + 220 + /* Check if a timestamp can be retrieved */ 221 + if (!(val & PTP_TWOSTEP_CTRL_PTP_VLD)) 222 + break; 223 + 224 + WARN_ON(val & PTP_TWOSTEP_CTRL_PTP_OVFL); 225 + 226 + if (!(val & PTP_TWOSTEP_CTRL_STAMP_TX)) 227 + continue; 228 + 229 + /* Retrieve the ts Tx port */ 230 + txport = PTP_TWOSTEP_CTRL_STAMP_PORT_GET(val); 231 + 232 + /* Retrieve its associated skb */ 233 + port = sparx5->ports[txport]; 234 + 235 + /* Retrieve the delay */ 236 + delay = spx5_rd(sparx5, PTP_TWOSTEP_STAMP_NSEC); 237 + delay = PTP_TWOSTEP_STAMP_NSEC_NS_GET(delay); 238 + 239 + /* Get next timestamp from fifo, which needs to be the 240 + * rx timestamp which represents the id of the frame 241 + */ 242 + spx5_rmw(PTP_TWOSTEP_CTRL_PTP_NXT_SET(1), 243 + PTP_TWOSTEP_CTRL_PTP_NXT, 244 + sparx5, PTP_TWOSTEP_CTRL); 245 + 246 + val = spx5_rd(sparx5, PTP_TWOSTEP_CTRL); 247 + 248 + /* Check if a timestamp can be retrieved */ 249 + if (!(val & PTP_TWOSTEP_CTRL_PTP_VLD)) 250 + break; 251 + 252 + /* Read RX timestamping to get the ID */ 253 + id = spx5_rd(sparx5, PTP_TWOSTEP_STAMP_NSEC); 254 + id <<= 8; 255 + id |= spx5_rd(sparx5, PTP_TWOSTEP_STAMP_SUBNS); 256 + 257 + spin_lock_irqsave(&port->tx_skbs.lock, flags); 258 + skb_queue_walk_safe(&port->tx_skbs, skb, skb_tmp) { 259 + if (SPARX5_SKB_CB(skb)->ts_id != id) 260 + continue; 261 + 262 + __skb_unlink(skb, &port->tx_skbs); 263 + skb_match = skb; 264 + break; 265 + } 266 + spin_unlock_irqrestore(&port->tx_skbs.lock, flags); 267 + 268 + /* Next ts */ 269 + spx5_rmw(PTP_TWOSTEP_CTRL_PTP_NXT_SET(1), 270 + PTP_TWOSTEP_CTRL_PTP_NXT, 271 + sparx5, PTP_TWOSTEP_CTRL); 272 + 273 + if (WARN_ON(!skb_match)) 274 + continue; 275 + 276 + spin_lock(&sparx5->ptp_ts_id_lock); 277 + sparx5->ptp_skbs--; 278 + spin_unlock(&sparx5->ptp_ts_id_lock); 279 + 280 + /* Get the h/w timestamp */ 281 + sparx5_get_hwtimestamp(sparx5, &ts, delay); 282 + 283 + /* Set the timestamp in the skb */ 284 + shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec); 285 + skb_tstamp_tx(skb_match, &shhwtstamps); 286 + 287 + dev_kfree_skb_any(skb_match); 288 + } 289 + 290 + return IRQ_HANDLED; 291 + } 292 + 293 + static const struct sparx5_regs lan969x_regs = { 294 + .tsize = lan969x_tsize, 295 + .gaddr = lan969x_gaddr, 296 + .gcnt = lan969x_gcnt, 297 + .gsize = lan969x_gsize, 298 + .raddr = lan969x_raddr, 299 + .rcnt = lan969x_rcnt, 300 + .fpos = lan969x_fpos, 301 + .fsize = lan969x_fsize, 302 + }; 303 + 304 + static const struct sparx5_consts lan969x_consts = { 305 + .n_ports = 30, 306 + .n_ports_all = 35, 307 + .n_hsch_l1_elems = 32, 308 + .n_hsch_queues = 4, 309 + .n_lb_groups = 5, 310 + .n_pgids = 1054, /* (1024 + n_ports) */ 311 + .n_sio_clks = 1, 312 + .n_own_upsids = 1, 313 + .n_auto_cals = 4, 314 + .n_filters = 256, 315 + .n_gates = 256, 316 + .n_sdlbs = 496, 317 + .n_dsm_cal_taxis = 5, 318 + .buf_size = 1572864, 319 + .qres_max_prio_idx = 315, 320 + .qres_max_colour_idx = 323, 321 + .tod_pin = 4, 322 + }; 323 + 324 + static const struct sparx5_ops lan969x_ops = { 325 + .is_port_2g5 = &lan969x_port_is_2g5, 326 + .is_port_5g = &lan969x_port_is_5g, 327 + .is_port_10g = &lan969x_port_is_10g, 328 + .is_port_25g = &lan969x_port_is_25g, 329 + .get_port_dev_index = &lan969x_port_dev_mapping, 330 + .get_port_dev_bit = &lan969x_get_dev_mode_bit, 331 + .get_hsch_max_group_rate = &lan969x_get_hsch_max_group_rate, 332 + .get_sdlb_group = &lan969x_get_sdlb_group, 333 + .set_port_mux = &lan969x_port_mux_set, 334 + .ptp_irq_handler = &lan969x_ptp_irq_handler, 335 + .dsm_calendar_calc = &lan969x_dsm_calendar_calc, 336 + }; 337 + 338 + const struct sparx5_match_data lan969x_desc = { 339 + .iomap = lan969x_main_iomap, 340 + .iomap_size = ARRAY_SIZE(lan969x_main_iomap), 341 + .ioranges = 2, 342 + .regs = &lan969x_regs, 343 + .consts = &lan969x_consts, 344 + .ops = &lan969x_ops, 345 + }; 346 + EXPORT_SYMBOL_GPL(lan969x_desc); 347 + 348 + MODULE_DESCRIPTION("Microchip lan969x switch driver"); 349 + MODULE_AUTHOR("Daniel Machon <daniel.machon@microchip.com>"); 350 + MODULE_LICENSE("Dual MIT/GPL");
+57
drivers/net/ethernet/microchip/lan969x/lan969x.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* Microchip lan969x Switch driver 3 + * 4 + * Copyright (c) 2024 Microchip Technology Inc. and its subsidiaries. 5 + */ 6 + 7 + #ifndef __LAN969X_H__ 8 + #define __LAN969X_H__ 9 + 10 + #include "../sparx5/sparx5_main.h" 11 + #include "../sparx5/sparx5_regs.h" 12 + 13 + /* lan969x.c */ 14 + extern const struct sparx5_match_data lan969x_desc; 15 + 16 + /* lan969x_regs.c */ 17 + extern const unsigned int lan969x_tsize[TSIZE_LAST]; 18 + extern const unsigned int lan969x_raddr[RADDR_LAST]; 19 + extern const unsigned int lan969x_rcnt[RCNT_LAST]; 20 + extern const unsigned int lan969x_gaddr[GADDR_LAST]; 21 + extern const unsigned int lan969x_gcnt[GCNT_LAST]; 22 + extern const unsigned int lan969x_gsize[GSIZE_LAST]; 23 + extern const unsigned int lan969x_fpos[FPOS_LAST]; 24 + extern const unsigned int lan969x_fsize[FSIZE_LAST]; 25 + 26 + static inline bool lan969x_port_is_2g5(int portno) 27 + { 28 + return portno == 1 || portno == 2 || portno == 3 || 29 + portno == 5 || portno == 6 || portno == 7 || 30 + portno == 10 || portno == 11 || portno == 14 || 31 + portno == 15 || portno == 18 || portno == 19 || 32 + portno == 22 || portno == 23; 33 + } 34 + 35 + static inline bool lan969x_port_is_5g(int portno) 36 + { 37 + return portno == 9 || portno == 13 || portno == 17 || 38 + portno == 21; 39 + } 40 + 41 + static inline bool lan969x_port_is_10g(int portno) 42 + { 43 + return portno == 0 || portno == 4 || portno == 8 || 44 + portno == 12 || portno == 16 || portno == 20 || 45 + portno == 24 || portno == 25 || portno == 26 || 46 + portno == 27; 47 + } 48 + 49 + static inline bool lan969x_port_is_25g(int portno) 50 + { 51 + return false; 52 + } 53 + 54 + /* lan969x_calendar.c */ 55 + int lan969x_dsm_calendar_calc(struct sparx5 *sparx5, u32 taxi, 56 + struct sparx5_calendar_data *data); 57 + #endif
+191
drivers/net/ethernet/microchip/lan969x/lan969x_calendar.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* Microchip lan969x Switch driver 3 + * 4 + * Copyright (c) 2024 Microchip Technology Inc. and its subsidiaries. 5 + */ 6 + 7 + #include "lan969x.h" 8 + 9 + #define LAN969X_DSM_CAL_DEVS_PER_TAXI 10 10 + #define LAN969X_DSM_CAL_TAXIS 5 11 + 12 + enum lan969x_dsm_cal_dev { 13 + DSM_CAL_DEV_2G5, 14 + DSM_CAL_DEV_5G, 15 + DSM_CAL_DEV_10G, 16 + DSM_CAL_DEV_OTHER, /* 1G or less */ 17 + DSM_CAL_DEV_MAX 18 + }; 19 + 20 + /* Each entry in the following struct defines properties for a given speed 21 + * (10G, 5G, 2.5G, or 1G or less). 22 + */ 23 + struct lan969x_dsm_cal_dev_speed { 24 + /* Number of devices that requires this speed. */ 25 + u32 n_devs; 26 + 27 + /* Array of devices that requires this speed. */ 28 + u32 devs[LAN969X_DSM_CAL_DEVS_PER_TAXI]; 29 + 30 + /* Number of slots required for one device running this speed. */ 31 + u32 n_slots; 32 + 33 + /* Gap between two slots for one device running this speed. */ 34 + u32 gap; 35 + }; 36 + 37 + static u32 38 + lan969x_taxi_ports[LAN969X_DSM_CAL_TAXIS][LAN969X_DSM_CAL_DEVS_PER_TAXI] = { 39 + { 0, 4, 1, 2, 3, 5, 6, 7, 28, 29 }, 40 + { 8, 12, 9, 13, 10, 11, 14, 15, 99, 99 }, 41 + { 16, 20, 17, 21, 18, 19, 22, 23, 99, 99 }, 42 + { 24, 25, 99, 99, 99, 99, 99, 99, 99, 99 }, 43 + { 26, 27, 99, 99, 99, 99, 99, 99, 99, 99 } 44 + }; 45 + 46 + static int lan969x_dsm_cal_idx_get(u32 *calendar, u32 cal_len, u32 *cal_idx) 47 + { 48 + if (*cal_idx >= cal_len) 49 + return -EINVAL; 50 + 51 + do { 52 + if (calendar[*cal_idx] == SPX5_DSM_CAL_EMPTY) 53 + return 0; 54 + 55 + (*cal_idx)++; 56 + } while (*cal_idx < cal_len); 57 + 58 + return -ENOENT; 59 + } 60 + 61 + static enum lan969x_dsm_cal_dev lan969x_dsm_cal_get_dev(int speed) 62 + { 63 + return (speed == 10000 ? DSM_CAL_DEV_10G : 64 + speed == 5000 ? DSM_CAL_DEV_5G : 65 + speed == 2500 ? DSM_CAL_DEV_2G5 : 66 + DSM_CAL_DEV_OTHER); 67 + } 68 + 69 + static int lan969x_dsm_cal_get_speed(enum lan969x_dsm_cal_dev dev) 70 + { 71 + return (dev == DSM_CAL_DEV_10G ? 10000 : 72 + dev == DSM_CAL_DEV_5G ? 5000 : 73 + dev == DSM_CAL_DEV_2G5 ? 2500 : 74 + 1000); 75 + } 76 + 77 + int lan969x_dsm_calendar_calc(struct sparx5 *sparx5, u32 taxi, 78 + struct sparx5_calendar_data *data) 79 + { 80 + struct lan969x_dsm_cal_dev_speed dev_speeds[DSM_CAL_DEV_MAX] = {}; 81 + u32 cal_len, n_slots, taxi_bw, n_devs = 0, required_bw = 0; 82 + struct lan969x_dsm_cal_dev_speed *speed; 83 + int err; 84 + 85 + /* Maximum bandwidth for this taxi */ 86 + taxi_bw = (128 * 1000000) / sparx5_clk_period(sparx5->coreclock); 87 + 88 + memcpy(data->taxi_ports, &lan969x_taxi_ports[taxi], 89 + LAN969X_DSM_CAL_DEVS_PER_TAXI * sizeof(u32)); 90 + 91 + for (int i = 0; i < LAN969X_DSM_CAL_DEVS_PER_TAXI; i++) { 92 + u32 portno = data->taxi_ports[i]; 93 + enum sparx5_cal_bw bw; 94 + 95 + bw = sparx5_get_port_cal_speed(sparx5, portno); 96 + 97 + if (portno < sparx5->data->consts->n_ports_all) 98 + data->taxi_speeds[i] = sparx5_cal_speed_to_value(bw); 99 + else 100 + data->taxi_speeds[i] = 0; 101 + } 102 + 103 + /* Determine the different port types (10G, 5G, 2.5G, <= 1G) in the 104 + * this taxi map. 105 + */ 106 + for (int i = 0; i < LAN969X_DSM_CAL_DEVS_PER_TAXI; i++) { 107 + u32 taxi_speed = data->taxi_speeds[i]; 108 + enum lan969x_dsm_cal_dev dev; 109 + 110 + if (taxi_speed == 0) 111 + continue; 112 + 113 + required_bw += taxi_speed; 114 + 115 + dev = lan969x_dsm_cal_get_dev(taxi_speed); 116 + speed = &dev_speeds[dev]; 117 + speed->devs[speed->n_devs++] = i; 118 + n_devs++; 119 + } 120 + 121 + if (required_bw > taxi_bw) { 122 + pr_err("Required bandwidth: %u is higher than total taxi bandwidth: %u", 123 + required_bw, taxi_bw); 124 + return -EINVAL; 125 + } 126 + 127 + if (n_devs == 0) { 128 + data->schedule[0] = SPX5_DSM_CAL_EMPTY; 129 + return 0; 130 + } 131 + 132 + cal_len = n_devs; 133 + 134 + /* Search for a calendar length that fits all active devices. */ 135 + while (cal_len < SPX5_DSM_CAL_LEN) { 136 + u32 bw_per_slot = taxi_bw / cal_len; 137 + 138 + n_slots = 0; 139 + 140 + for (int i = 0; i < DSM_CAL_DEV_MAX; i++) { 141 + speed = &dev_speeds[i]; 142 + 143 + if (speed->n_devs == 0) 144 + continue; 145 + 146 + required_bw = lan969x_dsm_cal_get_speed(i); 147 + speed->n_slots = DIV_ROUND_UP(required_bw, bw_per_slot); 148 + 149 + if (speed->n_slots) 150 + speed->gap = DIV_ROUND_UP(cal_len, 151 + speed->n_slots); 152 + else 153 + speed->gap = 0; 154 + 155 + n_slots += speed->n_slots * speed->n_devs; 156 + } 157 + 158 + if (n_slots <= cal_len) 159 + break; /* Found a suitable calendar length. */ 160 + 161 + /* Not good enough yet. */ 162 + cal_len = n_slots; 163 + } 164 + 165 + if (cal_len > SPX5_DSM_CAL_LEN) { 166 + pr_err("Invalid length: %u for taxi: %u", cal_len, taxi); 167 + return -EINVAL; 168 + } 169 + 170 + for (u32 i = 0; i < SPX5_DSM_CAL_LEN; i++) 171 + data->schedule[i] = SPX5_DSM_CAL_EMPTY; 172 + 173 + /* Place the remaining devices */ 174 + for (u32 i = 0; i < DSM_CAL_DEV_MAX; i++) { 175 + speed = &dev_speeds[i]; 176 + for (u32 dev = 0; dev < speed->n_devs; dev++) { 177 + u32 idx = 0; 178 + 179 + for (n_slots = 0; n_slots < speed->n_slots; n_slots++) { 180 + err = lan969x_dsm_cal_idx_get(data->schedule, 181 + cal_len, &idx); 182 + if (err) 183 + return err; 184 + data->schedule[idx] = speed->devs[dev]; 185 + idx += speed->gap; 186 + } 187 + } 188 + } 189 + 190 + return 0; 191 + }
+222
drivers/net/ethernet/microchip/lan969x/lan969x_regs.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* Microchip lan969x Switch driver 3 + * 4 + * Copyright (c) 2024 Microchip Technology Inc. 5 + */ 6 + 7 + /* This file is autogenerated by cml-utils 2024-09-30 11:48:29 +0200. 8 + * Commit ID: 9d07b8d19363f3cd3590ddb3f7a2e2768e16524b 9 + */ 10 + 11 + #include "lan969x.h" 12 + 13 + const unsigned int lan969x_tsize[TSIZE_LAST] = { 14 + [TC_DEV10G] = 10, 15 + [TC_DEV2G5] = 28, 16 + [TC_DEV5G] = 4, 17 + [TC_PCS10G_BR] = 10, 18 + [TC_PCS5G_BR] = 4, 19 + }; 20 + 21 + const unsigned int lan969x_raddr[RADDR_LAST] = { 22 + [RA_CPU_PROC_CTRL] = 160, 23 + [RA_GCB_SOFT_RST] = 12, 24 + [RA_GCB_HW_SGPIO_TO_SD_MAP_CFG] = 20, 25 + }; 26 + 27 + const unsigned int lan969x_rcnt[RCNT_LAST] = { 28 + [RC_ANA_AC_OWN_UPSID] = 1, 29 + [RC_ANA_ACL_VCAP_S2_CFG] = 35, 30 + [RC_ANA_ACL_OWN_UPSID] = 1, 31 + [RC_ANA_CL_OWN_UPSID] = 1, 32 + [RC_ANA_L2_OWN_UPSID] = 1, 33 + [RC_ASM_PORT_CFG] = 32, 34 + [RC_DSM_BUF_CFG] = 32, 35 + [RC_DSM_DEV_TX_STOP_WM_CFG] = 32, 36 + [RC_DSM_RX_PAUSE_CFG] = 32, 37 + [RC_DSM_MAC_CFG] = 32, 38 + [RC_DSM_MAC_ADDR_BASE_HIGH_CFG] = 30, 39 + [RC_DSM_MAC_ADDR_BASE_LOW_CFG] = 30, 40 + [RC_DSM_TAXI_CAL_CFG] = 6, 41 + [RC_GCB_HW_SGPIO_TO_SD_MAP_CFG] = 30, 42 + [RC_HSCH_PORT_MODE] = 35, 43 + [RC_QFWD_SWITCH_PORT_MODE] = 35, 44 + [RC_QSYS_PAUSE_CFG] = 35, 45 + [RC_QSYS_ATOP] = 35, 46 + [RC_QSYS_FWD_PRESSURE] = 35, 47 + [RC_QSYS_CAL_AUTO] = 4, 48 + [RC_REW_OWN_UPSID] = 1, 49 + [RC_REW_RTAG_ETAG_CTRL] = 35, 50 + }; 51 + 52 + const unsigned int lan969x_gaddr[GADDR_LAST] = { 53 + [GA_ANA_AC_RAM_CTRL] = 202000, 54 + [GA_ANA_AC_PS_COMMON] = 202880, 55 + [GA_ANA_AC_MIRROR_PROBE] = 203232, 56 + [GA_ANA_AC_SRC] = 201728, 57 + [GA_ANA_AC_PGID] = 131072, 58 + [GA_ANA_AC_TSN_SF] = 202028, 59 + [GA_ANA_AC_TSN_SF_CFG] = 148480, 60 + [GA_ANA_AC_TSN_SF_STATUS] = 147936, 61 + [GA_ANA_AC_SG_ACCESS] = 202032, 62 + [GA_ANA_AC_SG_CONFIG] = 202752, 63 + [GA_ANA_AC_SG_STATUS] = 147952, 64 + [GA_ANA_AC_SG_STATUS_STICKY] = 202044, 65 + [GA_ANA_AC_STAT_GLOBAL_CFG_PORT] = 202048, 66 + [GA_ANA_AC_STAT_CNT_CFG_PORT] = 204800, 67 + [GA_ANA_AC_STAT_GLOBAL_CFG_ACL] = 202068, 68 + [GA_ANA_ACL_COMMON] = 8192, 69 + [GA_ANA_ACL_KEY_SEL] = 9204, 70 + [GA_ANA_ACL_CNT_B] = 4096, 71 + [GA_ANA_ACL_STICKY] = 10852, 72 + [GA_ANA_AC_POL_POL_ALL_CFG] = 17504, 73 + [GA_ANA_AC_POL_COMMON_BDLB] = 19464, 74 + [GA_ANA_AC_POL_COMMON_BUM_SLB] = 19472, 75 + [GA_ANA_AC_SDLB_LBGRP_TBL] = 31788, 76 + [GA_ANA_CL_PORT] = 65536, 77 + [GA_ANA_CL_COMMON] = 87040, 78 + [GA_ANA_L2_COMMON] = 561928, 79 + [GA_ANA_L3_COMMON] = 370752, 80 + [GA_ANA_L3_VLAN_ARP_L3MC_STICKY] = 368580, 81 + [GA_ASM_CFG] = 18304, 82 + [GA_ASM_PFC_TIMER_CFG] = 15568, 83 + [GA_ASM_LBK_WM_CFG] = 15596, 84 + [GA_ASM_LBK_MISC_CFG] = 15608, 85 + [GA_ASM_RAM_CTRL] = 15684, 86 + [GA_EACL_ES2_KEY_SELECT_PROFILE] = 36864, 87 + [GA_EACL_CNT_TBL] = 30720, 88 + [GA_EACL_POL_CFG] = 38400, 89 + [GA_EACL_ES2_STICKY] = 29072, 90 + [GA_EACL_RAM_CTRL] = 29112, 91 + [GA_GCB_SIO_CTRL] = 560, 92 + [GA_HSCH_HSCH_DWRR] = 36480, 93 + [GA_HSCH_HSCH_MISC] = 36608, 94 + [GA_HSCH_HSCH_LEAK_LISTS] = 37256, 95 + [GA_HSCH_SYSTEM] = 37384, 96 + [GA_HSCH_MMGT] = 36260, 97 + [GA_HSCH_TAS_CONFIG] = 37696, 98 + [GA_PTP_PTP_CFG] = 512, 99 + [GA_PTP_PTP_TOD_DOMAINS] = 528, 100 + [GA_PTP_PHASE_DETECTOR_CTRL] = 628, 101 + [GA_QSYS_CALCFG] = 2164, 102 + [GA_QSYS_RAM_CTRL] = 2204, 103 + [GA_REW_COMMON] = 98304, 104 + [GA_REW_PORT] = 49152, 105 + [GA_REW_VOE_PORT_LM_CNT] = 90112, 106 + [GA_REW_RAM_CTRL] = 93992, 107 + [GA_VOP_RAM_CTRL] = 16368, 108 + [GA_XQS_SYSTEM] = 5744, 109 + [GA_XQS_QLIMIT_SHR] = 6912, 110 + }; 111 + 112 + const unsigned int lan969x_gcnt[GCNT_LAST] = { 113 + [GC_ANA_AC_SRC] = 67, 114 + [GC_ANA_AC_PGID] = 1054, 115 + [GC_ANA_AC_TSN_SF_CFG] = 256, 116 + [GC_ANA_AC_STAT_CNT_CFG_PORT] = 35, 117 + [GC_ANA_ACL_KEY_SEL] = 99, 118 + [GC_ANA_ACL_CNT_A] = 1024, 119 + [GC_ANA_ACL_CNT_B] = 1024, 120 + [GC_ANA_AC_SDLB_LBGRP_TBL] = 5, 121 + [GC_ANA_AC_SDLB_LBSET_TBL] = 496, 122 + [GC_ANA_CL_PORT] = 35, 123 + [GC_ANA_L2_ISDX_LIMIT] = 256, 124 + [GC_ANA_L2_ISDX] = 1024, 125 + [GC_ANA_L3_VLAN] = 4608, 126 + [GC_ASM_DEV_STATISTICS] = 30, 127 + [GC_EACL_ES2_KEY_SELECT_PROFILE] = 68, 128 + [GC_EACL_CNT_TBL] = 512, 129 + [GC_GCB_SIO_CTRL] = 1, 130 + [GC_HSCH_HSCH_CFG] = 1120, 131 + [GC_HSCH_HSCH_DWRR] = 32, 132 + [GC_PTP_PTP_PINS] = 8, 133 + [GC_PTP_PHASE_DETECTOR_CTRL] = 8, 134 + [GC_REW_PORT] = 35, 135 + [GC_REW_VOE_PORT_LM_CNT] = 240, 136 + }; 137 + 138 + const unsigned int lan969x_gsize[GSIZE_LAST] = { 139 + [GW_ANA_AC_SRC] = 4, 140 + [GW_ANA_L2_COMMON] = 712, 141 + [GW_ASM_CFG] = 1092, 142 + [GW_CPU_CPU_REGS] = 180, 143 + [GW_DEV2G5_PHASE_DETECTOR_CTRL] = 12, 144 + [GW_FDMA_FDMA] = 448, 145 + [GW_GCB_CHIP_REGS] = 180, 146 + [GW_HSCH_TAS_CONFIG] = 16, 147 + [GW_PTP_PHASE_DETECTOR_CTRL] = 12, 148 + [GW_QSYS_PAUSE_CFG] = 988, 149 + }; 150 + 151 + const unsigned int lan969x_fpos[FPOS_LAST] = { 152 + [FP_CPU_PROC_CTRL_AARCH64_MODE_ENA] = 7, 153 + [FP_CPU_PROC_CTRL_L2_RST_INVALIDATE_DIS] = 6, 154 + [FP_CPU_PROC_CTRL_L1_RST_INVALIDATE_DIS] = 5, 155 + [FP_CPU_PROC_CTRL_BE_EXCEP_MODE] = 4, 156 + [FP_CPU_PROC_CTRL_VINITHI] = 3, 157 + [FP_CPU_PROC_CTRL_CFGTE] = 2, 158 + [FP_CPU_PROC_CTRL_CP15S_DISABLE] = 1, 159 + [FP_CPU_PROC_CTRL_PROC_CRYPTO_DISABLE] = 0, 160 + [FP_CPU_PROC_CTRL_L2_FLUSH_REQ] = 8, 161 + [FP_DEV2G5_PHAD_CTRL_PHAD_ENA] = 5, 162 + [FP_DEV2G5_PHAD_CTRL_PHAD_FAILED] = 3, 163 + [FP_FDMA_CH_CFG_CH_XTR_STATUS_MODE] = 5, 164 + [FP_FDMA_CH_CFG_CH_INTR_DB_EOF_ONLY] = 4, 165 + [FP_FDMA_CH_CFG_CH_INJ_PORT] = 3, 166 + [FP_PTP_PTP_PIN_CFG_PTP_PIN_ACTION] = 27, 167 + [FP_PTP_PTP_PIN_CFG_PTP_PIN_SYNC] = 25, 168 + [FP_PTP_PTP_PIN_CFG_PTP_PIN_INV_POL] = 24, 169 + [FP_PTP_PHAD_CTRL_PHAD_ENA] = 5, 170 + [FP_PTP_PHAD_CTRL_PHAD_FAILED] = 3, 171 + }; 172 + 173 + const unsigned int lan969x_fsize[FSIZE_LAST] = { 174 + [FW_ANA_AC_PROBE_PORT_CFG_PROBE_PORT_MASK] = 30, 175 + [FW_ANA_AC_SRC_CFG_PORT_MASK] = 30, 176 + [FW_ANA_AC_PGID_CFG_PORT_MASK] = 30, 177 + [FW_ANA_AC_TSN_SF_PORT_NUM] = 7, 178 + [FW_ANA_AC_TSN_SF_CFG_TSN_SGID] = 8, 179 + [FW_ANA_AC_TSN_SF_STATUS_TSN_SFID] = 8, 180 + [FW_ANA_AC_SG_ACCESS_CTRL_SGID] = 8, 181 + [FW_ANA_AC_PORT_SGE_CFG_MASK] = 17, 182 + [FW_ANA_AC_SDLB_XLB_START_LBSET_START] = 9, 183 + [FW_ANA_AC_SDLB_LBGRP_MISC_THRES_SHIFT] = 3, 184 + [FW_ANA_AC_SDLB_LBGRP_STATE_TBL_PUP_LBSET_NEXT] = 9, 185 + [FW_ANA_AC_SDLB_XLB_NEXT_LBSET_NEXT] = 9, 186 + [FW_ANA_AC_SDLB_XLB_NEXT_LBGRP] = 3, 187 + [FW_ANA_AC_SDLB_INH_LBSET_ADDR_INH_LBSET_ADDR] = 9, 188 + [FW_ANA_L2_AUTO_LRN_CFG_AUTO_LRN_ENA] = 30, 189 + [FW_ANA_L2_DLB_CFG_DLB_IDX] = 9, 190 + [FW_ANA_L2_TSN_CFG_TSN_SFID] = 8, 191 + [FW_ANA_L3_VLAN_MASK_CFG_VLAN_PORT_MASK] = 30, 192 + [FW_FDMA_CH_CFG_CH_DCB_DB_CNT] = 2, 193 + [FW_GCB_HW_SGPIO_TO_SD_MAP_CFG_SGPIO_TO_SD_SEL] = 7, 194 + [FW_HSCH_SE_CFG_SE_DWRR_CNT] = 5, 195 + [FW_HSCH_SE_CONNECT_SE_LEAK_LINK] = 14, 196 + [FW_HSCH_SE_DLB_SENSE_SE_DLB_DPORT] = 6, 197 + [FW_HSCH_HSCH_CFG_CFG_CFG_SE_IDX] = 11, 198 + [FW_HSCH_HSCH_LEAK_CFG_LEAK_FIRST] = 14, 199 + [FW_HSCH_FLUSH_CTRL_FLUSH_PORT] = 6, 200 + [FW_HSCH_FLUSH_CTRL_FLUSH_HIER] = 14, 201 + [FW_LRN_COMMON_ACCESS_CTRL_CPU_ACCESS_DIRECT_ROW] = 13, 202 + [FW_LRN_MAC_ACCESS_CFG_3_MAC_ENTRY_ISDX_LIMIT_IDX] = 8, 203 + [FW_LRN_AUTOAGE_CFG_2_NEXT_ROW] = 13, 204 + [FW_PTP_PTP_PIN_INTR_INTR_PTP] = 8, 205 + [FW_PTP_PTP_PIN_INTR_ENA_INTR_PTP_ENA] = 8, 206 + [FW_PTP_PTP_INTR_IDENT_INTR_PTP_IDENT] = 8, 207 + [FW_PTP_PTP_PIN_CFG_PTP_PIN_SELECT] = 3, 208 + [FW_QFWD_FRAME_COPY_CFG_FRMC_PORT_VAL] = 6, 209 + [FW_QRES_RES_CFG_WM_HIGH] = 11, 210 + [FW_QRES_RES_STAT_MAXUSE] = 19, 211 + [FW_QRES_RES_STAT_CUR_INUSE] = 19, 212 + [FW_QSYS_PAUSE_CFG_PAUSE_START] = 11, 213 + [FW_QSYS_PAUSE_CFG_PAUSE_STOP] = 11, 214 + [FW_QSYS_ATOP_ATOP] = 11, 215 + [FW_QSYS_ATOP_TOT_CFG_ATOP_TOT] = 11, 216 + [FW_REW_RTAG_ETAG_CTRL_IPE_TBL] = 6, 217 + [FW_XQS_STAT_CFG_STAT_VIEW] = 10, 218 + [FW_XQS_QLIMIT_SHR_TOP_CFG_QLIMIT_SHR_TOP] = 14, 219 + [FW_XQS_QLIMIT_SHR_ATOP_CFG_QLIMIT_SHR_ATOP] = 14, 220 + [FW_XQS_QLIMIT_SHR_CTOP_CFG_QLIMIT_SHR_CTOP] = 14, 221 + [FW_XQS_QLIMIT_SHR_QLIM_CFG_QLIMIT_SHR_QLIM] = 14, 222 + };
+48 -24
drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c
··· 15 15 #define SPX5_CALBITS_PER_PORT 3 /* Bit per port in calendar register */ 16 16 17 17 /* DSM calendar information */ 18 - #define SPX5_DSM_CAL_EMPTY 0xFFFF 19 18 #define SPX5_DSM_CAL_TAXIS 8 20 19 #define SPX5_DSM_CAL_BW_LOSS 553 21 20 ··· 52 53 case SPX5_TARGET_CT_7558: 53 54 case SPX5_TARGET_CT_7558TSN: 54 55 return 201000; 56 + case SPX5_TARGET_CT_LAN9691VAO: 57 + return 46000; 58 + case SPX5_TARGET_CT_LAN9694RED: 59 + case SPX5_TARGET_CT_LAN9694TSN: 60 + case SPX5_TARGET_CT_LAN9694: 61 + return 68000; 62 + case SPX5_TARGET_CT_LAN9696RED: 63 + case SPX5_TARGET_CT_LAN9696TSN: 64 + case SPX5_TARGET_CT_LAN9692VAO: 65 + case SPX5_TARGET_CT_LAN9696: 66 + return 88000; 67 + case SPX5_TARGET_CT_LAN9698RED: 68 + case SPX5_TARGET_CT_LAN9698TSN: 69 + case SPX5_TARGET_CT_LAN9693VAO: 70 + case SPX5_TARGET_CT_LAN9698: 71 + return 101000; 55 72 default: 56 73 return 0; 57 74 } 58 75 } 59 76 60 - /* This is used in calendar configuration */ 61 - enum sparx5_cal_bw { 62 - SPX5_CAL_SPEED_NONE = 0, 63 - SPX5_CAL_SPEED_1G = 1, 64 - SPX5_CAL_SPEED_2G5 = 2, 65 - SPX5_CAL_SPEED_5G = 3, 66 - SPX5_CAL_SPEED_10G = 4, 67 - SPX5_CAL_SPEED_25G = 5, 68 - SPX5_CAL_SPEED_0G5 = 6, 69 - SPX5_CAL_SPEED_12G5 = 7 70 - }; 71 - 72 77 static u32 sparx5_clk_to_bandwidth(enum sparx5_core_clockfreq cclock) 73 78 { 74 79 switch (cclock) { 75 80 case SPX5_CORE_CLOCK_250MHZ: return 83000; /* 250000 / 3 */ 81 + case SPX5_CORE_CLOCK_328MHZ: return 109375; /* 328000 / 3 */ 76 82 case SPX5_CORE_CLOCK_500MHZ: return 166000; /* 500000 / 3 */ 77 83 case SPX5_CORE_CLOCK_625MHZ: return 208000; /* 625000 / 3 */ 78 84 default: return 0; ··· 85 81 return 0; 86 82 } 87 83 88 - static u32 sparx5_cal_speed_to_value(enum sparx5_cal_bw speed) 84 + u32 sparx5_cal_speed_to_value(enum sparx5_cal_bw speed) 89 85 { 90 86 switch (speed) { 91 87 case SPX5_CAL_SPEED_1G: return 1000; ··· 98 94 default: return 0; 99 95 } 100 96 } 97 + EXPORT_SYMBOL_GPL(sparx5_cal_speed_to_value); 101 98 102 99 static u32 sparx5_bandwidth_to_calendar(u32 bw) 103 100 { ··· 116 111 } 117 112 } 118 113 119 - static enum sparx5_cal_bw sparx5_get_port_cal_speed(struct sparx5 *sparx5, 120 - u32 portno) 114 + enum sparx5_cal_bw sparx5_get_port_cal_speed(struct sparx5 *sparx5, u32 portno) 121 115 { 122 116 struct sparx5_port *port; 123 117 ··· 150 146 return SPX5_CAL_SPEED_NONE; 151 147 return sparx5_bandwidth_to_calendar(port->conf.bandwidth); 152 148 } 149 + EXPORT_SYMBOL_GPL(sparx5_get_port_cal_speed); 153 150 154 151 /* Auto configure the QSYS calendar based on port configuration */ 155 152 int sparx5_config_auto_calendar(struct sparx5 *sparx5) ··· 531 526 static int sparx5_dsm_calendar_update(struct sparx5 *sparx5, u32 taxi, 532 527 struct sparx5_calendar_data *data) 533 528 { 534 - u32 idx; 535 - u32 cal_len = sparx5_dsm_cal_len(data->schedule), len; 529 + u32 cal_len = sparx5_dsm_cal_len(data->schedule), len, idx; 536 530 537 - spx5_wr(DSM_TAXI_CAL_CFG_CAL_PGM_ENA_SET(1), 538 - sparx5, 539 - DSM_TAXI_CAL_CFG(taxi)); 531 + if (!is_sparx5(sparx5)) { 532 + u32 val, act; 533 + 534 + val = spx5_rd(sparx5, DSM_TAXI_CAL_CFG(taxi)); 535 + act = DSM_TAXI_CAL_CFG_CAL_SEL_STAT_GET(val); 536 + 537 + spx5_rmw(DSM_TAXI_CAL_CFG_CAL_PGM_SEL_SET(!act), 538 + DSM_TAXI_CAL_CFG_CAL_PGM_SEL, 539 + sparx5, DSM_TAXI_CAL_CFG(taxi)); 540 + } 541 + 542 + spx5_rmw(DSM_TAXI_CAL_CFG_CAL_PGM_ENA_SET(1), 543 + DSM_TAXI_CAL_CFG_CAL_PGM_ENA, 544 + sparx5, 545 + DSM_TAXI_CAL_CFG(taxi)); 540 546 for (idx = 0; idx < cal_len; idx++) { 541 547 spx5_rmw(DSM_TAXI_CAL_CFG_CAL_IDX_SET(idx), 542 548 DSM_TAXI_CAL_CFG_CAL_IDX, ··· 558 542 sparx5, 559 543 DSM_TAXI_CAL_CFG(taxi)); 560 544 } 561 - spx5_wr(DSM_TAXI_CAL_CFG_CAL_PGM_ENA_SET(0), 562 - sparx5, 563 - DSM_TAXI_CAL_CFG(taxi)); 545 + spx5_rmw(DSM_TAXI_CAL_CFG_CAL_PGM_ENA_SET(0), 546 + DSM_TAXI_CAL_CFG_CAL_PGM_ENA, 547 + sparx5, 548 + DSM_TAXI_CAL_CFG(taxi)); 564 549 len = DSM_TAXI_CAL_CFG_CAL_CUR_LEN_GET(spx5_rd(sparx5, 565 550 DSM_TAXI_CAL_CFG(taxi))); 566 551 if (len != cal_len - 1) 567 552 goto update_err; 553 + 554 + if (!is_sparx5(sparx5)) { 555 + spx5_rmw(DSM_TAXI_CAL_CFG_CAL_SWITCH_SET(1), 556 + DSM_TAXI_CAL_CFG_CAL_SWITCH, 557 + sparx5, DSM_TAXI_CAL_CFG(taxi)); 558 + } 559 + 568 560 return 0; 569 561 update_err: 570 562 dev_err(sparx5->dev, "Incorrect calendar length: %u\n", len);
+1 -1
drivers/net/ethernet/microchip/sparx5/sparx5_fdma.c
··· 154 154 skb = rx->skb[fdma->dcb_index][fdma->db_index]; 155 155 skb_put(skb, fdma_db_len_get(db_hw)); 156 156 /* Now do the normal processing of the skb */ 157 - sparx5_ifh_parse((u32 *)skb->data, &fi); 157 + sparx5_ifh_parse(sparx5, (u32 *)skb->data, &fi); 158 158 /* Map to port netdev */ 159 159 port = fi.src_port < sparx5->data->consts->n_ports ? 160 160 sparx5->ports[fi.src_port] :
+72 -10
drivers/net/ethernet/microchip/sparx5/sparx5_main.c
··· 24 24 #include <linux/types.h> 25 25 #include <linux/reset.h> 26 26 27 + #include "../lan969x/lan969x.h" /* for lan969x match data */ 28 + 27 29 #include "sparx5_main_regs.h" 28 30 #include "sparx5_main.h" 29 31 #include "sparx5_port.h" ··· 227 225 default: 228 226 return false; 229 227 } 228 + } 229 + 230 + static void sparx5_init_features(struct sparx5 *sparx5) 231 + { 232 + switch (sparx5->target_ct) { 233 + case SPX5_TARGET_CT_7546: 234 + case SPX5_TARGET_CT_7549: 235 + case SPX5_TARGET_CT_7552: 236 + case SPX5_TARGET_CT_7556: 237 + case SPX5_TARGET_CT_7558: 238 + case SPX5_TARGET_CT_7546TSN: 239 + case SPX5_TARGET_CT_7549TSN: 240 + case SPX5_TARGET_CT_7552TSN: 241 + case SPX5_TARGET_CT_7556TSN: 242 + case SPX5_TARGET_CT_7558TSN: 243 + case SPX5_TARGET_CT_LAN9691VAO: 244 + case SPX5_TARGET_CT_LAN9694TSN: 245 + case SPX5_TARGET_CT_LAN9694RED: 246 + case SPX5_TARGET_CT_LAN9692VAO: 247 + case SPX5_TARGET_CT_LAN9696TSN: 248 + case SPX5_TARGET_CT_LAN9696RED: 249 + case SPX5_TARGET_CT_LAN9693VAO: 250 + case SPX5_TARGET_CT_LAN9698TSN: 251 + case SPX5_TARGET_CT_LAN9698RED: 252 + sparx5->features = (SPX5_FEATURE_PSFP | SPX5_FEATURE_PTP); 253 + break; 254 + default: 255 + break; 256 + } 257 + } 258 + 259 + bool sparx5_has_feature(struct sparx5 *sparx5, enum sparx5_feature feature) 260 + { 261 + return sparx5->features & feature; 230 262 } 231 263 232 264 static int sparx5_create_targets(struct sparx5 *sparx5) ··· 511 475 else if (sparx5->coreclock == SPX5_CORE_CLOCK_250MHZ) 512 476 freq = 0; /* Not supported */ 513 477 break; 478 + case SPX5_TARGET_CT_LAN9694: 479 + case SPX5_TARGET_CT_LAN9691VAO: 480 + case SPX5_TARGET_CT_LAN9694TSN: 481 + case SPX5_TARGET_CT_LAN9694RED: 482 + case SPX5_TARGET_CT_LAN9696: 483 + case SPX5_TARGET_CT_LAN9692VAO: 484 + case SPX5_TARGET_CT_LAN9696TSN: 485 + case SPX5_TARGET_CT_LAN9696RED: 486 + case SPX5_TARGET_CT_LAN9698: 487 + case SPX5_TARGET_CT_LAN9693VAO: 488 + case SPX5_TARGET_CT_LAN9698TSN: 489 + case SPX5_TARGET_CT_LAN9698RED: 490 + freq = SPX5_CORE_CLOCK_328MHZ; 491 + break; 514 492 default: 515 493 dev_err(sparx5->dev, "Target (%#04x) not supported\n", 516 494 sparx5->target_ct); ··· 566 516 CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_ROT_ENA | 567 517 CLKGEN_LCPLL1_CORE_CLK_CFG_CORE_CLK_ENA, 568 518 sparx5, CLKGEN_LCPLL1_CORE_CLK_CFG); 519 + } else { 520 + pol_upd_int = 820; // SPX5_CORE_CLOCK_328MHZ 569 521 } 570 522 571 523 /* Update state with chosen frequency */ 572 524 sparx5->coreclock = freq; 573 525 clk_period = sparx5_clk_period(freq); 574 526 575 - spx5_rmw(HSCH_SYS_CLK_PER_100PS_SET(clk_period / 100), 576 - HSCH_SYS_CLK_PER_100PS, 577 - sparx5, 578 - HSCH_SYS_CLK_PER); 527 + if (is_sparx5(sparx5)) 528 + spx5_rmw(HSCH_SYS_CLK_PER_100PS_SET(clk_period / 100), 529 + HSCH_SYS_CLK_PER_100PS, 530 + sparx5, 531 + HSCH_SYS_CLK_PER); 579 532 580 533 spx5_rmw(ANA_AC_POL_BDLB_DLB_CTRL_CLK_PERIOD_01NS_SET(clk_period / 100), 581 534 ANA_AC_POL_BDLB_DLB_CTRL_CLK_PERIOD_01NS, ··· 768 715 if (err) 769 716 return err; 770 717 771 - err = sparx5_vcap_init(sparx5); 772 - if (err) { 773 - sparx5_unregister_notifier_blocks(sparx5); 774 - return err; 718 + if (is_sparx5(sparx5)) { 719 + err = sparx5_vcap_init(sparx5); 720 + if (err) { 721 + sparx5_unregister_notifier_blocks(sparx5); 722 + return err; 723 + } 775 724 } 776 725 777 726 /* Start Frame DMA with fallback to register based INJ/XTR */ 778 727 err = -ENXIO; 779 - if (sparx5->fdma_irq >= 0) { 728 + if (sparx5->fdma_irq >= 0 && is_sparx5(sparx5)) { 780 729 if (GCB_CHIP_ID_REV_ID_GET(sparx5->chip_id) > 0) 781 730 err = devm_request_threaded_irq(sparx5->dev, 782 731 sparx5->fdma_irq, ··· 805 750 sparx5->xtr_irq = -ENXIO; 806 751 } 807 752 808 - if (sparx5->ptp_irq >= 0) { 753 + if (sparx5->ptp_irq >= 0 && 754 + sparx5_has_feature(sparx5, SPX5_FEATURE_PTP)) { 809 755 err = devm_request_threaded_irq(sparx5->dev, sparx5->ptp_irq, 810 756 NULL, ops->ptp_irq_handler, 811 757 IRQF_ONESHOT, "sparx5-ptp", ··· 950 894 sparx5->target_ct = (enum spx5_target_chiptype) 951 895 GCB_CHIP_ID_PART_ID_GET(sparx5->chip_id); 952 896 897 + /* Initialize the features based on the target */ 898 + sparx5_init_features(sparx5); 899 + 953 900 /* Initialize Switchcore and internal RAMs */ 954 901 err = sparx5_init_switchcore(sparx5); 955 902 if (err) { ··· 1090 1031 1091 1032 static const struct of_device_id mchp_sparx5_match[] = { 1092 1033 { .compatible = "microchip,sparx5-switch", .data = &sparx5_desc }, 1034 + #if IS_ENABLED(CONFIG_LAN969X_SWITCH) 1035 + { .compatible = "microchip,lan9691-switch", .data = &lan969x_desc }, 1036 + #endif 1093 1037 { } 1094 1038 }; 1095 1039 MODULE_DEVICE_TABLE(of, mchp_sparx5_match);
+60 -15
drivers/net/ethernet/microchip/sparx5/sparx5_main.h
··· 26 26 27 27 /* Target chip type */ 28 28 enum spx5_target_chiptype { 29 - SPX5_TARGET_CT_7546 = 0x7546, /* SparX-5-64 Enterprise */ 30 - SPX5_TARGET_CT_7549 = 0x7549, /* SparX-5-90 Enterprise */ 31 - SPX5_TARGET_CT_7552 = 0x7552, /* SparX-5-128 Enterprise */ 32 - SPX5_TARGET_CT_7556 = 0x7556, /* SparX-5-160 Enterprise */ 33 - SPX5_TARGET_CT_7558 = 0x7558, /* SparX-5-200 Enterprise */ 34 - SPX5_TARGET_CT_7546TSN = 0x47546, /* SparX-5-64i Industrial */ 35 - SPX5_TARGET_CT_7549TSN = 0x47549, /* SparX-5-90i Industrial */ 36 - SPX5_TARGET_CT_7552TSN = 0x47552, /* SparX-5-128i Industrial */ 37 - SPX5_TARGET_CT_7556TSN = 0x47556, /* SparX-5-160i Industrial */ 38 - SPX5_TARGET_CT_7558TSN = 0x47558, /* SparX-5-200i Industrial */ 29 + SPX5_TARGET_CT_7546 = 0x7546, /* SparX-5-64 Enterprise */ 30 + SPX5_TARGET_CT_7549 = 0x7549, /* SparX-5-90 Enterprise */ 31 + SPX5_TARGET_CT_7552 = 0x7552, /* SparX-5-128 Enterprise */ 32 + SPX5_TARGET_CT_7556 = 0x7556, /* SparX-5-160 Enterprise */ 33 + SPX5_TARGET_CT_7558 = 0x7558, /* SparX-5-200 Enterprise */ 34 + SPX5_TARGET_CT_7546TSN = 0x47546, /* SparX-5-64i Industrial */ 35 + SPX5_TARGET_CT_7549TSN = 0x47549, /* SparX-5-90i Industrial */ 36 + SPX5_TARGET_CT_7552TSN = 0x47552, /* SparX-5-128i Industrial */ 37 + SPX5_TARGET_CT_7556TSN = 0x47556, /* SparX-5-160i Industrial */ 38 + SPX5_TARGET_CT_7558TSN = 0x47558, /* SparX-5-200i Industrial */ 39 + SPX5_TARGET_CT_LAN9694 = 0x9694, /* lan969x-40 */ 40 + SPX5_TARGET_CT_LAN9691VAO = 0x9691, /* lan969x-40-VAO */ 41 + SPX5_TARGET_CT_LAN9694TSN = 0x9695, /* lan969x-40-TSN */ 42 + SPX5_TARGET_CT_LAN9694RED = 0x969A, /* lan969x-40-RED */ 43 + SPX5_TARGET_CT_LAN9696 = 0x9696, /* lan969x-60 */ 44 + SPX5_TARGET_CT_LAN9692VAO = 0x9692, /* lan969x-65-VAO */ 45 + SPX5_TARGET_CT_LAN9696TSN = 0x9697, /* lan969x-60-TSN */ 46 + SPX5_TARGET_CT_LAN9696RED = 0x969B, /* lan969x-60-RED */ 47 + SPX5_TARGET_CT_LAN9698 = 0x9698, /* lan969x-100 */ 48 + SPX5_TARGET_CT_LAN9693VAO = 0x9693, /* lan969x-100-VAO */ 49 + SPX5_TARGET_CT_LAN9698TSN = 0x9699, /* lan969x-100-TSN */ 50 + SPX5_TARGET_CT_LAN9698RED = 0x969C, /* lan969x-100-RED */ 39 51 }; 40 52 41 53 enum sparx5_port_max_tags { ··· 61 49 SPX5_VLAN_PORT_TYPE_C, /* C-port */ 62 50 SPX5_VLAN_PORT_TYPE_S, /* S-port */ 63 51 SPX5_VLAN_PORT_TYPE_S_CUSTOM /* S-port using custom type */ 52 + }; 53 + 54 + /* This is used in calendar configuration */ 55 + enum sparx5_cal_bw { 56 + SPX5_CAL_SPEED_NONE = 0, 57 + SPX5_CAL_SPEED_1G = 1, 58 + SPX5_CAL_SPEED_2G5 = 2, 59 + SPX5_CAL_SPEED_5G = 3, 60 + SPX5_CAL_SPEED_10G = 4, 61 + SPX5_CAL_SPEED_25G = 5, 62 + SPX5_CAL_SPEED_0G5 = 6, 63 + SPX5_CAL_SPEED_12G5 = 7 64 + }; 65 + 66 + enum sparx5_feature { 67 + SPX5_FEATURE_PSFP = BIT(0), 68 + SPX5_FEATURE_PTP = BIT(1), 64 69 }; 65 70 66 71 #define SPX5_PORTS 65 ··· 130 101 131 102 #define SPX5_DSM_CAL_LEN 64 132 103 #define SPX5_DSM_CAL_MAX_DEVS_PER_TAXI 13 104 + #define SPX5_DSM_CAL_EMPTY 0xFFFF 105 + 106 + #define SPARX5_MAX_PTP_ID 512 133 107 134 108 struct sparx5; 135 109 ··· 224 192 enum sparx5_core_clockfreq { 225 193 SPX5_CORE_CLOCK_DEFAULT, /* Defaults to the highest supported frequency */ 226 194 SPX5_CORE_CLOCK_250MHZ, /* 250MHZ core clock frequency */ 195 + SPX5_CORE_CLOCK_328MHZ, /* 328MHZ core clock frequency */ 227 196 SPX5_CORE_CLOCK_500MHZ, /* 500MHZ core clock frequency */ 228 197 SPX5_CORE_CLOCK_625MHZ, /* 625MHZ core clock frequency */ 229 198 }; ··· 342 309 struct device *dev; 343 310 u32 chip_id; 344 311 enum spx5_target_chiptype target_ct; 312 + u32 features; 345 313 void __iomem *regs[NUM_TARGETS]; 346 314 int port_count; 347 315 struct mutex lock; /* MAC reg lock */ ··· 410 376 411 377 /* sparx5_main.c */ 412 378 bool is_sparx5(struct sparx5 *sparx5); 379 + bool sparx5_has_feature(struct sparx5 *sparx5, enum sparx5_feature feature); 413 380 414 381 /* sparx5_switchdev.c */ 415 382 int sparx5_register_notifier_blocks(struct sparx5 *sparx5); ··· 423 388 }; 424 389 425 390 void sparx5_xtr_flush(struct sparx5 *sparx5, u8 grp); 426 - void sparx5_ifh_parse(u32 *ifh, struct frame_info *info); 391 + void sparx5_ifh_parse(struct sparx5 *sparx5, u32 *ifh, struct frame_info *info); 427 392 irqreturn_t sparx5_xtr_handler(int irq, void *_priv); 428 393 netdev_tx_t sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev); 429 394 int sparx5_manual_injection_mode(struct sparx5 *sparx5); ··· 474 439 int sparx5_config_dsm_calendar(struct sparx5 *sparx5); 475 440 int sparx5_dsm_calendar_calc(struct sparx5 *sparx5, u32 taxi, 476 441 struct sparx5_calendar_data *data); 442 + u32 sparx5_cal_speed_to_value(enum sparx5_cal_bw speed); 443 + enum sparx5_cal_bw sparx5_get_port_cal_speed(struct sparx5 *sparx5, u32 portno); 477 444 478 445 479 446 /* sparx5_ethtool.c */ ··· 493 456 #endif 494 457 495 458 /* sparx5_netdev.c */ 496 - void sparx5_set_port_ifh_timestamp(void *ifh_hdr, u64 timestamp); 459 + void sparx5_set_port_ifh_timestamp(struct sparx5 *sparx5, void *ifh_hdr, 460 + u64 timestamp); 497 461 void sparx5_set_port_ifh_rew_op(void *ifh_hdr, u32 rew_op); 498 - void sparx5_set_port_ifh_pdu_type(void *ifh_hdr, u32 pdu_type); 499 - void sparx5_set_port_ifh_pdu_w16_offset(void *ifh_hdr, u32 pdu_w16_offset); 462 + void sparx5_set_port_ifh_pdu_type(struct sparx5 *sparx5, void *ifh_hdr, 463 + u32 pdu_type); 464 + void sparx5_set_port_ifh_pdu_w16_offset(struct sparx5 *sparx5, void *ifh_hdr, 465 + u32 pdu_w16_offset); 500 466 void sparx5_set_port_ifh(struct sparx5 *sparx5, void *ifh_hdr, u16 portno); 501 467 bool sparx5_netdevice_check(const struct net_device *dev); 502 468 struct net_device *sparx5_create_netdev(struct sparx5 *sparx5, u32 portno); ··· 523 483 struct sk_buff *skb); 524 484 irqreturn_t sparx5_ptp_irq_handler(int irq, void *args); 525 485 int sparx5_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts); 486 + void sparx5_get_hwtimestamp(struct sparx5 *sparx5, 487 + struct timespec64 *ts, 488 + u32 nsec); 526 489 527 490 /* sparx5_vcap_impl.c */ 528 491 int sparx5_vcap_init(struct sparx5 *sparx5); ··· 582 539 int sparx5_sdlb_pup_token_get(struct sparx5 *sparx5, u32 pup_interval, 583 540 u64 rate); 584 541 585 - int sparx5_sdlb_clk_hz_get(struct sparx5 *sparx5); 542 + u64 sparx5_sdlb_clk_hz_get(struct sparx5 *sparx5); 586 543 int sparx5_sdlb_group_get_by_rate(struct sparx5 *sparx5, u32 rate, u32 burst); 587 544 int sparx5_sdlb_group_get_by_index(struct sparx5 *sparx5, u32 idx, u32 *group); 588 545 ··· 684 641 switch (cclock) { 685 642 case SPX5_CORE_CLOCK_250MHZ: 686 643 return 4000; 644 + case SPX5_CORE_CLOCK_328MHZ: 645 + return 3048; 687 646 case SPX5_CORE_CLOCK_500MHZ: 688 647 return 2000; 689 648 case SPX5_CORE_CLOCK_625MHZ:
+132
drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h
··· 2666 2666 #define CPU_PROC_CTRL_ACP_DISABLE_GET(x)\ 2667 2667 FIELD_GET(CPU_PROC_CTRL_ACP_DISABLE, x) 2668 2668 2669 + /* DEV1G:PHASE_DETECTOR_CTRL:PHAD_CTRL */ 2670 + #define DEV2G5_PHAD_CTRL(t, g) \ 2671 + __REG(TARGET_DEV2G5, t, regs->tsize[TC_DEV2G5], 200, g, 2, \ 2672 + regs->gsize[GW_DEV2G5_PHASE_DETECTOR_CTRL], 0, 0, 1, 4) 2673 + 2674 + #define DEV2G5_PHAD_CTRL_PHAD_ENA\ 2675 + BIT(regs->fpos[FP_DEV2G5_PHAD_CTRL_PHAD_ENA]) 2676 + #define DEV2G5_PHAD_CTRL_PHAD_ENA_SET(x)\ 2677 + spx5_field_prep(DEV2G5_PHAD_CTRL_PHAD_ENA, x) 2678 + #define DEV2G5_PHAD_CTRL_PHAD_ENA_GET(x)\ 2679 + spx5_field_get(DEV2G5_PHAD_CTRL_PHAD_ENA, x) 2680 + 2681 + /* LAN969X ONLY */ 2682 + #define DEV2G5_PHAD_CTRL_DIV_CFG GENMASK(11, 9) 2683 + #define DEV2G5_PHAD_CTRL_DIV_CFG_SET(x)\ 2684 + FIELD_PREP(DEV2G5_PHAD_CTRL_DIV_CFG, x) 2685 + #define DEV2G5_PHAD_CTRL_DIV_CFG_GET(x)\ 2686 + FIELD_GET(DEV2G5_PHAD_CTRL_DIV_CFG, x) 2687 + 2688 + /* DEV1G:PHASE_DETECTOR_CTRL:PHAD_CTRL */ 2689 + #define DEV2G5_PHAD_CTRL(t, g) \ 2690 + __REG(TARGET_DEV2G5, t, regs->tsize[TC_DEV2G5], 200, g, 2, \ 2691 + regs->gsize[GW_DEV2G5_PHASE_DETECTOR_CTRL], 0, 0, 1, 4) 2692 + 2693 + #define DEV2G5_PHAD_CTRL_PHAD_ENA\ 2694 + BIT(regs->fpos[FP_DEV2G5_PHAD_CTRL_PHAD_ENA]) 2695 + #define DEV2G5_PHAD_CTRL_PHAD_ENA_SET(x)\ 2696 + spx5_field_prep(DEV2G5_PHAD_CTRL_PHAD_ENA, x) 2697 + #define DEV2G5_PHAD_CTRL_PHAD_ENA_GET(x)\ 2698 + spx5_field_get(DEV2G5_PHAD_CTRL_PHAD_ENA, x) 2699 + 2700 + /* LAN969X ONLY */ 2701 + #define DEV2G5_PHAD_CTRL_DIV_CFG GENMASK(11, 9) 2702 + #define DEV2G5_PHAD_CTRL_DIV_CFG_SET(x)\ 2703 + FIELD_PREP(DEV2G5_PHAD_CTRL_DIV_CFG, x) 2704 + #define DEV2G5_PHAD_CTRL_DIV_CFG_GET(x)\ 2705 + FIELD_GET(DEV2G5_PHAD_CTRL_DIV_CFG, x) 2706 + 2669 2707 /* DEV10G:MAC_CFG_STATUS:MAC_ENA_CFG */ 2670 2708 #define DEV10G_MAC_ENA_CFG(t) \ 2671 2709 __REG(TARGET_DEV10G, t, regs->tsize[TC_DEV10G], 0, 0, 1, 60, 0, 0, 1, \ ··· 2906 2868 FIELD_PREP(DEV10G_DEV_RST_CTRL_MAC_RX_RST, x) 2907 2869 #define DEV10G_DEV_RST_CTRL_MAC_RX_RST_GET(x)\ 2908 2870 FIELD_GET(DEV10G_DEV_RST_CTRL_MAC_RX_RST, x) 2871 + 2872 + /* DEV10G:DEV_CFG_STATUS:PTP_STAMPER_CFG */ 2873 + #define DEV10G_PTP_STAMPER_CFG(t) \ 2874 + __REG(TARGET_DEV10G, t, regs->tsize[TC_DEV10G], 436, 0, 1, 52, 20, 0, \ 2875 + 1, 4) 2909 2876 2910 2877 /* DEV10G:PCS25G_CFG_STATUS:PCS25G_CFG */ 2911 2878 #define DEV10G_PCS25G_CFG(t) \ ··· 4310 4267 #define DEV5G_DEV_RST_CTRL_MAC_RX_RST_GET(x)\ 4311 4268 FIELD_GET(DEV5G_DEV_RST_CTRL_MAC_RX_RST, x) 4312 4269 4270 + /* DEV10G:DEV_CFG_STATUS:PTP_STAMPER_CFG */ 4271 + #define DEV5G_PTP_STAMPER_CFG(t) \ 4272 + __REG(TARGET_DEV5G, t, regs->tsize[TC_DEV5G], 436, 0, 1, 52, 20, 0, 1, \ 4273 + 4) 4274 + 4313 4275 /* DSM:RAM_CTRL:RAM_INIT */ 4314 4276 #define DSM_RAM_INIT \ 4315 4277 __REG(TARGET_DSM, 0, 1, 0, 0, 1, 4, 0, 0, 1, 4) ··· 4491 4443 FIELD_PREP(DSM_TAXI_CAL_CFG_CAL_PGM_ENA, x) 4492 4444 #define DSM_TAXI_CAL_CFG_CAL_PGM_ENA_GET(x)\ 4493 4445 FIELD_GET(DSM_TAXI_CAL_CFG_CAL_PGM_ENA, x) 4446 + 4447 + /* LAN969X ONLY */ 4448 + #define DSM_TAXI_CAL_CFG_CAL_SEL_STAT BIT(23) 4449 + #define DSM_TAXI_CAL_CFG_CAL_SEL_STAT_SET(x)\ 4450 + FIELD_PREP(DSM_TAXI_CAL_CFG_CAL_SEL_STAT, x) 4451 + #define DSM_TAXI_CAL_CFG_CAL_SEL_STAT_GET(x)\ 4452 + FIELD_GET(DSM_TAXI_CAL_CFG_CAL_SEL_STAT, x) 4453 + 4454 + /* LAN969X ONLY */ 4455 + #define DSM_TAXI_CAL_CFG_CAL_SWITCH BIT(22) 4456 + #define DSM_TAXI_CAL_CFG_CAL_SWITCH_SET(x)\ 4457 + FIELD_PREP(DSM_TAXI_CAL_CFG_CAL_SWITCH, x) 4458 + #define DSM_TAXI_CAL_CFG_CAL_SWITCH_GET(x)\ 4459 + FIELD_GET(DSM_TAXI_CAL_CFG_CAL_SWITCH, x) 4460 + 4461 + /* LAN969X ONLY */ 4462 + #define DSM_TAXI_CAL_CFG_CAL_PGM_SEL BIT(21) 4463 + #define DSM_TAXI_CAL_CFG_CAL_PGM_SEL_SET(x)\ 4464 + FIELD_PREP(DSM_TAXI_CAL_CFG_CAL_PGM_SEL, x) 4465 + #define DSM_TAXI_CAL_CFG_CAL_PGM_SEL_GET(x)\ 4466 + FIELD_GET(DSM_TAXI_CAL_CFG_CAL_PGM_SEL, x) 4494 4467 4495 4468 /* EACL:ES2_KEY_SELECT_PROFILE:VCAP_ES2_KEY_SEL */ 4496 4469 #define EACL_VCAP_ES2_KEY_SEL(g, r) \ ··· 6788 6719 __REG(TARGET_PTP, 0, 1, regs->gaddr[GA_PTP_PHASE_DETECTOR_CTRL], g, \ 6789 6720 regs->gcnt[GC_PTP_PHASE_DETECTOR_CTRL], \ 6790 6721 regs->gsize[GW_PTP_PHASE_DETECTOR_CTRL], 4, 0, 1, 4) 6722 + 6723 + /* LAN969X ONLY */ 6724 + /* DEVCPU_PTP:PTP_TS_FIFO:PTP_TWOSTEP_CTRL */ 6725 + #define PTP_TWOSTEP_CTRL \ 6726 + __REG(TARGET_PTP, 0, 1, 612, 0, 1, 16, 0, 0, 1, 4) 6727 + 6728 + #define PTP_TWOSTEP_CTRL_PTP_OVWR_ENA BIT(12) 6729 + #define PTP_TWOSTEP_CTRL_PTP_OVWR_ENA_SET(x)\ 6730 + FIELD_PREP(PTP_TWOSTEP_CTRL_PTP_OVWR_ENA, x) 6731 + #define PTP_TWOSTEP_CTRL_PTP_OVWR_ENA_GET(x)\ 6732 + FIELD_GET(PTP_TWOSTEP_CTRL_PTP_OVWR_ENA, x) 6733 + 6734 + #define PTP_TWOSTEP_CTRL_PTP_NXT BIT(11) 6735 + #define PTP_TWOSTEP_CTRL_PTP_NXT_SET(x)\ 6736 + FIELD_PREP(PTP_TWOSTEP_CTRL_PTP_NXT, x) 6737 + #define PTP_TWOSTEP_CTRL_PTP_NXT_GET(x)\ 6738 + FIELD_GET(PTP_TWOSTEP_CTRL_PTP_NXT, x) 6739 + 6740 + #define PTP_TWOSTEP_CTRL_PTP_VLD BIT(10) 6741 + #define PTP_TWOSTEP_CTRL_PTP_VLD_SET(x)\ 6742 + FIELD_PREP(PTP_TWOSTEP_CTRL_PTP_VLD, x) 6743 + #define PTP_TWOSTEP_CTRL_PTP_VLD_GET(x)\ 6744 + FIELD_GET(PTP_TWOSTEP_CTRL_PTP_VLD, x) 6745 + 6746 + #define PTP_TWOSTEP_CTRL_STAMP_TX BIT(9) 6747 + #define PTP_TWOSTEP_CTRL_STAMP_TX_SET(x)\ 6748 + FIELD_PREP(PTP_TWOSTEP_CTRL_STAMP_TX, x) 6749 + #define PTP_TWOSTEP_CTRL_STAMP_TX_GET(x)\ 6750 + FIELD_GET(PTP_TWOSTEP_CTRL_STAMP_TX, x) 6751 + 6752 + #define PTP_TWOSTEP_CTRL_STAMP_PORT GENMASK(8, 1) 6753 + #define PTP_TWOSTEP_CTRL_STAMP_PORT_SET(x)\ 6754 + FIELD_PREP(PTP_TWOSTEP_CTRL_STAMP_PORT, x) 6755 + #define PTP_TWOSTEP_CTRL_STAMP_PORT_GET(x)\ 6756 + FIELD_GET(PTP_TWOSTEP_CTRL_STAMP_PORT, x) 6757 + 6758 + #define PTP_TWOSTEP_CTRL_PTP_OVFL BIT(0) 6759 + #define PTP_TWOSTEP_CTRL_PTP_OVFL_SET(x)\ 6760 + FIELD_PREP(PTP_TWOSTEP_CTRL_PTP_OVFL, x) 6761 + #define PTP_TWOSTEP_CTRL_PTP_OVFL_GET(x)\ 6762 + FIELD_GET(PTP_TWOSTEP_CTRL_PTP_OVFL, x) 6763 + 6764 + /* LAN969X ONLY */ 6765 + /* DEVCPU_PTP:PTP_TS_FIFO:PTP_TWOSTEP_STAMP_NSEC */ 6766 + #define PTP_TWOSTEP_STAMP_NSEC \ 6767 + __REG(TARGET_PTP, 0, 1, 612, 0, 1, 16, 4, 0, 1, 4) 6768 + 6769 + #define PTP_TWOSTEP_STAMP_NSEC_NS GENMASK(29, 0) 6770 + #define PTP_TWOSTEP_STAMP_NSEC_NS_SET(x)\ 6771 + FIELD_PREP(PTP_TWOSTEP_STAMP_NSEC_NS, x) 6772 + #define PTP_TWOSTEP_STAMP_NSEC_NS_GET(x)\ 6773 + FIELD_GET(PTP_TWOSTEP_STAMP_NSEC_NS, x) 6774 + 6775 + /* LAN969X ONLY */ 6776 + /* DEVCPU_PTP:PTP_TS_FIFO:PTP_TWOSTEP_STAMP_SUBNS */ 6777 + #define PTP_TWOSTEP_STAMP_SUBNS \ 6778 + __REG(TARGET_PTP, 0, 1, 612, 0, 1, 16, 8, 0, 1, 4) 6779 + 6780 + #define PTP_TWOSTEP_STAMP_SUBNS_NS GENMASK(7, 0) 6781 + #define PTP_TWOSTEP_STAMP_SUBNS_NS_SET(x)\ 6782 + FIELD_PREP(PTP_TWOSTEP_STAMP_SUBNS_NS, x) 6783 + #define PTP_TWOSTEP_STAMP_SUBNS_NS_GET(x)\ 6784 + FIELD_GET(PTP_TWOSTEP_STAMP_SUBNS_NS, x) 6791 6785 6792 6786 /* QFWD:SYSTEM:SWITCH_PORT_MODE */ 6793 6787 #define QFWD_SWITCH_PORT_MODE(r) \
+8 -2
drivers/net/ethernet/microchip/sparx5/sparx5_mirror.c
··· 24 24 /* Get ports belonging to this mirror */ 25 25 static u64 sparx5_mirror_port_get(struct sparx5 *sparx5, u32 idx) 26 26 { 27 - return (u64)spx5_rd(sparx5, ANA_AC_PROBE_PORT_CFG1(idx)) << 32 | 28 - spx5_rd(sparx5, ANA_AC_PROBE_PORT_CFG(idx)); 27 + u64 val; 28 + 29 + val = spx5_rd(sparx5, ANA_AC_PROBE_PORT_CFG(idx)); 30 + 31 + if (is_sparx5(sparx5)) 32 + val |= (u64)spx5_rd(sparx5, ANA_AC_PROBE_PORT_CFG1(idx)) << 32; 33 + 34 + return val; 29 35 } 30 36 31 37 /* Add port to mirror (only front ports) */
+16 -10
drivers/net/ethernet/microchip/sparx5/sparx5_netdev.c
··· 64 64 /* MISC.CPU_MASK/DPORT = Destination port */ 65 65 ifh_encode_bitfield(ifh_hdr, portno, 29, 8); 66 66 /* MISC.PIPELINE_PT */ 67 - ifh_encode_bitfield(ifh_hdr, 16, 37, 5); 67 + ifh_encode_bitfield(ifh_hdr, is_sparx5(sparx5) ? 16 : 17, 37, 5); 68 68 /* MISC.PIPELINE_ACT */ 69 69 ifh_encode_bitfield(ifh_hdr, 1, 42, 3); 70 70 /* FWD.SRC_PORT = CPU */ 71 71 ifh_encode_bitfield(ifh_hdr, sparx5_get_pgid(sparx5, SPX5_PORT_CPU_0), 72 - 46, 7); 72 + 46, is_sparx5(sparx5) ? 7 : 6); 73 73 /* FWD.SFLOW_ID (disable SFlow sampling) */ 74 - ifh_encode_bitfield(ifh_hdr, 124, 57, 7); 74 + ifh_encode_bitfield(ifh_hdr, 124, is_sparx5(sparx5) ? 57 : 56, 7); 75 75 /* FWD.UPDATE_FCS = Enable. Enforce update of FCS. */ 76 - ifh_encode_bitfield(ifh_hdr, 1, 67, 1); 76 + ifh_encode_bitfield(ifh_hdr, 1, is_sparx5(sparx5) ? 67 : 66, 1); 77 77 } 78 78 79 79 void sparx5_set_port_ifh_rew_op(void *ifh_hdr, u32 rew_op) ··· 81 81 ifh_encode_bitfield(ifh_hdr, rew_op, VSTAX + 32, 10); 82 82 } 83 83 84 - void sparx5_set_port_ifh_pdu_type(void *ifh_hdr, u32 pdu_type) 84 + void sparx5_set_port_ifh_pdu_type(struct sparx5 *sparx5, void *ifh_hdr, 85 + u32 pdu_type) 85 86 { 86 - ifh_encode_bitfield(ifh_hdr, pdu_type, 191, 4); 87 + ifh_encode_bitfield(ifh_hdr, pdu_type, is_sparx5(sparx5) ? 191 : 190, 88 + 4); 87 89 } 88 90 89 - void sparx5_set_port_ifh_pdu_w16_offset(void *ifh_hdr, u32 pdu_w16_offset) 91 + void sparx5_set_port_ifh_pdu_w16_offset(struct sparx5 *sparx5, void *ifh_hdr, 92 + u32 pdu_w16_offset) 90 93 { 91 - ifh_encode_bitfield(ifh_hdr, pdu_w16_offset, 195, 6); 94 + ifh_encode_bitfield(ifh_hdr, pdu_w16_offset, 95 + is_sparx5(sparx5) ? 195 : 194, 6); 92 96 } 93 97 94 - void sparx5_set_port_ifh_timestamp(void *ifh_hdr, u64 timestamp) 98 + void sparx5_set_port_ifh_timestamp(struct sparx5 *sparx5, void *ifh_hdr, 99 + u64 timestamp) 95 100 { 96 - ifh_encode_bitfield(ifh_hdr, timestamp, 232, 40); 101 + ifh_encode_bitfield(ifh_hdr, timestamp, 232, 102 + is_sparx5(sparx5) ? 40 : 38); 97 103 } 98 104 99 105 static int sparx5_port_open(struct net_device *ndev)
+10 -6
drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
··· 32 32 spx5_wr(0, sparx5, QS_XTR_FLUSH); 33 33 } 34 34 35 - void sparx5_ifh_parse(u32 *ifh, struct frame_info *info) 35 + void sparx5_ifh_parse(struct sparx5 *sparx5, u32 *ifh, struct frame_info *info) 36 36 { 37 37 u8 *xtr_hdr = (u8 *)ifh; 38 38 ··· 43 43 ((u32)xtr_hdr[29] << 8) | 44 44 ((u32)xtr_hdr[30] << 0); 45 45 fwd = (fwd >> 5); 46 - info->src_port = FIELD_GET(GENMASK(7, 1), fwd); 46 + info->src_port = spx5_field_get(GENMASK(is_sparx5(sparx5) ? 7 : 6, 1), 47 + fwd); 47 48 48 49 /* 49 50 * Bit 270-271 are occasionally unexpectedly set by the hardware, ··· 73 72 ifh[i] = spx5_rd(sparx5, QS_XTR_RD(grp)); 74 73 75 74 /* Decode IFH (what's needed) */ 76 - sparx5_ifh_parse(ifh, &fi); 75 + sparx5_ifh_parse(sparx5, ifh, &fi); 77 76 78 77 /* Map to port netdev */ 79 78 port = fi.src_port < sparx5->data->consts->n_ports ? ··· 243 242 return NETDEV_TX_BUSY; 244 243 245 244 sparx5_set_port_ifh_rew_op(ifh, SPARX5_SKB_CB(skb)->rew_op); 246 - sparx5_set_port_ifh_pdu_type(ifh, SPARX5_SKB_CB(skb)->pdu_type); 247 - sparx5_set_port_ifh_pdu_w16_offset(ifh, SPARX5_SKB_CB(skb)->pdu_w16_offset); 248 - sparx5_set_port_ifh_timestamp(ifh, SPARX5_SKB_CB(skb)->ts_id); 245 + sparx5_set_port_ifh_pdu_type(sparx5, ifh, 246 + SPARX5_SKB_CB(skb)->pdu_type); 247 + sparx5_set_port_ifh_pdu_w16_offset(sparx5, ifh, 248 + SPARX5_SKB_CB(skb)->pdu_w16_offset); 249 + sparx5_set_port_ifh_timestamp(sparx5, ifh, 250 + SPARX5_SKB_CB(skb)->ts_id); 249 251 } 250 252 251 253 skb_tx_timestamp(skb);
+46
drivers/net/ethernet/microchip/sparx5/sparx5_port.c
··· 476 476 u32 mac_width = 8; 477 477 u32 addition = 0; 478 478 479 + if (!is_sparx5(sparx5)) 480 + return 0; 481 + 479 482 switch (speed) { 480 483 case SPEED_25000: 481 484 return 0; ··· 924 921 sparx5, 925 922 DEV2G5_DEV_RST_CTRL(port->portno)); 926 923 924 + /* Enable PHAD_CTRL for better timestamping */ 925 + if (!is_sparx5(sparx5)) { 926 + for (int i = 0; i < 2; ++i) { 927 + /* Divide the port clock by three for the two 928 + * phase detection registers. 929 + */ 930 + spx5_rmw(DEV2G5_PHAD_CTRL_DIV_CFG_SET(3) | 931 + DEV2G5_PHAD_CTRL_PHAD_ENA_SET(1), 932 + DEV2G5_PHAD_CTRL_DIV_CFG | 933 + DEV2G5_PHAD_CTRL_PHAD_ENA, 934 + sparx5, DEV2G5_PHAD_CTRL(port->portno, i)); 935 + } 936 + } 937 + 927 938 return 0; 928 939 } 929 940 ··· 995 978 struct sparx5_port_config *conf) 996 979 { 997 980 bool high_speed_dev = sparx5_is_baser(conf->portmode); 981 + const struct sparx5_ops *ops = sparx5->data->ops; 998 982 int err, urgency, stop_wm; 999 983 1000 984 err = sparx5_port_verify_speed(sparx5, port, conf); ··· 1010 992 err = sparx5_port_fc_setup(sparx5, port, conf); 1011 993 if (err) 1012 994 return err; 995 + 996 + if (!is_sparx5(sparx5) && ops->is_port_10g(port->portno) && 997 + conf->speed < SPEED_10000) 998 + spx5_rmw(DSM_DEV_TX_STOP_WM_CFG_DEV10G_SHADOW_ENA_SET(1), 999 + DSM_DEV_TX_STOP_WM_CFG_DEV10G_SHADOW_ENA, 1000 + sparx5, 1001 + DSM_DEV_TX_STOP_WM_CFG(port->portno)); 1013 1002 1014 1003 /* Set the DSM stop watermark */ 1015 1004 stop_wm = sparx5_port_fifo_sz(sparx5, port->portno, conf->speed); ··· 1167 1142 DEV25G_PCS25G_SD_CFG_SD_ENA_SET(sd_ena), 1168 1143 sparx5, 1169 1144 DEV25G_PCS25G_SD_CFG(pix)); 1145 + } 1146 + 1147 + if (!is_sparx5(sparx5)) { 1148 + void __iomem *inst; 1149 + u32 dev, tinst; 1150 + 1151 + if (ops->is_port_10g(port->portno)) { 1152 + dev = sparx5_to_high_dev(sparx5, port->portno); 1153 + tinst = sparx5_port_dev_index(sparx5, port->portno); 1154 + inst = spx5_inst_get(sparx5, dev, tinst); 1155 + 1156 + spx5_inst_wr(5, inst, 1157 + DEV10G_PTP_STAMPER_CFG(port->portno)); 1158 + } else if (ops->is_port_5g(port->portno)) { 1159 + dev = sparx5_to_high_dev(sparx5, port->portno); 1160 + tinst = sparx5_port_dev_index(sparx5, port->portno); 1161 + inst = spx5_inst_get(sparx5, dev, tinst); 1162 + 1163 + spx5_inst_wr(5, inst, 1164 + DEV5G_PTP_STAMPER_CFG(port->portno)); 1165 + } 1170 1166 } 1171 1167 1172 1168 return 0;
+10 -5
drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c
··· 11 11 #include "sparx5_main_regs.h" 12 12 #include "sparx5_main.h" 13 13 14 - #define SPARX5_MAX_PTP_ID 512 15 - 16 14 #define TOD_ACC_PIN 0x4 17 15 18 16 enum { ··· 36 38 case SPX5_CORE_CLOCK_250MHZ: 37 39 res = 2301339409586; 38 40 break; 41 + case SPX5_CORE_CLOCK_328MHZ: 42 + res = 1756832768924; 43 + break; 39 44 case SPX5_CORE_CLOCK_500MHZ: 40 45 res = 1150669704793; 41 46 break; ··· 60 59 switch (sparx5->coreclock) { 61 60 case SPX5_CORE_CLOCK_250MHZ: 62 61 res = 0x1FF0000000000000; 62 + break; 63 + case SPX5_CORE_CLOCK_328MHZ: 64 + res = 0x18604697DD0F9B5B; 63 65 break; 64 66 case SPX5_CORE_CLOCK_500MHZ: 65 67 res = 0x0FF8000000000000; ··· 273 269 spin_unlock_irqrestore(&sparx5->ptp_ts_id_lock, flags); 274 270 } 275 271 276 - static void sparx5_get_hwtimestamp(struct sparx5 *sparx5, 277 - struct timespec64 *ts, 278 - u32 nsec) 272 + void sparx5_get_hwtimestamp(struct sparx5 *sparx5, 273 + struct timespec64 *ts, 274 + u32 nsec) 279 275 { 280 276 /* Read current PTP time to get seconds */ 281 277 const struct sparx5_consts *consts = sparx5->data->consts; ··· 303 299 304 300 spin_unlock_irqrestore(&sparx5->ptp_clock_lock, flags); 305 301 } 302 + EXPORT_SYMBOL_GPL(sparx5_get_hwtimestamp); 306 303 307 304 irqreturn_t sparx5_ptp_irq_handler(int irq, void *args) 308 305 {
+2 -1
drivers/net/ethernet/microchip/sparx5/sparx5_qos.c
··· 367 367 static int sparx5_dwrr_conf_set(struct sparx5_port *port, 368 368 struct sparx5_dwrr *dwrr) 369 369 { 370 + u32 layer = is_sparx5(port->sparx5) ? 2 : 1; 370 371 int i; 371 372 372 - spx5_rmw(HSCH_HSCH_CFG_CFG_HSCH_LAYER_SET(2) | 373 + spx5_rmw(HSCH_HSCH_CFG_CFG_HSCH_LAYER_SET(layer) | 373 374 HSCH_HSCH_CFG_CFG_CFG_SE_IDX_SET(port->portno), 374 375 HSCH_HSCH_CFG_CFG_HSCH_LAYER | HSCH_HSCH_CFG_CFG_CFG_SE_IDX, 375 376 port->sparx5, HSCH_HSCH_CFG_CFG);
+4 -1
drivers/net/ethernet/microchip/sparx5/sparx5_regs.c
··· 4 4 * Copyright (c) 2024 Microchip Technology Inc. 5 5 */ 6 6 7 - /* This file is autogenerated by cml-utils 2024-09-24 14:02:24 +0200. 7 + /* This file is autogenerated by cml-utils 2024-09-30 11:48:29 +0200. 8 8 * Commit ID: 9d07b8d19363f3cd3590ddb3f7a2e2768e16524b 9 9 */ 10 10 ··· 140 140 [GW_ANA_L2_COMMON] = 700, 141 141 [GW_ASM_CFG] = 1088, 142 142 [GW_CPU_CPU_REGS] = 204, 143 + [GW_DEV2G5_PHASE_DETECTOR_CTRL] = 8, 143 144 [GW_FDMA_FDMA] = 428, 144 145 [GW_GCB_CHIP_REGS] = 424, 145 146 [GW_HSCH_TAS_CONFIG] = 12, ··· 158 157 [FP_CPU_PROC_CTRL_CP15S_DISABLE] = 6, 159 158 [FP_CPU_PROC_CTRL_PROC_CRYPTO_DISABLE] = 5, 160 159 [FP_CPU_PROC_CTRL_L2_FLUSH_REQ] = 1, 160 + [FP_DEV2G5_PHAD_CTRL_PHAD_ENA] = 7, 161 + [FP_DEV2G5_PHAD_CTRL_PHAD_FAILED] = 6, 161 162 [FP_FDMA_CH_CFG_CH_XTR_STATUS_MODE] = 7, 162 163 [FP_FDMA_CH_CFG_CH_INTR_DB_EOF_ONLY] = 6, 163 164 [FP_FDMA_CH_CFG_CH_INJ_PORT] = 5,
+4 -1
drivers/net/ethernet/microchip/sparx5/sparx5_regs.h
··· 4 4 * Copyright (c) 2024 Microchip Technology Inc. 5 5 */ 6 6 7 - /* This file is autogenerated by cml-utils 2024-09-24 14:02:24 +0200. 7 + /* This file is autogenerated by cml-utils 2024-09-30 11:48:29 +0200. 8 8 * Commit ID: 9d07b8d19363f3cd3590ddb3f7a2e2768e16524b 9 9 */ 10 10 ··· 151 151 GW_ANA_L2_COMMON, 152 152 GW_ASM_CFG, 153 153 GW_CPU_CPU_REGS, 154 + GW_DEV2G5_PHASE_DETECTOR_CTRL, 154 155 GW_FDMA_FDMA, 155 156 GW_GCB_CHIP_REGS, 156 157 GW_HSCH_TAS_CONFIG, ··· 170 169 FP_CPU_PROC_CTRL_CP15S_DISABLE, 171 170 FP_CPU_PROC_CTRL_PROC_CRYPTO_DISABLE, 172 171 FP_CPU_PROC_CTRL_L2_FLUSH_REQ, 172 + FP_DEV2G5_PHAD_CTRL_PHAD_ENA, 173 + FP_DEV2G5_PHAD_CTRL_PHAD_FAILED, 173 174 FP_FDMA_CH_CFG_CH_XTR_STATUS_MODE, 174 175 FP_FDMA_CH_CFG_CH_INTR_DB_EOF_ONLY, 175 176 FP_FDMA_CH_CFG_CH_INJ_PORT,
+3 -7
drivers/net/ethernet/microchip/sparx5/sparx5_sdlb.c
··· 25 25 return &sdlb_groups[idx]; 26 26 } 27 27 28 - int sparx5_sdlb_clk_hz_get(struct sparx5 *sparx5) 28 + u64 sparx5_sdlb_clk_hz_get(struct sparx5 *sparx5) 29 29 { 30 - u32 clk_per_100ps; 31 30 u64 clk_hz; 32 31 33 - clk_per_100ps = HSCH_SYS_CLK_PER_100PS_GET(spx5_rd(sparx5, 34 - HSCH_SYS_CLK_PER)); 35 - if (!clk_per_100ps) 36 - clk_per_100ps = SPX5_CLK_PER_100PS_DEFAULT; 32 + clk_hz = (10 * 1000 * 1000) / 33 + (sparx5_clk_period(sparx5->coreclock) / 100); 37 34 38 - clk_hz = (10 * 1000 * 1000) / clk_per_100ps; 39 35 return clk_hz *= 1000; 40 36 } 41 37
+5
drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c
··· 1284 1284 1285 1285 /* Setup PSFP */ 1286 1286 if (tc_sg_idx >= 0 || tc_pol_idx >= 0) { 1287 + if (!sparx5_has_feature(sparx5, SPX5_FEATURE_PSFP)) { 1288 + err = -EOPNOTSUPP; 1289 + goto out; 1290 + } 1291 + 1287 1292 err = sparx5_tc_flower_psfp_setup(sparx5, vrule, tc_sg_idx, 1288 1293 tc_pol_idx, &sg, &fm, &sf); 1289 1294 if (err)