1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Aeonsemi AS21XXxX PHY Driver 4 * 5 * Author: Christian Marangi <ansuelsmth@gmail.com> 6 */ 7 8 #include <linux/bitfield.h> 9 #include <linux/firmware.h> 10 #include <linux/module.h> 11 #include <linux/of.h> 12 #include <linux/phy.h> 13 14 #define VEND1_GLB_REG_CPU_RESET_ADDR_LO_BASEADDR 0x3 15 #define VEND1_GLB_REG_CPU_RESET_ADDR_HI_BASEADDR 0x4 16 17 #define VEND1_GLB_REG_CPU_CTRL 0xe 18 #define VEND1_GLB_CPU_CTRL_MASK GENMASK(4, 0) 19 #define VEND1_GLB_CPU_CTRL_LED_POLARITY_MASK GENMASK(12, 8) 20 #define VEND1_GLB_CPU_CTRL_LED_POLARITY(_n) FIELD_PREP(VEND1_GLB_CPU_CTRL_LED_POLARITY_MASK, \ 21 BIT(_n)) 22 23 #define VEND1_FW_START_ADDR 0x100 24 25 #define VEND1_GLB_REG_MDIO_INDIRECT_ADDRCMD 0x101 26 #define VEND1_GLB_REG_MDIO_INDIRECT_LOAD 0x102 27 28 #define VEND1_GLB_REG_MDIO_INDIRECT_STATUS 0x103 29 30 #define VEND1_PTP_CLK 0x142 31 #define VEND1_PTP_CLK_EN BIT(6) 32 33 /* 5 LED at step of 0x20 34 * FE: Fast-Ethernet (10/100) 35 * GE: Gigabit-Ethernet (1000) 36 * NG: New-Generation (2500/5000/10000) 37 */ 38 #define VEND1_LED_REG(_n) (0x1800 + ((_n) * 0x10)) 39 #define VEND1_LED_REG_A_EVENT GENMASK(15, 11) 40 #define VEND1_LED_CONF 0x1881 41 #define VEND1_LED_CONFG_BLINK GENMASK(7, 0) 42 43 #define VEND1_SPEED_STATUS 0x4002 44 #define VEND1_SPEED_MASK GENMASK(7, 0) 45 #define VEND1_SPEED_10000 FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x3) 46 #define VEND1_SPEED_5000 FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x5) 47 #define VEND1_SPEED_2500 FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x9) 48 #define VEND1_SPEED_1000 FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x10) 49 #define VEND1_SPEED_100 FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x20) 50 #define VEND1_SPEED_10 FIELD_PREP_CONST(VEND1_SPEED_MASK, 0x0) 51 52 #define VEND1_IPC_CMD 0x5801 53 #define AEON_IPC_CMD_PARITY BIT(15) 54 #define AEON_IPC_CMD_SIZE GENMASK(10, 6) 55 #define AEON_IPC_CMD_OPCODE GENMASK(5, 0) 56 57 #define IPC_CMD_NOOP 0x0 /* Do nothing */ 58 #define IPC_CMD_INFO 0x1 /* Get Firmware Version */ 59 #define IPC_CMD_SYS_CPU 0x2 /* SYS_CPU */ 60 #define IPC_CMD_BULK_DATA 0xa /* Pass bulk data in ipc registers. */ 61 #define IPC_CMD_BULK_WRITE 0xc /* Write bulk data to memory */ 62 #define IPC_CMD_CFG_PARAM 0x1a /* Write config parameters to memory */ 63 #define IPC_CMD_NG_TESTMODE 0x1b /* Set NG test mode and tone */ 64 #define IPC_CMD_TEMP_MON 0x15 /* Temperature monitoring function */ 65 #define IPC_CMD_SET_LED 0x23 /* Set led */ 66 67 #define VEND1_IPC_STS 0x5802 68 #define AEON_IPC_STS_PARITY BIT(15) 69 #define AEON_IPC_STS_SIZE GENMASK(14, 10) 70 #define AEON_IPC_STS_OPCODE GENMASK(9, 4) 71 #define AEON_IPC_STS_STATUS GENMASK(3, 0) 72 #define AEON_IPC_STS_STATUS_RCVD FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0x1) 73 #define AEON_IPC_STS_STATUS_PROCESS FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0x2) 74 #define AEON_IPC_STS_STATUS_SUCCESS FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0x4) 75 #define AEON_IPC_STS_STATUS_ERROR FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0x8) 76 #define AEON_IPC_STS_STATUS_BUSY FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0xe) 77 #define AEON_IPC_STS_STATUS_READY FIELD_PREP_CONST(AEON_IPC_STS_STATUS, 0xf) 78 79 #define VEND1_IPC_DATA0 0x5808 80 #define VEND1_IPC_DATA1 0x5809 81 #define VEND1_IPC_DATA2 0x580a 82 #define VEND1_IPC_DATA3 0x580b 83 #define VEND1_IPC_DATA4 0x580c 84 #define VEND1_IPC_DATA5 0x580d 85 #define VEND1_IPC_DATA6 0x580e 86 #define VEND1_IPC_DATA7 0x580f 87 #define VEND1_IPC_DATA(_n) (VEND1_IPC_DATA0 + (_n)) 88 89 /* Sub command of CMD_INFO */ 90 #define IPC_INFO_VERSION 0x1 91 92 /* Sub command of CMD_SYS_CPU */ 93 #define IPC_SYS_CPU_REBOOT 0x3 94 #define IPC_SYS_CPU_IMAGE_OFST 0x4 95 #define IPC_SYS_CPU_IMAGE_CHECK 0x5 96 #define IPC_SYS_CPU_PHY_ENABLE 0x6 97 98 /* Sub command of CMD_CFG_PARAM */ 99 #define IPC_CFG_PARAM_DIRECT 0x4 100 101 /* CFG DIRECT sub command */ 102 #define IPC_CFG_PARAM_DIRECT_NG_PHYCTRL 0x1 103 #define IPC_CFG_PARAM_DIRECT_CU_AN 0x2 104 #define IPC_CFG_PARAM_DIRECT_SDS_PCS 0x3 105 #define IPC_CFG_PARAM_DIRECT_AUTO_EEE 0x4 106 #define IPC_CFG_PARAM_DIRECT_SDS_PMA 0x5 107 #define IPC_CFG_PARAM_DIRECT_DPC_RA 0x6 108 #define IPC_CFG_PARAM_DIRECT_DPC_PKT_CHK 0x7 109 #define IPC_CFG_PARAM_DIRECT_DPC_SDS_WAIT_ETH 0x8 110 #define IPC_CFG_PARAM_DIRECT_WDT 0x9 111 #define IPC_CFG_PARAM_DIRECT_SDS_RESTART_AN 0x10 112 #define IPC_CFG_PARAM_DIRECT_TEMP_MON 0x11 113 #define IPC_CFG_PARAM_DIRECT_WOL 0x12 114 115 /* Sub command of CMD_TEMP_MON */ 116 #define IPC_CMD_TEMP_MON_GET 0x4 117 118 #define AS21XXX_MDIO_AN_C22 0xffe0 119 120 #define PHY_ID_AS21XXX 0x75009410 121 /* AS21xxx ID Legend 122 * AS21x1xxB1 123 * ^ ^^ 124 * | |J: Supports SyncE/PTP 125 * | |P: No SyncE/PTP support 126 * | 1: Supports 2nd Serdes 127 * | 2: Not 2nd Serdes support 128 * 0: 10G, 5G, 2.5G 129 * 5: 5G, 2.5G 130 * 2: 2.5G 131 */ 132 #define PHY_ID_AS21011JB1 0x75009402 133 #define PHY_ID_AS21011PB1 0x75009412 134 #define PHY_ID_AS21010JB1 0x75009422 135 #define PHY_ID_AS21010PB1 0x75009432 136 #define PHY_ID_AS21511JB1 0x75009442 137 #define PHY_ID_AS21511PB1 0x75009452 138 #define PHY_ID_AS21510JB1 0x75009462 139 #define PHY_ID_AS21510PB1 0x75009472 140 #define PHY_ID_AS21210JB1 0x75009482 141 #define PHY_ID_AS21210PB1 0x75009492 142 #define PHY_VENDOR_AEONSEMI 0x75009400 143 144 #define AEON_MAX_LEDS 5 145 #define AEON_IPC_DELAY 10000 146 #define AEON_IPC_TIMEOUT (AEON_IPC_DELAY * 100) 147 #define AEON_IPC_DATA_NUM_REGISTERS 8 148 #define AEON_IPC_DATA_MAX (AEON_IPC_DATA_NUM_REGISTERS * sizeof(u16)) 149 150 #define AEON_BOOT_ADDR 0x1000 151 #define AEON_CPU_BOOT_ADDR 0x2000 152 #define AEON_CPU_CTRL_FW_LOAD (BIT(4) | BIT(2) | BIT(1) | BIT(0)) 153 #define AEON_CPU_CTRL_FW_START BIT(0) 154 155 enum as21xxx_led_event { 156 VEND1_LED_REG_A_EVENT_ON_10 = 0x0, 157 VEND1_LED_REG_A_EVENT_ON_100, 158 VEND1_LED_REG_A_EVENT_ON_1000, 159 VEND1_LED_REG_A_EVENT_ON_2500, 160 VEND1_LED_REG_A_EVENT_ON_5000, 161 VEND1_LED_REG_A_EVENT_ON_10000, 162 VEND1_LED_REG_A_EVENT_ON_FE_GE, 163 VEND1_LED_REG_A_EVENT_ON_NG, 164 VEND1_LED_REG_A_EVENT_ON_FULL_DUPLEX, 165 VEND1_LED_REG_A_EVENT_ON_COLLISION, 166 VEND1_LED_REG_A_EVENT_BLINK_TX, 167 VEND1_LED_REG_A_EVENT_BLINK_RX, 168 VEND1_LED_REG_A_EVENT_BLINK_ACT, 169 VEND1_LED_REG_A_EVENT_ON_LINK, 170 VEND1_LED_REG_A_EVENT_ON_LINK_BLINK_ACT, 171 VEND1_LED_REG_A_EVENT_ON_LINK_BLINK_RX, 172 VEND1_LED_REG_A_EVENT_ON_FE_GE_BLINK_ACT, 173 VEND1_LED_REG_A_EVENT_ON_NG_BLINK_ACT, 174 VEND1_LED_REG_A_EVENT_ON_NG_BLINK_FE_GE, 175 VEND1_LED_REG_A_EVENT_ON_FD_BLINK_COLLISION, 176 VEND1_LED_REG_A_EVENT_ON, 177 VEND1_LED_REG_A_EVENT_OFF, 178 }; 179 180 struct as21xxx_led_pattern_info { 181 unsigned int pattern; 182 u16 val; 183 }; 184 185 struct as21xxx_priv { 186 bool parity_status; 187 /* Protect concurrent IPC access */ 188 struct mutex ipc_lock; 189 }; 190 191 static struct as21xxx_led_pattern_info as21xxx_led_supported_pattern[] = { 192 { 193 .pattern = BIT(TRIGGER_NETDEV_LINK_10), 194 .val = VEND1_LED_REG_A_EVENT_ON_10 195 }, 196 { 197 .pattern = BIT(TRIGGER_NETDEV_LINK_100), 198 .val = VEND1_LED_REG_A_EVENT_ON_100 199 }, 200 { 201 .pattern = BIT(TRIGGER_NETDEV_LINK_1000), 202 .val = VEND1_LED_REG_A_EVENT_ON_1000 203 }, 204 { 205 .pattern = BIT(TRIGGER_NETDEV_LINK_2500), 206 .val = VEND1_LED_REG_A_EVENT_ON_2500 207 }, 208 { 209 .pattern = BIT(TRIGGER_NETDEV_LINK_5000), 210 .val = VEND1_LED_REG_A_EVENT_ON_5000 211 }, 212 { 213 .pattern = BIT(TRIGGER_NETDEV_LINK_10000), 214 .val = VEND1_LED_REG_A_EVENT_ON_10000 215 }, 216 { 217 .pattern = BIT(TRIGGER_NETDEV_LINK), 218 .val = VEND1_LED_REG_A_EVENT_ON_LINK 219 }, 220 { 221 .pattern = BIT(TRIGGER_NETDEV_LINK_10) | 222 BIT(TRIGGER_NETDEV_LINK_100) | 223 BIT(TRIGGER_NETDEV_LINK_1000), 224 .val = VEND1_LED_REG_A_EVENT_ON_FE_GE 225 }, 226 { 227 .pattern = BIT(TRIGGER_NETDEV_LINK_2500) | 228 BIT(TRIGGER_NETDEV_LINK_5000) | 229 BIT(TRIGGER_NETDEV_LINK_10000), 230 .val = VEND1_LED_REG_A_EVENT_ON_NG 231 }, 232 { 233 .pattern = BIT(TRIGGER_NETDEV_FULL_DUPLEX), 234 .val = VEND1_LED_REG_A_EVENT_ON_FULL_DUPLEX 235 }, 236 { 237 .pattern = BIT(TRIGGER_NETDEV_TX), 238 .val = VEND1_LED_REG_A_EVENT_BLINK_TX 239 }, 240 { 241 .pattern = BIT(TRIGGER_NETDEV_RX), 242 .val = VEND1_LED_REG_A_EVENT_BLINK_RX 243 }, 244 { 245 .pattern = BIT(TRIGGER_NETDEV_TX) | 246 BIT(TRIGGER_NETDEV_RX), 247 .val = VEND1_LED_REG_A_EVENT_BLINK_ACT 248 }, 249 { 250 .pattern = BIT(TRIGGER_NETDEV_LINK_10) | 251 BIT(TRIGGER_NETDEV_LINK_100) | 252 BIT(TRIGGER_NETDEV_LINK_1000) | 253 BIT(TRIGGER_NETDEV_LINK_2500) | 254 BIT(TRIGGER_NETDEV_LINK_5000) | 255 BIT(TRIGGER_NETDEV_LINK_10000), 256 .val = VEND1_LED_REG_A_EVENT_ON_LINK 257 }, 258 { 259 .pattern = BIT(TRIGGER_NETDEV_LINK_10) | 260 BIT(TRIGGER_NETDEV_LINK_100) | 261 BIT(TRIGGER_NETDEV_LINK_1000) | 262 BIT(TRIGGER_NETDEV_LINK_2500) | 263 BIT(TRIGGER_NETDEV_LINK_5000) | 264 BIT(TRIGGER_NETDEV_LINK_10000) | 265 BIT(TRIGGER_NETDEV_TX) | 266 BIT(TRIGGER_NETDEV_RX), 267 .val = VEND1_LED_REG_A_EVENT_ON_LINK_BLINK_ACT 268 }, 269 { 270 .pattern = BIT(TRIGGER_NETDEV_LINK_10) | 271 BIT(TRIGGER_NETDEV_LINK_100) | 272 BIT(TRIGGER_NETDEV_LINK_1000) | 273 BIT(TRIGGER_NETDEV_LINK_2500) | 274 BIT(TRIGGER_NETDEV_LINK_5000) | 275 BIT(TRIGGER_NETDEV_LINK_10000) | 276 BIT(TRIGGER_NETDEV_RX), 277 .val = VEND1_LED_REG_A_EVENT_ON_LINK_BLINK_RX 278 }, 279 { 280 .pattern = BIT(TRIGGER_NETDEV_LINK_10) | 281 BIT(TRIGGER_NETDEV_LINK_100) | 282 BIT(TRIGGER_NETDEV_LINK_1000) | 283 BIT(TRIGGER_NETDEV_TX) | 284 BIT(TRIGGER_NETDEV_RX), 285 .val = VEND1_LED_REG_A_EVENT_ON_FE_GE_BLINK_ACT 286 }, 287 { 288 .pattern = BIT(TRIGGER_NETDEV_LINK_2500) | 289 BIT(TRIGGER_NETDEV_LINK_5000) | 290 BIT(TRIGGER_NETDEV_LINK_10000) | 291 BIT(TRIGGER_NETDEV_TX) | 292 BIT(TRIGGER_NETDEV_RX), 293 .val = VEND1_LED_REG_A_EVENT_ON_NG_BLINK_ACT 294 } 295 }; 296 297 static int aeon_firmware_boot(struct phy_device *phydev, const u8 *data, 298 size_t size) 299 { 300 int i, ret; 301 u16 val; 302 303 ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLB_REG_CPU_CTRL, 304 VEND1_GLB_CPU_CTRL_MASK, AEON_CPU_CTRL_FW_LOAD); 305 if (ret) 306 return ret; 307 308 ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_FW_START_ADDR, 309 AEON_BOOT_ADDR); 310 if (ret) 311 return ret; 312 313 ret = phy_modify_mmd(phydev, MDIO_MMD_VEND1, 314 VEND1_GLB_REG_MDIO_INDIRECT_ADDRCMD, 315 0x3ffc, 0xc000); 316 if (ret) 317 return ret; 318 319 val = phy_read_mmd(phydev, MDIO_MMD_VEND1, 320 VEND1_GLB_REG_MDIO_INDIRECT_STATUS); 321 if (val > 1) { 322 phydev_err(phydev, "wrong origin mdio_indirect_status: %x\n", val); 323 return -EINVAL; 324 } 325 326 /* Firmware is always aligned to u16 */ 327 for (i = 0; i < size; i += 2) { 328 val = data[i + 1] << 8 | data[i]; 329 330 ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 331 VEND1_GLB_REG_MDIO_INDIRECT_LOAD, val); 332 if (ret) 333 return ret; 334 } 335 336 ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 337 VEND1_GLB_REG_CPU_RESET_ADDR_LO_BASEADDR, 338 lower_16_bits(AEON_CPU_BOOT_ADDR)); 339 if (ret) 340 return ret; 341 342 ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, 343 VEND1_GLB_REG_CPU_RESET_ADDR_HI_BASEADDR, 344 upper_16_bits(AEON_CPU_BOOT_ADDR)); 345 if (ret) 346 return ret; 347 348 return phy_modify_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLB_REG_CPU_CTRL, 349 VEND1_GLB_CPU_CTRL_MASK, AEON_CPU_CTRL_FW_START); 350 } 351 352 static int aeon_firmware_load(struct phy_device *phydev) 353 { 354 struct device *dev = &phydev->mdio.dev; 355 const struct firmware *fw; 356 const char *fw_name; 357 int ret; 358 359 ret = of_property_read_string(dev->of_node, "firmware-name", 360 &fw_name); 361 if (ret) 362 return ret; 363 364 ret = request_firmware(&fw, fw_name, dev); 365 if (ret) { 366 phydev_err(phydev, "failed to find FW file %s (%d)\n", 367 fw_name, ret); 368 return ret; 369 } 370 371 ret = aeon_firmware_boot(phydev, fw->data, fw->size); 372 373 release_firmware(fw); 374 375 return ret; 376 } 377 378 static bool aeon_ipc_ready(u16 val, bool parity_status) 379 { 380 u16 status; 381 382 if (FIELD_GET(AEON_IPC_STS_PARITY, val) != parity_status) 383 return false; 384 385 status = val & AEON_IPC_STS_STATUS; 386 387 return status != AEON_IPC_STS_STATUS_RCVD && 388 status != AEON_IPC_STS_STATUS_PROCESS && 389 status != AEON_IPC_STS_STATUS_BUSY; 390 } 391 392 static int aeon_ipc_wait_cmd(struct phy_device *phydev, bool parity_status) 393 { 394 u16 val; 395 396 /* Exit condition logic: 397 * - Wait for parity bit equal 398 * - Wait for status success, error OR ready 399 */ 400 return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, VEND1_IPC_STS, val, 401 aeon_ipc_ready(val, parity_status), 402 AEON_IPC_DELAY, AEON_IPC_TIMEOUT, false); 403 } 404 405 static int aeon_ipc_send_cmd(struct phy_device *phydev, 406 struct as21xxx_priv *priv, 407 u16 cmd, u16 *ret_sts) 408 { 409 bool curr_parity; 410 int ret; 411 412 /* The IPC sync by using a single parity bit. 413 * Each CMD have alternately this bit set or clear 414 * to understand correct flow and packet order. 415 */ 416 curr_parity = priv->parity_status; 417 if (priv->parity_status) 418 cmd |= AEON_IPC_CMD_PARITY; 419 420 /* Always update parity for next packet */ 421 priv->parity_status = !priv->parity_status; 422 423 ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_IPC_CMD, cmd); 424 if (ret) 425 return ret; 426 427 /* Wait for packet to be processed */ 428 usleep_range(AEON_IPC_DELAY, AEON_IPC_DELAY + 5000); 429 430 /* With no ret_sts, ignore waiting for packet completion 431 * (ipc parity bit sync) 432 */ 433 if (!ret_sts) 434 return 0; 435 436 ret = aeon_ipc_wait_cmd(phydev, curr_parity); 437 if (ret) 438 return ret; 439 440 ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_IPC_STS); 441 if (ret < 0) 442 return ret; 443 444 *ret_sts = ret; 445 if ((*ret_sts & AEON_IPC_STS_STATUS) != AEON_IPC_STS_STATUS_SUCCESS) 446 return -EINVAL; 447 448 return 0; 449 } 450 451 /* If data is NULL, return 0 or negative error. 452 * If data not NULL, return number of Bytes received from IPC or 453 * a negative error. 454 */ 455 static int aeon_ipc_send_msg(struct phy_device *phydev, 456 u16 opcode, u16 *data, unsigned int data_len, 457 u16 *ret_data) 458 { 459 struct as21xxx_priv *priv = phydev->priv; 460 unsigned int ret_size; 461 u16 cmd, ret_sts; 462 int ret; 463 int i; 464 465 /* IPC have a max of 8 register to transfer data, 466 * make sure we never exceed this. 467 */ 468 if (data_len > AEON_IPC_DATA_MAX) 469 return -EINVAL; 470 471 for (i = 0; i < data_len / sizeof(u16); i++) 472 phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_IPC_DATA(i), 473 data[i]); 474 475 cmd = FIELD_PREP(AEON_IPC_CMD_SIZE, data_len) | 476 FIELD_PREP(AEON_IPC_CMD_OPCODE, opcode); 477 478 mutex_lock(&priv->ipc_lock); 479 480 ret = aeon_ipc_send_cmd(phydev, priv, cmd, &ret_sts); 481 if (ret) { 482 phydev_err(phydev, "failed to send ipc msg for %x: %d\n", 483 opcode, ret); 484 goto out; 485 } 486 487 if (!data) 488 goto out; 489 490 if ((ret_sts & AEON_IPC_STS_STATUS) == AEON_IPC_STS_STATUS_ERROR) { 491 ret = -EINVAL; 492 goto out; 493 } 494 495 /* Prevent IPC from stack smashing the kernel. 496 * We can't trust IPC to return a good value and we always 497 * preallocate space for 16 Bytes. 498 */ 499 ret_size = FIELD_GET(AEON_IPC_STS_SIZE, ret_sts); 500 if (ret_size > AEON_IPC_DATA_MAX) { 501 ret = -EINVAL; 502 goto out; 503 } 504 505 /* Read data from IPC data register for ret_size value from IPC */ 506 for (i = 0; i < DIV_ROUND_UP(ret_size, sizeof(u16)); i++) { 507 ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_IPC_DATA(i)); 508 if (ret < 0) 509 goto out; 510 511 ret_data[i] = ret; 512 } 513 514 ret = ret_size; 515 516 out: 517 mutex_unlock(&priv->ipc_lock); 518 519 return ret; 520 } 521 522 static int aeon_ipc_noop(struct phy_device *phydev, 523 struct as21xxx_priv *priv, u16 *ret_sts) 524 { 525 u16 cmd; 526 527 cmd = FIELD_PREP(AEON_IPC_CMD_SIZE, 0) | 528 FIELD_PREP(AEON_IPC_CMD_OPCODE, IPC_CMD_NOOP); 529 530 return aeon_ipc_send_cmd(phydev, priv, cmd, ret_sts); 531 } 532 533 /* Logic to sync parity bit with IPC. 534 * We send 2 NOP cmd with same partity and we wait for IPC 535 * to handle the packet only for the second one. This way 536 * we make sure we are sync for every next cmd. 537 */ 538 static int aeon_ipc_sync_parity(struct phy_device *phydev, 539 struct as21xxx_priv *priv) 540 { 541 u16 ret_sts; 542 int ret; 543 544 mutex_lock(&priv->ipc_lock); 545 546 /* Send NOP with no parity */ 547 aeon_ipc_noop(phydev, priv, NULL); 548 549 /* Reset packet parity */ 550 priv->parity_status = false; 551 552 /* Send second NOP with no parity */ 553 ret = aeon_ipc_noop(phydev, priv, &ret_sts); 554 555 mutex_unlock(&priv->ipc_lock); 556 557 /* We expect to return -EINVAL */ 558 if (ret != -EINVAL) 559 return ret; 560 561 if ((ret_sts & AEON_IPC_STS_STATUS) != AEON_IPC_STS_STATUS_READY) { 562 phydev_err(phydev, "Invalid IPC status on sync parity: %x\n", 563 ret_sts); 564 return -EINVAL; 565 } 566 567 return 0; 568 } 569 570 static int aeon_ipc_get_fw_version(struct phy_device *phydev) 571 { 572 u16 ret_data[AEON_IPC_DATA_NUM_REGISTERS], data[1]; 573 char fw_version[AEON_IPC_DATA_MAX + 1]; 574 int ret; 575 576 data[0] = IPC_INFO_VERSION; 577 578 ret = aeon_ipc_send_msg(phydev, IPC_CMD_INFO, data, 579 sizeof(data), ret_data); 580 if (ret < 0) 581 return ret; 582 583 /* Make sure FW version is NULL terminated */ 584 memcpy(fw_version, ret_data, ret); 585 fw_version[ret] = '\0'; 586 587 phydev_info(phydev, "Firmware Version: %s\n", fw_version); 588 589 return 0; 590 } 591 592 static int aeon_dpc_ra_enable(struct phy_device *phydev) 593 { 594 u16 data[2]; 595 596 data[0] = IPC_CFG_PARAM_DIRECT; 597 data[1] = IPC_CFG_PARAM_DIRECT_DPC_RA; 598 599 return aeon_ipc_send_msg(phydev, IPC_CMD_CFG_PARAM, data, 600 sizeof(data), NULL); 601 } 602 603 static int as21xxx_probe(struct phy_device *phydev) 604 { 605 struct as21xxx_priv *priv; 606 int ret; 607 608 priv = devm_kzalloc(&phydev->mdio.dev, 609 sizeof(*priv), GFP_KERNEL); 610 if (!priv) 611 return -ENOMEM; 612 phydev->priv = priv; 613 614 ret = devm_mutex_init(&phydev->mdio.dev, 615 &priv->ipc_lock); 616 if (ret) 617 return ret; 618 619 ret = aeon_ipc_sync_parity(phydev, priv); 620 if (ret) 621 return ret; 622 623 ret = aeon_ipc_get_fw_version(phydev); 624 if (ret) 625 return ret; 626 627 /* Enable PTP clk if not already Enabled */ 628 ret = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_PTP_CLK, 629 VEND1_PTP_CLK_EN); 630 if (ret) 631 return ret; 632 633 return aeon_dpc_ra_enable(phydev); 634 } 635 636 static int as21xxx_read_link(struct phy_device *phydev, int *bmcr) 637 { 638 int status; 639 640 /* Normal C22 BMCR report inconsistent data, use 641 * the mapped C22 in C45 to have more consistent link info. 642 */ 643 *bmcr = phy_read_mmd(phydev, MDIO_MMD_AN, 644 AS21XXX_MDIO_AN_C22 + MII_BMCR); 645 if (*bmcr < 0) 646 return *bmcr; 647 648 /* Autoneg is being started, therefore disregard current 649 * link status and report link as down. 650 */ 651 if (*bmcr & BMCR_ANRESTART) { 652 phydev->link = 0; 653 return 0; 654 } 655 656 status = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1); 657 if (status < 0) 658 return status; 659 660 phydev->link = !!(status & MDIO_STAT1_LSTATUS); 661 662 return 0; 663 } 664 665 static int as21xxx_read_c22_lpa(struct phy_device *phydev) 666 { 667 int lpagb; 668 669 /* MII_STAT1000 are only filled in the mapped C22 670 * in C45, use that to fill lpagb values and check. 671 */ 672 lpagb = phy_read_mmd(phydev, MDIO_MMD_AN, 673 AS21XXX_MDIO_AN_C22 + MII_STAT1000); 674 if (lpagb < 0) 675 return lpagb; 676 677 if (lpagb & LPA_1000MSFAIL) { 678 int adv = phy_read_mmd(phydev, MDIO_MMD_AN, 679 AS21XXX_MDIO_AN_C22 + MII_CTRL1000); 680 681 if (adv < 0) 682 return adv; 683 684 if (adv & CTL1000_ENABLE_MASTER) 685 phydev_err(phydev, "Master/Slave resolution failed, maybe conflicting manual settings?\n"); 686 else 687 phydev_err(phydev, "Master/Slave resolution failed\n"); 688 return -ENOLINK; 689 } 690 691 mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, 692 lpagb); 693 694 return 0; 695 } 696 697 static int as21xxx_read_status(struct phy_device *phydev) 698 { 699 int bmcr, old_link = phydev->link; 700 int ret; 701 702 ret = as21xxx_read_link(phydev, &bmcr); 703 if (ret) 704 return ret; 705 706 /* why bother the PHY if nothing can have changed */ 707 if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) 708 return 0; 709 710 phydev->speed = SPEED_UNKNOWN; 711 phydev->duplex = DUPLEX_UNKNOWN; 712 phydev->pause = 0; 713 phydev->asym_pause = 0; 714 715 if (phydev->autoneg == AUTONEG_ENABLE) { 716 ret = genphy_c45_read_lpa(phydev); 717 if (ret) 718 return ret; 719 720 ret = as21xxx_read_c22_lpa(phydev); 721 if (ret) 722 return ret; 723 724 phy_resolve_aneg_linkmode(phydev); 725 } else { 726 int speed; 727 728 linkmode_zero(phydev->lp_advertising); 729 730 speed = phy_read_mmd(phydev, MDIO_MMD_VEND1, 731 VEND1_SPEED_STATUS); 732 if (speed < 0) 733 return speed; 734 735 switch (speed & VEND1_SPEED_STATUS) { 736 case VEND1_SPEED_10000: 737 phydev->speed = SPEED_10000; 738 phydev->duplex = DUPLEX_FULL; 739 break; 740 case VEND1_SPEED_5000: 741 phydev->speed = SPEED_5000; 742 phydev->duplex = DUPLEX_FULL; 743 break; 744 case VEND1_SPEED_2500: 745 phydev->speed = SPEED_2500; 746 phydev->duplex = DUPLEX_FULL; 747 break; 748 case VEND1_SPEED_1000: 749 phydev->speed = SPEED_1000; 750 if (bmcr & BMCR_FULLDPLX) 751 phydev->duplex = DUPLEX_FULL; 752 else 753 phydev->duplex = DUPLEX_HALF; 754 break; 755 case VEND1_SPEED_100: 756 phydev->speed = SPEED_100; 757 phydev->duplex = DUPLEX_FULL; 758 break; 759 case VEND1_SPEED_10: 760 phydev->speed = SPEED_10; 761 phydev->duplex = DUPLEX_FULL; 762 break; 763 default: 764 return -EINVAL; 765 } 766 } 767 768 return 0; 769 } 770 771 static int as21xxx_led_brightness_set(struct phy_device *phydev, 772 u8 index, enum led_brightness value) 773 { 774 u16 val = VEND1_LED_REG_A_EVENT_OFF; 775 776 if (index > AEON_MAX_LEDS) 777 return -EINVAL; 778 779 if (value) 780 val = VEND1_LED_REG_A_EVENT_ON; 781 782 return phy_modify_mmd(phydev, MDIO_MMD_VEND1, 783 VEND1_LED_REG(index), 784 VEND1_LED_REG_A_EVENT, 785 FIELD_PREP(VEND1_LED_REG_A_EVENT, val)); 786 } 787 788 static int as21xxx_led_hw_is_supported(struct phy_device *phydev, u8 index, 789 unsigned long rules) 790 { 791 int i; 792 793 if (index > AEON_MAX_LEDS) 794 return -EINVAL; 795 796 for (i = 0; i < ARRAY_SIZE(as21xxx_led_supported_pattern); i++) 797 if (rules == as21xxx_led_supported_pattern[i].pattern) 798 return 0; 799 800 return -EOPNOTSUPP; 801 } 802 803 static int as21xxx_led_hw_control_get(struct phy_device *phydev, u8 index, 804 unsigned long *rules) 805 { 806 int i, val; 807 808 if (index > AEON_MAX_LEDS) 809 return -EINVAL; 810 811 val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_LED_REG(index)); 812 if (val < 0) 813 return val; 814 815 val = FIELD_GET(VEND1_LED_REG_A_EVENT, val); 816 for (i = 0; i < ARRAY_SIZE(as21xxx_led_supported_pattern); i++) 817 if (val == as21xxx_led_supported_pattern[i].val) { 818 *rules = as21xxx_led_supported_pattern[i].pattern; 819 return 0; 820 } 821 822 /* Should be impossible */ 823 return -EINVAL; 824 } 825 826 static int as21xxx_led_hw_control_set(struct phy_device *phydev, u8 index, 827 unsigned long rules) 828 { 829 u16 val = 0; 830 int i; 831 832 if (index > AEON_MAX_LEDS) 833 return -EINVAL; 834 835 for (i = 0; i < ARRAY_SIZE(as21xxx_led_supported_pattern); i++) 836 if (rules == as21xxx_led_supported_pattern[i].pattern) { 837 val = as21xxx_led_supported_pattern[i].val; 838 break; 839 } 840 841 return phy_modify_mmd(phydev, MDIO_MMD_VEND1, 842 VEND1_LED_REG(index), 843 VEND1_LED_REG_A_EVENT, 844 FIELD_PREP(VEND1_LED_REG_A_EVENT, val)); 845 } 846 847 static int as21xxx_led_polarity_set(struct phy_device *phydev, int index, 848 unsigned long modes) 849 { 850 bool led_active_low = false; 851 u16 mask, val = 0; 852 u32 mode; 853 854 if (index > AEON_MAX_LEDS) 855 return -EINVAL; 856 857 for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) { 858 switch (mode) { 859 case PHY_LED_ACTIVE_LOW: 860 led_active_low = true; 861 break; 862 case PHY_LED_ACTIVE_HIGH: /* default mode */ 863 led_active_low = false; 864 break; 865 default: 866 return -EINVAL; 867 } 868 } 869 870 mask = VEND1_GLB_CPU_CTRL_LED_POLARITY(index); 871 if (led_active_low) 872 val = VEND1_GLB_CPU_CTRL_LED_POLARITY(index); 873 874 return phy_modify_mmd(phydev, MDIO_MMD_VEND1, 875 VEND1_GLB_REG_CPU_CTRL, 876 mask, val); 877 } 878 879 static int as21xxx_match_phy_device(struct phy_device *phydev, 880 const struct phy_driver *phydrv) 881 { 882 struct as21xxx_priv *priv; 883 u16 ret_sts; 884 u32 phy_id; 885 int ret; 886 887 /* Skip PHY that are not AS21xxx or already have firmware loaded */ 888 if (phydev->c45_ids.device_ids[MDIO_MMD_PCS] != PHY_ID_AS21XXX) 889 return genphy_match_phy_device(phydev, phydrv); 890 891 /* Read PHY ID to handle firmware just loaded */ 892 ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MII_PHYSID1); 893 if (ret < 0) 894 return ret; 895 phy_id = ret << 16; 896 897 ret = phy_read_mmd(phydev, MDIO_MMD_PCS, MII_PHYSID2); 898 if (ret < 0) 899 return ret; 900 phy_id |= ret; 901 902 /* With PHY ID not the generic AS21xxx one assume 903 * the firmware just loaded 904 */ 905 if (phy_id != PHY_ID_AS21XXX) 906 return phy_id == phydrv->phy_id; 907 908 /* Allocate temp priv and load the firmware */ 909 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 910 if (!priv) 911 return -ENOMEM; 912 913 mutex_init(&priv->ipc_lock); 914 915 ret = aeon_firmware_load(phydev); 916 if (ret) 917 goto out; 918 919 /* Sync parity... */ 920 ret = aeon_ipc_sync_parity(phydev, priv); 921 if (ret) 922 goto out; 923 924 /* ...and send a third NOOP cmd to wait for firmware finish loading */ 925 ret = aeon_ipc_noop(phydev, priv, &ret_sts); 926 if (ret) 927 goto out; 928 929 out: 930 mutex_destroy(&priv->ipc_lock); 931 kfree(priv); 932 933 /* Return can either be 0 or a negative error code. 934 * Returning 0 here means THIS is NOT a suitable PHY. 935 * 936 * For the specific case of the generic Aeonsemi PHY ID that 937 * needs the firmware the be loaded first to have a correct PHY ID, 938 * this is OK as a matching PHY ID will be found right after. 939 * This relies on the driver probe order where the first PHY driver 940 * probed is the generic one. 941 */ 942 return ret; 943 } 944 945 static struct phy_driver as21xxx_drivers[] = { 946 { 947 /* PHY expose in C45 as 0x7500 0x9410 948 * before firmware is loaded. 949 * This driver entry must be attempted first to load 950 * the firmware and thus update the ID registers. 951 */ 952 PHY_ID_MATCH_EXACT(PHY_ID_AS21XXX), 953 .name = "Aeonsemi AS21xxx", 954 .match_phy_device = as21xxx_match_phy_device, 955 }, 956 { 957 PHY_ID_MATCH_EXACT(PHY_ID_AS21011JB1), 958 .name = "Aeonsemi AS21011JB1", 959 .probe = as21xxx_probe, 960 .match_phy_device = as21xxx_match_phy_device, 961 .read_status = as21xxx_read_status, 962 .led_brightness_set = as21xxx_led_brightness_set, 963 .led_hw_is_supported = as21xxx_led_hw_is_supported, 964 .led_hw_control_set = as21xxx_led_hw_control_set, 965 .led_hw_control_get = as21xxx_led_hw_control_get, 966 .led_polarity_set = as21xxx_led_polarity_set, 967 }, 968 { 969 PHY_ID_MATCH_EXACT(PHY_ID_AS21011PB1), 970 .name = "Aeonsemi AS21011PB1", 971 .probe = as21xxx_probe, 972 .match_phy_device = as21xxx_match_phy_device, 973 .read_status = as21xxx_read_status, 974 .led_brightness_set = as21xxx_led_brightness_set, 975 .led_hw_is_supported = as21xxx_led_hw_is_supported, 976 .led_hw_control_set = as21xxx_led_hw_control_set, 977 .led_hw_control_get = as21xxx_led_hw_control_get, 978 .led_polarity_set = as21xxx_led_polarity_set, 979 }, 980 { 981 PHY_ID_MATCH_EXACT(PHY_ID_AS21010PB1), 982 .name = "Aeonsemi AS21010PB1", 983 .probe = as21xxx_probe, 984 .match_phy_device = as21xxx_match_phy_device, 985 .read_status = as21xxx_read_status, 986 .led_brightness_set = as21xxx_led_brightness_set, 987 .led_hw_is_supported = as21xxx_led_hw_is_supported, 988 .led_hw_control_set = as21xxx_led_hw_control_set, 989 .led_hw_control_get = as21xxx_led_hw_control_get, 990 .led_polarity_set = as21xxx_led_polarity_set, 991 }, 992 { 993 PHY_ID_MATCH_EXACT(PHY_ID_AS21010JB1), 994 .name = "Aeonsemi AS21010JB1", 995 .probe = as21xxx_probe, 996 .match_phy_device = as21xxx_match_phy_device, 997 .read_status = as21xxx_read_status, 998 .led_brightness_set = as21xxx_led_brightness_set, 999 .led_hw_is_supported = as21xxx_led_hw_is_supported, 1000 .led_hw_control_set = as21xxx_led_hw_control_set, 1001 .led_hw_control_get = as21xxx_led_hw_control_get, 1002 .led_polarity_set = as21xxx_led_polarity_set, 1003 }, 1004 { 1005 PHY_ID_MATCH_EXACT(PHY_ID_AS21210PB1), 1006 .name = "Aeonsemi AS21210PB1", 1007 .probe = as21xxx_probe, 1008 .match_phy_device = as21xxx_match_phy_device, 1009 .read_status = as21xxx_read_status, 1010 .led_brightness_set = as21xxx_led_brightness_set, 1011 .led_hw_is_supported = as21xxx_led_hw_is_supported, 1012 .led_hw_control_set = as21xxx_led_hw_control_set, 1013 .led_hw_control_get = as21xxx_led_hw_control_get, 1014 .led_polarity_set = as21xxx_led_polarity_set, 1015 }, 1016 { 1017 PHY_ID_MATCH_EXACT(PHY_ID_AS21510JB1), 1018 .name = "Aeonsemi AS21510JB1", 1019 .probe = as21xxx_probe, 1020 .match_phy_device = as21xxx_match_phy_device, 1021 .read_status = as21xxx_read_status, 1022 .led_brightness_set = as21xxx_led_brightness_set, 1023 .led_hw_is_supported = as21xxx_led_hw_is_supported, 1024 .led_hw_control_set = as21xxx_led_hw_control_set, 1025 .led_hw_control_get = as21xxx_led_hw_control_get, 1026 .led_polarity_set = as21xxx_led_polarity_set, 1027 }, 1028 { 1029 PHY_ID_MATCH_EXACT(PHY_ID_AS21510PB1), 1030 .name = "Aeonsemi AS21510PB1", 1031 .probe = as21xxx_probe, 1032 .match_phy_device = as21xxx_match_phy_device, 1033 .read_status = as21xxx_read_status, 1034 .led_brightness_set = as21xxx_led_brightness_set, 1035 .led_hw_is_supported = as21xxx_led_hw_is_supported, 1036 .led_hw_control_set = as21xxx_led_hw_control_set, 1037 .led_hw_control_get = as21xxx_led_hw_control_get, 1038 .led_polarity_set = as21xxx_led_polarity_set, 1039 }, 1040 { 1041 PHY_ID_MATCH_EXACT(PHY_ID_AS21511JB1), 1042 .name = "Aeonsemi AS21511JB1", 1043 .probe = as21xxx_probe, 1044 .match_phy_device = as21xxx_match_phy_device, 1045 .read_status = as21xxx_read_status, 1046 .led_brightness_set = as21xxx_led_brightness_set, 1047 .led_hw_is_supported = as21xxx_led_hw_is_supported, 1048 .led_hw_control_set = as21xxx_led_hw_control_set, 1049 .led_hw_control_get = as21xxx_led_hw_control_get, 1050 .led_polarity_set = as21xxx_led_polarity_set, 1051 }, 1052 { 1053 PHY_ID_MATCH_EXACT(PHY_ID_AS21210JB1), 1054 .name = "Aeonsemi AS21210JB1", 1055 .probe = as21xxx_probe, 1056 .match_phy_device = as21xxx_match_phy_device, 1057 .read_status = as21xxx_read_status, 1058 .led_brightness_set = as21xxx_led_brightness_set, 1059 .led_hw_is_supported = as21xxx_led_hw_is_supported, 1060 .led_hw_control_set = as21xxx_led_hw_control_set, 1061 .led_hw_control_get = as21xxx_led_hw_control_get, 1062 .led_polarity_set = as21xxx_led_polarity_set, 1063 }, 1064 { 1065 PHY_ID_MATCH_EXACT(PHY_ID_AS21511PB1), 1066 .name = "Aeonsemi AS21511PB1", 1067 .probe = as21xxx_probe, 1068 .match_phy_device = as21xxx_match_phy_device, 1069 .read_status = as21xxx_read_status, 1070 .led_brightness_set = as21xxx_led_brightness_set, 1071 .led_hw_is_supported = as21xxx_led_hw_is_supported, 1072 .led_hw_control_set = as21xxx_led_hw_control_set, 1073 .led_hw_control_get = as21xxx_led_hw_control_get, 1074 .led_polarity_set = as21xxx_led_polarity_set, 1075 }, 1076 }; 1077 module_phy_driver(as21xxx_drivers); 1078 1079 static struct mdio_device_id __maybe_unused as21xxx_tbl[] = { 1080 { PHY_ID_MATCH_VENDOR(PHY_VENDOR_AEONSEMI) }, 1081 { } 1082 }; 1083 MODULE_DEVICE_TABLE(mdio, as21xxx_tbl); 1084 1085 MODULE_DESCRIPTION("Aeonsemi AS21xxx PHY driver"); 1086 MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>"); 1087 MODULE_LICENSE("GPL"); 1088