1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2015 - 2023 Beijing WangXun Technology Co., Ltd. */ 3 4 #include <linux/gpio/machine.h> 5 #include <linux/gpio/driver.h> 6 #include <linux/gpio/property.h> 7 #include <linux/clk-provider.h> 8 #include <linux/clkdev.h> 9 #include <linux/i2c.h> 10 #include <linux/pci.h> 11 #include <linux/platform_device.h> 12 #include <linux/regmap.h> 13 #include <linux/pcs/pcs-xpcs.h> 14 #include <linux/phylink.h> 15 16 #include "../libwx/wx_type.h" 17 #include "../libwx/wx_lib.h" 18 #include "../libwx/wx_hw.h" 19 #include "txgbe_type.h" 20 #include "txgbe_phy.h" 21 #include "txgbe_hw.h" 22 23 static int txgbe_swnodes_register(struct txgbe *txgbe) 24 { 25 struct txgbe_nodes *nodes = &txgbe->nodes; 26 struct pci_dev *pdev = txgbe->wx->pdev; 27 struct software_node *swnodes; 28 u32 id; 29 30 id = pci_dev_id(pdev); 31 32 snprintf(nodes->gpio_name, sizeof(nodes->gpio_name), "txgbe_gpio-%x", id); 33 snprintf(nodes->i2c_name, sizeof(nodes->i2c_name), "txgbe_i2c-%x", id); 34 snprintf(nodes->sfp_name, sizeof(nodes->sfp_name), "txgbe_sfp-%x", id); 35 snprintf(nodes->phylink_name, sizeof(nodes->phylink_name), "txgbe_phylink-%x", id); 36 37 swnodes = nodes->swnodes; 38 39 /* GPIO 0: tx fault 40 * GPIO 1: tx disable 41 * GPIO 2: sfp module absent 42 * GPIO 3: rx signal lost 43 * GPIO 4: rate select, 1G(0) 10G(1) 44 * GPIO 5: rate select, 1G(0) 10G(1) 45 */ 46 nodes->gpio_props[0] = PROPERTY_ENTRY_STRING("pinctrl-names", "default"); 47 swnodes[SWNODE_GPIO] = NODE_PROP(nodes->gpio_name, nodes->gpio_props); 48 nodes->gpio0_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_GPIO], 0, GPIO_ACTIVE_HIGH); 49 nodes->gpio1_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_GPIO], 1, GPIO_ACTIVE_HIGH); 50 nodes->gpio2_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_GPIO], 2, GPIO_ACTIVE_LOW); 51 nodes->gpio3_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_GPIO], 3, GPIO_ACTIVE_HIGH); 52 nodes->gpio4_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_GPIO], 4, GPIO_ACTIVE_HIGH); 53 nodes->gpio5_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_GPIO], 5, GPIO_ACTIVE_HIGH); 54 55 nodes->i2c_props[0] = PROPERTY_ENTRY_STRING("compatible", "snps,designware-i2c"); 56 nodes->i2c_props[1] = PROPERTY_ENTRY_BOOL("wx,i2c-snps-model"); 57 nodes->i2c_props[2] = PROPERTY_ENTRY_U32("clock-frequency", I2C_MAX_STANDARD_MODE_FREQ); 58 swnodes[SWNODE_I2C] = NODE_PROP(nodes->i2c_name, nodes->i2c_props); 59 nodes->i2c_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_I2C]); 60 61 nodes->sfp_props[0] = PROPERTY_ENTRY_STRING("compatible", "sff,sfp"); 62 nodes->sfp_props[1] = PROPERTY_ENTRY_REF_ARRAY("i2c-bus", nodes->i2c_ref); 63 nodes->sfp_props[2] = PROPERTY_ENTRY_REF_ARRAY("tx-fault-gpios", nodes->gpio0_ref); 64 nodes->sfp_props[3] = PROPERTY_ENTRY_REF_ARRAY("tx-disable-gpios", nodes->gpio1_ref); 65 nodes->sfp_props[4] = PROPERTY_ENTRY_REF_ARRAY("mod-def0-gpios", nodes->gpio2_ref); 66 nodes->sfp_props[5] = PROPERTY_ENTRY_REF_ARRAY("los-gpios", nodes->gpio3_ref); 67 nodes->sfp_props[6] = PROPERTY_ENTRY_REF_ARRAY("rate-select1-gpios", nodes->gpio4_ref); 68 nodes->sfp_props[7] = PROPERTY_ENTRY_REF_ARRAY("rate-select0-gpios", nodes->gpio5_ref); 69 swnodes[SWNODE_SFP] = NODE_PROP(nodes->sfp_name, nodes->sfp_props); 70 nodes->sfp_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_SFP]); 71 72 nodes->phylink_props[0] = PROPERTY_ENTRY_STRING("managed", "in-band-status"); 73 nodes->phylink_props[1] = PROPERTY_ENTRY_REF_ARRAY("sfp", nodes->sfp_ref); 74 swnodes[SWNODE_PHYLINK] = NODE_PROP(nodes->phylink_name, nodes->phylink_props); 75 76 nodes->group[SWNODE_GPIO] = &swnodes[SWNODE_GPIO]; 77 nodes->group[SWNODE_I2C] = &swnodes[SWNODE_I2C]; 78 nodes->group[SWNODE_SFP] = &swnodes[SWNODE_SFP]; 79 nodes->group[SWNODE_PHYLINK] = &swnodes[SWNODE_PHYLINK]; 80 81 return software_node_register_node_group(nodes->group); 82 } 83 84 static int txgbe_pcs_read(struct mii_bus *bus, int addr, int devnum, int regnum) 85 { 86 struct wx *wx = bus->priv; 87 u32 offset, val; 88 89 if (addr) 90 return -EOPNOTSUPP; 91 92 offset = devnum << 16 | regnum; 93 94 /* Set the LAN port indicator to IDA_ADDR */ 95 wr32(wx, TXGBE_XPCS_IDA_ADDR, offset); 96 97 /* Read the data from IDA_DATA register */ 98 val = rd32(wx, TXGBE_XPCS_IDA_DATA); 99 100 return (u16)val; 101 } 102 103 static int txgbe_pcs_write(struct mii_bus *bus, int addr, int devnum, int regnum, u16 val) 104 { 105 struct wx *wx = bus->priv; 106 u32 offset; 107 108 if (addr) 109 return -EOPNOTSUPP; 110 111 offset = devnum << 16 | regnum; 112 113 /* Set the LAN port indicator to IDA_ADDR */ 114 wr32(wx, TXGBE_XPCS_IDA_ADDR, offset); 115 116 /* Write the data to IDA_DATA register */ 117 wr32(wx, TXGBE_XPCS_IDA_DATA, val); 118 119 return 0; 120 } 121 122 static int txgbe_mdio_pcs_init(struct txgbe *txgbe) 123 { 124 struct mii_bus *mii_bus; 125 struct phylink_pcs *pcs; 126 struct pci_dev *pdev; 127 struct wx *wx; 128 int ret = 0; 129 130 wx = txgbe->wx; 131 pdev = wx->pdev; 132 133 mii_bus = devm_mdiobus_alloc(&pdev->dev); 134 if (!mii_bus) 135 return -ENOMEM; 136 137 mii_bus->name = "txgbe_pcs_mdio_bus"; 138 mii_bus->read_c45 = &txgbe_pcs_read; 139 mii_bus->write_c45 = &txgbe_pcs_write; 140 mii_bus->parent = &pdev->dev; 141 mii_bus->phy_mask = ~0; 142 mii_bus->priv = wx; 143 snprintf(mii_bus->id, MII_BUS_ID_SIZE, "txgbe_pcs-%x", 144 pci_dev_id(pdev)); 145 146 ret = devm_mdiobus_register(&pdev->dev, mii_bus); 147 if (ret) 148 return ret; 149 150 pcs = xpcs_create_pcs_mdiodev(mii_bus, 0); 151 if (IS_ERR(pcs)) 152 return PTR_ERR(pcs); 153 154 txgbe->pcs = pcs; 155 156 return 0; 157 } 158 159 static struct phylink_pcs *txgbe_phylink_mac_select(struct phylink_config *config, 160 phy_interface_t interface) 161 { 162 struct wx *wx = phylink_to_wx(config); 163 struct txgbe *txgbe = wx->priv; 164 165 if (wx->media_type != sp_media_copper) 166 return txgbe->pcs; 167 168 return NULL; 169 } 170 171 static void txgbe_mac_config(struct phylink_config *config, unsigned int mode, 172 const struct phylink_link_state *state) 173 { 174 } 175 176 static void txgbe_mac_link_down(struct phylink_config *config, 177 unsigned int mode, phy_interface_t interface) 178 { 179 struct wx *wx = phylink_to_wx(config); 180 181 wr32m(wx, WX_MAC_TX_CFG, WX_MAC_TX_CFG_TE, 0); 182 } 183 184 static void txgbe_mac_link_up(struct phylink_config *config, 185 struct phy_device *phy, 186 unsigned int mode, phy_interface_t interface, 187 int speed, int duplex, 188 bool tx_pause, bool rx_pause) 189 { 190 struct wx *wx = phylink_to_wx(config); 191 u32 txcfg, wdg; 192 193 wx_fc_enable(wx, tx_pause, rx_pause); 194 195 txcfg = rd32(wx, WX_MAC_TX_CFG); 196 txcfg &= ~WX_MAC_TX_CFG_SPEED_MASK; 197 198 switch (speed) { 199 case SPEED_10000: 200 txcfg |= WX_MAC_TX_CFG_SPEED_10G; 201 break; 202 case SPEED_1000: 203 case SPEED_100: 204 case SPEED_10: 205 txcfg |= WX_MAC_TX_CFG_SPEED_1G; 206 break; 207 default: 208 break; 209 } 210 211 wr32(wx, WX_MAC_TX_CFG, txcfg | WX_MAC_TX_CFG_TE); 212 213 /* Re configure MAC Rx */ 214 wr32m(wx, WX_MAC_RX_CFG, WX_MAC_RX_CFG_RE, WX_MAC_RX_CFG_RE); 215 wr32(wx, WX_MAC_PKT_FLT, WX_MAC_PKT_FLT_PR); 216 wdg = rd32(wx, WX_MAC_WDG_TIMEOUT); 217 wr32(wx, WX_MAC_WDG_TIMEOUT, wdg); 218 } 219 220 static int txgbe_mac_prepare(struct phylink_config *config, unsigned int mode, 221 phy_interface_t interface) 222 { 223 struct wx *wx = phylink_to_wx(config); 224 225 wr32m(wx, WX_MAC_TX_CFG, WX_MAC_TX_CFG_TE, 0); 226 wr32m(wx, WX_MAC_RX_CFG, WX_MAC_RX_CFG_RE, 0); 227 228 return txgbe_disable_sec_tx_path(wx); 229 } 230 231 static int txgbe_mac_finish(struct phylink_config *config, unsigned int mode, 232 phy_interface_t interface) 233 { 234 struct wx *wx = phylink_to_wx(config); 235 236 txgbe_enable_sec_tx_path(wx); 237 wr32m(wx, WX_MAC_RX_CFG, WX_MAC_RX_CFG_RE, WX_MAC_RX_CFG_RE); 238 239 return 0; 240 } 241 242 static const struct phylink_mac_ops txgbe_mac_ops = { 243 .mac_select_pcs = txgbe_phylink_mac_select, 244 .mac_prepare = txgbe_mac_prepare, 245 .mac_finish = txgbe_mac_finish, 246 .mac_config = txgbe_mac_config, 247 .mac_link_down = txgbe_mac_link_down, 248 .mac_link_up = txgbe_mac_link_up, 249 }; 250 251 static int txgbe_phylink_init(struct txgbe *txgbe) 252 { 253 struct fwnode_handle *fwnode = NULL; 254 struct phylink_config *config; 255 struct wx *wx = txgbe->wx; 256 phy_interface_t phy_mode; 257 struct phylink *phylink; 258 259 config = &wx->phylink_config; 260 config->dev = &wx->netdev->dev; 261 config->type = PHYLINK_NETDEV; 262 config->mac_capabilities = MAC_10000FD | MAC_1000FD | MAC_100FD | 263 MAC_SYM_PAUSE | MAC_ASYM_PAUSE; 264 265 if (wx->media_type == sp_media_copper) { 266 phy_mode = PHY_INTERFACE_MODE_XAUI; 267 __set_bit(PHY_INTERFACE_MODE_XAUI, config->supported_interfaces); 268 } else { 269 phy_mode = PHY_INTERFACE_MODE_10GBASER; 270 fwnode = software_node_fwnode(txgbe->nodes.group[SWNODE_PHYLINK]); 271 __set_bit(PHY_INTERFACE_MODE_10GBASER, config->supported_interfaces); 272 __set_bit(PHY_INTERFACE_MODE_1000BASEX, config->supported_interfaces); 273 __set_bit(PHY_INTERFACE_MODE_SGMII, config->supported_interfaces); 274 } 275 276 phylink = phylink_create(config, fwnode, phy_mode, &txgbe_mac_ops); 277 if (IS_ERR(phylink)) 278 return PTR_ERR(phylink); 279 280 if (wx->phydev) { 281 int ret; 282 283 ret = phylink_connect_phy(phylink, wx->phydev); 284 if (ret) { 285 phylink_destroy(phylink); 286 return ret; 287 } 288 } 289 290 wx->phylink = phylink; 291 292 return 0; 293 } 294 295 irqreturn_t txgbe_link_irq_handler(int irq, void *data) 296 { 297 struct txgbe *txgbe = data; 298 struct wx *wx = txgbe->wx; 299 u32 status; 300 bool up; 301 302 status = rd32(wx, TXGBE_CFG_PORT_ST); 303 up = !!(status & TXGBE_CFG_PORT_ST_LINK_UP); 304 305 phylink_pcs_change(txgbe->pcs, up); 306 307 return IRQ_HANDLED; 308 } 309 310 static int txgbe_gpio_get(struct gpio_chip *chip, unsigned int offset) 311 { 312 struct wx *wx = gpiochip_get_data(chip); 313 int val; 314 315 val = rd32m(wx, WX_GPIO_EXT, BIT(offset)); 316 317 return !!(val & BIT(offset)); 318 } 319 320 static int txgbe_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) 321 { 322 struct wx *wx = gpiochip_get_data(chip); 323 u32 val; 324 325 val = rd32(wx, WX_GPIO_DDR); 326 if (BIT(offset) & val) 327 return GPIO_LINE_DIRECTION_OUT; 328 329 return GPIO_LINE_DIRECTION_IN; 330 } 331 332 static int txgbe_gpio_direction_in(struct gpio_chip *chip, unsigned int offset) 333 { 334 struct wx *wx = gpiochip_get_data(chip); 335 unsigned long flags; 336 337 raw_spin_lock_irqsave(&wx->gpio_lock, flags); 338 wr32m(wx, WX_GPIO_DDR, BIT(offset), 0); 339 raw_spin_unlock_irqrestore(&wx->gpio_lock, flags); 340 341 return 0; 342 } 343 344 static int txgbe_gpio_direction_out(struct gpio_chip *chip, unsigned int offset, 345 int val) 346 { 347 struct wx *wx = gpiochip_get_data(chip); 348 unsigned long flags; 349 u32 set; 350 351 set = val ? BIT(offset) : 0; 352 353 raw_spin_lock_irqsave(&wx->gpio_lock, flags); 354 wr32m(wx, WX_GPIO_DR, BIT(offset), set); 355 wr32m(wx, WX_GPIO_DDR, BIT(offset), BIT(offset)); 356 raw_spin_unlock_irqrestore(&wx->gpio_lock, flags); 357 358 return 0; 359 } 360 361 static int txgbe_gpio_init(struct txgbe *txgbe) 362 { 363 struct gpio_chip *gc; 364 struct device *dev; 365 struct wx *wx; 366 int ret; 367 368 wx = txgbe->wx; 369 dev = &wx->pdev->dev; 370 371 raw_spin_lock_init(&wx->gpio_lock); 372 373 gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL); 374 if (!gc) 375 return -ENOMEM; 376 377 gc->label = devm_kasprintf(dev, GFP_KERNEL, "txgbe_gpio-%x", 378 pci_dev_id(wx->pdev)); 379 if (!gc->label) 380 return -ENOMEM; 381 382 gc->base = -1; 383 gc->ngpio = 6; 384 gc->owner = THIS_MODULE; 385 gc->parent = dev; 386 gc->fwnode = software_node_fwnode(txgbe->nodes.group[SWNODE_GPIO]); 387 gc->get = txgbe_gpio_get; 388 gc->get_direction = txgbe_gpio_get_direction; 389 gc->direction_input = txgbe_gpio_direction_in; 390 gc->direction_output = txgbe_gpio_direction_out; 391 392 ret = devm_gpiochip_add_data(dev, gc, wx); 393 if (ret) 394 return ret; 395 396 txgbe->gpio = gc; 397 398 return 0; 399 } 400 401 static int txgbe_clock_register(struct txgbe *txgbe) 402 { 403 struct pci_dev *pdev = txgbe->wx->pdev; 404 struct clk_lookup *clock; 405 char clk_name[32]; 406 struct clk *clk; 407 408 snprintf(clk_name, sizeof(clk_name), "i2c_designware.%d", 409 pci_dev_id(pdev)); 410 411 clk = clk_register_fixed_rate(NULL, clk_name, NULL, 0, 156250000); 412 if (IS_ERR(clk)) 413 return PTR_ERR(clk); 414 415 clock = clkdev_create(clk, NULL, "%s", clk_name); 416 if (!clock) { 417 clk_unregister(clk); 418 return -ENOMEM; 419 } 420 421 txgbe->clk = clk; 422 txgbe->clock = clock; 423 424 return 0; 425 } 426 427 static int txgbe_i2c_read(void *context, unsigned int reg, unsigned int *val) 428 { 429 struct wx *wx = context; 430 431 *val = rd32(wx, reg + TXGBE_I2C_BASE); 432 433 return 0; 434 } 435 436 static int txgbe_i2c_write(void *context, unsigned int reg, unsigned int val) 437 { 438 struct wx *wx = context; 439 440 wr32(wx, reg + TXGBE_I2C_BASE, val); 441 442 return 0; 443 } 444 445 static const struct regmap_config i2c_regmap_config = { 446 .reg_bits = 32, 447 .val_bits = 32, 448 .reg_read = txgbe_i2c_read, 449 .reg_write = txgbe_i2c_write, 450 .fast_io = true, 451 }; 452 453 static int txgbe_i2c_register(struct txgbe *txgbe) 454 { 455 struct platform_device_info info = {}; 456 struct platform_device *i2c_dev; 457 struct regmap *i2c_regmap; 458 struct pci_dev *pdev; 459 struct wx *wx; 460 461 wx = txgbe->wx; 462 pdev = wx->pdev; 463 i2c_regmap = devm_regmap_init(&pdev->dev, NULL, wx, &i2c_regmap_config); 464 if (IS_ERR(i2c_regmap)) { 465 wx_err(wx, "failed to init I2C regmap\n"); 466 return PTR_ERR(i2c_regmap); 467 } 468 469 info.parent = &pdev->dev; 470 info.fwnode = software_node_fwnode(txgbe->nodes.group[SWNODE_I2C]); 471 info.name = "i2c_designware"; 472 info.id = pci_dev_id(pdev); 473 474 info.res = &DEFINE_RES_IRQ(pdev->irq); 475 info.num_res = 1; 476 i2c_dev = platform_device_register_full(&info); 477 if (IS_ERR(i2c_dev)) 478 return PTR_ERR(i2c_dev); 479 480 txgbe->i2c_dev = i2c_dev; 481 482 return 0; 483 } 484 485 static int txgbe_sfp_register(struct txgbe *txgbe) 486 { 487 struct pci_dev *pdev = txgbe->wx->pdev; 488 struct platform_device_info info = {}; 489 struct platform_device *sfp_dev; 490 491 info.parent = &pdev->dev; 492 info.fwnode = software_node_fwnode(txgbe->nodes.group[SWNODE_SFP]); 493 info.name = "sfp"; 494 info.id = pci_dev_id(pdev); 495 sfp_dev = platform_device_register_full(&info); 496 if (IS_ERR(sfp_dev)) 497 return PTR_ERR(sfp_dev); 498 499 txgbe->sfp_dev = sfp_dev; 500 501 return 0; 502 } 503 504 static int txgbe_ext_phy_init(struct txgbe *txgbe) 505 { 506 struct phy_device *phydev; 507 struct mii_bus *mii_bus; 508 struct pci_dev *pdev; 509 struct wx *wx; 510 int ret = 0; 511 512 wx = txgbe->wx; 513 pdev = wx->pdev; 514 515 mii_bus = devm_mdiobus_alloc(&pdev->dev); 516 if (!mii_bus) 517 return -ENOMEM; 518 519 mii_bus->name = "txgbe_mii_bus"; 520 mii_bus->read_c45 = &wx_phy_read_reg_mdi_c45; 521 mii_bus->write_c45 = &wx_phy_write_reg_mdi_c45; 522 mii_bus->parent = &pdev->dev; 523 mii_bus->phy_mask = GENMASK(31, 1); 524 mii_bus->priv = wx; 525 snprintf(mii_bus->id, MII_BUS_ID_SIZE, "txgbe-%x", pci_dev_id(pdev)); 526 527 ret = devm_mdiobus_register(&pdev->dev, mii_bus); 528 if (ret) { 529 wx_err(wx, "failed to register MDIO bus: %d\n", ret); 530 return ret; 531 } 532 533 phydev = phy_find_first(mii_bus); 534 if (!phydev) { 535 wx_err(wx, "no PHY found\n"); 536 return -ENODEV; 537 } 538 539 phy_attached_info(phydev); 540 541 wx->link = 0; 542 wx->speed = 0; 543 wx->duplex = 0; 544 wx->phydev = phydev; 545 546 ret = txgbe_phylink_init(txgbe); 547 if (ret) { 548 wx_err(wx, "failed to init phylink: %d\n", ret); 549 return ret; 550 } 551 552 return 0; 553 } 554 555 int txgbe_init_phy(struct txgbe *txgbe) 556 { 557 struct wx *wx = txgbe->wx; 558 int ret; 559 560 if (txgbe->wx->media_type == sp_media_copper) 561 return txgbe_ext_phy_init(txgbe); 562 563 ret = txgbe_swnodes_register(txgbe); 564 if (ret) { 565 wx_err(wx, "failed to register software nodes\n"); 566 return ret; 567 } 568 569 ret = txgbe_mdio_pcs_init(txgbe); 570 if (ret) { 571 wx_err(wx, "failed to init mdio pcs: %d\n", ret); 572 goto err_unregister_swnode; 573 } 574 575 ret = txgbe_phylink_init(txgbe); 576 if (ret) { 577 wx_err(wx, "failed to init phylink\n"); 578 goto err_destroy_xpcs; 579 } 580 581 ret = txgbe_gpio_init(txgbe); 582 if (ret) { 583 wx_err(wx, "failed to init gpio\n"); 584 goto err_destroy_phylink; 585 } 586 587 ret = txgbe_clock_register(txgbe); 588 if (ret) { 589 wx_err(wx, "failed to register clock: %d\n", ret); 590 goto err_destroy_phylink; 591 } 592 593 ret = txgbe_i2c_register(txgbe); 594 if (ret) { 595 wx_err(wx, "failed to init i2c interface: %d\n", ret); 596 goto err_unregister_clk; 597 } 598 599 ret = txgbe_sfp_register(txgbe); 600 if (ret) { 601 wx_err(wx, "failed to register sfp\n"); 602 goto err_unregister_i2c; 603 } 604 605 return 0; 606 607 err_unregister_i2c: 608 platform_device_unregister(txgbe->i2c_dev); 609 err_unregister_clk: 610 clkdev_drop(txgbe->clock); 611 clk_unregister(txgbe->clk); 612 err_destroy_phylink: 613 phylink_destroy(wx->phylink); 614 err_destroy_xpcs: 615 xpcs_destroy_pcs(txgbe->pcs); 616 err_unregister_swnode: 617 software_node_unregister_node_group(txgbe->nodes.group); 618 619 return ret; 620 } 621 622 void txgbe_remove_phy(struct txgbe *txgbe) 623 { 624 if (txgbe->wx->media_type == sp_media_copper) { 625 phylink_disconnect_phy(txgbe->wx->phylink); 626 phylink_destroy(txgbe->wx->phylink); 627 return; 628 } 629 630 platform_device_unregister(txgbe->sfp_dev); 631 platform_device_unregister(txgbe->i2c_dev); 632 clkdev_drop(txgbe->clock); 633 clk_unregister(txgbe->clk); 634 phylink_destroy(txgbe->wx->phylink); 635 xpcs_destroy_pcs(txgbe->pcs); 636 software_node_unregister_node_group(txgbe->nodes.group); 637 } 638