1 /* 2 * net/dsa/slave.c - Slave device handling 3 * Copyright (c) 2008-2009 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 11 #include <linux/list.h> 12 #include <linux/netdevice.h> 13 #include <linux/etherdevice.h> 14 #include <linux/phy.h> 15 #include "dsa_priv.h" 16 17 /* slave mii_bus handling ***************************************************/ 18 static int dsa_slave_phy_read(struct mii_bus *bus, int addr, int reg) 19 { 20 struct dsa_switch *ds = bus->priv; 21 22 if (ds->phys_port_mask & (1 << addr)) 23 return ds->drv->phy_read(ds, addr, reg); 24 25 return 0xffff; 26 } 27 28 static int dsa_slave_phy_write(struct mii_bus *bus, int addr, int reg, u16 val) 29 { 30 struct dsa_switch *ds = bus->priv; 31 32 if (ds->phys_port_mask & (1 << addr)) 33 return ds->drv->phy_write(ds, addr, reg, val); 34 35 return 0; 36 } 37 38 void dsa_slave_mii_bus_init(struct dsa_switch *ds) 39 { 40 ds->slave_mii_bus->priv = (void *)ds; 41 ds->slave_mii_bus->name = "dsa slave smi"; 42 ds->slave_mii_bus->read = dsa_slave_phy_read; 43 ds->slave_mii_bus->write = dsa_slave_phy_write; 44 snprintf(ds->slave_mii_bus->id, MII_BUS_ID_SIZE, "%s:%.2x", 45 ds->master_mii_bus->id, ds->pd->sw_addr); 46 ds->slave_mii_bus->parent = &ds->master_mii_bus->dev; 47 } 48 49 50 /* slave device handling ****************************************************/ 51 static int dsa_slave_init(struct net_device *dev) 52 { 53 struct dsa_slave_priv *p = netdev_priv(dev); 54 55 dev->iflink = p->parent->dst->master_netdev->ifindex; 56 57 return 0; 58 } 59 60 static int dsa_slave_open(struct net_device *dev) 61 { 62 struct dsa_slave_priv *p = netdev_priv(dev); 63 struct net_device *master = p->parent->dst->master_netdev; 64 int err; 65 66 if (!(master->flags & IFF_UP)) 67 return -ENETDOWN; 68 69 if (compare_ether_addr(dev->dev_addr, master->dev_addr)) { 70 err = dev_unicast_add(master, dev->dev_addr); 71 if (err < 0) 72 goto out; 73 } 74 75 if (dev->flags & IFF_ALLMULTI) { 76 err = dev_set_allmulti(master, 1); 77 if (err < 0) 78 goto del_unicast; 79 } 80 if (dev->flags & IFF_PROMISC) { 81 err = dev_set_promiscuity(master, 1); 82 if (err < 0) 83 goto clear_allmulti; 84 } 85 86 return 0; 87 88 clear_allmulti: 89 if (dev->flags & IFF_ALLMULTI) 90 dev_set_allmulti(master, -1); 91 del_unicast: 92 if (compare_ether_addr(dev->dev_addr, master->dev_addr)) 93 dev_unicast_delete(master, dev->dev_addr); 94 out: 95 return err; 96 } 97 98 static int dsa_slave_close(struct net_device *dev) 99 { 100 struct dsa_slave_priv *p = netdev_priv(dev); 101 struct net_device *master = p->parent->dst->master_netdev; 102 103 dev_mc_unsync(master, dev); 104 dev_unicast_unsync(master, dev); 105 if (dev->flags & IFF_ALLMULTI) 106 dev_set_allmulti(master, -1); 107 if (dev->flags & IFF_PROMISC) 108 dev_set_promiscuity(master, -1); 109 110 if (compare_ether_addr(dev->dev_addr, master->dev_addr)) 111 dev_unicast_delete(master, dev->dev_addr); 112 113 return 0; 114 } 115 116 static void dsa_slave_change_rx_flags(struct net_device *dev, int change) 117 { 118 struct dsa_slave_priv *p = netdev_priv(dev); 119 struct net_device *master = p->parent->dst->master_netdev; 120 121 if (change & IFF_ALLMULTI) 122 dev_set_allmulti(master, dev->flags & IFF_ALLMULTI ? 1 : -1); 123 if (change & IFF_PROMISC) 124 dev_set_promiscuity(master, dev->flags & IFF_PROMISC ? 1 : -1); 125 } 126 127 static void dsa_slave_set_rx_mode(struct net_device *dev) 128 { 129 struct dsa_slave_priv *p = netdev_priv(dev); 130 struct net_device *master = p->parent->dst->master_netdev; 131 132 dev_mc_sync(master, dev); 133 dev_unicast_sync(master, dev); 134 } 135 136 static int dsa_slave_set_mac_address(struct net_device *dev, void *a) 137 { 138 struct dsa_slave_priv *p = netdev_priv(dev); 139 struct net_device *master = p->parent->dst->master_netdev; 140 struct sockaddr *addr = a; 141 int err; 142 143 if (!is_valid_ether_addr(addr->sa_data)) 144 return -EADDRNOTAVAIL; 145 146 if (!(dev->flags & IFF_UP)) 147 goto out; 148 149 if (compare_ether_addr(addr->sa_data, master->dev_addr)) { 150 err = dev_unicast_add(master, addr->sa_data); 151 if (err < 0) 152 return err; 153 } 154 155 if (compare_ether_addr(dev->dev_addr, master->dev_addr)) 156 dev_unicast_delete(master, dev->dev_addr); 157 158 out: 159 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); 160 161 return 0; 162 } 163 164 static int dsa_slave_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 165 { 166 struct dsa_slave_priv *p = netdev_priv(dev); 167 struct mii_ioctl_data *mii_data = if_mii(ifr); 168 169 if (p->phy != NULL) 170 return phy_mii_ioctl(p->phy, mii_data, cmd); 171 172 return -EOPNOTSUPP; 173 } 174 175 176 /* ethtool operations *******************************************************/ 177 static int 178 dsa_slave_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 179 { 180 struct dsa_slave_priv *p = netdev_priv(dev); 181 int err; 182 183 err = -EOPNOTSUPP; 184 if (p->phy != NULL) { 185 err = phy_read_status(p->phy); 186 if (err == 0) 187 err = phy_ethtool_gset(p->phy, cmd); 188 } 189 190 return err; 191 } 192 193 static int 194 dsa_slave_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) 195 { 196 struct dsa_slave_priv *p = netdev_priv(dev); 197 198 if (p->phy != NULL) 199 return phy_ethtool_sset(p->phy, cmd); 200 201 return -EOPNOTSUPP; 202 } 203 204 static void dsa_slave_get_drvinfo(struct net_device *dev, 205 struct ethtool_drvinfo *drvinfo) 206 { 207 strncpy(drvinfo->driver, "dsa", 32); 208 strncpy(drvinfo->version, dsa_driver_version, 32); 209 strncpy(drvinfo->fw_version, "N/A", 32); 210 strncpy(drvinfo->bus_info, "platform", 32); 211 } 212 213 static int dsa_slave_nway_reset(struct net_device *dev) 214 { 215 struct dsa_slave_priv *p = netdev_priv(dev); 216 217 if (p->phy != NULL) 218 return genphy_restart_aneg(p->phy); 219 220 return -EOPNOTSUPP; 221 } 222 223 static u32 dsa_slave_get_link(struct net_device *dev) 224 { 225 struct dsa_slave_priv *p = netdev_priv(dev); 226 227 if (p->phy != NULL) { 228 genphy_update_link(p->phy); 229 return p->phy->link; 230 } 231 232 return -EOPNOTSUPP; 233 } 234 235 static void dsa_slave_get_strings(struct net_device *dev, 236 uint32_t stringset, uint8_t *data) 237 { 238 struct dsa_slave_priv *p = netdev_priv(dev); 239 struct dsa_switch *ds = p->parent; 240 241 if (stringset == ETH_SS_STATS) { 242 int len = ETH_GSTRING_LEN; 243 244 strncpy(data, "tx_packets", len); 245 strncpy(data + len, "tx_bytes", len); 246 strncpy(data + 2 * len, "rx_packets", len); 247 strncpy(data + 3 * len, "rx_bytes", len); 248 if (ds->drv->get_strings != NULL) 249 ds->drv->get_strings(ds, p->port, data + 4 * len); 250 } 251 } 252 253 static void dsa_slave_get_ethtool_stats(struct net_device *dev, 254 struct ethtool_stats *stats, 255 uint64_t *data) 256 { 257 struct dsa_slave_priv *p = netdev_priv(dev); 258 struct dsa_switch *ds = p->parent; 259 260 data[0] = p->dev->stats.tx_packets; 261 data[1] = p->dev->stats.tx_bytes; 262 data[2] = p->dev->stats.rx_packets; 263 data[3] = p->dev->stats.rx_bytes; 264 if (ds->drv->get_ethtool_stats != NULL) 265 ds->drv->get_ethtool_stats(ds, p->port, data + 4); 266 } 267 268 static int dsa_slave_get_sset_count(struct net_device *dev, int sset) 269 { 270 struct dsa_slave_priv *p = netdev_priv(dev); 271 struct dsa_switch *ds = p->parent; 272 273 if (sset == ETH_SS_STATS) { 274 int count; 275 276 count = 4; 277 if (ds->drv->get_sset_count != NULL) 278 count += ds->drv->get_sset_count(ds); 279 280 return count; 281 } 282 283 return -EOPNOTSUPP; 284 } 285 286 static const struct ethtool_ops dsa_slave_ethtool_ops = { 287 .get_settings = dsa_slave_get_settings, 288 .set_settings = dsa_slave_set_settings, 289 .get_drvinfo = dsa_slave_get_drvinfo, 290 .nway_reset = dsa_slave_nway_reset, 291 .get_link = dsa_slave_get_link, 292 .set_sg = ethtool_op_set_sg, 293 .get_strings = dsa_slave_get_strings, 294 .get_ethtool_stats = dsa_slave_get_ethtool_stats, 295 .get_sset_count = dsa_slave_get_sset_count, 296 }; 297 298 #ifdef CONFIG_NET_DSA_TAG_DSA 299 static const struct net_device_ops dsa_netdev_ops = { 300 .ndo_init = dsa_slave_init, 301 .ndo_open = dsa_slave_open, 302 .ndo_stop = dsa_slave_close, 303 .ndo_start_xmit = dsa_xmit, 304 .ndo_change_rx_flags = dsa_slave_change_rx_flags, 305 .ndo_set_rx_mode = dsa_slave_set_rx_mode, 306 .ndo_set_multicast_list = dsa_slave_set_rx_mode, 307 .ndo_set_mac_address = dsa_slave_set_mac_address, 308 .ndo_do_ioctl = dsa_slave_ioctl, 309 }; 310 #endif 311 #ifdef CONFIG_NET_DSA_TAG_EDSA 312 static const struct net_device_ops edsa_netdev_ops = { 313 .ndo_init = dsa_slave_init, 314 .ndo_open = dsa_slave_open, 315 .ndo_stop = dsa_slave_close, 316 .ndo_start_xmit = edsa_xmit, 317 .ndo_change_rx_flags = dsa_slave_change_rx_flags, 318 .ndo_set_rx_mode = dsa_slave_set_rx_mode, 319 .ndo_set_multicast_list = dsa_slave_set_rx_mode, 320 .ndo_set_mac_address = dsa_slave_set_mac_address, 321 .ndo_do_ioctl = dsa_slave_ioctl, 322 }; 323 #endif 324 #ifdef CONFIG_NET_DSA_TAG_TRAILER 325 static const struct net_device_ops trailer_netdev_ops = { 326 .ndo_init = dsa_slave_init, 327 .ndo_open = dsa_slave_open, 328 .ndo_stop = dsa_slave_close, 329 .ndo_start_xmit = trailer_xmit, 330 .ndo_change_rx_flags = dsa_slave_change_rx_flags, 331 .ndo_set_rx_mode = dsa_slave_set_rx_mode, 332 .ndo_set_multicast_list = dsa_slave_set_rx_mode, 333 .ndo_set_mac_address = dsa_slave_set_mac_address, 334 .ndo_do_ioctl = dsa_slave_ioctl, 335 }; 336 #endif 337 338 /* slave device setup *******************************************************/ 339 struct net_device * 340 dsa_slave_create(struct dsa_switch *ds, struct device *parent, 341 int port, char *name) 342 { 343 struct net_device *master = ds->dst->master_netdev; 344 struct net_device *slave_dev; 345 struct dsa_slave_priv *p; 346 int ret; 347 348 slave_dev = alloc_netdev(sizeof(struct dsa_slave_priv), 349 name, ether_setup); 350 if (slave_dev == NULL) 351 return slave_dev; 352 353 slave_dev->features = master->vlan_features; 354 SET_ETHTOOL_OPS(slave_dev, &dsa_slave_ethtool_ops); 355 memcpy(slave_dev->dev_addr, master->dev_addr, ETH_ALEN); 356 slave_dev->tx_queue_len = 0; 357 358 switch (ds->dst->tag_protocol) { 359 #ifdef CONFIG_NET_DSA_TAG_DSA 360 case htons(ETH_P_DSA): 361 slave_dev->netdev_ops = &dsa_netdev_ops; 362 break; 363 #endif 364 #ifdef CONFIG_NET_DSA_TAG_EDSA 365 case htons(ETH_P_EDSA): 366 slave_dev->netdev_ops = &edsa_netdev_ops; 367 break; 368 #endif 369 #ifdef CONFIG_NET_DSA_TAG_TRAILER 370 case htons(ETH_P_TRAILER): 371 slave_dev->netdev_ops = &trailer_netdev_ops; 372 break; 373 #endif 374 default: 375 BUG(); 376 } 377 378 SET_NETDEV_DEV(slave_dev, parent); 379 slave_dev->vlan_features = master->vlan_features; 380 381 p = netdev_priv(slave_dev); 382 p->dev = slave_dev; 383 p->parent = ds; 384 p->port = port; 385 p->phy = ds->slave_mii_bus->phy_map[port]; 386 387 ret = register_netdev(slave_dev); 388 if (ret) { 389 printk(KERN_ERR "%s: error %d registering interface %s\n", 390 master->name, ret, slave_dev->name); 391 free_netdev(slave_dev); 392 return NULL; 393 } 394 395 netif_carrier_off(slave_dev); 396 397 if (p->phy != NULL) { 398 phy_attach(slave_dev, dev_name(&p->phy->dev), 399 0, PHY_INTERFACE_MODE_GMII); 400 401 p->phy->autoneg = AUTONEG_ENABLE; 402 p->phy->speed = 0; 403 p->phy->duplex = 0; 404 p->phy->advertising = p->phy->supported | ADVERTISED_Autoneg; 405 phy_start_aneg(p->phy); 406 } 407 408 return slave_dev; 409 } 410