sxgbe_xpcs.c 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /* 10G controller driver for Samsung SoCs
  2. *
  3. * Copyright (C) 2013 Samsung Electronics Co., Ltd.
  4. * http://www.samsung.com
  5. *
  6. * Author: Siva Reddy Kallam <siva.kallam@samsung.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. */
  12. #include <linux/bitops.h>
  13. #include <linux/kernel.h>
  14. #include <linux/netdevice.h>
  15. #include <linux/phy.h>
  16. #include "sxgbe_common.h"
  17. #include "sxgbe_xpcs.h"
  18. static int sxgbe_xpcs_read(struct net_device *ndev, unsigned int reg)
  19. {
  20. u32 value;
  21. struct sxgbe_priv_data *priv = netdev_priv(ndev);
  22. value = readl(priv->ioaddr + XPCS_OFFSET + reg);
  23. return value;
  24. }
  25. static int sxgbe_xpcs_write(struct net_device *ndev, int reg, int data)
  26. {
  27. struct sxgbe_priv_data *priv = netdev_priv(ndev);
  28. writel(data, priv->ioaddr + XPCS_OFFSET + reg);
  29. return 0;
  30. }
  31. int sxgbe_xpcs_init(struct net_device *ndev)
  32. {
  33. u32 value;
  34. value = sxgbe_xpcs_read(ndev, SR_PCS_MMD_CONTROL1);
  35. /* 10G XAUI mode */
  36. sxgbe_xpcs_write(ndev, SR_PCS_CONTROL2, XPCS_TYPE_SEL_X);
  37. sxgbe_xpcs_write(ndev, VR_PCS_MMD_XAUI_MODE_CONTROL, XPCS_XAUI_MODE);
  38. sxgbe_xpcs_write(ndev, VR_PCS_MMD_XAUI_MODE_CONTROL, value | BIT(13));
  39. sxgbe_xpcs_write(ndev, SR_PCS_MMD_CONTROL1, value | BIT(11));
  40. do {
  41. value = sxgbe_xpcs_read(ndev, VR_PCS_MMD_DIGITAL_STATUS);
  42. } while ((value & XPCS_QSEQ_STATE_MPLLOFF) == XPCS_QSEQ_STATE_STABLE);
  43. value = sxgbe_xpcs_read(ndev, SR_PCS_MMD_CONTROL1);
  44. sxgbe_xpcs_write(ndev, SR_PCS_MMD_CONTROL1, value & ~BIT(11));
  45. do {
  46. value = sxgbe_xpcs_read(ndev, VR_PCS_MMD_DIGITAL_STATUS);
  47. } while ((value & XPCS_QSEQ_STATE_MPLLOFF) != XPCS_QSEQ_STATE_STABLE);
  48. return 0;
  49. }
  50. int sxgbe_xpcs_init_1G(struct net_device *ndev)
  51. {
  52. int value;
  53. /* 10GBASE-X PCS (1G) mode */
  54. sxgbe_xpcs_write(ndev, SR_PCS_CONTROL2, XPCS_TYPE_SEL_X);
  55. sxgbe_xpcs_write(ndev, VR_PCS_MMD_XAUI_MODE_CONTROL, XPCS_XAUI_MODE);
  56. value = sxgbe_xpcs_read(ndev, SR_PCS_MMD_CONTROL1);
  57. sxgbe_xpcs_write(ndev, SR_PCS_MMD_CONTROL1, value & ~BIT(13));
  58. value = sxgbe_xpcs_read(ndev, SR_MII_MMD_CONTROL);
  59. sxgbe_xpcs_write(ndev, SR_MII_MMD_CONTROL, value | BIT(6));
  60. sxgbe_xpcs_write(ndev, SR_MII_MMD_CONTROL, value & ~BIT(13));
  61. value = sxgbe_xpcs_read(ndev, SR_PCS_MMD_CONTROL1);
  62. sxgbe_xpcs_write(ndev, SR_PCS_MMD_CONTROL1, value | BIT(11));
  63. do {
  64. value = sxgbe_xpcs_read(ndev, VR_PCS_MMD_DIGITAL_STATUS);
  65. } while ((value & XPCS_QSEQ_STATE_MPLLOFF) != XPCS_QSEQ_STATE_STABLE);
  66. value = sxgbe_xpcs_read(ndev, SR_PCS_MMD_CONTROL1);
  67. sxgbe_xpcs_write(ndev, SR_PCS_MMD_CONTROL1, value & ~BIT(11));
  68. /* Auto Negotiation cluase 37 enable */
  69. value = sxgbe_xpcs_read(ndev, SR_MII_MMD_CONTROL);
  70. sxgbe_xpcs_write(ndev, SR_MII_MMD_CONTROL, value | BIT(12));
  71. return 0;
  72. }