207-npe_driver_multiphy_support.patch 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. TODO: take care of additional PHYs through the PHY abstraction layer
  2. --- a/arch/arm/mach-ixp4xx/include/mach/platform.h
  3. +++ b/arch/arm/mach-ixp4xx/include/mach/platform.h
  4. @@ -74,7 +74,7 @@ extern unsigned long ixp4xx_exp_bus_size
  5. /*
  6. * Clock Speed Definitions.
  7. */
  8. -#define IXP4XX_PERIPHERAL_BUS_CLOCK (66) /* 66Mhzi APB BUS */
  9. +#define IXP4XX_PERIPHERAL_BUS_CLOCK (66) /* 66Mhzi APB BUS */
  10. #define IXP4XX_UART_XTAL 14745600
  11. /*
  12. @@ -95,12 +95,23 @@ struct ixp4xx_pata_data {
  13. #define IXP4XX_ETH_NPEB 0x10
  14. #define IXP4XX_ETH_NPEC 0x20
  15. +#define IXP4XX_ETH_PHY_MAX_ADDR 32
  16. +
  17. /* Information about built-in Ethernet MAC interfaces */
  18. struct eth_plat_info {
  19. u8 phy; /* MII PHY ID, 0 - 31 */
  20. u8 rxq; /* configurable, currently 0 - 31 only */
  21. u8 txreadyq;
  22. u8 hwaddr[6];
  23. +
  24. + u32 phy_mask;
  25. +#if 0
  26. + int speed;
  27. + int duplex;
  28. +#else
  29. + int speed_10;
  30. + int half_duplex;
  31. +#endif
  32. };
  33. /* Information about built-in HSS (synchronous serial) interfaces */
  34. --- a/drivers/net/ethernet/xscale/ixp4xx_eth.c
  35. +++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c
  36. @@ -610,6 +610,37 @@ static int ixp4xx_phy_connect(struct net
  37. struct eth_plat_info *plat = port->plat;
  38. char phy_id[MII_BUS_ID_SIZE + 3];
  39. + if (plat->phy == IXP4XX_ETH_PHY_MAX_ADDR) {
  40. +#if 0
  41. + switch (plat->speed) {
  42. + case SPEED_10:
  43. + case SPEED_100:
  44. + break;
  45. + default:
  46. + printk(KERN_ERR "%s: invalid speed (%d)\n",
  47. + dev->name, plat->speed);
  48. + return -EINVAL;
  49. + }
  50. +
  51. + switch (plat->duplex) {
  52. + case DUPLEX_HALF:
  53. + case DUPLEX_FULL:
  54. + break;
  55. + default:
  56. + printk(KERN_ERR "%s: invalid duplex mode (%d)\n",
  57. + dev->name, plat->duplex);
  58. + return -EINVAL;
  59. + }
  60. + port->speed = plat->speed;
  61. + port->duplex = plat->duplex;
  62. +#else
  63. + port->speed = plat->speed_10 ? SPEED_10 : SPEED_100;
  64. + port->duplex = plat->half_duplex ? DUPLEX_HALF : DUPLEX_FULL;
  65. +#endif
  66. +
  67. + return 0;
  68. + }
  69. +
  70. snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT,
  71. mdio_bus->id, plat->phy);
  72. port->phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link,
  73. @@ -632,21 +663,32 @@ static void ixp4xx_phy_disconnect(struct
  74. {
  75. struct port *port = netdev_priv(dev);
  76. - phy_disconnect(port->phydev);
  77. + if (port->phydev)
  78. + phy_disconnect(port->phydev);
  79. }
  80. static void ixp4xx_phy_start(struct net_device *dev)
  81. {
  82. struct port *port = netdev_priv(dev);
  83. - phy_start(port->phydev);
  84. + if (port->phydev) {
  85. + phy_start(port->phydev);
  86. + } else {
  87. + port->link = 1;
  88. + ixp4xx_update_link(dev);
  89. + }
  90. }
  91. static void ixp4xx_phy_stop(struct net_device *dev)
  92. {
  93. struct port *port = netdev_priv(dev);
  94. - phy_stop(port->phydev);
  95. + if (port->phydev) {
  96. + phy_stop(port->phydev);
  97. + } else {
  98. + port->link = 0;
  99. + ixp4xx_update_link(dev);
  100. + }
  101. }
  102. static inline void debug_pkt(struct net_device *dev, const char *func,
  103. @@ -1048,6 +1090,9 @@ static int eth_ioctl(struct net_device *
  104. return hwtstamp_get(dev, req);
  105. }
  106. + if (!port->phydev)
  107. + return -EOPNOTSUPP;
  108. +
  109. return phy_mii_ioctl(port->phydev, req, cmd);
  110. }
  111. @@ -1068,18 +1113,30 @@ static void ixp4xx_get_drvinfo(struct ne
  112. static int ixp4xx_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
  113. {
  114. struct port *port = netdev_priv(dev);
  115. +
  116. + if (!port->phydev)
  117. + return -EOPNOTSUPP;
  118. +
  119. return phy_ethtool_gset(port->phydev, cmd);
  120. }
  121. static int ixp4xx_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
  122. {
  123. struct port *port = netdev_priv(dev);
  124. +
  125. + if (!port->phydev)
  126. + return -EOPNOTSUPP;
  127. +
  128. return phy_ethtool_sset(port->phydev, cmd);
  129. }
  130. static int ixp4xx_nway_reset(struct net_device *dev)
  131. {
  132. struct port *port = netdev_priv(dev);
  133. +
  134. + if (!port->phydev)
  135. + return -EOPNOTSUPP;
  136. +
  137. return phy_start_aneg(port->phydev);
  138. }