aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/stmmac/stmmac_ethtool.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/stmmac/stmmac_ethtool.c')
-rw-r--r--drivers/net/stmmac/stmmac_ethtool.c104
1 files changed, 36 insertions, 68 deletions
diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c
index f080509923f0..ae5213a8c4cd 100644
--- a/drivers/net/stmmac/stmmac_ethtool.c
+++ b/drivers/net/stmmac/stmmac_ethtool.c
@@ -89,12 +89,12 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = {
89}; 89};
90#define STMMAC_STATS_LEN ARRAY_SIZE(stmmac_gstrings_stats) 90#define STMMAC_STATS_LEN ARRAY_SIZE(stmmac_gstrings_stats)
91 91
92void stmmac_ethtool_getdrvinfo(struct net_device *dev, 92static void stmmac_ethtool_getdrvinfo(struct net_device *dev,
93 struct ethtool_drvinfo *info) 93 struct ethtool_drvinfo *info)
94{ 94{
95 struct stmmac_priv *priv = netdev_priv(dev); 95 struct stmmac_priv *priv = netdev_priv(dev);
96 96
97 if (!priv->is_gmac) 97 if (!priv->plat->has_gmac)
98 strcpy(info->driver, MAC100_ETHTOOL_NAME); 98 strcpy(info->driver, MAC100_ETHTOOL_NAME);
99 else 99 else
100 strcpy(info->driver, GMAC_ETHTOOL_NAME); 100 strcpy(info->driver, GMAC_ETHTOOL_NAME);
@@ -104,7 +104,8 @@ void stmmac_ethtool_getdrvinfo(struct net_device *dev,
104 info->n_stats = STMMAC_STATS_LEN; 104 info->n_stats = STMMAC_STATS_LEN;
105} 105}
106 106
107int stmmac_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd) 107static int stmmac_ethtool_getsettings(struct net_device *dev,
108 struct ethtool_cmd *cmd)
108{ 109{
109 struct stmmac_priv *priv = netdev_priv(dev); 110 struct stmmac_priv *priv = netdev_priv(dev);
110 struct phy_device *phy = priv->phydev; 111 struct phy_device *phy = priv->phydev;
@@ -126,7 +127,8 @@ int stmmac_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd)
126 return rc; 127 return rc;
127} 128}
128 129
129int stmmac_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd) 130static int stmmac_ethtool_setsettings(struct net_device *dev,
131 struct ethtool_cmd *cmd)
130{ 132{
131 struct stmmac_priv *priv = netdev_priv(dev); 133 struct stmmac_priv *priv = netdev_priv(dev);
132 struct phy_device *phy = priv->phydev; 134 struct phy_device *phy = priv->phydev;
@@ -139,32 +141,32 @@ int stmmac_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd)
139 return rc; 141 return rc;
140} 142}
141 143
142u32 stmmac_ethtool_getmsglevel(struct net_device *dev) 144static u32 stmmac_ethtool_getmsglevel(struct net_device *dev)
143{ 145{
144 struct stmmac_priv *priv = netdev_priv(dev); 146 struct stmmac_priv *priv = netdev_priv(dev);
145 return priv->msg_enable; 147 return priv->msg_enable;
146} 148}
147 149
148void stmmac_ethtool_setmsglevel(struct net_device *dev, u32 level) 150static void stmmac_ethtool_setmsglevel(struct net_device *dev, u32 level)
149{ 151{
150 struct stmmac_priv *priv = netdev_priv(dev); 152 struct stmmac_priv *priv = netdev_priv(dev);
151 priv->msg_enable = level; 153 priv->msg_enable = level;
152 154
153} 155}
154 156
155int stmmac_check_if_running(struct net_device *dev) 157static int stmmac_check_if_running(struct net_device *dev)
156{ 158{
157 if (!netif_running(dev)) 159 if (!netif_running(dev))
158 return -EBUSY; 160 return -EBUSY;
159 return 0; 161 return 0;
160} 162}
161 163
162int stmmac_ethtool_get_regs_len(struct net_device *dev) 164static int stmmac_ethtool_get_regs_len(struct net_device *dev)
163{ 165{
164 return REG_SPACE_SIZE; 166 return REG_SPACE_SIZE;
165} 167}
166 168
167void stmmac_ethtool_gregs(struct net_device *dev, 169static void stmmac_ethtool_gregs(struct net_device *dev,
168 struct ethtool_regs *regs, void *space) 170 struct ethtool_regs *regs, void *space)
169{ 171{
170 int i; 172 int i;
@@ -174,44 +176,27 @@ void stmmac_ethtool_gregs(struct net_device *dev,
174 176
175 memset(reg_space, 0x0, REG_SPACE_SIZE); 177 memset(reg_space, 0x0, REG_SPACE_SIZE);
176 178
177 if (!priv->is_gmac) { 179 if (!priv->plat->has_gmac) {
178 /* MAC registers */ 180 /* MAC registers */
179 for (i = 0; i < 12; i++) 181 for (i = 0; i < 12; i++)
180 reg_space[i] = readl(dev->base_addr + (i * 4)); 182 reg_space[i] = readl(priv->ioaddr + (i * 4));
181 /* DMA registers */ 183 /* DMA registers */
182 for (i = 0; i < 9; i++) 184 for (i = 0; i < 9; i++)
183 reg_space[i + 12] = 185 reg_space[i + 12] =
184 readl(dev->base_addr + (DMA_BUS_MODE + (i * 4))); 186 readl(priv->ioaddr + (DMA_BUS_MODE + (i * 4)));
185 reg_space[22] = readl(dev->base_addr + DMA_CUR_TX_BUF_ADDR); 187 reg_space[22] = readl(priv->ioaddr + DMA_CUR_TX_BUF_ADDR);
186 reg_space[23] = readl(dev->base_addr + DMA_CUR_RX_BUF_ADDR); 188 reg_space[23] = readl(priv->ioaddr + DMA_CUR_RX_BUF_ADDR);
187 } else { 189 } else {
188 /* MAC registers */ 190 /* MAC registers */
189 for (i = 0; i < 55; i++) 191 for (i = 0; i < 55; i++)
190 reg_space[i] = readl(dev->base_addr + (i * 4)); 192 reg_space[i] = readl(priv->ioaddr + (i * 4));
191 /* DMA registers */ 193 /* DMA registers */
192 for (i = 0; i < 22; i++) 194 for (i = 0; i < 22; i++)
193 reg_space[i + 55] = 195 reg_space[i + 55] =
194 readl(dev->base_addr + (DMA_BUS_MODE + (i * 4))); 196 readl(priv->ioaddr + (DMA_BUS_MODE + (i * 4)));
195 } 197 }
196} 198}
197 199
198int stmmac_ethtool_set_tx_csum(struct net_device *netdev, u32 data)
199{
200 if (data)
201 netdev->features |= NETIF_F_HW_CSUM;
202 else
203 netdev->features &= ~NETIF_F_HW_CSUM;
204
205 return 0;
206}
207
208u32 stmmac_ethtool_get_rx_csum(struct net_device *dev)
209{
210 struct stmmac_priv *priv = netdev_priv(dev);
211
212 return priv->rx_csum;
213}
214
215static void 200static void
216stmmac_get_pauseparam(struct net_device *netdev, 201stmmac_get_pauseparam(struct net_device *netdev,
217 struct ethtool_pauseparam *pause) 202 struct ethtool_pauseparam *pause)
@@ -249,25 +234,14 @@ stmmac_set_pauseparam(struct net_device *netdev,
249 new_pause |= FLOW_TX; 234 new_pause |= FLOW_TX;
250 235
251 priv->flow_ctrl = new_pause; 236 priv->flow_ctrl = new_pause;
237 phy->autoneg = pause->autoneg;
252 238
253 if (phy->autoneg) { 239 if (phy->autoneg) {
254 if (netif_running(netdev)) { 240 if (netif_running(netdev))
255 struct ethtool_cmd cmd; 241 ret = phy_start_aneg(phy);
256 /* auto-negotiation automatically restarted */ 242 } else
257 cmd.cmd = ETHTOOL_NWAY_RST; 243 priv->hw->mac->flow_ctrl(priv->ioaddr, phy->duplex,
258 cmd.supported = phy->supported;
259 cmd.advertising = phy->advertising;
260 cmd.autoneg = phy->autoneg;
261 cmd.speed = phy->speed;
262 cmd.duplex = phy->duplex;
263 cmd.phy_address = phy->addr;
264 ret = phy_ethtool_sset(phy, &cmd);
265 }
266 } else {
267 unsigned long ioaddr = netdev->base_addr;
268 priv->hw->mac->flow_ctrl(ioaddr, phy->duplex,
269 priv->flow_ctrl, priv->pause); 244 priv->flow_ctrl, priv->pause);
270 }
271 spin_unlock(&priv->lock); 245 spin_unlock(&priv->lock);
272 return ret; 246 return ret;
273} 247}
@@ -276,12 +250,11 @@ static void stmmac_get_ethtool_stats(struct net_device *dev,
276 struct ethtool_stats *dummy, u64 *data) 250 struct ethtool_stats *dummy, u64 *data)
277{ 251{
278 struct stmmac_priv *priv = netdev_priv(dev); 252 struct stmmac_priv *priv = netdev_priv(dev);
279 unsigned long ioaddr = dev->base_addr;
280 int i; 253 int i;
281 254
282 /* Update HW stats if supported */ 255 /* Update HW stats if supported */
283 priv->hw->dma->dma_diagnostic_fr(&dev->stats, (void *) &priv->xstats, 256 priv->hw->dma->dma_diagnostic_fr(&dev->stats, (void *) &priv->xstats,
284 ioaddr); 257 priv->ioaddr);
285 258
286 for (i = 0; i < STMMAC_STATS_LEN; i++) { 259 for (i = 0; i < STMMAC_STATS_LEN; i++) {
287 char *p = (char *)priv + stmmac_gstrings_stats[i].stat_offset; 260 char *p = (char *)priv + stmmac_gstrings_stats[i].stat_offset;
@@ -325,8 +298,8 @@ static void stmmac_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
325 struct stmmac_priv *priv = netdev_priv(dev); 298 struct stmmac_priv *priv = netdev_priv(dev);
326 299
327 spin_lock_irq(&priv->lock); 300 spin_lock_irq(&priv->lock);
328 if (priv->wolenabled == PMT_SUPPORTED) { 301 if (device_can_wakeup(priv->device)) {
329 wol->supported = WAKE_MAGIC; 302 wol->supported = WAKE_MAGIC | WAKE_UCAST;
330 wol->wolopts = priv->wolopts; 303 wol->wolopts = priv->wolopts;
331 } 304 }
332 spin_unlock_irq(&priv->lock); 305 spin_unlock_irq(&priv->lock);
@@ -335,18 +308,22 @@ static void stmmac_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
335static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 308static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
336{ 309{
337 struct stmmac_priv *priv = netdev_priv(dev); 310 struct stmmac_priv *priv = netdev_priv(dev);
338 u32 support = WAKE_MAGIC; 311 u32 support = WAKE_MAGIC | WAKE_UCAST;
339 312
340 if (priv->wolenabled == PMT_NOT_SUPPORTED) 313 if (!device_can_wakeup(priv->device))
341 return -EINVAL; 314 return -EINVAL;
342 315
343 if (wol->wolopts & ~support) 316 if (wol->wolopts & ~support)
344 return -EINVAL; 317 return -EINVAL;
345 318
346 if (wol->wolopts == 0) 319 if (wol->wolopts) {
347 device_set_wakeup_enable(priv->device, 0); 320 pr_info("stmmac: wakeup enable\n");
348 else
349 device_set_wakeup_enable(priv->device, 1); 321 device_set_wakeup_enable(priv->device, 1);
322 enable_irq_wake(dev->irq);
323 } else {
324 device_set_wakeup_enable(priv->device, 0);
325 disable_irq_wake(dev->irq);
326 }
350 327
351 spin_lock_irq(&priv->lock); 328 spin_lock_irq(&priv->lock);
352 priv->wolopts = wol->wolopts; 329 priv->wolopts = wol->wolopts;
@@ -365,11 +342,6 @@ static struct ethtool_ops stmmac_ethtool_ops = {
365 .get_regs = stmmac_ethtool_gregs, 342 .get_regs = stmmac_ethtool_gregs,
366 .get_regs_len = stmmac_ethtool_get_regs_len, 343 .get_regs_len = stmmac_ethtool_get_regs_len,
367 .get_link = ethtool_op_get_link, 344 .get_link = ethtool_op_get_link,
368 .get_rx_csum = stmmac_ethtool_get_rx_csum,
369 .get_tx_csum = ethtool_op_get_tx_csum,
370 .set_tx_csum = stmmac_ethtool_set_tx_csum,
371 .get_sg = ethtool_op_get_sg,
372 .set_sg = ethtool_op_set_sg,
373 .get_pauseparam = stmmac_get_pauseparam, 345 .get_pauseparam = stmmac_get_pauseparam,
374 .set_pauseparam = stmmac_set_pauseparam, 346 .set_pauseparam = stmmac_set_pauseparam,
375 .get_ethtool_stats = stmmac_get_ethtool_stats, 347 .get_ethtool_stats = stmmac_get_ethtool_stats,
@@ -377,10 +349,6 @@ static struct ethtool_ops stmmac_ethtool_ops = {
377 .get_wol = stmmac_get_wol, 349 .get_wol = stmmac_get_wol,
378 .set_wol = stmmac_set_wol, 350 .set_wol = stmmac_set_wol,
379 .get_sset_count = stmmac_get_sset_count, 351 .get_sset_count = stmmac_get_sset_count,
380#ifdef NETIF_F_TSO
381 .get_tso = ethtool_op_get_tso,
382 .set_tso = ethtool_op_set_tso,
383#endif
384}; 352};
385 353
386void stmmac_set_ethtool_ops(struct net_device *netdev) 354void stmmac_set_ethtool_ops(struct net_device *netdev)