You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  17. * 02110-1301, USA.
  18. */
  19. FILE_LICENCE ( GPL2_OR_LATER );
  20. #include <string.h>
  21. #include <unistd.h>
  22. #include <errno.h>
  23. #include <ipxe/mii.h>
  24. /** @file
  25. *
  26. * Media Independent Interface
  27. *
  28. */
  29. /**
  30. * Restart autonegotiation
  31. *
  32. * @v mii MII interface
  33. * @ret rc Return status code
  34. */
  35. int mii_restart ( struct mii_interface *mii ) {
  36. int bmcr;
  37. int rc;
  38. /* Read BMCR */
  39. bmcr = mii_read ( mii, MII_BMCR );
  40. if ( bmcr < 0 ) {
  41. rc = bmcr;
  42. DBGC ( mii, "MII %p could not read BMCR: %s\n",
  43. mii, strerror ( rc ) );
  44. return rc;
  45. }
  46. /* Enable and restart autonegotiation */
  47. bmcr |= ( BMCR_ANENABLE | BMCR_ANRESTART );
  48. if ( ( rc = mii_write ( mii, MII_BMCR, bmcr ) ) != 0 ) {
  49. DBGC ( mii, "MII %p could not write BMCR: %s\n",
  50. mii, strerror ( rc ) );
  51. return rc;
  52. }
  53. DBGC ( mii, "MII %p restarted autonegotiation\n", mii );
  54. return 0;
  55. }
  56. /**
  57. * Reset MII interface
  58. *
  59. * @v mii MII interface
  60. * @ret rc Return status code
  61. */
  62. int mii_reset ( struct mii_interface *mii ) {
  63. unsigned int i;
  64. int bmcr;
  65. int rc;
  66. /* Power-up, enable autonegotiation and initiate reset */
  67. if ( ( rc = mii_write ( mii, MII_BMCR,
  68. ( BMCR_RESET | BMCR_ANENABLE ) ) ) != 0 ) {
  69. DBGC ( mii, "MII %p could not write BMCR: %s\n",
  70. mii, strerror ( rc ) );
  71. return rc;
  72. }
  73. /* Wait for reset to complete */
  74. for ( i = 0 ; i < MII_RESET_MAX_WAIT_MS ; i++ ) {
  75. /* Check if reset has completed */
  76. bmcr = mii_read ( mii, MII_BMCR );
  77. if ( bmcr < 0 ) {
  78. rc = bmcr;
  79. DBGC ( mii, "MII %p could not read BMCR: %s\n",
  80. mii, strerror ( rc ) );
  81. return rc;
  82. }
  83. /* If reset is not complete, delay 1ms and retry */
  84. if ( bmcr & BMCR_RESET ) {
  85. mdelay ( 1 );
  86. continue;
  87. }
  88. /* Force autonegotation on again, in case it was
  89. * cleared by the reset.
  90. */
  91. if ( ( rc = mii_restart ( mii ) ) != 0 )
  92. return rc;
  93. DBGC ( mii, "MII %p reset after %dms\n", mii, i );
  94. return 0;
  95. }
  96. DBGC ( mii, "MII %p timed out waiting for reset\n", mii );
  97. return -ETIMEDOUT;
  98. }