slave.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. /*
  2. * net/dsa/slave.c - Slave device handling
  3. * Copyright (c) 2008 Marvell Semiconductor
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. */
  10. #include <linux/list.h>
  11. #include <linux/netdevice.h>
  12. #include <linux/etherdevice.h>
  13. #include <linux/phy.h>
  14. #include "dsa_priv.h"
  15. /* slave mii_bus handling ***************************************************/
  16. static int dsa_slave_phy_read(struct mii_bus *bus, int addr, int reg)
  17. {
  18. struct dsa_switch *ds = bus->priv;
  19. if (ds->valid_port_mask & (1 << addr))
  20. return ds->drv->phy_read(ds, addr, reg);
  21. return 0xffff;
  22. }
  23. static int dsa_slave_phy_write(struct mii_bus *bus, int addr, int reg, u16 val)
  24. {
  25. struct dsa_switch *ds = bus->priv;
  26. if (ds->valid_port_mask & (1 << addr))
  27. return ds->drv->phy_write(ds, addr, reg, val);
  28. return 0;
  29. }
  30. void dsa_slave_mii_bus_init(struct dsa_switch *ds)
  31. {
  32. ds->slave_mii_bus->priv = (void *)ds;
  33. ds->slave_mii_bus->name = "dsa slave smi";
  34. ds->slave_mii_bus->read = dsa_slave_phy_read;
  35. ds->slave_mii_bus->write = dsa_slave_phy_write;
  36. snprintf(ds->slave_mii_bus->id, MII_BUS_ID_SIZE, "%s:%.2x",
  37. ds->master_mii_bus->id, ds->pd->sw_addr);
  38. ds->slave_mii_bus->parent = &(ds->master_mii_bus->dev);
  39. }
  40. /* slave device handling ****************************************************/
  41. static int dsa_slave_open(struct net_device *dev)
  42. {
  43. struct dsa_slave_priv *p = netdev_priv(dev);
  44. struct net_device *master = p->parent->master_netdev;
  45. int err;
  46. if (!(master->flags & IFF_UP))
  47. return -ENETDOWN;
  48. if (compare_ether_addr(dev->dev_addr, master->dev_addr)) {
  49. err = dev_unicast_add(master, dev->dev_addr, ETH_ALEN);
  50. if (err < 0)
  51. goto out;
  52. }
  53. if (dev->flags & IFF_ALLMULTI) {
  54. err = dev_set_allmulti(master, 1);
  55. if (err < 0)
  56. goto del_unicast;
  57. }
  58. if (dev->flags & IFF_PROMISC) {
  59. err = dev_set_promiscuity(master, 1);
  60. if (err < 0)
  61. goto clear_allmulti;
  62. }
  63. return 0;
  64. clear_allmulti:
  65. if (dev->flags & IFF_ALLMULTI)
  66. dev_set_allmulti(master, -1);
  67. del_unicast:
  68. if (compare_ether_addr(dev->dev_addr, master->dev_addr))
  69. dev_unicast_delete(master, dev->dev_addr, ETH_ALEN);
  70. out:
  71. return err;
  72. }
  73. static int dsa_slave_close(struct net_device *dev)
  74. {
  75. struct dsa_slave_priv *p = netdev_priv(dev);
  76. struct net_device *master = p->parent->master_netdev;
  77. dev_mc_unsync(master, dev);
  78. dev_unicast_unsync(master, dev);
  79. if (dev->flags & IFF_ALLMULTI)
  80. dev_set_allmulti(master, -1);
  81. if (dev->flags & IFF_PROMISC)
  82. dev_set_promiscuity(master, -1);
  83. if (compare_ether_addr(dev->dev_addr, master->dev_addr))
  84. dev_unicast_delete(master, dev->dev_addr, ETH_ALEN);
  85. return 0;
  86. }
  87. static void dsa_slave_change_rx_flags(struct net_device *dev, int change)
  88. {
  89. struct dsa_slave_priv *p = netdev_priv(dev);
  90. struct net_device *master = p->parent->master_netdev;
  91. if (change & IFF_ALLMULTI)
  92. dev_set_allmulti(master, dev->flags & IFF_ALLMULTI ? 1 : -1);
  93. if (change & IFF_PROMISC)
  94. dev_set_promiscuity(master, dev->flags & IFF_PROMISC ? 1 : -1);
  95. }
  96. static void dsa_slave_set_rx_mode(struct net_device *dev)
  97. {
  98. struct dsa_slave_priv *p = netdev_priv(dev);
  99. struct net_device *master = p->parent->master_netdev;
  100. dev_mc_sync(master, dev);
  101. dev_unicast_sync(master, dev);
  102. }
  103. static int dsa_slave_set_mac_address(struct net_device *dev, void *a)
  104. {
  105. struct dsa_slave_priv *p = netdev_priv(dev);
  106. struct net_device *master = p->parent->master_netdev;
  107. struct sockaddr *addr = a;
  108. int err;
  109. if (!is_valid_ether_addr(addr->sa_data))
  110. return -EADDRNOTAVAIL;
  111. if (!(dev->flags & IFF_UP))
  112. goto out;
  113. if (compare_ether_addr(addr->sa_data, master->dev_addr)) {
  114. err = dev_unicast_add(master, addr->sa_data, ETH_ALEN);
  115. if (err < 0)
  116. return err;
  117. }
  118. if (compare_ether_addr(dev->dev_addr, master->dev_addr))
  119. dev_unicast_delete(master, dev->dev_addr, ETH_ALEN);
  120. out:
  121. memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
  122. return 0;
  123. }
  124. static int dsa_slave_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
  125. {
  126. struct dsa_slave_priv *p = netdev_priv(dev);
  127. struct mii_ioctl_data *mii_data = if_mii(ifr);
  128. if (p->phy != NULL)
  129. return phy_mii_ioctl(p->phy, mii_data, cmd);
  130. return -EOPNOTSUPP;
  131. }
  132. /* ethtool operations *******************************************************/
  133. static int
  134. dsa_slave_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
  135. {
  136. struct dsa_slave_priv *p = netdev_priv(dev);
  137. int err;
  138. err = -EOPNOTSUPP;
  139. if (p->phy != NULL) {
  140. err = phy_read_status(p->phy);
  141. if (err == 0)
  142. err = phy_ethtool_gset(p->phy, cmd);
  143. }
  144. return err;
  145. }
  146. static int
  147. dsa_slave_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
  148. {
  149. struct dsa_slave_priv *p = netdev_priv(dev);
  150. if (p->phy != NULL)
  151. return phy_ethtool_sset(p->phy, cmd);
  152. return -EOPNOTSUPP;
  153. }
  154. static void dsa_slave_get_drvinfo(struct net_device *dev,
  155. struct ethtool_drvinfo *drvinfo)
  156. {
  157. strncpy(drvinfo->driver, "dsa", 32);
  158. strncpy(drvinfo->version, dsa_driver_version, 32);
  159. strncpy(drvinfo->fw_version, "N/A", 32);
  160. strncpy(drvinfo->bus_info, "platform", 32);
  161. }
  162. static int dsa_slave_nway_reset(struct net_device *dev)
  163. {
  164. struct dsa_slave_priv *p = netdev_priv(dev);
  165. if (p->phy != NULL)
  166. return genphy_restart_aneg(p->phy);
  167. return -EOPNOTSUPP;
  168. }
  169. static u32 dsa_slave_get_link(struct net_device *dev)
  170. {
  171. struct dsa_slave_priv *p = netdev_priv(dev);
  172. if (p->phy != NULL) {
  173. genphy_update_link(p->phy);
  174. return p->phy->link;
  175. }
  176. return -EOPNOTSUPP;
  177. }
  178. static void dsa_slave_get_strings(struct net_device *dev,
  179. uint32_t stringset, uint8_t *data)
  180. {
  181. struct dsa_slave_priv *p = netdev_priv(dev);
  182. struct dsa_switch *ds = p->parent;
  183. if (stringset == ETH_SS_STATS) {
  184. int len = ETH_GSTRING_LEN;
  185. strncpy(data, "tx_packets", len);
  186. strncpy(data + len, "tx_bytes", len);
  187. strncpy(data + 2 * len, "rx_packets", len);
  188. strncpy(data + 3 * len, "rx_bytes", len);
  189. if (ds->drv->get_strings != NULL)
  190. ds->drv->get_strings(ds, p->port, data + 4 * len);
  191. }
  192. }
  193. static void dsa_slave_get_ethtool_stats(struct net_device *dev,
  194. struct ethtool_stats *stats,
  195. uint64_t *data)
  196. {
  197. struct dsa_slave_priv *p = netdev_priv(dev);
  198. struct dsa_switch *ds = p->parent;
  199. data[0] = p->dev->stats.tx_packets;
  200. data[1] = p->dev->stats.tx_bytes;
  201. data[2] = p->dev->stats.rx_packets;
  202. data[3] = p->dev->stats.rx_bytes;
  203. if (ds->drv->get_ethtool_stats != NULL)
  204. ds->drv->get_ethtool_stats(ds, p->port, data + 4);
  205. }
  206. static int dsa_slave_get_sset_count(struct net_device *dev, int sset)
  207. {
  208. struct dsa_slave_priv *p = netdev_priv(dev);
  209. struct dsa_switch *ds = p->parent;
  210. if (sset == ETH_SS_STATS) {
  211. int count;
  212. count = 4;
  213. if (ds->drv->get_sset_count != NULL)
  214. count += ds->drv->get_sset_count(ds);
  215. return count;
  216. }
  217. return -EOPNOTSUPP;
  218. }
  219. static const struct ethtool_ops dsa_slave_ethtool_ops = {
  220. .get_settings = dsa_slave_get_settings,
  221. .set_settings = dsa_slave_set_settings,
  222. .get_drvinfo = dsa_slave_get_drvinfo,
  223. .nway_reset = dsa_slave_nway_reset,
  224. .get_link = dsa_slave_get_link,
  225. .set_sg = ethtool_op_set_sg,
  226. .get_strings = dsa_slave_get_strings,
  227. .get_ethtool_stats = dsa_slave_get_ethtool_stats,
  228. .get_sset_count = dsa_slave_get_sset_count,
  229. };
  230. /* slave device setup *******************************************************/
  231. struct net_device *
  232. dsa_slave_create(struct dsa_switch *ds, struct device *parent,
  233. int port, char *name)
  234. {
  235. struct net_device *master = ds->master_netdev;
  236. struct net_device *slave_dev;
  237. struct dsa_slave_priv *p;
  238. int ret;
  239. slave_dev = alloc_netdev(sizeof(struct dsa_slave_priv),
  240. name, ether_setup);
  241. if (slave_dev == NULL)
  242. return slave_dev;
  243. slave_dev->features = master->vlan_features;
  244. SET_ETHTOOL_OPS(slave_dev, &dsa_slave_ethtool_ops);
  245. memcpy(slave_dev->dev_addr, master->dev_addr, ETH_ALEN);
  246. slave_dev->tx_queue_len = 0;
  247. switch (ds->tag_protocol) {
  248. #ifdef CONFIG_NET_DSA_TAG_DSA
  249. case htons(ETH_P_DSA):
  250. slave_dev->hard_start_xmit = dsa_xmit;
  251. break;
  252. #endif
  253. #ifdef CONFIG_NET_DSA_TAG_EDSA
  254. case htons(ETH_P_EDSA):
  255. slave_dev->hard_start_xmit = edsa_xmit;
  256. break;
  257. #endif
  258. #ifdef CONFIG_NET_DSA_TAG_TRAILER
  259. case htons(ETH_P_TRAILER):
  260. slave_dev->hard_start_xmit = trailer_xmit;
  261. break;
  262. #endif
  263. default:
  264. BUG();
  265. }
  266. slave_dev->open = dsa_slave_open;
  267. slave_dev->stop = dsa_slave_close;
  268. slave_dev->change_rx_flags = dsa_slave_change_rx_flags;
  269. slave_dev->set_rx_mode = dsa_slave_set_rx_mode;
  270. slave_dev->set_multicast_list = dsa_slave_set_rx_mode;
  271. slave_dev->set_mac_address = dsa_slave_set_mac_address;
  272. slave_dev->do_ioctl = dsa_slave_ioctl;
  273. SET_NETDEV_DEV(slave_dev, parent);
  274. slave_dev->vlan_features = master->vlan_features;
  275. p = netdev_priv(slave_dev);
  276. p->dev = slave_dev;
  277. p->parent = ds;
  278. p->port = port;
  279. p->phy = ds->slave_mii_bus->phy_map[port];
  280. ret = register_netdev(slave_dev);
  281. if (ret) {
  282. printk(KERN_ERR "%s: error %d registering interface %s\n",
  283. master->name, ret, slave_dev->name);
  284. free_netdev(slave_dev);
  285. return NULL;
  286. }
  287. netif_carrier_off(slave_dev);
  288. if (p->phy != NULL) {
  289. phy_attach(slave_dev, p->phy->dev.bus_id,
  290. 0, PHY_INTERFACE_MODE_GMII);
  291. p->phy->autoneg = AUTONEG_ENABLE;
  292. p->phy->speed = 0;
  293. p->phy->duplex = 0;
  294. p->phy->advertising = p->phy->supported | ADVERTISED_Autoneg;
  295. phy_start_aneg(p->phy);
  296. }
  297. return slave_dev;
  298. }