423-bcm63xx_enet_add_b53_support.patch 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h
  2. +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h
  3. @@ -336,6 +336,9 @@ struct bcm_enet_priv {
  4. struct bcm63xx_enetsw_port used_ports[ENETSW_MAX_PORT];
  5. int sw_port_link[ENETSW_MAX_PORT];
  6. + /* platform device for associated switch */
  7. + struct platform_device *b53_device;
  8. +
  9. /* used to poll switch port state */
  10. struct timer_list swphy_poll;
  11. spinlock_t enetsw_mdio_lock;
  12. --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
  13. +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
  14. @@ -31,6 +31,7 @@
  15. #include <linux/platform_device.h>
  16. #include <linux/if_vlan.h>
  17. #include <linux/gpio/consumer.h>
  18. +#include <linux/platform_data/b53.h>
  19. #include <bcm63xx_dev_enet.h>
  20. #include "bcm63xx_enet.h"
  21. @@ -1974,7 +1975,8 @@ static int bcm_enet_remove(struct platfo
  22. return 0;
  23. }
  24. -struct platform_driver bcm63xx_enet_driver = {
  25. +
  26. +static struct platform_driver bcm63xx_enet_driver = {
  27. .probe = bcm_enet_probe,
  28. .remove = bcm_enet_remove,
  29. .driver = {
  30. @@ -1983,6 +1985,42 @@ struct platform_driver bcm63xx_enet_driv
  31. },
  32. };
  33. +struct b53_platform_data bcm63xx_b53_pdata = {
  34. + .chip_id = 0x6300,
  35. + .big_endian = 1,
  36. +};
  37. +
  38. +struct platform_device bcm63xx_b53_dev = {
  39. + .name = "b53-switch",
  40. + .id = -1,
  41. + .dev = {
  42. + .platform_data = &bcm63xx_b53_pdata,
  43. + },
  44. +};
  45. +
  46. +static int bcmenet_switch_register(struct bcm_enet_priv *priv, u16 port_mask)
  47. +{
  48. + int ret;
  49. +
  50. + bcm63xx_b53_pdata.regs = priv->base;
  51. + bcm63xx_b53_pdata.enabled_ports = port_mask;
  52. + bcm63xx_b53_pdata.alias = priv->net_dev->name;
  53. +
  54. + ret = platform_device_register(&bcm63xx_b53_dev);
  55. + if (!ret)
  56. + priv->b53_device = &bcm63xx_b53_dev;
  57. +
  58. + return ret;
  59. +}
  60. +
  61. +static void bcmenet_switch_unregister(struct bcm_enet_priv *priv)
  62. +{
  63. + if (priv->b53_device)
  64. + platform_device_unregister(&bcm63xx_b53_dev);
  65. +
  66. + priv->b53_device = NULL;
  67. +}
  68. +
  69. /*
  70. * switch mii access callbacks
  71. */
  72. @@ -2241,29 +2279,6 @@ static int bcm_enetsw_open(struct net_de
  73. enetsw_writeb(priv, rgmii_ctrl, ENETSW_RGMII_CTRL_REG(i));
  74. }
  75. - /* reset mib */
  76. - val = enetsw_readb(priv, ENETSW_GMCR_REG);
  77. - val |= ENETSW_GMCR_RST_MIB_MASK;
  78. - enetsw_writeb(priv, val, ENETSW_GMCR_REG);
  79. - mdelay(1);
  80. - val &= ~ENETSW_GMCR_RST_MIB_MASK;
  81. - enetsw_writeb(priv, val, ENETSW_GMCR_REG);
  82. - mdelay(1);
  83. -
  84. - /* force CPU port state */
  85. - val = enetsw_readb(priv, ENETSW_IMPOV_REG);
  86. - val |= ENETSW_IMPOV_FORCE_MASK | ENETSW_IMPOV_LINKUP_MASK;
  87. - enetsw_writeb(priv, val, ENETSW_IMPOV_REG);
  88. -
  89. - /* enable switch forward engine */
  90. - val = enetsw_readb(priv, ENETSW_SWMODE_REG);
  91. - val |= ENETSW_SWMODE_FWD_EN_MASK;
  92. - enetsw_writeb(priv, val, ENETSW_SWMODE_REG);
  93. -
  94. - /* enable jumbo on all ports */
  95. - enetsw_writel(priv, 0x1ff, ENETSW_JMBCTL_PORT_REG);
  96. - enetsw_writew(priv, 9728, ENETSW_JMBCTL_MAXSIZE_REG);
  97. -
  98. /* initialize flow control buffer allocation */
  99. enet_dma_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0,
  100. ENETDMA_BUFALLOC_REG(priv->rx_chan));
  101. @@ -2722,6 +2737,9 @@ static int bcm_enetsw_probe(struct platf
  102. struct bcm63xx_enetsw_platform_data *pd;
  103. struct resource *res_mem;
  104. int ret, irq_rx, irq_tx;
  105. + unsigned i, num_ports = 0;
  106. + u16 port_mask = BIT(8);
  107. + u8 val;
  108. /* stop if shared driver failed, assume driver->probe will be
  109. * called in the same order we register devices (correct ?)
  110. @@ -2811,6 +2829,43 @@ static int bcm_enetsw_probe(struct platf
  111. priv->pdev = pdev;
  112. priv->net_dev = dev;
  113. + /* reset mib */
  114. + val = enetsw_readb(priv, ENETSW_GMCR_REG);
  115. + val |= ENETSW_GMCR_RST_MIB_MASK;
  116. + enetsw_writeb(priv, val, ENETSW_GMCR_REG);
  117. + mdelay(1);
  118. + val &= ~ENETSW_GMCR_RST_MIB_MASK;
  119. + enetsw_writeb(priv, val, ENETSW_GMCR_REG);
  120. + mdelay(1);
  121. +
  122. + /* force CPU port state */
  123. + val = enetsw_readb(priv, ENETSW_IMPOV_REG);
  124. + val |= ENETSW_IMPOV_FORCE_MASK | ENETSW_IMPOV_LINKUP_MASK;
  125. + enetsw_writeb(priv, val, ENETSW_IMPOV_REG);
  126. +
  127. + /* enable switch forward engine */
  128. + val = enetsw_readb(priv, ENETSW_SWMODE_REG);
  129. + val |= ENETSW_SWMODE_FWD_EN_MASK;
  130. + enetsw_writeb(priv, val, ENETSW_SWMODE_REG);
  131. +
  132. + /* enable jumbo on all ports */
  133. + enetsw_writel(priv, 0x1ff, ENETSW_JMBCTL_PORT_REG);
  134. + enetsw_writew(priv, 9728, ENETSW_JMBCTL_MAXSIZE_REG);
  135. +
  136. + for (i = 0; i < priv->num_ports; i++) {
  137. + struct bcm63xx_enetsw_port *port = &priv->used_ports[i];
  138. +
  139. + if (!port->used)
  140. + continue;
  141. +
  142. + num_ports++;
  143. + port_mask |= BIT(i);
  144. + }
  145. +
  146. + /* only register if there is more than one external port */
  147. + if (num_ports > 1)
  148. + bcmenet_switch_register(priv, port_mask);
  149. +
  150. return 0;
  151. out_put_clk:
  152. @@ -2839,6 +2894,9 @@ static int bcm_enetsw_remove(struct plat
  153. priv = netdev_priv(dev);
  154. unregister_netdev(dev);
  155. + /* remove switch */
  156. + bcmenet_switch_unregister(priv);
  157. +
  158. /* release device resources */
  159. iounmap(priv->base);
  160. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);