ocelot.c (f81483aaeb59da530b286fe5d081e1705eb5c886) | ocelot.c (a14e6b69f393d651913edcbe4ec0dec27b8b4b40) |
---|---|
1// SPDX-License-Identifier: (GPL-2.0 OR MIT) 2/* 3 * Microsemi Ocelot Switch driver 4 * 5 * Copyright (c) 2017 Microsemi Corporation 6 */ 7#include <linux/dsa/ocelot.h> 8#include <linux/if_bridge.h> --- 47 unchanged lines hidden (view full) --- 56 macl |= mac[4] << 8; 57 macl |= mac[5] << 0; 58 59 ocelot_write(ocelot, macl, ANA_TABLES_MACLDATA); 60 ocelot_write(ocelot, mach, ANA_TABLES_MACHDATA); 61 62} 63 | 1// SPDX-License-Identifier: (GPL-2.0 OR MIT) 2/* 3 * Microsemi Ocelot Switch driver 4 * 5 * Copyright (c) 2017 Microsemi Corporation 6 */ 7#include <linux/dsa/ocelot.h> 8#include <linux/if_bridge.h> --- 47 unchanged lines hidden (view full) --- 56 macl |= mac[4] << 8; 57 macl |= mac[5] << 0; 58 59 ocelot_write(ocelot, macl, ANA_TABLES_MACLDATA); 60 ocelot_write(ocelot, mach, ANA_TABLES_MACHDATA); 61 62} 63 |
64int ocelot_mact_learn(struct ocelot *ocelot, int port, 65 const unsigned char mac[ETH_ALEN], 66 unsigned int vid, enum macaccess_entry_type type) | 64static int __ocelot_mact_learn(struct ocelot *ocelot, int port, 65 const unsigned char mac[ETH_ALEN], 66 unsigned int vid, enum macaccess_entry_type type) |
67{ 68 u32 cmd = ANA_TABLES_MACACCESS_VALID | 69 ANA_TABLES_MACACCESS_DEST_IDX(port) | 70 ANA_TABLES_MACACCESS_ENTRYTYPE(type) | 71 ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_LEARN); 72 unsigned int mc_ports; 73 int err; 74 75 /* Set MAC_CPU_COPY if the CPU port is used by a multicast entry */ 76 if (type == ENTRYTYPE_MACv4) 77 mc_ports = (mac[1] << 8) | mac[2]; 78 else if (type == ENTRYTYPE_MACv6) 79 mc_ports = (mac[0] << 8) | mac[1]; 80 else 81 mc_ports = 0; 82 83 if (mc_ports & BIT(ocelot->num_phys_ports)) 84 cmd |= ANA_TABLES_MACACCESS_MAC_CPU_COPY; 85 | 67{ 68 u32 cmd = ANA_TABLES_MACACCESS_VALID | 69 ANA_TABLES_MACACCESS_DEST_IDX(port) | 70 ANA_TABLES_MACACCESS_ENTRYTYPE(type) | 71 ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_LEARN); 72 unsigned int mc_ports; 73 int err; 74 75 /* Set MAC_CPU_COPY if the CPU port is used by a multicast entry */ 76 if (type == ENTRYTYPE_MACv4) 77 mc_ports = (mac[1] << 8) | mac[2]; 78 else if (type == ENTRYTYPE_MACv6) 79 mc_ports = (mac[0] << 8) | mac[1]; 80 else 81 mc_ports = 0; 82 83 if (mc_ports & BIT(ocelot->num_phys_ports)) 84 cmd |= ANA_TABLES_MACACCESS_MAC_CPU_COPY; 85 |
86 mutex_lock(&ocelot->mact_lock); 87 | |
88 ocelot_mact_select(ocelot, mac, vid); 89 90 /* Issue a write command */ 91 ocelot_write(ocelot, cmd, ANA_TABLES_MACACCESS); 92 93 err = ocelot_mact_wait_for_completion(ocelot); 94 | 86 ocelot_mact_select(ocelot, mac, vid); 87 88 /* Issue a write command */ 89 ocelot_write(ocelot, cmd, ANA_TABLES_MACACCESS); 90 91 err = ocelot_mact_wait_for_completion(ocelot); 92 |
93 return err; 94} 95 96int ocelot_mact_learn(struct ocelot *ocelot, int port, 97 const unsigned char mac[ETH_ALEN], 98 unsigned int vid, enum macaccess_entry_type type) 99{ 100 int ret; 101 102 mutex_lock(&ocelot->mact_lock); 103 ret = __ocelot_mact_learn(ocelot, port, mac, vid, type); |
|
95 mutex_unlock(&ocelot->mact_lock); 96 | 104 mutex_unlock(&ocelot->mact_lock); 105 |
97 return err; | 106 return ret; |
98} 99EXPORT_SYMBOL(ocelot_mact_learn); 100 101int ocelot_mact_forget(struct ocelot *ocelot, 102 const unsigned char mac[ETH_ALEN], unsigned int vid) 103{ 104 int err; 105 --- 9 unchanged lines hidden (view full) --- 115 err = ocelot_mact_wait_for_completion(ocelot); 116 117 mutex_unlock(&ocelot->mact_lock); 118 119 return err; 120} 121EXPORT_SYMBOL(ocelot_mact_forget); 122 | 107} 108EXPORT_SYMBOL(ocelot_mact_learn); 109 110int ocelot_mact_forget(struct ocelot *ocelot, 111 const unsigned char mac[ETH_ALEN], unsigned int vid) 112{ 113 int err; 114 --- 9 unchanged lines hidden (view full) --- 124 err = ocelot_mact_wait_for_completion(ocelot); 125 126 mutex_unlock(&ocelot->mact_lock); 127 128 return err; 129} 130EXPORT_SYMBOL(ocelot_mact_forget); 131 |
132int ocelot_mact_lookup(struct ocelot *ocelot, int *dst_idx, 133 const unsigned char mac[ETH_ALEN], 134 unsigned int vid, enum macaccess_entry_type *type) 135{ 136 int val; 137 138 mutex_lock(&ocelot->mact_lock); 139 140 ocelot_mact_select(ocelot, mac, vid); 141 142 /* Issue a read command with MACACCESS_VALID=1. */ 143 ocelot_write(ocelot, ANA_TABLES_MACACCESS_VALID | 144 ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_READ), 145 ANA_TABLES_MACACCESS); 146 147 if (ocelot_mact_wait_for_completion(ocelot)) { 148 mutex_unlock(&ocelot->mact_lock); 149 return -ETIMEDOUT; 150 } 151 152 /* Read back the entry flags */ 153 val = ocelot_read(ocelot, ANA_TABLES_MACACCESS); 154 155 mutex_unlock(&ocelot->mact_lock); 156 157 if (!(val & ANA_TABLES_MACACCESS_VALID)) 158 return -ENOENT; 159 160 *dst_idx = ANA_TABLES_MACACCESS_DEST_IDX_X(val); 161 *type = ANA_TABLES_MACACCESS_ENTRYTYPE_X(val); 162 163 return 0; 164} 165EXPORT_SYMBOL(ocelot_mact_lookup); 166 167int ocelot_mact_learn_streamdata(struct ocelot *ocelot, int dst_idx, 168 const unsigned char mac[ETH_ALEN], 169 unsigned int vid, 170 enum macaccess_entry_type type, 171 int sfid, int ssid) 172{ 173 int ret; 174 175 mutex_lock(&ocelot->mact_lock); 176 177 ocelot_write(ocelot, 178 (sfid < 0 ? 0 : ANA_TABLES_STREAMDATA_SFID_VALID) | 179 ANA_TABLES_STREAMDATA_SFID(sfid) | 180 (ssid < 0 ? 0 : ANA_TABLES_STREAMDATA_SSID_VALID) | 181 ANA_TABLES_STREAMDATA_SSID(ssid), 182 ANA_TABLES_STREAMDATA); 183 184 ret = __ocelot_mact_learn(ocelot, dst_idx, mac, vid, type); 185 186 mutex_unlock(&ocelot->mact_lock); 187 188 return ret; 189} 190EXPORT_SYMBOL(ocelot_mact_learn_streamdata); 191 |
|
123static void ocelot_mact_init(struct ocelot *ocelot) 124{ 125 /* Configure the learning mode entries attributes: 126 * - Do not copy the frame to the CPU extraction queues. 127 * - Use the vlan and mac_cpoy for dmac lookup. 128 */ 129 ocelot_rmw(ocelot, 0, 130 ANA_AGENCTRL_LEARN_CPU_COPY | ANA_AGENCTRL_IGNORE_DMAC_FLAGS --- 458 unchanged lines hidden (view full) --- 589void ocelot_phylink_mac_link_down(struct ocelot *ocelot, int port, 590 unsigned int link_an_mode, 591 phy_interface_t interface, 592 unsigned long quirks) 593{ 594 struct ocelot_port *ocelot_port = ocelot->ports[port]; 595 int err; 596 | 192static void ocelot_mact_init(struct ocelot *ocelot) 193{ 194 /* Configure the learning mode entries attributes: 195 * - Do not copy the frame to the CPU extraction queues. 196 * - Use the vlan and mac_cpoy for dmac lookup. 197 */ 198 ocelot_rmw(ocelot, 0, 199 ANA_AGENCTRL_LEARN_CPU_COPY | ANA_AGENCTRL_IGNORE_DMAC_FLAGS --- 458 unchanged lines hidden (view full) --- 658void ocelot_phylink_mac_link_down(struct ocelot *ocelot, int port, 659 unsigned int link_an_mode, 660 phy_interface_t interface, 661 unsigned long quirks) 662{ 663 struct ocelot_port *ocelot_port = ocelot->ports[port]; 664 int err; 665 |
666 ocelot_port->speed = SPEED_UNKNOWN; 667 |
|
597 ocelot_port_rmwl(ocelot_port, 0, DEV_MAC_ENA_CFG_RX_ENA, 598 DEV_MAC_ENA_CFG); 599 | 668 ocelot_port_rmwl(ocelot_port, 0, DEV_MAC_ENA_CFG_RX_ENA, 669 DEV_MAC_ENA_CFG); 670 |
671 if (ocelot->ops->cut_through_fwd) { 672 mutex_lock(&ocelot->fwd_domain_lock); 673 ocelot->ops->cut_through_fwd(ocelot); 674 mutex_unlock(&ocelot->fwd_domain_lock); 675 } 676 |
|
600 ocelot_fields_write(ocelot, port, QSYS_SWITCH_PORT_MODE_PORT_ENA, 0); 601 602 err = ocelot_port_flush(ocelot, port); 603 if (err) 604 dev_err(ocelot->dev, "failed to flush port %d: %d\n", 605 port, err); 606 607 /* Put the port in reset. */ --- 15 unchanged lines hidden (view full) --- 623 int speed, int duplex, 624 bool tx_pause, bool rx_pause, 625 unsigned long quirks) 626{ 627 struct ocelot_port *ocelot_port = ocelot->ports[port]; 628 int mac_speed, mode = 0; 629 u32 mac_fc_cfg; 630 | 677 ocelot_fields_write(ocelot, port, QSYS_SWITCH_PORT_MODE_PORT_ENA, 0); 678 679 err = ocelot_port_flush(ocelot, port); 680 if (err) 681 dev_err(ocelot->dev, "failed to flush port %d: %d\n", 682 port, err); 683 684 /* Put the port in reset. */ --- 15 unchanged lines hidden (view full) --- 700 int speed, int duplex, 701 bool tx_pause, bool rx_pause, 702 unsigned long quirks) 703{ 704 struct ocelot_port *ocelot_port = ocelot->ports[port]; 705 int mac_speed, mode = 0; 706 u32 mac_fc_cfg; 707 |
708 ocelot_port->speed = speed; 709 |
|
631 /* The MAC might be integrated in systems where the MAC speed is fixed 632 * and it's the PCS who is performing the rate adaptation, so we have 633 * to write "1000Mbps" into the LINK_SPEED field of DEV_CLOCK_CFG 634 * (which is also its default value). 635 */ 636 if ((quirks & OCELOT_QUIRK_PCS_PERFORMS_RATE_ADAPTATION) || 637 speed == SPEED_1000) { 638 mac_speed = OCELOT_SPEED_1000; --- 56 unchanged lines hidden (view full) --- 695 ocelot_fields_write(ocelot, port, SYS_PAUSE_CFG_PAUSE_ENA, tx_pause); 696 697 /* Undo the effects of ocelot_phylink_mac_link_down: 698 * enable MAC module 699 */ 700 ocelot_port_writel(ocelot_port, DEV_MAC_ENA_CFG_RX_ENA | 701 DEV_MAC_ENA_CFG_TX_ENA, DEV_MAC_ENA_CFG); 702 | 710 /* The MAC might be integrated in systems where the MAC speed is fixed 711 * and it's the PCS who is performing the rate adaptation, so we have 712 * to write "1000Mbps" into the LINK_SPEED field of DEV_CLOCK_CFG 713 * (which is also its default value). 714 */ 715 if ((quirks & OCELOT_QUIRK_PCS_PERFORMS_RATE_ADAPTATION) || 716 speed == SPEED_1000) { 717 mac_speed = OCELOT_SPEED_1000; --- 56 unchanged lines hidden (view full) --- 774 ocelot_fields_write(ocelot, port, SYS_PAUSE_CFG_PAUSE_ENA, tx_pause); 775 776 /* Undo the effects of ocelot_phylink_mac_link_down: 777 * enable MAC module 778 */ 779 ocelot_port_writel(ocelot_port, DEV_MAC_ENA_CFG_RX_ENA | 780 DEV_MAC_ENA_CFG_TX_ENA, DEV_MAC_ENA_CFG); 781 |
782 /* If the port supports cut-through forwarding, update the masks before 783 * enabling forwarding on the port. 784 */ 785 if (ocelot->ops->cut_through_fwd) { 786 mutex_lock(&ocelot->fwd_domain_lock); 787 ocelot->ops->cut_through_fwd(ocelot); 788 mutex_unlock(&ocelot->fwd_domain_lock); 789 } 790 |
|
703 /* Core: Enable port for frame transfer */ 704 ocelot_fields_write(ocelot, port, 705 QSYS_SWITCH_PORT_MODE_PORT_ENA, 1); 706} 707EXPORT_SYMBOL_GPL(ocelot_phylink_mac_link_up); 708 709static int ocelot_port_add_txtstamp_skb(struct ocelot *ocelot, int port, 710 struct sk_buff *clone) --- 250 unchanged lines hidden (view full) --- 961 err = ocelot_rx_frame_word(ocelot, grp, true, &xfh[i]); 962 if (err != 4) 963 return (err < 0) ? err : -EIO; 964 } 965 966 return 0; 967} 968 | 791 /* Core: Enable port for frame transfer */ 792 ocelot_fields_write(ocelot, port, 793 QSYS_SWITCH_PORT_MODE_PORT_ENA, 1); 794} 795EXPORT_SYMBOL_GPL(ocelot_phylink_mac_link_up); 796 797static int ocelot_port_add_txtstamp_skb(struct ocelot *ocelot, int port, 798 struct sk_buff *clone) --- 250 unchanged lines hidden (view full) --- 1049 err = ocelot_rx_frame_word(ocelot, grp, true, &xfh[i]); 1050 if (err != 4) 1051 return (err < 0) ? err : -EIO; 1052 } 1053 1054 return 0; 1055} 1056 |
969int ocelot_xtr_poll_frame(struct ocelot *ocelot, int grp, struct sk_buff **nskb) | 1057void ocelot_ptp_rx_timestamp(struct ocelot *ocelot, struct sk_buff *skb, 1058 u64 timestamp) |
970{ 971 struct skb_shared_hwtstamps *shhwtstamps; 972 u64 tod_in_ns, full_ts_in_ns; | 1059{ 1060 struct skb_shared_hwtstamps *shhwtstamps; 1061 u64 tod_in_ns, full_ts_in_ns; |
1062 struct timespec64 ts; 1063 1064 ocelot_ptp_gettime64(&ocelot->ptp_info, &ts); 1065 1066 tod_in_ns = ktime_set(ts.tv_sec, ts.tv_nsec); 1067 if ((tod_in_ns & 0xffffffff) < timestamp) 1068 full_ts_in_ns = (((tod_in_ns >> 32) - 1) << 32) | 1069 timestamp; 1070 else 1071 full_ts_in_ns = (tod_in_ns & GENMASK_ULL(63, 32)) | 1072 timestamp; 1073 1074 shhwtstamps = skb_hwtstamps(skb); 1075 memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps)); 1076 shhwtstamps->hwtstamp = full_ts_in_ns; 1077} 1078EXPORT_SYMBOL(ocelot_ptp_rx_timestamp); 1079 1080int ocelot_xtr_poll_frame(struct ocelot *ocelot, int grp, struct sk_buff **nskb) 1081{ |
|
973 u64 timestamp, src_port, len; 974 u32 xfh[OCELOT_TAG_LEN / 4]; 975 struct net_device *dev; | 1082 u64 timestamp, src_port, len; 1083 u32 xfh[OCELOT_TAG_LEN / 4]; 1084 struct net_device *dev; |
976 struct timespec64 ts; | |
977 struct sk_buff *skb; 978 int sz, buf_len; 979 u32 val, *buf; 980 int err; 981 982 err = ocelot_xtr_poll_xfh(ocelot, grp, xfh); 983 if (err) 984 return err; --- 39 unchanged lines hidden (view full) --- 1024 /* Update the statistics if part of the FCS was read before */ 1025 len -= ETH_FCS_LEN - sz; 1026 1027 if (unlikely(dev->features & NETIF_F_RXFCS)) { 1028 buf = (u32 *)skb_put(skb, ETH_FCS_LEN); 1029 *buf = val; 1030 } 1031 | 1085 struct sk_buff *skb; 1086 int sz, buf_len; 1087 u32 val, *buf; 1088 int err; 1089 1090 err = ocelot_xtr_poll_xfh(ocelot, grp, xfh); 1091 if (err) 1092 return err; --- 39 unchanged lines hidden (view full) --- 1132 /* Update the statistics if part of the FCS was read before */ 1133 len -= ETH_FCS_LEN - sz; 1134 1135 if (unlikely(dev->features & NETIF_F_RXFCS)) { 1136 buf = (u32 *)skb_put(skb, ETH_FCS_LEN); 1137 *buf = val; 1138 } 1139 |
1032 if (ocelot->ptp) { 1033 ocelot_ptp_gettime64(&ocelot->ptp_info, &ts); | 1140 if (ocelot->ptp) 1141 ocelot_ptp_rx_timestamp(ocelot, skb, timestamp); |
1034 | 1142 |
1035 tod_in_ns = ktime_set(ts.tv_sec, ts.tv_nsec); 1036 if ((tod_in_ns & 0xffffffff) < timestamp) 1037 full_ts_in_ns = (((tod_in_ns >> 32) - 1) << 32) | 1038 timestamp; 1039 else 1040 full_ts_in_ns = (tod_in_ns & GENMASK_ULL(63, 32)) | 1041 timestamp; 1042 1043 shhwtstamps = skb_hwtstamps(skb); 1044 memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps)); 1045 shhwtstamps->hwtstamp = full_ts_in_ns; 1046 } 1047 | |
1048 /* Everything we see on an interface that is in the HW bridge 1049 * has already been forwarded. 1050 */ 1051 if (ocelot->ports[src_port]->bridge) 1052 skb->offload_fwd_mark = 1; 1053 1054 skb->protocol = eth_type_trans(skb, dev); 1055 --- 15 unchanged lines hidden (view full) --- 1071 return false; 1072 if (val & QS_INJ_STATUS_WMARK_REACHED(BIT(grp))) 1073 return false; 1074 1075 return true; 1076} 1077EXPORT_SYMBOL(ocelot_can_inject); 1078 | 1143 /* Everything we see on an interface that is in the HW bridge 1144 * has already been forwarded. 1145 */ 1146 if (ocelot->ports[src_port]->bridge) 1147 skb->offload_fwd_mark = 1; 1148 1149 skb->protocol = eth_type_trans(skb, dev); 1150 --- 15 unchanged lines hidden (view full) --- 1166 return false; 1167 if (val & QS_INJ_STATUS_WMARK_REACHED(BIT(grp))) 1168 return false; 1169 1170 return true; 1171} 1172EXPORT_SYMBOL(ocelot_can_inject); 1173 |
1174void ocelot_ifh_port_set(void *ifh, int port, u32 rew_op, u32 vlan_tag) 1175{ 1176 ocelot_ifh_set_bypass(ifh, 1); 1177 ocelot_ifh_set_dest(ifh, BIT_ULL(port)); 1178 ocelot_ifh_set_tag_type(ifh, IFH_TAG_TYPE_C); 1179 if (vlan_tag) 1180 ocelot_ifh_set_vlan_tci(ifh, vlan_tag); 1181 if (rew_op) 1182 ocelot_ifh_set_rew_op(ifh, rew_op); 1183} 1184EXPORT_SYMBOL(ocelot_ifh_port_set); 1185 |
|
1079void ocelot_port_inject_frame(struct ocelot *ocelot, int port, int grp, 1080 u32 rew_op, struct sk_buff *skb) 1081{ 1082 u32 ifh[OCELOT_TAG_LEN / 4] = {0}; 1083 unsigned int i, count, last; 1084 1085 ocelot_write_rix(ocelot, QS_INJ_CTRL_GAP_SIZE(1) | 1086 QS_INJ_CTRL_SOF, QS_INJ_CTRL, grp); 1087 | 1186void ocelot_port_inject_frame(struct ocelot *ocelot, int port, int grp, 1187 u32 rew_op, struct sk_buff *skb) 1188{ 1189 u32 ifh[OCELOT_TAG_LEN / 4] = {0}; 1190 unsigned int i, count, last; 1191 1192 ocelot_write_rix(ocelot, QS_INJ_CTRL_GAP_SIZE(1) | 1193 QS_INJ_CTRL_SOF, QS_INJ_CTRL, grp); 1194 |
1088 ocelot_ifh_set_bypass(ifh, 1); 1089 ocelot_ifh_set_dest(ifh, BIT_ULL(port)); 1090 ocelot_ifh_set_tag_type(ifh, IFH_TAG_TYPE_C); 1091 ocelot_ifh_set_vlan_tci(ifh, skb_vlan_tag_get(skb)); 1092 ocelot_ifh_set_rew_op(ifh, rew_op); | 1195 ocelot_ifh_port_set(ifh, port, rew_op, skb_vlan_tag_get(skb)); |
1093 1094 for (i = 0; i < OCELOT_TAG_LEN / 4; i++) 1095 ocelot_write_rix(ocelot, ifh[i], QS_INJ_WR, grp); 1096 1097 count = DIV_ROUND_UP(skb->len, 4); 1098 last = skb->len % 4; 1099 for (i = 0; i < count; i++) 1100 ocelot_write_rix(ocelot, ((u32 *)skb->data)[i], QS_INJ_WR, grp); --- 172 unchanged lines hidden (view full) --- 1273 } 1274 1275 mutex_unlock(&ocelot->mact_lock); 1276 1277 return err; 1278} 1279EXPORT_SYMBOL(ocelot_fdb_dump); 1280 | 1196 1197 for (i = 0; i < OCELOT_TAG_LEN / 4; i++) 1198 ocelot_write_rix(ocelot, ifh[i], QS_INJ_WR, grp); 1199 1200 count = DIV_ROUND_UP(skb->len, 4); 1201 last = skb->len % 4; 1202 for (i = 0; i < count; i++) 1203 ocelot_write_rix(ocelot, ((u32 *)skb->data)[i], QS_INJ_WR, grp); --- 172 unchanged lines hidden (view full) --- 1376 } 1377 1378 mutex_unlock(&ocelot->mact_lock); 1379 1380 return err; 1381} 1382EXPORT_SYMBOL(ocelot_fdb_dump); 1383 |
1384static void ocelot_populate_l2_ptp_trap_key(struct ocelot_vcap_filter *trap) 1385{ 1386 trap->key_type = OCELOT_VCAP_KEY_ETYPE; 1387 *(__be16 *)trap->key.etype.etype.value = htons(ETH_P_1588); 1388 *(__be16 *)trap->key.etype.etype.mask = htons(0xffff); 1389} 1390 1391static void 1392ocelot_populate_ipv4_ptp_event_trap_key(struct ocelot_vcap_filter *trap) 1393{ 1394 trap->key_type = OCELOT_VCAP_KEY_IPV4; 1395 trap->key.ipv4.dport.value = PTP_EV_PORT; 1396 trap->key.ipv4.dport.mask = 0xffff; 1397} 1398 1399static void 1400ocelot_populate_ipv6_ptp_event_trap_key(struct ocelot_vcap_filter *trap) 1401{ 1402 trap->key_type = OCELOT_VCAP_KEY_IPV6; 1403 trap->key.ipv6.dport.value = PTP_EV_PORT; 1404 trap->key.ipv6.dport.mask = 0xffff; 1405} 1406 1407static void 1408ocelot_populate_ipv4_ptp_general_trap_key(struct ocelot_vcap_filter *trap) 1409{ 1410 trap->key_type = OCELOT_VCAP_KEY_IPV4; 1411 trap->key.ipv4.dport.value = PTP_GEN_PORT; 1412 trap->key.ipv4.dport.mask = 0xffff; 1413} 1414 1415static void 1416ocelot_populate_ipv6_ptp_general_trap_key(struct ocelot_vcap_filter *trap) 1417{ 1418 trap->key_type = OCELOT_VCAP_KEY_IPV6; 1419 trap->key.ipv6.dport.value = PTP_GEN_PORT; 1420 trap->key.ipv6.dport.mask = 0xffff; 1421} 1422 1423static int ocelot_trap_add(struct ocelot *ocelot, int port, 1424 unsigned long cookie, 1425 void (*populate)(struct ocelot_vcap_filter *f)) 1426{ 1427 struct ocelot_vcap_block *block_vcap_is2; 1428 struct ocelot_vcap_filter *trap; 1429 bool new = false; 1430 int err; 1431 1432 block_vcap_is2 = &ocelot->block[VCAP_IS2]; 1433 1434 trap = ocelot_vcap_block_find_filter_by_id(block_vcap_is2, cookie, 1435 false); 1436 if (!trap) { 1437 trap = kzalloc(sizeof(*trap), GFP_KERNEL); 1438 if (!trap) 1439 return -ENOMEM; 1440 1441 populate(trap); 1442 trap->prio = 1; 1443 trap->id.cookie = cookie; 1444 trap->id.tc_offload = false; 1445 trap->block_id = VCAP_IS2; 1446 trap->type = OCELOT_VCAP_FILTER_OFFLOAD; 1447 trap->lookup = 0; 1448 trap->action.cpu_copy_ena = true; 1449 trap->action.mask_mode = OCELOT_MASK_MODE_PERMIT_DENY; 1450 trap->action.port_mask = 0; 1451 new = true; 1452 } 1453 1454 trap->ingress_port_mask |= BIT(port); 1455 1456 if (new) 1457 err = ocelot_vcap_filter_add(ocelot, trap, NULL); 1458 else 1459 err = ocelot_vcap_filter_replace(ocelot, trap); 1460 if (err) { 1461 trap->ingress_port_mask &= ~BIT(port); 1462 if (!trap->ingress_port_mask) 1463 kfree(trap); 1464 return err; 1465 } 1466 1467 return 0; 1468} 1469 1470static int ocelot_trap_del(struct ocelot *ocelot, int port, 1471 unsigned long cookie) 1472{ 1473 struct ocelot_vcap_block *block_vcap_is2; 1474 struct ocelot_vcap_filter *trap; 1475 1476 block_vcap_is2 = &ocelot->block[VCAP_IS2]; 1477 1478 trap = ocelot_vcap_block_find_filter_by_id(block_vcap_is2, cookie, 1479 false); 1480 if (!trap) 1481 return 0; 1482 1483 trap->ingress_port_mask &= ~BIT(port); 1484 if (!trap->ingress_port_mask) 1485 return ocelot_vcap_filter_del(ocelot, trap); 1486 1487 return ocelot_vcap_filter_replace(ocelot, trap); 1488} 1489 1490static int ocelot_l2_ptp_trap_add(struct ocelot *ocelot, int port) 1491{ 1492 unsigned long l2_cookie = ocelot->num_phys_ports + 1; 1493 1494 return ocelot_trap_add(ocelot, port, l2_cookie, 1495 ocelot_populate_l2_ptp_trap_key); 1496} 1497 1498static int ocelot_l2_ptp_trap_del(struct ocelot *ocelot, int port) 1499{ 1500 unsigned long l2_cookie = ocelot->num_phys_ports + 1; 1501 1502 return ocelot_trap_del(ocelot, port, l2_cookie); 1503} 1504 1505static int ocelot_ipv4_ptp_trap_add(struct ocelot *ocelot, int port) 1506{ 1507 unsigned long ipv4_gen_cookie = ocelot->num_phys_ports + 2; 1508 unsigned long ipv4_ev_cookie = ocelot->num_phys_ports + 3; 1509 int err; 1510 1511 err = ocelot_trap_add(ocelot, port, ipv4_ev_cookie, 1512 ocelot_populate_ipv4_ptp_event_trap_key); 1513 if (err) 1514 return err; 1515 1516 err = ocelot_trap_add(ocelot, port, ipv4_gen_cookie, 1517 ocelot_populate_ipv4_ptp_general_trap_key); 1518 if (err) 1519 ocelot_trap_del(ocelot, port, ipv4_ev_cookie); 1520 1521 return err; 1522} 1523 1524static int ocelot_ipv4_ptp_trap_del(struct ocelot *ocelot, int port) 1525{ 1526 unsigned long ipv4_gen_cookie = ocelot->num_phys_ports + 2; 1527 unsigned long ipv4_ev_cookie = ocelot->num_phys_ports + 3; 1528 int err; 1529 1530 err = ocelot_trap_del(ocelot, port, ipv4_ev_cookie); 1531 err |= ocelot_trap_del(ocelot, port, ipv4_gen_cookie); 1532 return err; 1533} 1534 1535static int ocelot_ipv6_ptp_trap_add(struct ocelot *ocelot, int port) 1536{ 1537 unsigned long ipv6_gen_cookie = ocelot->num_phys_ports + 4; 1538 unsigned long ipv6_ev_cookie = ocelot->num_phys_ports + 5; 1539 int err; 1540 1541 err = ocelot_trap_add(ocelot, port, ipv6_ev_cookie, 1542 ocelot_populate_ipv6_ptp_event_trap_key); 1543 if (err) 1544 return err; 1545 1546 err = ocelot_trap_add(ocelot, port, ipv6_gen_cookie, 1547 ocelot_populate_ipv6_ptp_general_trap_key); 1548 if (err) 1549 ocelot_trap_del(ocelot, port, ipv6_ev_cookie); 1550 1551 return err; 1552} 1553 1554static int ocelot_ipv6_ptp_trap_del(struct ocelot *ocelot, int port) 1555{ 1556 unsigned long ipv6_gen_cookie = ocelot->num_phys_ports + 4; 1557 unsigned long ipv6_ev_cookie = ocelot->num_phys_ports + 5; 1558 int err; 1559 1560 err = ocelot_trap_del(ocelot, port, ipv6_ev_cookie); 1561 err |= ocelot_trap_del(ocelot, port, ipv6_gen_cookie); 1562 return err; 1563} 1564 1565static int ocelot_setup_ptp_traps(struct ocelot *ocelot, int port, 1566 bool l2, bool l4) 1567{ 1568 int err; 1569 1570 if (l2) 1571 err = ocelot_l2_ptp_trap_add(ocelot, port); 1572 else 1573 err = ocelot_l2_ptp_trap_del(ocelot, port); 1574 if (err) 1575 return err; 1576 1577 if (l4) { 1578 err = ocelot_ipv4_ptp_trap_add(ocelot, port); 1579 if (err) 1580 goto err_ipv4; 1581 1582 err = ocelot_ipv6_ptp_trap_add(ocelot, port); 1583 if (err) 1584 goto err_ipv6; 1585 } else { 1586 err = ocelot_ipv4_ptp_trap_del(ocelot, port); 1587 1588 err |= ocelot_ipv6_ptp_trap_del(ocelot, port); 1589 } 1590 if (err) 1591 return err; 1592 1593 return 0; 1594 1595err_ipv6: 1596 ocelot_ipv4_ptp_trap_del(ocelot, port); 1597err_ipv4: 1598 if (l2) 1599 ocelot_l2_ptp_trap_del(ocelot, port); 1600 return err; 1601} 1602 |
|
1281int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr) 1282{ 1283 return copy_to_user(ifr->ifr_data, &ocelot->hwtstamp_config, 1284 sizeof(ocelot->hwtstamp_config)) ? -EFAULT : 0; 1285} 1286EXPORT_SYMBOL(ocelot_hwstamp_get); 1287 1288int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr) 1289{ 1290 struct ocelot_port *ocelot_port = ocelot->ports[port]; | 1603int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr) 1604{ 1605 return copy_to_user(ifr->ifr_data, &ocelot->hwtstamp_config, 1606 sizeof(ocelot->hwtstamp_config)) ? -EFAULT : 0; 1607} 1608EXPORT_SYMBOL(ocelot_hwstamp_get); 1609 1610int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr) 1611{ 1612 struct ocelot_port *ocelot_port = ocelot->ports[port]; |
1613 bool l2 = false, l4 = false; |
|
1291 struct hwtstamp_config cfg; | 1614 struct hwtstamp_config cfg; |
1615 int err; |
|
1292 1293 if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) 1294 return -EFAULT; 1295 | 1616 1617 if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) 1618 return -EFAULT; 1619 |
1296 /* reserved for future extensions */ 1297 if (cfg.flags) 1298 return -EINVAL; 1299 | |
1300 /* Tx type sanity check */ 1301 switch (cfg.tx_type) { 1302 case HWTSTAMP_TX_ON: 1303 ocelot_port->ptp_cmd = IFH_REW_OP_TWO_STEP_PTP; 1304 break; 1305 case HWTSTAMP_TX_ONESTEP_SYNC: 1306 /* IFH_REW_OP_ONE_STEP_PTP updates the correctional field, we 1307 * need to update the origin time. --- 7 unchanged lines hidden (view full) --- 1315 return -ERANGE; 1316 } 1317 1318 mutex_lock(&ocelot->ptp_lock); 1319 1320 switch (cfg.rx_filter) { 1321 case HWTSTAMP_FILTER_NONE: 1322 break; | 1620 /* Tx type sanity check */ 1621 switch (cfg.tx_type) { 1622 case HWTSTAMP_TX_ON: 1623 ocelot_port->ptp_cmd = IFH_REW_OP_TWO_STEP_PTP; 1624 break; 1625 case HWTSTAMP_TX_ONESTEP_SYNC: 1626 /* IFH_REW_OP_ONE_STEP_PTP updates the correctional field, we 1627 * need to update the origin time. --- 7 unchanged lines hidden (view full) --- 1635 return -ERANGE; 1636 } 1637 1638 mutex_lock(&ocelot->ptp_lock); 1639 1640 switch (cfg.rx_filter) { 1641 case HWTSTAMP_FILTER_NONE: 1642 break; |
1323 case HWTSTAMP_FILTER_ALL: 1324 case HWTSTAMP_FILTER_SOME: 1325 case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: 1326 case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: 1327 case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: 1328 case HWTSTAMP_FILTER_NTP_ALL: | |
1329 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: 1330 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: 1331 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: | 1643 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: 1644 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: 1645 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: |
1646 l4 = true; 1647 break; |
|
1332 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: 1333 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: 1334 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: | 1648 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: 1649 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: 1650 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: |
1651 l2 = true; 1652 break; |
|
1335 case HWTSTAMP_FILTER_PTP_V2_EVENT: 1336 case HWTSTAMP_FILTER_PTP_V2_SYNC: 1337 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: | 1653 case HWTSTAMP_FILTER_PTP_V2_EVENT: 1654 case HWTSTAMP_FILTER_PTP_V2_SYNC: 1655 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: |
1338 cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; | 1656 l2 = true; 1657 l4 = true; |
1339 break; 1340 default: 1341 mutex_unlock(&ocelot->ptp_lock); 1342 return -ERANGE; 1343 } 1344 | 1658 break; 1659 default: 1660 mutex_unlock(&ocelot->ptp_lock); 1661 return -ERANGE; 1662 } 1663 |
1664 err = ocelot_setup_ptp_traps(ocelot, port, l2, l4); 1665 if (err) { 1666 mutex_unlock(&ocelot->ptp_lock); 1667 return err; 1668 } 1669 1670 if (l2 && l4) 1671 cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; 1672 else if (l2) 1673 cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; 1674 else if (l4) 1675 cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; 1676 else 1677 cfg.rx_filter = HWTSTAMP_FILTER_NONE; 1678 |
|
1345 /* Commit back the result & save it */ 1346 memcpy(&ocelot->hwtstamp_config, &cfg, sizeof(cfg)); 1347 mutex_unlock(&ocelot->ptp_lock); 1348 1349 return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; 1350} 1351EXPORT_SYMBOL(ocelot_hwstamp_set); 1352 --- 86 unchanged lines hidden (view full) --- 1439 info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE | 1440 SOF_TIMESTAMPING_RX_SOFTWARE | 1441 SOF_TIMESTAMPING_SOFTWARE | 1442 SOF_TIMESTAMPING_TX_HARDWARE | 1443 SOF_TIMESTAMPING_RX_HARDWARE | 1444 SOF_TIMESTAMPING_RAW_HARDWARE; 1445 info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON) | 1446 BIT(HWTSTAMP_TX_ONESTEP_SYNC); | 1679 /* Commit back the result & save it */ 1680 memcpy(&ocelot->hwtstamp_config, &cfg, sizeof(cfg)); 1681 mutex_unlock(&ocelot->ptp_lock); 1682 1683 return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; 1684} 1685EXPORT_SYMBOL(ocelot_hwstamp_set); 1686 --- 86 unchanged lines hidden (view full) --- 1773 info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE | 1774 SOF_TIMESTAMPING_RX_SOFTWARE | 1775 SOF_TIMESTAMPING_SOFTWARE | 1776 SOF_TIMESTAMPING_TX_HARDWARE | 1777 SOF_TIMESTAMPING_RX_HARDWARE | 1778 SOF_TIMESTAMPING_RAW_HARDWARE; 1779 info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON) | 1780 BIT(HWTSTAMP_TX_ONESTEP_SYNC); |
1447 info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_ALL); | 1781 info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | 1782 BIT(HWTSTAMP_FILTER_PTP_V2_EVENT) | 1783 BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | 1784 BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT); |
1448 1449 return 0; 1450} 1451EXPORT_SYMBOL(ocelot_get_ts_info); 1452 | 1785 1786 return 0; 1787} 1788EXPORT_SYMBOL(ocelot_get_ts_info); 1789 |
1453static u32 ocelot_get_bond_mask(struct ocelot *ocelot, struct net_device *bond, 1454 bool only_active_ports) | 1790static u32 ocelot_get_bond_mask(struct ocelot *ocelot, struct net_device *bond) |
1455{ 1456 u32 mask = 0; 1457 int port; 1458 1459 for (port = 0; port < ocelot->num_phys_ports; port++) { 1460 struct ocelot_port *ocelot_port = ocelot->ports[port]; 1461 1462 if (!ocelot_port) 1463 continue; 1464 | 1791{ 1792 u32 mask = 0; 1793 int port; 1794 1795 for (port = 0; port < ocelot->num_phys_ports; port++) { 1796 struct ocelot_port *ocelot_port = ocelot->ports[port]; 1797 1798 if (!ocelot_port) 1799 continue; 1800 |
1465 if (ocelot_port->bond == bond) { 1466 if (only_active_ports && !ocelot_port->lag_tx_active) 1467 continue; 1468 | 1801 if (ocelot_port->bond == bond) |
1469 mask |= BIT(port); | 1802 mask |= BIT(port); |
1470 } | |
1471 } 1472 1473 return mask; 1474} 1475 | 1803 } 1804 1805 return mask; 1806} 1807 |
1476static u32 ocelot_get_bridge_fwd_mask(struct ocelot *ocelot, int src_port, 1477 struct net_device *bridge) | 1808u32 ocelot_get_bridge_fwd_mask(struct ocelot *ocelot, int src_port) |
1478{ 1479 struct ocelot_port *ocelot_port = ocelot->ports[src_port]; | 1809{ 1810 struct ocelot_port *ocelot_port = ocelot->ports[src_port]; |
1811 const struct net_device *bridge; |
|
1480 u32 mask = 0; 1481 int port; 1482 | 1812 u32 mask = 0; 1813 int port; 1814 |
1483 if (!ocelot_port || ocelot_port->bridge != bridge || 1484 ocelot_port->stp_state != BR_STATE_FORWARDING) | 1815 if (!ocelot_port || ocelot_port->stp_state != BR_STATE_FORWARDING) |
1485 return 0; 1486 | 1816 return 0; 1817 |
1818 bridge = ocelot_port->bridge; 1819 if (!bridge) 1820 return 0; 1821 |
|
1487 for (port = 0; port < ocelot->num_phys_ports; port++) { 1488 ocelot_port = ocelot->ports[port]; 1489 1490 if (!ocelot_port) 1491 continue; 1492 1493 if (ocelot_port->stp_state == BR_STATE_FORWARDING && 1494 ocelot_port->bridge == bridge) 1495 mask |= BIT(port); 1496 } 1497 1498 return mask; 1499} | 1822 for (port = 0; port < ocelot->num_phys_ports; port++) { 1823 ocelot_port = ocelot->ports[port]; 1824 1825 if (!ocelot_port) 1826 continue; 1827 1828 if (ocelot_port->stp_state == BR_STATE_FORWARDING && 1829 ocelot_port->bridge == bridge) 1830 mask |= BIT(port); 1831 } 1832 1833 return mask; 1834} |
1835EXPORT_SYMBOL_GPL(ocelot_get_bridge_fwd_mask); |
|
1500 | 1836 |
1501static u32 ocelot_get_dsa_8021q_cpu_mask(struct ocelot *ocelot) | 1837u32 ocelot_get_dsa_8021q_cpu_mask(struct ocelot *ocelot) |
1502{ 1503 u32 mask = 0; 1504 int port; 1505 1506 for (port = 0; port < ocelot->num_phys_ports; port++) { 1507 struct ocelot_port *ocelot_port = ocelot->ports[port]; 1508 1509 if (!ocelot_port) 1510 continue; 1511 1512 if (ocelot_port->is_dsa_8021q_cpu) 1513 mask |= BIT(port); 1514 } 1515 1516 return mask; 1517} | 1838{ 1839 u32 mask = 0; 1840 int port; 1841 1842 for (port = 0; port < ocelot->num_phys_ports; port++) { 1843 struct ocelot_port *ocelot_port = ocelot->ports[port]; 1844 1845 if (!ocelot_port) 1846 continue; 1847 1848 if (ocelot_port->is_dsa_8021q_cpu) 1849 mask |= BIT(port); 1850 } 1851 1852 return mask; 1853} |
1854EXPORT_SYMBOL_GPL(ocelot_get_dsa_8021q_cpu_mask); |
|
1518 | 1855 |
1519void ocelot_apply_bridge_fwd_mask(struct ocelot *ocelot) | 1856void ocelot_apply_bridge_fwd_mask(struct ocelot *ocelot, bool joining) |
1520{ 1521 unsigned long cpu_fwd_mask; 1522 int port; 1523 | 1857{ 1858 unsigned long cpu_fwd_mask; 1859 int port; 1860 |
1861 lockdep_assert_held(&ocelot->fwd_domain_lock); 1862 1863 /* If cut-through forwarding is supported, update the masks before a 1864 * port joins the forwarding domain, to avoid potential underruns if it 1865 * has the highest speed from the new domain. 1866 */ 1867 if (joining && ocelot->ops->cut_through_fwd) 1868 ocelot->ops->cut_through_fwd(ocelot); 1869 |
|
1524 /* If a DSA tag_8021q CPU exists, it needs to be included in the 1525 * regular forwarding path of the front ports regardless of whether 1526 * those are bridged or standalone. 1527 * If DSA tag_8021q is not used, this returns 0, which is fine because 1528 * the hardware-based CPU port module can be a destination for packets 1529 * even if it isn't part of PGID_SRC. 1530 */ 1531 cpu_fwd_mask = ocelot_get_dsa_8021q_cpu_mask(ocelot); --- 11 unchanged lines hidden (view full) --- 1543 } else if (ocelot_port->is_dsa_8021q_cpu) { 1544 /* The DSA tag_8021q CPU ports need to be able to 1545 * forward packets to all other ports except for 1546 * themselves 1547 */ 1548 mask = GENMASK(ocelot->num_phys_ports - 1, 0); 1549 mask &= ~cpu_fwd_mask; 1550 } else if (ocelot_port->bridge) { | 1870 /* If a DSA tag_8021q CPU exists, it needs to be included in the 1871 * regular forwarding path of the front ports regardless of whether 1872 * those are bridged or standalone. 1873 * If DSA tag_8021q is not used, this returns 0, which is fine because 1874 * the hardware-based CPU port module can be a destination for packets 1875 * even if it isn't part of PGID_SRC. 1876 */ 1877 cpu_fwd_mask = ocelot_get_dsa_8021q_cpu_mask(ocelot); --- 11 unchanged lines hidden (view full) --- 1889 } else if (ocelot_port->is_dsa_8021q_cpu) { 1890 /* The DSA tag_8021q CPU ports need to be able to 1891 * forward packets to all other ports except for 1892 * themselves 1893 */ 1894 mask = GENMASK(ocelot->num_phys_ports - 1, 0); 1895 mask &= ~cpu_fwd_mask; 1896 } else if (ocelot_port->bridge) { |
1551 struct net_device *bridge = ocelot_port->bridge; | |
1552 struct net_device *bond = ocelot_port->bond; 1553 | 1897 struct net_device *bond = ocelot_port->bond; 1898 |
1554 mask = ocelot_get_bridge_fwd_mask(ocelot, port, bridge); | 1899 mask = ocelot_get_bridge_fwd_mask(ocelot, port); |
1555 mask |= cpu_fwd_mask; 1556 mask &= ~BIT(port); | 1900 mask |= cpu_fwd_mask; 1901 mask &= ~BIT(port); |
1557 if (bond) { 1558 mask &= ~ocelot_get_bond_mask(ocelot, bond, 1559 false); 1560 } | 1902 if (bond) 1903 mask &= ~ocelot_get_bond_mask(ocelot, bond); |
1561 } else { 1562 /* Standalone ports forward only to DSA tag_8021q CPU 1563 * ports (if those exist), or to the hardware CPU port 1564 * module otherwise. 1565 */ 1566 mask = cpu_fwd_mask; 1567 } 1568 1569 ocelot_write_rix(ocelot, mask, ANA_PGID_PGID, PGID_SRC + port); 1570 } | 1904 } else { 1905 /* Standalone ports forward only to DSA tag_8021q CPU 1906 * ports (if those exist), or to the hardware CPU port 1907 * module otherwise. 1908 */ 1909 mask = cpu_fwd_mask; 1910 } 1911 1912 ocelot_write_rix(ocelot, mask, ANA_PGID_PGID, PGID_SRC + port); 1913 } |
1914 1915 /* If cut-through forwarding is supported and a port is leaving, there 1916 * is a chance that cut-through was disabled on the other ports due to 1917 * the port which is leaving (it has a higher link speed). We need to 1918 * update the cut-through masks of the remaining ports no earlier than 1919 * after the port has left, to prevent underruns from happening between 1920 * the cut-through update and the forwarding domain update. 1921 */ 1922 if (!joining && ocelot->ops->cut_through_fwd) 1923 ocelot->ops->cut_through_fwd(ocelot); |
|
1571} 1572EXPORT_SYMBOL(ocelot_apply_bridge_fwd_mask); 1573 1574void ocelot_bridge_stp_state_set(struct ocelot *ocelot, int port, u8 state) 1575{ 1576 struct ocelot_port *ocelot_port = ocelot->ports[port]; 1577 u32 learn_ena = 0; 1578 | 1924} 1925EXPORT_SYMBOL(ocelot_apply_bridge_fwd_mask); 1926 1927void ocelot_bridge_stp_state_set(struct ocelot *ocelot, int port, u8 state) 1928{ 1929 struct ocelot_port *ocelot_port = ocelot->ports[port]; 1930 u32 learn_ena = 0; 1931 |
1932 mutex_lock(&ocelot->fwd_domain_lock); 1933 |
|
1579 ocelot_port->stp_state = state; 1580 1581 if ((state == BR_STATE_LEARNING || state == BR_STATE_FORWARDING) && 1582 ocelot_port->learn_ena) 1583 learn_ena = ANA_PORT_PORT_CFG_LEARN_ENA; 1584 1585 ocelot_rmw_gix(ocelot, learn_ena, ANA_PORT_PORT_CFG_LEARN_ENA, 1586 ANA_PORT_PORT_CFG, port); 1587 | 1934 ocelot_port->stp_state = state; 1935 1936 if ((state == BR_STATE_LEARNING || state == BR_STATE_FORWARDING) && 1937 ocelot_port->learn_ena) 1938 learn_ena = ANA_PORT_PORT_CFG_LEARN_ENA; 1939 1940 ocelot_rmw_gix(ocelot, learn_ena, ANA_PORT_PORT_CFG_LEARN_ENA, 1941 ANA_PORT_PORT_CFG, port); 1942 |
1588 ocelot_apply_bridge_fwd_mask(ocelot); | 1943 ocelot_apply_bridge_fwd_mask(ocelot, state == BR_STATE_FORWARDING); 1944 1945 mutex_unlock(&ocelot->fwd_domain_lock); |
1589} 1590EXPORT_SYMBOL(ocelot_bridge_stp_state_set); 1591 1592void ocelot_set_ageing_time(struct ocelot *ocelot, unsigned int msecs) 1593{ 1594 unsigned int age_period = ANA_AUTOAGE_AGE_PERIOD(msecs / 2000); 1595 1596 /* Setting AGE_PERIOD to zero effectively disables automatic aging, --- 213 unchanged lines hidden (view full) --- 1810} 1811EXPORT_SYMBOL(ocelot_port_mdb_del); 1812 1813void ocelot_port_bridge_join(struct ocelot *ocelot, int port, 1814 struct net_device *bridge) 1815{ 1816 struct ocelot_port *ocelot_port = ocelot->ports[port]; 1817 | 1946} 1947EXPORT_SYMBOL(ocelot_bridge_stp_state_set); 1948 1949void ocelot_set_ageing_time(struct ocelot *ocelot, unsigned int msecs) 1950{ 1951 unsigned int age_period = ANA_AUTOAGE_AGE_PERIOD(msecs / 2000); 1952 1953 /* Setting AGE_PERIOD to zero effectively disables automatic aging, --- 213 unchanged lines hidden (view full) --- 2167} 2168EXPORT_SYMBOL(ocelot_port_mdb_del); 2169 2170void ocelot_port_bridge_join(struct ocelot *ocelot, int port, 2171 struct net_device *bridge) 2172{ 2173 struct ocelot_port *ocelot_port = ocelot->ports[port]; 2174 |
2175 mutex_lock(&ocelot->fwd_domain_lock); 2176 |
|
1818 ocelot_port->bridge = bridge; 1819 | 2177 ocelot_port->bridge = bridge; 2178 |
1820 ocelot_apply_bridge_fwd_mask(ocelot); | 2179 ocelot_apply_bridge_fwd_mask(ocelot, true); 2180 2181 mutex_unlock(&ocelot->fwd_domain_lock); |
1821} 1822EXPORT_SYMBOL(ocelot_port_bridge_join); 1823 1824void ocelot_port_bridge_leave(struct ocelot *ocelot, int port, 1825 struct net_device *bridge) 1826{ 1827 struct ocelot_port *ocelot_port = ocelot->ports[port]; 1828 | 2182} 2183EXPORT_SYMBOL(ocelot_port_bridge_join); 2184 2185void ocelot_port_bridge_leave(struct ocelot *ocelot, int port, 2186 struct net_device *bridge) 2187{ 2188 struct ocelot_port *ocelot_port = ocelot->ports[port]; 2189 |
2190 mutex_lock(&ocelot->fwd_domain_lock); 2191 |
|
1829 ocelot_port->bridge = NULL; 1830 1831 ocelot_port_set_pvid(ocelot, port, NULL); 1832 ocelot_port_manage_port_tag(ocelot, port); | 2192 ocelot_port->bridge = NULL; 2193 2194 ocelot_port_set_pvid(ocelot, port, NULL); 2195 ocelot_port_manage_port_tag(ocelot, port); |
1833 ocelot_apply_bridge_fwd_mask(ocelot); | 2196 ocelot_apply_bridge_fwd_mask(ocelot, false); 2197 2198 mutex_unlock(&ocelot->fwd_domain_lock); |
1834} 1835EXPORT_SYMBOL(ocelot_port_bridge_leave); 1836 1837static void ocelot_set_aggr_pgids(struct ocelot *ocelot) 1838{ 1839 unsigned long visited = GENMASK(ocelot->num_phys_ports - 1, 0); 1840 int i, port, lag; 1841 --- 27 unchanged lines hidden (view full) --- 1869 struct net_device *bond = ocelot->ports[lag]->bond; 1870 int num_active_ports = 0; 1871 unsigned long bond_mask; 1872 u8 aggr_idx[16]; 1873 1874 if (!bond || (visited & BIT(lag))) 1875 continue; 1876 | 2199} 2200EXPORT_SYMBOL(ocelot_port_bridge_leave); 2201 2202static void ocelot_set_aggr_pgids(struct ocelot *ocelot) 2203{ 2204 unsigned long visited = GENMASK(ocelot->num_phys_ports - 1, 0); 2205 int i, port, lag; 2206 --- 27 unchanged lines hidden (view full) --- 2234 struct net_device *bond = ocelot->ports[lag]->bond; 2235 int num_active_ports = 0; 2236 unsigned long bond_mask; 2237 u8 aggr_idx[16]; 2238 2239 if (!bond || (visited & BIT(lag))) 2240 continue; 2241 |
1877 bond_mask = ocelot_get_bond_mask(ocelot, bond, true); | 2242 bond_mask = ocelot_get_bond_mask(ocelot, bond); |
1878 1879 for_each_set_bit(port, &bond_mask, ocelot->num_phys_ports) { | 2243 2244 for_each_set_bit(port, &bond_mask, ocelot->num_phys_ports) { |
2245 struct ocelot_port *ocelot_port = ocelot->ports[port]; 2246 |
|
1880 // Destination mask 1881 ocelot_write_rix(ocelot, bond_mask, 1882 ANA_PGID_PGID, port); | 2247 // Destination mask 2248 ocelot_write_rix(ocelot, bond_mask, 2249 ANA_PGID_PGID, port); |
1883 aggr_idx[num_active_ports++] = port; | 2250 2251 if (ocelot_port->lag_tx_active) 2252 aggr_idx[num_active_ports++] = port; |
1884 } 1885 1886 for_each_aggr_pgid(ocelot, i) { 1887 u32 ac; 1888 1889 ac = ocelot_read_rix(ocelot, ANA_PGID_PGID, i); 1890 ac &= ~bond_mask; 1891 /* Don't do division by zero if there was no active --- 32 unchanged lines hidden (view full) --- 1924 struct ocelot_port *ocelot_port = ocelot->ports[port]; 1925 struct net_device *bond; 1926 1927 if (!ocelot_port) 1928 continue; 1929 1930 bond = ocelot_port->bond; 1931 if (bond) { | 2253 } 2254 2255 for_each_aggr_pgid(ocelot, i) { 2256 u32 ac; 2257 2258 ac = ocelot_read_rix(ocelot, ANA_PGID_PGID, i); 2259 ac &= ~bond_mask; 2260 /* Don't do division by zero if there was no active --- 32 unchanged lines hidden (view full) --- 2293 struct ocelot_port *ocelot_port = ocelot->ports[port]; 2294 struct net_device *bond; 2295 2296 if (!ocelot_port) 2297 continue; 2298 2299 bond = ocelot_port->bond; 2300 if (bond) { |
1932 int lag = __ffs(ocelot_get_bond_mask(ocelot, bond, 1933 false)); | 2301 int lag = __ffs(ocelot_get_bond_mask(ocelot, bond)); |
1934 1935 ocelot_rmw_gix(ocelot, 1936 ANA_PORT_PORT_CFG_PORTID_VAL(lag), 1937 ANA_PORT_PORT_CFG_PORTID_VAL_M, 1938 ANA_PORT_PORT_CFG, port); 1939 } else { 1940 ocelot_rmw_gix(ocelot, 1941 ANA_PORT_PORT_CFG_PORTID_VAL(port), --- 5 unchanged lines hidden (view full) --- 1947 1948int ocelot_port_lag_join(struct ocelot *ocelot, int port, 1949 struct net_device *bond, 1950 struct netdev_lag_upper_info *info) 1951{ 1952 if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) 1953 return -EOPNOTSUPP; 1954 | 2302 2303 ocelot_rmw_gix(ocelot, 2304 ANA_PORT_PORT_CFG_PORTID_VAL(lag), 2305 ANA_PORT_PORT_CFG_PORTID_VAL_M, 2306 ANA_PORT_PORT_CFG, port); 2307 } else { 2308 ocelot_rmw_gix(ocelot, 2309 ANA_PORT_PORT_CFG_PORTID_VAL(port), --- 5 unchanged lines hidden (view full) --- 2315 2316int ocelot_port_lag_join(struct ocelot *ocelot, int port, 2317 struct net_device *bond, 2318 struct netdev_lag_upper_info *info) 2319{ 2320 if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) 2321 return -EOPNOTSUPP; 2322 |
2323 mutex_lock(&ocelot->fwd_domain_lock); 2324 |
|
1955 ocelot->ports[port]->bond = bond; 1956 1957 ocelot_setup_logical_port_ids(ocelot); | 2325 ocelot->ports[port]->bond = bond; 2326 2327 ocelot_setup_logical_port_ids(ocelot); |
1958 ocelot_apply_bridge_fwd_mask(ocelot); | 2328 ocelot_apply_bridge_fwd_mask(ocelot, true); |
1959 ocelot_set_aggr_pgids(ocelot); 1960 | 2329 ocelot_set_aggr_pgids(ocelot); 2330 |
2331 mutex_unlock(&ocelot->fwd_domain_lock); 2332 |
|
1961 return 0; 1962} 1963EXPORT_SYMBOL(ocelot_port_lag_join); 1964 1965void ocelot_port_lag_leave(struct ocelot *ocelot, int port, 1966 struct net_device *bond) 1967{ | 2333 return 0; 2334} 2335EXPORT_SYMBOL(ocelot_port_lag_join); 2336 2337void ocelot_port_lag_leave(struct ocelot *ocelot, int port, 2338 struct net_device *bond) 2339{ |
2340 mutex_lock(&ocelot->fwd_domain_lock); 2341 |
|
1968 ocelot->ports[port]->bond = NULL; 1969 1970 ocelot_setup_logical_port_ids(ocelot); | 2342 ocelot->ports[port]->bond = NULL; 2343 2344 ocelot_setup_logical_port_ids(ocelot); |
1971 ocelot_apply_bridge_fwd_mask(ocelot); | 2345 ocelot_apply_bridge_fwd_mask(ocelot, false); |
1972 ocelot_set_aggr_pgids(ocelot); | 2346 ocelot_set_aggr_pgids(ocelot); |
2347 2348 mutex_unlock(&ocelot->fwd_domain_lock); |
|
1973} 1974EXPORT_SYMBOL(ocelot_port_lag_leave); 1975 1976void ocelot_port_lag_change(struct ocelot *ocelot, int port, bool lag_tx_active) 1977{ 1978 struct ocelot_port *ocelot_port = ocelot->ports[port]; 1979 1980 ocelot_port->lag_tx_active = lag_tx_active; --- 274 unchanged lines hidden (view full) --- 2255 ocelot->num_phys_ports * ocelot->num_stats, 2256 sizeof(u64), GFP_KERNEL); 2257 if (!ocelot->stats) 2258 return -ENOMEM; 2259 2260 mutex_init(&ocelot->stats_lock); 2261 mutex_init(&ocelot->ptp_lock); 2262 mutex_init(&ocelot->mact_lock); | 2349} 2350EXPORT_SYMBOL(ocelot_port_lag_leave); 2351 2352void ocelot_port_lag_change(struct ocelot *ocelot, int port, bool lag_tx_active) 2353{ 2354 struct ocelot_port *ocelot_port = ocelot->ports[port]; 2355 2356 ocelot_port->lag_tx_active = lag_tx_active; --- 274 unchanged lines hidden (view full) --- 2631 ocelot->num_phys_ports * ocelot->num_stats, 2632 sizeof(u64), GFP_KERNEL); 2633 if (!ocelot->stats) 2634 return -ENOMEM; 2635 2636 mutex_init(&ocelot->stats_lock); 2637 mutex_init(&ocelot->ptp_lock); 2638 mutex_init(&ocelot->mact_lock); |
2639 mutex_init(&ocelot->fwd_domain_lock); |
|
2263 spin_lock_init(&ocelot->ptp_clock_lock); 2264 spin_lock_init(&ocelot->ts_id_lock); 2265 snprintf(queue_name, sizeof(queue_name), "%s-stats", 2266 dev_name(ocelot->dev)); 2267 ocelot->stats_queue = create_singlethread_workqueue(queue_name); 2268 if (!ocelot->stats_queue) 2269 return -ENOMEM; 2270 --- 7 unchanged lines hidden (view full) --- 2278 INIT_LIST_HEAD(&ocelot->pgids); 2279 INIT_LIST_HEAD(&ocelot->vlans); 2280 ocelot_detect_features(ocelot); 2281 ocelot_mact_init(ocelot); 2282 ocelot_vlan_init(ocelot); 2283 ocelot_vcap_init(ocelot); 2284 ocelot_cpu_port_init(ocelot); 2285 | 2640 spin_lock_init(&ocelot->ptp_clock_lock); 2641 spin_lock_init(&ocelot->ts_id_lock); 2642 snprintf(queue_name, sizeof(queue_name), "%s-stats", 2643 dev_name(ocelot->dev)); 2644 ocelot->stats_queue = create_singlethread_workqueue(queue_name); 2645 if (!ocelot->stats_queue) 2646 return -ENOMEM; 2647 --- 7 unchanged lines hidden (view full) --- 2655 INIT_LIST_HEAD(&ocelot->pgids); 2656 INIT_LIST_HEAD(&ocelot->vlans); 2657 ocelot_detect_features(ocelot); 2658 ocelot_mact_init(ocelot); 2659 ocelot_vlan_init(ocelot); 2660 ocelot_vcap_init(ocelot); 2661 ocelot_cpu_port_init(ocelot); 2662 |
2663 if (ocelot->ops->psfp_init) 2664 ocelot->ops->psfp_init(ocelot); 2665 |
|
2286 for (port = 0; port < ocelot->num_phys_ports; port++) { 2287 /* Clear all counters (5 groups) */ 2288 ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(port) | 2289 SYS_STAT_CFG_STAT_CLEAR_SHOT(0x7f), 2290 SYS_STAT_CFG); 2291 } 2292 2293 /* Only use S-Tag */ --- 114 unchanged lines hidden --- | 2666 for (port = 0; port < ocelot->num_phys_ports; port++) { 2667 /* Clear all counters (5 groups) */ 2668 ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(port) | 2669 SYS_STAT_CFG_STAT_CLEAR_SHOT(0x7f), 2670 SYS_STAT_CFG); 2671 } 2672 2673 /* Only use S-Tag */ --- 114 unchanged lines hidden --- |