11cd7523fSDaniel Machon // SPDX-License-Identifier: GPL-2.0+
21cd7523fSDaniel Machon /* Microchip lan969x Switch driver
31cd7523fSDaniel Machon *
41cd7523fSDaniel Machon * Copyright (c) 2024 Microchip Technology Inc. and its subsidiaries.
51cd7523fSDaniel Machon */
61cd7523fSDaniel Machon
71cd7523fSDaniel Machon #include "lan969x.h"
81cd7523fSDaniel Machon
91cd7523fSDaniel Machon #define LAN969X_SDLB_GRP_CNT 5
101cd7523fSDaniel Machon #define LAN969X_HSCH_LEAK_GRP_CNT 4
111cd7523fSDaniel Machon
121cd7523fSDaniel Machon static const struct sparx5_main_io_resource lan969x_main_iomap[] = {
131cd7523fSDaniel Machon { TARGET_CPU, 0xc0000, 0 }, /* 0xe00c0000 */
141cd7523fSDaniel Machon { TARGET_FDMA, 0xc0400, 0 }, /* 0xe00c0400 */
151cd7523fSDaniel Machon { TARGET_GCB, 0x2010000, 1 }, /* 0xe2010000 */
161cd7523fSDaniel Machon { TARGET_QS, 0x2030000, 1 }, /* 0xe2030000 */
171cd7523fSDaniel Machon { TARGET_PTP, 0x2040000, 1 }, /* 0xe2040000 */
181cd7523fSDaniel Machon { TARGET_ANA_ACL, 0x2050000, 1 }, /* 0xe2050000 */
191cd7523fSDaniel Machon { TARGET_LRN, 0x2060000, 1 }, /* 0xe2060000 */
201cd7523fSDaniel Machon { TARGET_VCAP_SUPER, 0x2080000, 1 }, /* 0xe2080000 */
211cd7523fSDaniel Machon { TARGET_QSYS, 0x20a0000, 1 }, /* 0xe20a0000 */
221cd7523fSDaniel Machon { TARGET_QFWD, 0x20b0000, 1 }, /* 0xe20b0000 */
231cd7523fSDaniel Machon { TARGET_XQS, 0x20c0000, 1 }, /* 0xe20c0000 */
241cd7523fSDaniel Machon { TARGET_VCAP_ES2, 0x20d0000, 1 }, /* 0xe20d0000 */
251cd7523fSDaniel Machon { TARGET_VCAP_ES0, 0x20e0000, 1 }, /* 0xe20e0000 */
261cd7523fSDaniel Machon { TARGET_ANA_AC_POL, 0x2200000, 1 }, /* 0xe2200000 */
271cd7523fSDaniel Machon { TARGET_QRES, 0x2280000, 1 }, /* 0xe2280000 */
281cd7523fSDaniel Machon { TARGET_EACL, 0x22c0000, 1 }, /* 0xe22c0000 */
291cd7523fSDaniel Machon { TARGET_ANA_CL, 0x2400000, 1 }, /* 0xe2400000 */
301cd7523fSDaniel Machon { TARGET_ANA_L3, 0x2480000, 1 }, /* 0xe2480000 */
311cd7523fSDaniel Machon { TARGET_ANA_AC_SDLB, 0x2500000, 1 }, /* 0xe2500000 */
321cd7523fSDaniel Machon { TARGET_HSCH, 0x2580000, 1 }, /* 0xe2580000 */
331cd7523fSDaniel Machon { TARGET_REW, 0x2600000, 1 }, /* 0xe2600000 */
341cd7523fSDaniel Machon { TARGET_ANA_L2, 0x2800000, 1 }, /* 0xe2800000 */
351cd7523fSDaniel Machon { TARGET_ANA_AC, 0x2900000, 1 }, /* 0xe2900000 */
361cd7523fSDaniel Machon { TARGET_VOP, 0x2a00000, 1 }, /* 0xe2a00000 */
371cd7523fSDaniel Machon { TARGET_DEV2G5, 0x3004000, 1 }, /* 0xe3004000 */
381cd7523fSDaniel Machon { TARGET_DEV10G, 0x3008000, 1 }, /* 0xe3008000 */
391cd7523fSDaniel Machon { TARGET_PCS10G_BR, 0x300c000, 1 }, /* 0xe300c000 */
401cd7523fSDaniel Machon { TARGET_DEV2G5 + 1, 0x3010000, 1 }, /* 0xe3010000 */
411cd7523fSDaniel Machon { TARGET_DEV2G5 + 2, 0x3014000, 1 }, /* 0xe3014000 */
421cd7523fSDaniel Machon { TARGET_DEV2G5 + 3, 0x3018000, 1 }, /* 0xe3018000 */
431cd7523fSDaniel Machon { TARGET_DEV2G5 + 4, 0x301c000, 1 }, /* 0xe301c000 */
441cd7523fSDaniel Machon { TARGET_DEV10G + 1, 0x3020000, 1 }, /* 0xe3020000 */
451cd7523fSDaniel Machon { TARGET_PCS10G_BR + 1, 0x3024000, 1 }, /* 0xe3024000 */
461cd7523fSDaniel Machon { TARGET_DEV2G5 + 5, 0x3028000, 1 }, /* 0xe3028000 */
471cd7523fSDaniel Machon { TARGET_DEV2G5 + 6, 0x302c000, 1 }, /* 0xe302c000 */
481cd7523fSDaniel Machon { TARGET_DEV2G5 + 7, 0x3030000, 1 }, /* 0xe3030000 */
491cd7523fSDaniel Machon { TARGET_DEV2G5 + 8, 0x3034000, 1 }, /* 0xe3034000 */
501cd7523fSDaniel Machon { TARGET_DEV10G + 2, 0x3038000, 1 }, /* 0xe3038000 */
511cd7523fSDaniel Machon { TARGET_PCS10G_BR + 2, 0x303c000, 1 }, /* 0xe303c000 */
521cd7523fSDaniel Machon { TARGET_DEV2G5 + 9, 0x3040000, 1 }, /* 0xe3040000 */
531cd7523fSDaniel Machon { TARGET_DEV5G, 0x3044000, 1 }, /* 0xe3044000 */
541cd7523fSDaniel Machon { TARGET_PCS5G_BR, 0x3048000, 1 }, /* 0xe3048000 */
551cd7523fSDaniel Machon { TARGET_DEV2G5 + 10, 0x304c000, 1 }, /* 0xe304c000 */
561cd7523fSDaniel Machon { TARGET_DEV2G5 + 11, 0x3050000, 1 }, /* 0xe3050000 */
571cd7523fSDaniel Machon { TARGET_DEV2G5 + 12, 0x3054000, 1 }, /* 0xe3054000 */
581cd7523fSDaniel Machon { TARGET_DEV10G + 3, 0x3058000, 1 }, /* 0xe3058000 */
591cd7523fSDaniel Machon { TARGET_PCS10G_BR + 3, 0x305c000, 1 }, /* 0xe305c000 */
601cd7523fSDaniel Machon { TARGET_DEV2G5 + 13, 0x3060000, 1 }, /* 0xe3060000 */
611cd7523fSDaniel Machon { TARGET_DEV5G + 1, 0x3064000, 1 }, /* 0xe3064000 */
621cd7523fSDaniel Machon { TARGET_PCS5G_BR + 1, 0x3068000, 1 }, /* 0xe3068000 */
631cd7523fSDaniel Machon { TARGET_DEV2G5 + 14, 0x306c000, 1 }, /* 0xe306c000 */
641cd7523fSDaniel Machon { TARGET_DEV2G5 + 15, 0x3070000, 1 }, /* 0xe3070000 */
651cd7523fSDaniel Machon { TARGET_DEV2G5 + 16, 0x3074000, 1 }, /* 0xe3074000 */
661cd7523fSDaniel Machon { TARGET_DEV10G + 4, 0x3078000, 1 }, /* 0xe3078000 */
671cd7523fSDaniel Machon { TARGET_PCS10G_BR + 4, 0x307c000, 1 }, /* 0xe307c000 */
681cd7523fSDaniel Machon { TARGET_DEV2G5 + 17, 0x3080000, 1 }, /* 0xe3080000 */
691cd7523fSDaniel Machon { TARGET_DEV5G + 2, 0x3084000, 1 }, /* 0xe3084000 */
701cd7523fSDaniel Machon { TARGET_PCS5G_BR + 2, 0x3088000, 1 }, /* 0xe3088000 */
711cd7523fSDaniel Machon { TARGET_DEV2G5 + 18, 0x308c000, 1 }, /* 0xe308c000 */
721cd7523fSDaniel Machon { TARGET_DEV2G5 + 19, 0x3090000, 1 }, /* 0xe3090000 */
731cd7523fSDaniel Machon { TARGET_DEV2G5 + 20, 0x3094000, 1 }, /* 0xe3094000 */
741cd7523fSDaniel Machon { TARGET_DEV10G + 5, 0x3098000, 1 }, /* 0xe3098000 */
751cd7523fSDaniel Machon { TARGET_PCS10G_BR + 5, 0x309c000, 1 }, /* 0xe309c000 */
761cd7523fSDaniel Machon { TARGET_DEV2G5 + 21, 0x30a0000, 1 }, /* 0xe30a0000 */
771cd7523fSDaniel Machon { TARGET_DEV5G + 3, 0x30a4000, 1 }, /* 0xe30a4000 */
781cd7523fSDaniel Machon { TARGET_PCS5G_BR + 3, 0x30a8000, 1 }, /* 0xe30a8000 */
791cd7523fSDaniel Machon { TARGET_DEV2G5 + 22, 0x30ac000, 1 }, /* 0xe30ac000 */
801cd7523fSDaniel Machon { TARGET_DEV2G5 + 23, 0x30b0000, 1 }, /* 0xe30b0000 */
811cd7523fSDaniel Machon { TARGET_DEV2G5 + 24, 0x30b4000, 1 }, /* 0xe30b4000 */
821cd7523fSDaniel Machon { TARGET_DEV10G + 6, 0x30b8000, 1 }, /* 0xe30b8000 */
831cd7523fSDaniel Machon { TARGET_PCS10G_BR + 6, 0x30bc000, 1 }, /* 0xe30bc000 */
841cd7523fSDaniel Machon { TARGET_DEV2G5 + 25, 0x30c0000, 1 }, /* 0xe30c0000 */
851cd7523fSDaniel Machon { TARGET_DEV10G + 7, 0x30c4000, 1 }, /* 0xe30c4000 */
861cd7523fSDaniel Machon { TARGET_PCS10G_BR + 7, 0x30c8000, 1 }, /* 0xe30c8000 */
871cd7523fSDaniel Machon { TARGET_DEV2G5 + 26, 0x30cc000, 1 }, /* 0xe30cc000 */
881cd7523fSDaniel Machon { TARGET_DEV10G + 8, 0x30d0000, 1 }, /* 0xe30d0000 */
891cd7523fSDaniel Machon { TARGET_PCS10G_BR + 8, 0x30d4000, 1 }, /* 0xe30d4000 */
901cd7523fSDaniel Machon { TARGET_DEV2G5 + 27, 0x30d8000, 1 }, /* 0xe30d8000 */
911cd7523fSDaniel Machon { TARGET_DEV10G + 9, 0x30dc000, 1 }, /* 0xe30dc000 */
921cd7523fSDaniel Machon { TARGET_PCS10G_BR + 9, 0x30e0000, 1 }, /* 0xe30e0000 */
931cd7523fSDaniel Machon { TARGET_DEVRGMII, 0x30e4000, 1 }, /* 0xe30e4000 */
941cd7523fSDaniel Machon { TARGET_DEVRGMII + 1, 0x30e8000, 1 }, /* 0xe30e8000 */
951cd7523fSDaniel Machon { TARGET_DSM, 0x30ec000, 1 }, /* 0xe30ec000 */
961cd7523fSDaniel Machon { TARGET_PORT_CONF, 0x30f0000, 1 }, /* 0xe30f0000 */
971cd7523fSDaniel Machon { TARGET_ASM, 0x3200000, 1 }, /* 0xe3200000 */
981cd7523fSDaniel Machon { TARGET_HSIO_WRAP, 0x3408000, 1 }, /* 0xe3408000 */
991cd7523fSDaniel Machon };
1001cd7523fSDaniel Machon
1011cd7523fSDaniel Machon static struct sparx5_sdlb_group lan969x_sdlb_groups[LAN969X_SDLB_GRP_CNT] = {
1021cd7523fSDaniel Machon { 1000000000, 8192 / 2, 64 }, /* 1 G */
1031cd7523fSDaniel Machon { 500000000, 8192 / 2, 64 }, /* 500 M */
1041cd7523fSDaniel Machon { 100000000, 8192 / 4, 64 }, /* 100 M */
1051cd7523fSDaniel Machon { 50000000, 8192 / 4, 64 }, /* 50 M */
1061cd7523fSDaniel Machon { 5000000, 8192 / 8, 64 }, /* 10 M */
1071cd7523fSDaniel Machon };
1081cd7523fSDaniel Machon
1091cd7523fSDaniel Machon static u32 lan969x_hsch_max_group_rate[LAN969X_HSCH_LEAK_GRP_CNT] = {
1101cd7523fSDaniel Machon 655355, 1048568, 6553550, 10485680
1111cd7523fSDaniel Machon };
1121cd7523fSDaniel Machon
lan969x_get_sdlb_group(int idx)1131cd7523fSDaniel Machon static struct sparx5_sdlb_group *lan969x_get_sdlb_group(int idx)
1141cd7523fSDaniel Machon {
1151cd7523fSDaniel Machon return &lan969x_sdlb_groups[idx];
1161cd7523fSDaniel Machon }
1171cd7523fSDaniel Machon
lan969x_get_hsch_max_group_rate(int grp)1181cd7523fSDaniel Machon static u32 lan969x_get_hsch_max_group_rate(int grp)
1191cd7523fSDaniel Machon {
1201cd7523fSDaniel Machon return lan969x_hsch_max_group_rate[grp];
1211cd7523fSDaniel Machon }
1221cd7523fSDaniel Machon
lan969x_get_dev_mode_bit(struct sparx5 * sparx5,int port)1231cd7523fSDaniel Machon static u32 lan969x_get_dev_mode_bit(struct sparx5 *sparx5, int port)
1241cd7523fSDaniel Machon {
1251cd7523fSDaniel Machon if (lan969x_port_is_2g5(port) || lan969x_port_is_5g(port))
1261cd7523fSDaniel Machon return port;
1271cd7523fSDaniel Machon
1281cd7523fSDaniel Machon /* 10G */
1291cd7523fSDaniel Machon switch (port) {
1301cd7523fSDaniel Machon case 0:
1311cd7523fSDaniel Machon return 12;
1321cd7523fSDaniel Machon case 4:
1331cd7523fSDaniel Machon return 13;
1341cd7523fSDaniel Machon case 8:
1351cd7523fSDaniel Machon return 14;
1361cd7523fSDaniel Machon case 12:
1371cd7523fSDaniel Machon return 0;
1381cd7523fSDaniel Machon default:
1391cd7523fSDaniel Machon return port;
1401cd7523fSDaniel Machon }
1411cd7523fSDaniel Machon }
1421cd7523fSDaniel Machon
lan969x_port_dev_mapping(struct sparx5 * sparx5,int port)1431cd7523fSDaniel Machon static u32 lan969x_port_dev_mapping(struct sparx5 *sparx5, int port)
1441cd7523fSDaniel Machon {
1451cd7523fSDaniel Machon if (lan969x_port_is_5g(port)) {
1461cd7523fSDaniel Machon switch (port) {
1471cd7523fSDaniel Machon case 9:
1481cd7523fSDaniel Machon return 0;
1491cd7523fSDaniel Machon case 13:
1501cd7523fSDaniel Machon return 1;
1511cd7523fSDaniel Machon case 17:
1521cd7523fSDaniel Machon return 2;
1531cd7523fSDaniel Machon case 21:
1541cd7523fSDaniel Machon return 3;
1551cd7523fSDaniel Machon }
1561cd7523fSDaniel Machon }
1571cd7523fSDaniel Machon
1581cd7523fSDaniel Machon if (lan969x_port_is_10g(port)) {
1591cd7523fSDaniel Machon switch (port) {
1601cd7523fSDaniel Machon case 0:
1611cd7523fSDaniel Machon return 0;
1621cd7523fSDaniel Machon case 4:
1631cd7523fSDaniel Machon return 1;
1641cd7523fSDaniel Machon case 8:
1651cd7523fSDaniel Machon return 2;
1661cd7523fSDaniel Machon case 12:
1671cd7523fSDaniel Machon return 3;
1681cd7523fSDaniel Machon case 16:
1691cd7523fSDaniel Machon return 4;
1701cd7523fSDaniel Machon case 20:
1711cd7523fSDaniel Machon return 5;
1721cd7523fSDaniel Machon case 24:
1731cd7523fSDaniel Machon return 6;
1741cd7523fSDaniel Machon case 25:
1751cd7523fSDaniel Machon return 7;
1761cd7523fSDaniel Machon case 26:
1771cd7523fSDaniel Machon return 8;
1781cd7523fSDaniel Machon case 27:
1791cd7523fSDaniel Machon return 9;
1801cd7523fSDaniel Machon }
1811cd7523fSDaniel Machon }
1821cd7523fSDaniel Machon
1831cd7523fSDaniel Machon /* 2g5 port */
1841cd7523fSDaniel Machon return port;
1851cd7523fSDaniel Machon }
1861cd7523fSDaniel Machon
lan969x_port_mux_set(struct sparx5 * sparx5,struct sparx5_port * port,struct sparx5_port_config * conf)1871cd7523fSDaniel Machon static int lan969x_port_mux_set(struct sparx5 *sparx5, struct sparx5_port *port,
1881cd7523fSDaniel Machon struct sparx5_port_config *conf)
1891cd7523fSDaniel Machon {
1901cd7523fSDaniel Machon u32 portno = port->portno;
1911cd7523fSDaniel Machon u32 inst;
1921cd7523fSDaniel Machon
1931cd7523fSDaniel Machon if (port->conf.portmode == conf->portmode)
1941cd7523fSDaniel Machon return 0; /* Nothing to do */
1951cd7523fSDaniel Machon
1961cd7523fSDaniel Machon switch (conf->portmode) {
1971cd7523fSDaniel Machon case PHY_INTERFACE_MODE_QSGMII: /* QSGMII: 4x2G5 devices. Mode Q' */
1981cd7523fSDaniel Machon inst = (portno - portno % 4) / 4;
1991cd7523fSDaniel Machon spx5_rmw(BIT(inst), BIT(inst), sparx5, PORT_CONF_QSGMII_ENA);
2001cd7523fSDaniel Machon break;
2011cd7523fSDaniel Machon default:
2021cd7523fSDaniel Machon break;
2031cd7523fSDaniel Machon }
2041cd7523fSDaniel Machon return 0;
2051cd7523fSDaniel Machon }
2061cd7523fSDaniel Machon
lan969x_ptp_irq_handler(int irq,void * args)2071cd7523fSDaniel Machon static irqreturn_t lan969x_ptp_irq_handler(int irq, void *args)
2081cd7523fSDaniel Machon {
2091cd7523fSDaniel Machon int budget = SPARX5_MAX_PTP_ID;
2101cd7523fSDaniel Machon struct sparx5 *sparx5 = args;
2111cd7523fSDaniel Machon
2121cd7523fSDaniel Machon while (budget--) {
2131cd7523fSDaniel Machon struct sk_buff *skb, *skb_tmp, *skb_match = NULL;
2141cd7523fSDaniel Machon struct skb_shared_hwtstamps shhwtstamps;
2151cd7523fSDaniel Machon struct sparx5_port *port;
2161cd7523fSDaniel Machon struct timespec64 ts;
2171cd7523fSDaniel Machon unsigned long flags;
2181cd7523fSDaniel Machon u32 val, id, txport;
2191cd7523fSDaniel Machon u32 delay;
2201cd7523fSDaniel Machon
2211cd7523fSDaniel Machon val = spx5_rd(sparx5, PTP_TWOSTEP_CTRL);
2221cd7523fSDaniel Machon
2231cd7523fSDaniel Machon /* Check if a timestamp can be retrieved */
2241cd7523fSDaniel Machon if (!(val & PTP_TWOSTEP_CTRL_PTP_VLD))
2251cd7523fSDaniel Machon break;
2261cd7523fSDaniel Machon
2271cd7523fSDaniel Machon WARN_ON(val & PTP_TWOSTEP_CTRL_PTP_OVFL);
2281cd7523fSDaniel Machon
2291cd7523fSDaniel Machon if (!(val & PTP_TWOSTEP_CTRL_STAMP_TX))
2301cd7523fSDaniel Machon continue;
2311cd7523fSDaniel Machon
2321cd7523fSDaniel Machon /* Retrieve the ts Tx port */
2331cd7523fSDaniel Machon txport = PTP_TWOSTEP_CTRL_STAMP_PORT_GET(val);
2341cd7523fSDaniel Machon
2351cd7523fSDaniel Machon /* Retrieve its associated skb */
2361cd7523fSDaniel Machon port = sparx5->ports[txport];
2371cd7523fSDaniel Machon
2381cd7523fSDaniel Machon /* Retrieve the delay */
2391cd7523fSDaniel Machon delay = spx5_rd(sparx5, PTP_TWOSTEP_STAMP_NSEC);
2401cd7523fSDaniel Machon delay = PTP_TWOSTEP_STAMP_NSEC_NS_GET(delay);
2411cd7523fSDaniel Machon
2421cd7523fSDaniel Machon /* Get next timestamp from fifo, which needs to be the
2431cd7523fSDaniel Machon * rx timestamp which represents the id of the frame
2441cd7523fSDaniel Machon */
2451cd7523fSDaniel Machon spx5_rmw(PTP_TWOSTEP_CTRL_PTP_NXT_SET(1),
2461cd7523fSDaniel Machon PTP_TWOSTEP_CTRL_PTP_NXT,
2471cd7523fSDaniel Machon sparx5, PTP_TWOSTEP_CTRL);
2481cd7523fSDaniel Machon
2491cd7523fSDaniel Machon val = spx5_rd(sparx5, PTP_TWOSTEP_CTRL);
2501cd7523fSDaniel Machon
2511cd7523fSDaniel Machon /* Check if a timestamp can be retrieved */
2521cd7523fSDaniel Machon if (!(val & PTP_TWOSTEP_CTRL_PTP_VLD))
2531cd7523fSDaniel Machon break;
2541cd7523fSDaniel Machon
2551cd7523fSDaniel Machon /* Read RX timestamping to get the ID */
2561cd7523fSDaniel Machon id = spx5_rd(sparx5, PTP_TWOSTEP_STAMP_NSEC);
2571cd7523fSDaniel Machon id <<= 8;
2581cd7523fSDaniel Machon id |= spx5_rd(sparx5, PTP_TWOSTEP_STAMP_SUBNS);
2591cd7523fSDaniel Machon
2601cd7523fSDaniel Machon spin_lock_irqsave(&port->tx_skbs.lock, flags);
2611cd7523fSDaniel Machon skb_queue_walk_safe(&port->tx_skbs, skb, skb_tmp) {
2621cd7523fSDaniel Machon if (SPARX5_SKB_CB(skb)->ts_id != id)
2631cd7523fSDaniel Machon continue;
2641cd7523fSDaniel Machon
2651cd7523fSDaniel Machon __skb_unlink(skb, &port->tx_skbs);
2661cd7523fSDaniel Machon skb_match = skb;
2671cd7523fSDaniel Machon break;
2681cd7523fSDaniel Machon }
2691cd7523fSDaniel Machon spin_unlock_irqrestore(&port->tx_skbs.lock, flags);
2701cd7523fSDaniel Machon
2711cd7523fSDaniel Machon /* Next ts */
2721cd7523fSDaniel Machon spx5_rmw(PTP_TWOSTEP_CTRL_PTP_NXT_SET(1),
2731cd7523fSDaniel Machon PTP_TWOSTEP_CTRL_PTP_NXT,
2741cd7523fSDaniel Machon sparx5, PTP_TWOSTEP_CTRL);
2751cd7523fSDaniel Machon
276*aa5fc889SDaniel Machon if (WARN_ON(!skb_match))
2771cd7523fSDaniel Machon continue;
278*aa5fc889SDaniel Machon
2791cd7523fSDaniel Machon spin_lock_irqsave(&sparx5->ptp_ts_id_lock, flags);
2801cd7523fSDaniel Machon sparx5->ptp_skbs--;
2811cd7523fSDaniel Machon spin_unlock_irqrestore(&sparx5->ptp_ts_id_lock, flags);
2821cd7523fSDaniel Machon
2831cd7523fSDaniel Machon /* Get the h/w timestamp */
2841cd7523fSDaniel Machon sparx5_get_hwtimestamp(sparx5, &ts, delay);
2851cd7523fSDaniel Machon
2861cd7523fSDaniel Machon /* Set the timestamp in the skb */
2871cd7523fSDaniel Machon shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec);
2881cd7523fSDaniel Machon skb_tstamp_tx(skb_match, &shhwtstamps);
2891cd7523fSDaniel Machon
2901cd7523fSDaniel Machon dev_kfree_skb_any(skb_match);
2911cd7523fSDaniel Machon }
2921cd7523fSDaniel Machon
2931cd7523fSDaniel Machon return IRQ_HANDLED;
2941cd7523fSDaniel Machon }
2951cd7523fSDaniel Machon
2961cd7523fSDaniel Machon static const struct sparx5_regs lan969x_regs = {
2971cd7523fSDaniel Machon .tsize = lan969x_tsize,
2981cd7523fSDaniel Machon .gaddr = lan969x_gaddr,
2991cd7523fSDaniel Machon .gcnt = lan969x_gcnt,
3001cd7523fSDaniel Machon .gsize = lan969x_gsize,
3011cd7523fSDaniel Machon .raddr = lan969x_raddr,
3021cd7523fSDaniel Machon .rcnt = lan969x_rcnt,
3031cd7523fSDaniel Machon .fpos = lan969x_fpos,
3041cd7523fSDaniel Machon .fsize = lan969x_fsize,
3051cd7523fSDaniel Machon };
3061cd7523fSDaniel Machon
3071cd7523fSDaniel Machon static const struct sparx5_consts lan969x_consts = {
3081cd7523fSDaniel Machon .n_ports = 30,
3091cd7523fSDaniel Machon .n_ports_all = 35,
3101cd7523fSDaniel Machon .n_hsch_l1_elems = 32,
3111cd7523fSDaniel Machon .n_hsch_queues = 4,
3121cd7523fSDaniel Machon .n_lb_groups = 5,
3131cd7523fSDaniel Machon .n_pgids = 1054, /* (1024 + n_ports) */
3141cd7523fSDaniel Machon .n_sio_clks = 1,
3151cd7523fSDaniel Machon .n_own_upsids = 1,
3161cd7523fSDaniel Machon .n_auto_cals = 4,
3171cd7523fSDaniel Machon .n_filters = 256,
3181cd7523fSDaniel Machon .n_gates = 256,
3191cd7523fSDaniel Machon .n_sdlbs = 496,
3201cd7523fSDaniel Machon .n_dsm_cal_taxis = 5,
3211cd7523fSDaniel Machon .buf_size = 1572864,
3221cd7523fSDaniel Machon .qres_max_prio_idx = 315,
3231cd7523fSDaniel Machon .qres_max_colour_idx = 323,
3241cd7523fSDaniel Machon .tod_pin = 4,
3251cd7523fSDaniel Machon .vcaps = lan969x_vcaps,
3261cd7523fSDaniel Machon .vcap_stats = &lan969x_vcap_stats,
3271cd7523fSDaniel Machon .vcaps_cfg = lan969x_vcap_inst_cfg,
3281cd7523fSDaniel Machon };
3291cd7523fSDaniel Machon
3301cd7523fSDaniel Machon static const struct sparx5_ops lan969x_ops = {
3311cd7523fSDaniel Machon .is_port_2g5 = &lan969x_port_is_2g5,
3321cd7523fSDaniel Machon .is_port_5g = &lan969x_port_is_5g,
3331cd7523fSDaniel Machon .is_port_10g = &lan969x_port_is_10g,
3341cd7523fSDaniel Machon .is_port_25g = &lan969x_port_is_25g,
3351cd7523fSDaniel Machon .is_port_rgmii = &lan969x_port_is_rgmii,
3361cd7523fSDaniel Machon .get_port_dev_index = &lan969x_port_dev_mapping,
3371cd7523fSDaniel Machon .get_port_dev_bit = &lan969x_get_dev_mode_bit,
3381cd7523fSDaniel Machon .get_hsch_max_group_rate = &lan969x_get_hsch_max_group_rate,
3391cd7523fSDaniel Machon .get_sdlb_group = &lan969x_get_sdlb_group,
3401cd7523fSDaniel Machon .set_port_mux = &lan969x_port_mux_set,
3411cd7523fSDaniel Machon .ptp_irq_handler = &lan969x_ptp_irq_handler,
3421cd7523fSDaniel Machon .dsm_calendar_calc = &lan969x_dsm_calendar_calc,
3431cd7523fSDaniel Machon .port_config_rgmii = &lan969x_port_config_rgmii,
3441cd7523fSDaniel Machon .fdma_init = &lan969x_fdma_init,
3451cd7523fSDaniel Machon .fdma_deinit = &lan969x_fdma_deinit,
3461cd7523fSDaniel Machon .fdma_poll = &lan969x_fdma_napi_poll,
3471cd7523fSDaniel Machon .fdma_xmit = &lan969x_fdma_xmit,
3481cd7523fSDaniel Machon };
349
350 const struct sparx5_match_data lan969x_desc = {
351 .iomap = lan969x_main_iomap,
352 .iomap_size = ARRAY_SIZE(lan969x_main_iomap),
353 .ioranges = 2,
354 .regs = &lan969x_regs,
355 .consts = &lan969x_consts,
356 .ops = &lan969x_ops,
357 };
358