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_uc_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_uc_del(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_uc_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_uc_del(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_uc_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_uc_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_uc_del(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 168 if (p->phy != NULL) 169 return phy_mii_ioctl(p->phy, ifr, cmd); 170 171 return -EOPNOTSUPP; 172 } 173 174 175 /* ethtool operations *******************************************************/ 176 static int 177 dsa_slave_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 178 { 179 struct dsa_slave_priv *p = netdev_priv(dev); 180 int err; 181 182 err = -EOPNOTSUPP; 183 if (p->phy != NULL) { 184 err = phy_read_status(p->phy); 185 if (err == 0) 186 err = phy_ethtool_gset(p->phy, cmd); 187 } 188 189 return err; 190 } 191 192 static int 193 dsa_slave_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) 194 { 195 struct dsa_slave_priv *p = netdev_priv(dev); 196 197 if (p->phy != NULL) 198 return phy_ethtool_sset(p->phy, cmd); 199 200 return -EOPNOTSUPP; 201 } 202 203 static void dsa_slave_get_drvinfo(struct net_device *dev, 204 struct ethtool_drvinfo *drvinfo) 205 { 206 strncpy(drvinfo->driver, "dsa", 32); 207 strncpy(drvinfo->version, dsa_driver_version, 32); 208 strncpy(drvinfo->fw_version, "N/A", 32); 209 strncpy(drvinfo->bus_info, "platform", 32); 210 } 211 212 static int dsa_slave_nway_reset(struct net_device *dev) 213 { 214 struct dsa_slave_priv *p = netdev_priv(dev); 215 216 if (p->phy != NULL) 217 return genphy_restart_aneg(p->phy); 218 219 return -EOPNOTSUPP; 220 } 221 222 static u32 dsa_slave_get_link(struct net_device *dev) 223 { 224 struct dsa_slave_priv *p = netdev_priv(dev); 225 226 if (p->phy != NULL) { 227 genphy_update_link(p->phy); 228 return p->phy->link; 229 } 230 231 return -EOPNOTSUPP; 232 } 233 234 static void dsa_slave_get_strings(struct net_device *dev, 235 uint32_t stringset, uint8_t *data) 236 { 237 struct dsa_slave_priv *p = netdev_priv(dev); 238 struct dsa_switch *ds = p->parent; 239 240 if (stringset == ETH_SS_STATS) { 241 int len = ETH_GSTRING_LEN; 242 243 strncpy(data, "tx_packets", len); 244 strncpy(data + len, "tx_bytes", len); 245 strncpy(data + 2 * len, "rx_packets", len); 246 strncpy(data + 3 * len, "rx_bytes", len); 247 if (ds->drv->get_strings != NULL) 248 ds->drv->get_strings(ds, p->port, data + 4 * len); 249 } 250 } 251 252 static void dsa_slave_get_ethtool_stats(struct net_device *dev, 253 struct ethtool_stats *stats, 254 uint64_t *data) 255 { 256 struct dsa_slave_priv *p = netdev_priv(dev); 257 struct dsa_switch *ds = p->parent; 258 259 data[0] = p->dev->stats.tx_packets; 260 data[1] = p->dev->stats.tx_bytes; 261 data[2] = p->dev->stats.rx_packets; 262 data[3] = p->dev->stats.rx_bytes; 263 if (ds->drv->get_ethtool_stats != NULL) 264 ds->drv->get_ethtool_stats(ds, p->port, data + 4); 265 } 266 267 static int dsa_slave_get_sset_count(struct net_device *dev, int sset) 268 { 269 struct dsa_slave_priv *p = netdev_priv(dev); 270 struct dsa_switch *ds = p->parent; 271 272 if (sset == ETH_SS_STATS) { 273 int count; 274 275 count = 4; 276 if (ds->drv->get_sset_count != NULL) 277 count += ds->drv->get_sset_count(ds); 278 279 return count; 280 } 281 282 return -EOPNOTSUPP; 283 } 284 285 static const struct ethtool_ops dsa_slave_ethtool_ops = { 286 .get_settings = dsa_slave_get_settings, 287 .set_settings = dsa_slave_set_settings, 288 .get_drvinfo = dsa_slave_get_drvinfo, 289 .nway_reset = dsa_slave_nway_reset, 290 .get_link = dsa_slave_get_link, 291 .set_sg = ethtool_op_set_sg, 292 .get_strings = dsa_slave_get_strings, 293 .get_ethtool_stats = dsa_slave_get_ethtool_stats, 294 .get_sset_count = dsa_slave_get_sset_count, 295 }; 296 297 #ifdef CONFIG_NET_DSA_TAG_DSA 298 static const struct net_device_ops dsa_netdev_ops = { 299 .ndo_init = dsa_slave_init, 300 .ndo_open = dsa_slave_open, 301 .ndo_stop = dsa_slave_close, 302 .ndo_start_xmit = dsa_xmit, 303 .ndo_change_rx_flags = dsa_slave_change_rx_flags, 304 .ndo_set_rx_mode = dsa_slave_set_rx_mode, 305 .ndo_set_multicast_list = dsa_slave_set_rx_mode, 306 .ndo_set_mac_address = dsa_slave_set_mac_address, 307 .ndo_do_ioctl = dsa_slave_ioctl, 308 }; 309 #endif 310 #ifdef CONFIG_NET_DSA_TAG_EDSA 311 static const struct net_device_ops edsa_netdev_ops = { 312 .ndo_init = dsa_slave_init, 313 .ndo_open = dsa_slave_open, 314 .ndo_stop = dsa_slave_close, 315 .ndo_start_xmit = edsa_xmit, 316 .ndo_change_rx_flags = dsa_slave_change_rx_flags, 317 .ndo_set_rx_mode = dsa_slave_set_rx_mode, 318 .ndo_set_multicast_list = dsa_slave_set_rx_mode, 319 .ndo_set_mac_address = dsa_slave_set_mac_address, 320 .ndo_do_ioctl = dsa_slave_ioctl, 321 }; 322 #endif 323 #ifdef CONFIG_NET_DSA_TAG_TRAILER 324 static const struct net_device_ops trailer_netdev_ops = { 325 .ndo_init = dsa_slave_init, 326 .ndo_open = dsa_slave_open, 327 .ndo_stop = dsa_slave_close, 328 .ndo_start_xmit = trailer_xmit, 329 .ndo_change_rx_flags = dsa_slave_change_rx_flags, 330 .ndo_set_rx_mode = dsa_slave_set_rx_mode, 331 .ndo_set_multicast_list = dsa_slave_set_rx_mode, 332 .ndo_set_mac_address = dsa_slave_set_mac_address, 333 .ndo_do_ioctl = dsa_slave_ioctl, 334 }; 335 #endif 336 337 /* slave device setup *******************************************************/ 338 struct net_device * 339 dsa_slave_create(struct dsa_switch *ds, struct device *parent, 340 int port, char *name) 341 { 342 struct net_device *master = ds->dst->master_netdev; 343 struct net_device *slave_dev; 344 struct dsa_slave_priv *p; 345 int ret; 346 347 slave_dev = alloc_netdev(sizeof(struct dsa_slave_priv), 348 name, ether_setup); 349 if (slave_dev == NULL) 350 return slave_dev; 351 352 slave_dev->features = master->vlan_features; 353 SET_ETHTOOL_OPS(slave_dev, &dsa_slave_ethtool_ops); 354 memcpy(slave_dev->dev_addr, master->dev_addr, ETH_ALEN); 355 slave_dev->tx_queue_len = 0; 356 357 switch (ds->dst->tag_protocol) { 358 #ifdef CONFIG_NET_DSA_TAG_DSA 359 case htons(ETH_P_DSA): 360 slave_dev->netdev_ops = &dsa_netdev_ops; 361 break; 362 #endif 363 #ifdef CONFIG_NET_DSA_TAG_EDSA 364 case htons(ETH_P_EDSA): 365 slave_dev->netdev_ops = &edsa_netdev_ops; 366 break; 367 #endif 368 #ifdef CONFIG_NET_DSA_TAG_TRAILER 369 case htons(ETH_P_TRAILER): 370 slave_dev->netdev_ops = &trailer_netdev_ops; 371 break; 372 #endif 373 default: 374 BUG(); 375 } 376 377 SET_NETDEV_DEV(slave_dev, parent); 378 slave_dev->vlan_features = master->vlan_features; 379 380 p = netdev_priv(slave_dev); 381 p->dev = slave_dev; 382 p->parent = ds; 383 p->port = port; 384 p->phy = ds->slave_mii_bus->phy_map[port]; 385 386 ret = register_netdev(slave_dev); 387 if (ret) { 388 printk(KERN_ERR "%s: error %d registering interface %s\n", 389 master->name, ret, slave_dev->name); 390 free_netdev(slave_dev); 391 return NULL; 392 } 393 394 netif_carrier_off(slave_dev); 395 396 if (p->phy != NULL) { 397 phy_attach(slave_dev, dev_name(&p->phy->dev), 398 0, PHY_INTERFACE_MODE_GMII); 399 400 p->phy->autoneg = AUTONEG_ENABLE; 401 p->phy->speed = 0; 402 p->phy->duplex = 0; 403 p->phy->advertising = p->phy->supported | ADVERTISED_Autoneg; 404 phy_start_aneg(p->phy); 405 } 406 407 return slave_dev; 408 } 409