1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (c) 2024 Pengutronix, Oleksij Rempel <kernel@pengutronix.de> 3 4 #include <linux/dsa/ksz_common.h> 5 #include <net/dsa.h> 6 #include <net/dscp.h> 7 #include <net/ieee8021q.h> 8 9 #include "ksz_common.h" 10 #include "ksz_dcb.h" 11 #include "ksz8.h" 12 13 /* Port X Control 0 register. 14 * The datasheet specifies: Port 1 - 0x10, Port 2 - 0x20, Port 3 - 0x30. 15 * However, the driver uses get_port_addr(), which maps Port 1 to offset 0. 16 * Therefore, we define the base offset as 0x00 here to align with that logic. 17 */ 18 #define KSZ8_REG_PORT_1_CTRL_0 0x00 19 #define KSZ8463_REG_PORT_1_CTRL_0 0x6C 20 #define KSZ8_PORT_DIFFSERV_ENABLE BIT(6) 21 #define KSZ8_PORT_802_1P_ENABLE BIT(5) 22 #define KSZ8_PORT_BASED_PRIO_M GENMASK(4, 3) 23 24 #define KSZ8463_REG_TOS_DSCP_CTRL 0x16 25 #define KSZ88X3_REG_TOS_DSCP_CTRL 0x60 26 #define KSZ8765_REG_TOS_DSCP_CTRL 0x90 27 28 #define KSZ9477_REG_SW_MAC_TOS_CTRL 0x033e 29 #define KSZ9477_SW_TOS_DSCP_REMAP BIT(0) 30 #define KSZ9477_SW_TOS_DSCP_DEFAULT_PRIO_M GENMASK(5, 3) 31 32 #define KSZ9477_REG_DIFFSERV_PRIO_MAP 0x0340 33 34 #define KSZ9477_REG_PORT_MRI_PRIO_CTRL 0x0801 35 #define KSZ9477_PORT_HIGHEST_PRIO BIT(7) 36 #define KSZ9477_PORT_OR_PRIO BIT(6) 37 #define KSZ9477_PORT_MAC_PRIO_ENABLE BIT(4) 38 #define KSZ9477_PORT_VLAN_PRIO_ENABLE BIT(3) 39 #define KSZ9477_PORT_802_1P_PRIO_ENABLE BIT(2) 40 #define KSZ9477_PORT_DIFFSERV_PRIO_ENABLE BIT(1) 41 #define KSZ9477_PORT_ACL_PRIO_ENABLE BIT(0) 42 43 #define KSZ9477_REG_PORT_MRI_MAC_CTRL 0x0802 44 #define KSZ9477_PORT_BASED_PRIO_M GENMASK(2, 0) 45 46 struct ksz_apptrust_map { 47 u8 apptrust; 48 u8 bit; 49 }; 50 51 static const struct ksz_apptrust_map ksz8_apptrust_map_to_bit[] = { 52 { DCB_APP_SEL_PCP, KSZ8_PORT_802_1P_ENABLE }, 53 { IEEE_8021QAZ_APP_SEL_DSCP, KSZ8_PORT_DIFFSERV_ENABLE }, 54 }; 55 56 static const struct ksz_apptrust_map ksz9477_apptrust_map_to_bit[] = { 57 { DCB_APP_SEL_PCP, KSZ9477_PORT_802_1P_PRIO_ENABLE }, 58 { IEEE_8021QAZ_APP_SEL_DSCP, KSZ9477_PORT_DIFFSERV_PRIO_ENABLE }, 59 }; 60 61 /* ksz_supported_apptrust[] - Supported apptrust selectors and Priority Order 62 * of Internal Priority Map (IPM) sources. 63 * 64 * This array defines the apptrust selectors supported by the hardware, where 65 * the index within the array indicates the priority of the selector - lower 66 * indices correspond to higher priority. This fixed priority scheme is due to 67 * the hardware's design, which does not support configurable priority among 68 * different priority sources. 69 * 70 * The priority sources, including Tail Tag, ACL, VLAN PCP and DSCP are ordered 71 * by the hardware's fixed logic, as detailed below. The order reflects a 72 * non-configurable precedence where certain types of priority information 73 * override others: 74 * 75 * 1. Tail Tag - Highest priority, overrides ACL, VLAN PCP, and DSCP priorities. 76 * 2. ACL - Overrides VLAN PCP and DSCP priorities. 77 * 3. VLAN PCP - Overrides DSCP priority. 78 * 4. DSCP - Lowest priority, does not override any other priority source. 79 * 80 * In this context, the array's lower index (higher priority) for 81 * 'DCB_APP_SEL_PCP' suggests its relative priority over 82 * 'IEEE_8021QAZ_APP_SEL_DSCP' within the system's fixed priority scheme. 83 * 84 * DCB_APP_SEL_PCP - Priority Code Point selector 85 * IEEE_8021QAZ_APP_SEL_DSCP - Differentiated Services Code Point selector 86 */ 87 static const u8 ksz_supported_apptrust[] = { 88 DCB_APP_SEL_PCP, 89 IEEE_8021QAZ_APP_SEL_DSCP, 90 }; 91 92 static const char * const ksz_supported_apptrust_variants[] = { 93 "empty", "dscp", "pcp", "dscp pcp" 94 }; 95 96 static void ksz_get_default_port_prio_reg(struct ksz_device *dev, int *reg, 97 u8 *mask, int *shift) 98 { 99 if (is_ksz8(dev)) { 100 *reg = KSZ8_REG_PORT_1_CTRL_0; 101 *mask = KSZ8_PORT_BASED_PRIO_M; 102 *shift = __bf_shf(KSZ8_PORT_BASED_PRIO_M); 103 if (ksz_is_ksz8463(dev)) 104 *reg = KSZ8463_REG_PORT_1_CTRL_0; 105 } else { 106 *reg = KSZ9477_REG_PORT_MRI_MAC_CTRL; 107 *mask = KSZ9477_PORT_BASED_PRIO_M; 108 *shift = __bf_shf(KSZ9477_PORT_BASED_PRIO_M); 109 } 110 } 111 112 /** 113 * ksz_get_dscp_prio_reg - Retrieves the DSCP-to-priority-mapping register 114 * @dev: Pointer to the KSZ switch device structure 115 * @reg: Pointer to the register address to be set 116 * @per_reg: Pointer to the number of DSCP values per register 117 * @mask: Pointer to the mask to be set 118 * 119 * This function retrieves the DSCP to priority mapping register, the number of 120 * DSCP values per register, and the mask to be set. 121 */ 122 static void ksz_get_dscp_prio_reg(struct ksz_device *dev, int *reg, 123 int *per_reg, u8 *mask) 124 { 125 if (ksz_is_ksz87xx(dev) || ksz_is_8895_family(dev)) { 126 *reg = KSZ8765_REG_TOS_DSCP_CTRL; 127 *per_reg = 4; 128 *mask = GENMASK(1, 0); 129 } else if (ksz_is_ksz88x3(dev) || ksz_is_ksz8463(dev)) { 130 *reg = KSZ88X3_REG_TOS_DSCP_CTRL; 131 *per_reg = 4; 132 *mask = GENMASK(1, 0); 133 if (ksz_is_ksz8463(dev)) 134 *reg = KSZ8463_REG_TOS_DSCP_CTRL; 135 } else { 136 *reg = KSZ9477_REG_DIFFSERV_PRIO_MAP; 137 *per_reg = 2; 138 *mask = GENMASK(2, 0); 139 } 140 } 141 142 /** 143 * ksz_get_apptrust_map_and_reg - Retrieves the apptrust map and register 144 * @dev: Pointer to the KSZ switch device structure 145 * @map: Pointer to the apptrust map to be set 146 * @reg: Pointer to the register address to be set 147 * @mask: Pointer to the mask to be set 148 * 149 * This function retrieves the apptrust map and register address for the 150 * apptrust configuration. 151 */ 152 static void ksz_get_apptrust_map_and_reg(struct ksz_device *dev, 153 const struct ksz_apptrust_map **map, 154 int *reg, u8 *mask) 155 { 156 if (is_ksz8(dev)) { 157 *map = ksz8_apptrust_map_to_bit; 158 *reg = KSZ8_REG_PORT_1_CTRL_0; 159 *mask = KSZ8_PORT_DIFFSERV_ENABLE | KSZ8_PORT_802_1P_ENABLE; 160 if (ksz_is_ksz8463(dev)) 161 *reg = KSZ8463_REG_PORT_1_CTRL_0; 162 } else { 163 *map = ksz9477_apptrust_map_to_bit; 164 *reg = KSZ9477_REG_PORT_MRI_PRIO_CTRL; 165 *mask = KSZ9477_PORT_802_1P_PRIO_ENABLE | 166 KSZ9477_PORT_DIFFSERV_PRIO_ENABLE; 167 } 168 } 169 170 /** 171 * ksz_port_get_default_prio - Retrieves the default priority for a port on a 172 * KSZ switch 173 * @ds: Pointer to the DSA switch structure 174 * @port: Port number from which to get the default priority 175 * 176 * This function fetches the default priority for the specified port on a KSZ 177 * switch. 178 * 179 * Return: The default priority of the port on success, or a negative error 180 * code on failure. 181 */ 182 int ksz_port_get_default_prio(struct dsa_switch *ds, int port) 183 { 184 struct ksz_device *dev = ds->priv; 185 int ret, reg, shift; 186 u8 data, mask; 187 188 ksz_get_default_port_prio_reg(dev, ®, &mask, &shift); 189 190 ret = ksz_pread8(dev, port, reg, &data); 191 if (ret) 192 return ret; 193 194 return (data & mask) >> shift; 195 } 196 197 /** 198 * ksz_port_set_default_prio - Sets the default priority for a port on a KSZ 199 * switch 200 * @ds: Pointer to the DSA switch structure 201 * @port: Port number for which to set the default priority 202 * @prio: Priority value to set 203 * 204 * This function sets the default priority for the specified port on a KSZ 205 * switch. 206 * 207 * Return: 0 on success, or a negative error code on failure. 208 */ 209 int ksz_port_set_default_prio(struct dsa_switch *ds, int port, u8 prio) 210 { 211 struct ksz_device *dev = ds->priv; 212 int reg, shift; 213 u8 mask; 214 215 if (prio >= dev->info->num_ipms) 216 return -EINVAL; 217 218 ksz_get_default_port_prio_reg(dev, ®, &mask, &shift); 219 220 return ksz_prmw8(dev, port, reg, mask, (prio << shift) & mask); 221 } 222 223 /** 224 * ksz_port_get_dscp_prio - Retrieves the priority for a DSCP value on a KSZ 225 * switch 226 * @ds: Pointer to the DSA switch structure 227 * @port: Port number for which to get the priority 228 * @dscp: DSCP value for which to get the priority 229 * 230 * This function fetches the priority value from switch global DSCP-to-priorty 231 * mapping table for the specified DSCP value. 232 * 233 * Return: The priority value for the DSCP on success, or a negative error 234 * code on failure. 235 */ 236 int ksz_port_get_dscp_prio(struct dsa_switch *ds, int port, u8 dscp) 237 { 238 struct ksz_device *dev = ds->priv; 239 int reg, per_reg, ret, shift; 240 u8 data, mask; 241 242 ksz_get_dscp_prio_reg(dev, ®, &per_reg, &mask); 243 244 /* If DSCP remapping is disabled, DSCP bits 3-5 are used as Internal 245 * Priority Map (IPM) 246 */ 247 if (!is_ksz8(dev)) { 248 ret = ksz_read8(dev, KSZ9477_REG_SW_MAC_TOS_CTRL, &data); 249 if (ret) 250 return ret; 251 252 /* If DSCP remapping is disabled, DSCP bits 3-5 are used as 253 * Internal Priority Map (IPM) 254 */ 255 if (!(data & KSZ9477_SW_TOS_DSCP_REMAP)) 256 return FIELD_GET(KSZ9477_SW_TOS_DSCP_DEFAULT_PRIO_M, 257 dscp); 258 } 259 260 /* In case DSCP remapping is enabled, we need to write the DSCP to 261 * priority mapping table. 262 */ 263 reg += dscp / per_reg; 264 ret = ksz_read8(dev, reg, &data); 265 if (ret) 266 return ret; 267 268 shift = (dscp % per_reg) * (8 / per_reg); 269 270 return (data >> shift) & mask; 271 } 272 273 /** 274 * ksz_set_global_dscp_entry - Sets the global DSCP-to-priority mapping entry 275 * @dev: Pointer to the KSZ switch device structure 276 * @dscp: DSCP value for which to set the priority 277 * @ipm: Priority value to set 278 * 279 * This function sets the global DSCP-to-priority mapping entry for the 280 * specified DSCP value. 281 * 282 * Return: 0 on success, or a negative error code on failure. 283 */ 284 static int ksz_set_global_dscp_entry(struct ksz_device *dev, u8 dscp, u8 ipm) 285 { 286 int reg, per_reg, shift; 287 u8 mask; 288 289 ksz_get_dscp_prio_reg(dev, ®, &per_reg, &mask); 290 291 shift = (dscp % per_reg) * (8 / per_reg); 292 293 return ksz_rmw8(dev, reg + (dscp / per_reg), mask << shift, 294 ipm << shift); 295 } 296 297 /** 298 * ksz_init_global_dscp_map - Initializes the global DSCP-to-priority mapping 299 * @dev: Pointer to the KSZ switch device structure 300 * 301 * This function initializes the global DSCP-to-priority mapping table for the 302 * switch. 303 * 304 * Return: 0 on success, or a negative error code on failure 305 */ 306 static int ksz_init_global_dscp_map(struct ksz_device *dev) 307 { 308 int ret, dscp; 309 310 /* On KSZ9xxx variants, DSCP remapping is disabled by default. 311 * Enable to have, predictable and reproducible behavior across 312 * different devices. 313 */ 314 if (!is_ksz8(dev)) { 315 ret = ksz_rmw8(dev, KSZ9477_REG_SW_MAC_TOS_CTRL, 316 KSZ9477_SW_TOS_DSCP_REMAP, 317 KSZ9477_SW_TOS_DSCP_REMAP); 318 if (ret) 319 return ret; 320 } 321 322 for (dscp = 0; dscp < DSCP_MAX; dscp++) { 323 int ipm, tt; 324 325 /* Map DSCP to Traffic Type, which is corresponding to the 326 * Internal Priority Map (IPM) in the switch. 327 */ 328 if (!is_ksz8(dev)) { 329 ipm = ietf_dscp_to_ieee8021q_tt(dscp); 330 } else { 331 /* On KSZ8xxx variants we do not have IPM to queue 332 * remapping table. We need to convert DSCP to Traffic 333 * Type and then to queue. 334 */ 335 tt = ietf_dscp_to_ieee8021q_tt(dscp); 336 if (tt < 0) 337 return tt; 338 339 ipm = ieee8021q_tt_to_tc(tt, dev->info->num_tx_queues); 340 } 341 342 if (ipm < 0) 343 return ipm; 344 345 ret = ksz_set_global_dscp_entry(dev, dscp, ipm); 346 } 347 348 return 0; 349 } 350 351 /** 352 * ksz_port_add_dscp_prio - Adds a DSCP-to-priority mapping entry for a port on 353 * a KSZ switch. 354 * @ds: Pointer to the DSA switch structure 355 * @port: Port number for which to add the DSCP-to-priority mapping entry 356 * @dscp: DSCP value for which to add the priority 357 * @prio: Priority value to set 358 * 359 * Return: 0 on success, or a negative error code on failure 360 */ 361 int ksz_port_add_dscp_prio(struct dsa_switch *ds, int port, u8 dscp, u8 prio) 362 { 363 struct ksz_device *dev = ds->priv; 364 365 if (prio >= dev->info->num_ipms) 366 return -ERANGE; 367 368 return ksz_set_global_dscp_entry(dev, dscp, prio); 369 } 370 371 /** 372 * ksz_port_del_dscp_prio - Deletes a DSCP-to-priority mapping entry for a port 373 * on a KSZ switch. 374 * @ds: Pointer to the DSA switch structure 375 * @port: Port number for which to delete the DSCP-to-priority mapping entry 376 * @dscp: DSCP value for which to delete the priority 377 * @prio: Priority value to delete 378 * 379 * Return: 0 on success, or a negative error code on failure 380 */ 381 int ksz_port_del_dscp_prio(struct dsa_switch *ds, int port, u8 dscp, u8 prio) 382 { 383 struct ksz_device *dev = ds->priv; 384 int ipm; 385 386 if (ksz_port_get_dscp_prio(ds, port, dscp) != prio) 387 return 0; 388 389 if (is_ksz8(dev)) { 390 ipm = ieee8021q_tt_to_tc(IEEE8021Q_TT_BE, 391 dev->info->num_tx_queues); 392 if (ipm < 0) 393 return ipm; 394 } else { 395 ipm = IEEE8021Q_TT_BE; 396 } 397 398 return ksz_set_global_dscp_entry(dev, dscp, ipm); 399 } 400 401 /** 402 * ksz_apptrust_error - Prints an error message for an invalid apptrust selector 403 * @dev: Pointer to the KSZ switch device structure 404 * 405 * This function prints an error message when an invalid apptrust selector is 406 * provided. 407 */ 408 static void ksz_apptrust_error(struct ksz_device *dev) 409 { 410 char supported_apptrust_variants[64]; 411 int i; 412 413 supported_apptrust_variants[0] = '\0'; 414 for (i = 0; i < ARRAY_SIZE(ksz_supported_apptrust_variants); i++) { 415 if (i > 0) 416 strlcat(supported_apptrust_variants, ", ", 417 sizeof(supported_apptrust_variants)); 418 strlcat(supported_apptrust_variants, 419 ksz_supported_apptrust_variants[i], 420 sizeof(supported_apptrust_variants)); 421 } 422 423 dev_err(dev->dev, "Invalid apptrust selector or priority order. Supported: %s\n", 424 supported_apptrust_variants); 425 } 426 427 /** 428 * ksz_port_set_apptrust_validate - Validates the apptrust selectors 429 * @dev: Pointer to the KSZ switch device structure 430 * @port: Port number for which to set the apptrust selectors 431 * @sel: Array of apptrust selectors to validate 432 * @nsel: Number of apptrust selectors in the array 433 * 434 * This function validates the apptrust selectors provided and ensures that 435 * they are in the correct order. 436 * 437 * This family of switches supports two apptrust selectors: DCB_APP_SEL_PCP and 438 * IEEE_8021QAZ_APP_SEL_DSCP. The priority order of the selectors is fixed and 439 * cannot be changed. The order is as follows: 440 * 1. DCB_APP_SEL_PCP - Priority Code Point selector (highest priority) 441 * 2. IEEE_8021QAZ_APP_SEL_DSCP - Differentiated Services Code Point selector 442 * (lowest priority) 443 * 444 * Return: 0 on success, or a negative error code on failure 445 */ 446 static int ksz_port_set_apptrust_validate(struct ksz_device *dev, int port, 447 const u8 *sel, int nsel) 448 { 449 int i, j, found; 450 int j_prev = 0; 451 452 /* Iterate through the requested selectors */ 453 for (i = 0; i < nsel; i++) { 454 found = 0; 455 456 /* Check if the current selector is supported by the hardware */ 457 for (j = 0; j < sizeof(ksz_supported_apptrust); j++) { 458 if (sel[i] != ksz_supported_apptrust[j]) 459 continue; 460 461 found = 1; 462 463 /* Ensure that no higher priority selector (lower index) 464 * precedes a lower priority one 465 */ 466 if (i > 0 && j <= j_prev) 467 goto err_sel_not_vaild; 468 469 j_prev = j; 470 break; 471 } 472 473 if (!found) 474 goto err_sel_not_vaild; 475 } 476 477 return 0; 478 479 err_sel_not_vaild: 480 ksz_apptrust_error(dev); 481 482 return -EINVAL; 483 } 484 485 /** 486 * ksz_port_set_apptrust - Sets the apptrust selectors for a port on a KSZ 487 * switch 488 * @ds: Pointer to the DSA switch structure 489 * @port: Port number for which to set the apptrust selectors 490 * @sel: Array of apptrust selectors to set 491 * @nsel: Number of apptrust selectors in the array 492 * 493 * This function sets the apptrust selectors for the specified port on a KSZ 494 * switch. 495 * 496 * Return: 0 on success, or a negative error code on failure 497 */ 498 int ksz_port_set_apptrust(struct dsa_switch *ds, int port, 499 const u8 *sel, int nsel) 500 { 501 const struct ksz_apptrust_map *map; 502 struct ksz_device *dev = ds->priv; 503 int reg, i, ret; 504 u8 data = 0; 505 u8 mask; 506 507 ret = ksz_port_set_apptrust_validate(dev, port, sel, nsel); 508 if (ret) 509 return ret; 510 511 ksz_get_apptrust_map_and_reg(dev, &map, ®, &mask); 512 513 for (i = 0; i < nsel; i++) { 514 int j; 515 516 for (j = 0; j < ARRAY_SIZE(ksz_supported_apptrust); j++) { 517 if (sel[i] != ksz_supported_apptrust[j]) 518 continue; 519 520 data |= map[j].bit; 521 break; 522 } 523 } 524 525 return ksz_prmw8(dev, port, reg, mask, data); 526 } 527 528 /** 529 * ksz_port_get_apptrust - Retrieves the apptrust selectors for a port on a KSZ 530 * switch 531 * @ds: Pointer to the DSA switch structure 532 * @port: Port number for which to get the apptrust selectors 533 * @sel: Array to store the apptrust selectors 534 * @nsel: Number of apptrust selectors in the array 535 * 536 * This function fetches the apptrust selectors for the specified port on a KSZ 537 * switch. 538 * 539 * Return: 0 on success, or a negative error code on failure 540 */ 541 int ksz_port_get_apptrust(struct dsa_switch *ds, int port, u8 *sel, int *nsel) 542 { 543 const struct ksz_apptrust_map *map; 544 struct ksz_device *dev = ds->priv; 545 int reg, i, ret; 546 u8 data; 547 u8 mask; 548 549 ksz_get_apptrust_map_and_reg(dev, &map, ®, &mask); 550 551 ret = ksz_pread8(dev, port, reg, &data); 552 if (ret) 553 return ret; 554 555 *nsel = 0; 556 for (i = 0; i < ARRAY_SIZE(ksz_supported_apptrust); i++) { 557 if (data & map[i].bit) 558 sel[(*nsel)++] = ksz_supported_apptrust[i]; 559 } 560 561 return 0; 562 } 563 564 /** 565 * ksz_dcb_init_port - Initializes the DCB configuration for a port on a KSZ 566 * @dev: Pointer to the KSZ switch device structure 567 * @port: Port number for which to initialize the DCB configuration 568 * 569 * This function initializes the DCB configuration for the specified port on a 570 * KSZ switch. Particular DCB configuration is set for the port, including the 571 * default priority and apptrust selectors. 572 * The default priority is set to Best Effort, and the apptrust selectors are 573 * set to all supported selectors. 574 * 575 * Return: 0 on success, or a negative error code on failure 576 */ 577 int ksz_dcb_init_port(struct ksz_device *dev, int port) 578 { 579 const u8 ksz_default_apptrust[] = { DCB_APP_SEL_PCP }; 580 int ret, ipm; 581 582 if (is_ksz8(dev)) { 583 ipm = ieee8021q_tt_to_tc(IEEE8021Q_TT_BE, 584 dev->info->num_tx_queues); 585 if (ipm < 0) 586 return ipm; 587 } else { 588 ipm = IEEE8021Q_TT_BE; 589 } 590 591 /* Set the default priority for the port to Best Effort */ 592 ret = ksz_port_set_default_prio(dev->ds, port, ipm); 593 if (ret) 594 return ret; 595 596 return ksz_port_set_apptrust(dev->ds, port, ksz_default_apptrust, 597 ARRAY_SIZE(ksz_default_apptrust)); 598 } 599 600 /** 601 * ksz_dcb_init - Initializes the DCB configuration for a KSZ switch 602 * @dev: Pointer to the KSZ switch device structure 603 * 604 * This function initializes the DCB configuration for a KSZ switch. The global 605 * DSCP-to-priority mapping table is initialized. 606 * 607 * Return: 0 on success, or a negative error code on failure 608 */ 609 int ksz_dcb_init(struct ksz_device *dev) 610 { 611 return ksz_init_global_dscp_map(dev); 612 } 613