2 * net/dsa/slave.c - Slave device handling
3 * Copyright (c) 2008 Marvell Semiconductor
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.
11 #include <linux/list.h>
12 #include <linux/netdevice.h>
13 #include <linux/phy.h>
16 /* slave mii_bus handling ***************************************************/
17 static int dsa_slave_phy_read(struct mii_bus
*bus
, int addr
, int reg
)
19 struct dsa_switch
*ds
= bus
->priv
;
21 if (ds
->valid_port_mask
& (1 << addr
))
22 return ds
->drv
->phy_read(ds
, addr
, reg
);
27 static int dsa_slave_phy_write(struct mii_bus
*bus
, int addr
, int reg
, u16 val
)
29 struct dsa_switch
*ds
= bus
->priv
;
31 if (ds
->valid_port_mask
& (1 << addr
))
32 return ds
->drv
->phy_write(ds
, addr
, reg
, val
);
37 void dsa_slave_mii_bus_init(struct dsa_switch
*ds
)
39 ds
->slave_mii_bus
->priv
= (void *)ds
;
40 ds
->slave_mii_bus
->name
= "dsa slave smi";
41 ds
->slave_mii_bus
->read
= dsa_slave_phy_read
;
42 ds
->slave_mii_bus
->write
= dsa_slave_phy_write
;
43 snprintf(ds
->slave_mii_bus
->id
, MII_BUS_ID_SIZE
, "%s:%.2x",
44 ds
->master_mii_bus
->id
, ds
->pd
->sw_addr
);
45 ds
->slave_mii_bus
->parent
= &(ds
->master_mii_bus
->dev
);
49 /* slave device handling ****************************************************/
50 static int dsa_slave_open(struct net_device
*dev
)
55 static int dsa_slave_close(struct net_device
*dev
)
60 static void dsa_slave_change_rx_flags(struct net_device
*dev
, int change
)
62 struct dsa_slave_priv
*p
= netdev_priv(dev
);
63 struct net_device
*master
= p
->parent
->master_netdev
;
65 if (change
& IFF_ALLMULTI
)
66 dev_set_allmulti(master
, dev
->flags
& IFF_ALLMULTI
? 1 : -1);
67 if (change
& IFF_PROMISC
)
68 dev_set_promiscuity(master
, dev
->flags
& IFF_PROMISC
? 1 : -1);
71 static void dsa_slave_set_rx_mode(struct net_device
*dev
)
73 struct dsa_slave_priv
*p
= netdev_priv(dev
);
74 struct net_device
*master
= p
->parent
->master_netdev
;
76 dev_mc_sync(master
, dev
);
77 dev_unicast_sync(master
, dev
);
80 static int dsa_slave_set_mac_address(struct net_device
*dev
, void *addr
)
82 memcpy(dev
->dev_addr
, addr
+ 2, 6);
87 static int dsa_slave_ioctl(struct net_device
*dev
, struct ifreq
*ifr
, int cmd
)
89 struct dsa_slave_priv
*p
= netdev_priv(dev
);
90 struct mii_ioctl_data
*mii_data
= if_mii(ifr
);
93 return phy_mii_ioctl(p
->phy
, mii_data
, cmd
);
99 /* ethtool operations *******************************************************/
101 dsa_slave_get_settings(struct net_device
*dev
, struct ethtool_cmd
*cmd
)
103 struct dsa_slave_priv
*p
= netdev_priv(dev
);
107 if (p
->phy
!= NULL
) {
108 err
= phy_read_status(p
->phy
);
110 err
= phy_ethtool_gset(p
->phy
, cmd
);
117 dsa_slave_set_settings(struct net_device
*dev
, struct ethtool_cmd
*cmd
)
119 struct dsa_slave_priv
*p
= netdev_priv(dev
);
122 return phy_ethtool_sset(p
->phy
, cmd
);
127 static void dsa_slave_get_drvinfo(struct net_device
*dev
,
128 struct ethtool_drvinfo
*drvinfo
)
130 strncpy(drvinfo
->driver
, "dsa", 32);
131 strncpy(drvinfo
->version
, dsa_driver_version
, 32);
132 strncpy(drvinfo
->fw_version
, "N/A", 32);
133 strncpy(drvinfo
->bus_info
, "platform", 32);
136 static int dsa_slave_nway_reset(struct net_device
*dev
)
138 struct dsa_slave_priv
*p
= netdev_priv(dev
);
141 return genphy_restart_aneg(p
->phy
);
146 static u32
dsa_slave_get_link(struct net_device
*dev
)
148 struct dsa_slave_priv
*p
= netdev_priv(dev
);
150 if (p
->phy
!= NULL
) {
151 genphy_update_link(p
->phy
);
158 static void dsa_slave_get_strings(struct net_device
*dev
,
159 uint32_t stringset
, uint8_t *data
)
161 struct dsa_slave_priv
*p
= netdev_priv(dev
);
162 struct dsa_switch
*ds
= p
->parent
;
164 if (stringset
== ETH_SS_STATS
) {
165 int len
= ETH_GSTRING_LEN
;
167 strncpy(data
, "tx_packets", len
);
168 strncpy(data
+ len
, "tx_bytes", len
);
169 strncpy(data
+ 2 * len
, "rx_packets", len
);
170 strncpy(data
+ 3 * len
, "rx_bytes", len
);
171 if (ds
->drv
->get_strings
!= NULL
)
172 ds
->drv
->get_strings(ds
, p
->port
, data
+ 4 * len
);
176 static void dsa_slave_get_ethtool_stats(struct net_device
*dev
,
177 struct ethtool_stats
*stats
,
180 struct dsa_slave_priv
*p
= netdev_priv(dev
);
181 struct dsa_switch
*ds
= p
->parent
;
183 data
[0] = p
->dev
->stats
.tx_packets
;
184 data
[1] = p
->dev
->stats
.tx_bytes
;
185 data
[2] = p
->dev
->stats
.rx_packets
;
186 data
[3] = p
->dev
->stats
.rx_bytes
;
187 if (ds
->drv
->get_ethtool_stats
!= NULL
)
188 ds
->drv
->get_ethtool_stats(ds
, p
->port
, data
+ 4);
191 static int dsa_slave_get_sset_count(struct net_device
*dev
, int sset
)
193 struct dsa_slave_priv
*p
= netdev_priv(dev
);
194 struct dsa_switch
*ds
= p
->parent
;
196 if (sset
== ETH_SS_STATS
) {
200 if (ds
->drv
->get_sset_count
!= NULL
)
201 count
+= ds
->drv
->get_sset_count(ds
);
209 static const struct ethtool_ops dsa_slave_ethtool_ops
= {
210 .get_settings
= dsa_slave_get_settings
,
211 .set_settings
= dsa_slave_set_settings
,
212 .get_drvinfo
= dsa_slave_get_drvinfo
,
213 .nway_reset
= dsa_slave_nway_reset
,
214 .get_link
= dsa_slave_get_link
,
215 .set_sg
= ethtool_op_set_sg
,
216 .get_strings
= dsa_slave_get_strings
,
217 .get_ethtool_stats
= dsa_slave_get_ethtool_stats
,
218 .get_sset_count
= dsa_slave_get_sset_count
,
222 /* slave device setup *******************************************************/
224 dsa_slave_create(struct dsa_switch
*ds
, struct device
*parent
,
225 int port
, char *name
)
227 struct net_device
*master
= ds
->master_netdev
;
228 struct net_device
*slave_dev
;
229 struct dsa_slave_priv
*p
;
232 slave_dev
= alloc_netdev(sizeof(struct dsa_slave_priv
),
234 if (slave_dev
== NULL
)
237 slave_dev
->features
= master
->vlan_features
;
238 SET_ETHTOOL_OPS(slave_dev
, &dsa_slave_ethtool_ops
);
239 memcpy(slave_dev
->dev_addr
, master
->dev_addr
, ETH_ALEN
);
240 slave_dev
->tx_queue_len
= 0;
241 switch (ds
->tag_protocol
) {
242 #ifdef CONFIG_NET_DSA_TAG_DSA
243 case htons(ETH_P_DSA
):
244 slave_dev
->hard_start_xmit
= dsa_xmit
;
247 #ifdef CONFIG_NET_DSA_TAG_EDSA
248 case htons(ETH_P_EDSA
):
249 slave_dev
->hard_start_xmit
= edsa_xmit
;
252 #ifdef CONFIG_NET_DSA_TAG_TRAILER
253 case htons(ETH_P_TRAILER
):
254 slave_dev
->hard_start_xmit
= trailer_xmit
;
260 slave_dev
->open
= dsa_slave_open
;
261 slave_dev
->stop
= dsa_slave_close
;
262 slave_dev
->change_rx_flags
= dsa_slave_change_rx_flags
;
263 slave_dev
->set_rx_mode
= dsa_slave_set_rx_mode
;
264 slave_dev
->set_multicast_list
= dsa_slave_set_rx_mode
;
265 slave_dev
->set_mac_address
= dsa_slave_set_mac_address
;
266 slave_dev
->do_ioctl
= dsa_slave_ioctl
;
267 SET_NETDEV_DEV(slave_dev
, parent
);
268 slave_dev
->vlan_features
= master
->vlan_features
;
270 p
= netdev_priv(slave_dev
);
274 p
->phy
= ds
->slave_mii_bus
->phy_map
[port
];
276 ret
= register_netdev(slave_dev
);
278 printk(KERN_ERR
"%s: error %d registering interface %s\n",
279 master
->name
, ret
, slave_dev
->name
);
280 free_netdev(slave_dev
);
284 netif_carrier_off(slave_dev
);
286 if (p
->phy
!= NULL
) {
287 phy_attach(slave_dev
, p
->phy
->dev
.bus_id
,
288 0, PHY_INTERFACE_MODE_GMII
);
290 p
->phy
->autoneg
= AUTONEG_ENABLE
;
293 p
->phy
->advertising
= p
->phy
->supported
| ADVERTISED_Autoneg
;
294 phy_start_aneg(p
->phy
);