1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 1999 - 2010 Intel Corporation.
4  * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
5  *
6  * This code was derived from the Intel e1000e Linux driver.
7  */
8 #include "pch_gbe.h"
9 #include "pch_gbe_phy.h"
10 
11 static const char pch_driver_version[] = "1.01";
12 
13 /*
14  * pch_gbe_stats - Stats item information
15  */
16 struct pch_gbe_stats {
17 	char string[ETH_GSTRING_LEN];
18 	size_t size;
19 	size_t offset;
20 };
21 
22 #define PCH_GBE_STAT(m)						\
23 {								\
24 	.string = #m,						\
25 	.size = sizeof_field(struct pch_gbe_hw_stats, m),	\
26 	.offset = offsetof(struct pch_gbe_hw_stats, m),		\
27 }
28 
29 /*
30  * pch_gbe_gstrings_stats - ethtool information status name list
31  */
32 static const struct pch_gbe_stats pch_gbe_gstrings_stats[] = {
33 	PCH_GBE_STAT(rx_packets),
34 	PCH_GBE_STAT(tx_packets),
35 	PCH_GBE_STAT(rx_bytes),
36 	PCH_GBE_STAT(tx_bytes),
37 	PCH_GBE_STAT(rx_errors),
38 	PCH_GBE_STAT(tx_errors),
39 	PCH_GBE_STAT(rx_dropped),
40 	PCH_GBE_STAT(tx_dropped),
41 	PCH_GBE_STAT(multicast),
42 	PCH_GBE_STAT(collisions),
43 	PCH_GBE_STAT(rx_crc_errors),
44 	PCH_GBE_STAT(rx_frame_errors),
45 	PCH_GBE_STAT(rx_alloc_buff_failed),
46 	PCH_GBE_STAT(tx_length_errors),
47 	PCH_GBE_STAT(tx_aborted_errors),
48 	PCH_GBE_STAT(tx_carrier_errors),
49 	PCH_GBE_STAT(tx_timeout_count),
50 	PCH_GBE_STAT(tx_restart_count),
51 	PCH_GBE_STAT(intr_rx_dsc_empty_count),
52 	PCH_GBE_STAT(intr_rx_frame_err_count),
53 	PCH_GBE_STAT(intr_rx_fifo_err_count),
54 	PCH_GBE_STAT(intr_rx_dma_err_count),
55 	PCH_GBE_STAT(intr_tx_fifo_err_count),
56 	PCH_GBE_STAT(intr_tx_dma_err_count),
57 	PCH_GBE_STAT(intr_tcpip_err_count)
58 };
59 
60 #define PCH_GBE_QUEUE_STATS_LEN 0
61 #define PCH_GBE_GLOBAL_STATS_LEN	ARRAY_SIZE(pch_gbe_gstrings_stats)
62 #define PCH_GBE_STATS_LEN (PCH_GBE_GLOBAL_STATS_LEN + PCH_GBE_QUEUE_STATS_LEN)
63 
64 #define PCH_GBE_MAC_REGS_LEN    (sizeof(struct pch_gbe_regs) / 4)
65 #define PCH_GBE_REGS_LEN        (PCH_GBE_MAC_REGS_LEN + PCH_GBE_PHY_REGS_LEN)
66 /**
67  * pch_gbe_get_link_ksettings - Get device-specific settings
68  * @netdev: Network interface device structure
69  * @ecmd:   Ethtool command
70  * Returns:
71  *	0:			Successful.
72  *	Negative value:		Failed.
73  */
74 static int pch_gbe_get_link_ksettings(struct net_device *netdev,
75 				      struct ethtool_link_ksettings *ecmd)
76 {
77 	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
78 	u32 supported, advertising;
79 
80 	mii_ethtool_get_link_ksettings(&adapter->mii, ecmd);
81 
82 	ethtool_convert_link_mode_to_legacy_u32(&supported,
83 						ecmd->link_modes.supported);
84 	ethtool_convert_link_mode_to_legacy_u32(&advertising,
85 						ecmd->link_modes.advertising);
86 
87 	supported &= ~(SUPPORTED_TP | SUPPORTED_1000baseT_Half);
88 	advertising &= ~(ADVERTISED_TP | ADVERTISED_1000baseT_Half);
89 
90 	ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.supported,
91 						supported);
92 	ethtool_convert_legacy_u32_to_link_mode(ecmd->link_modes.advertising,
93 						advertising);
94 
95 	if (!netif_carrier_ok(adapter->netdev))
96 		ecmd->base.speed = SPEED_UNKNOWN;
97 
98 	return 0;
99 }
100 
101 /**
102  * pch_gbe_set_link_ksettings - Set device-specific settings
103  * @netdev: Network interface device structure
104  * @ecmd:   Ethtool command
105  * Returns:
106  *	0:			Successful.
107  *	Negative value:		Failed.
108  */
109 static int pch_gbe_set_link_ksettings(struct net_device *netdev,
110 				      const struct ethtool_link_ksettings *ecmd)
111 {
112 	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
113 	struct pch_gbe_hw *hw = &adapter->hw;
114 	struct ethtool_link_ksettings copy_ecmd;
115 	u32 speed = ecmd->base.speed;
116 	u32 advertising;
117 	int ret;
118 
119 	pch_gbe_phy_write_reg_miic(hw, MII_BMCR, BMCR_RESET);
120 
121 	memcpy(&copy_ecmd, ecmd, sizeof(*ecmd));
122 
123 	/* when set_settings() is called with a ethtool_cmd previously
124 	 * filled by get_settings() on a down link, speed is -1: */
125 	if (speed == UINT_MAX) {
126 		speed = SPEED_1000;
127 		copy_ecmd.base.speed = speed;
128 		copy_ecmd.base.duplex = DUPLEX_FULL;
129 	}
130 	ret = mii_ethtool_set_link_ksettings(&adapter->mii, &copy_ecmd);
131 	if (ret) {
132 		netdev_err(netdev, "Error: mii_ethtool_set_link_ksettings\n");
133 		return ret;
134 	}
135 	hw->mac.link_speed = speed;
136 	hw->mac.link_duplex = copy_ecmd.base.duplex;
137 	ethtool_convert_link_mode_to_legacy_u32(
138 		&advertising, copy_ecmd.link_modes.advertising);
139 	hw->phy.autoneg_advertised = advertising;
140 	hw->mac.autoneg = copy_ecmd.base.autoneg;
141 
142 	/* reset the link */
143 	if (netif_running(adapter->netdev)) {
144 		pch_gbe_down(adapter);
145 		ret = pch_gbe_up(adapter);
146 	} else {
147 		pch_gbe_reset(adapter);
148 	}
149 	return ret;
150 }
151 
152 /**
153  * pch_gbe_get_regs_len - Report the size of device registers
154  * @netdev: Network interface device structure
155  * Returns: the size of device registers.
156  */
157 static int pch_gbe_get_regs_len(struct net_device *netdev)
158 {
159 	return PCH_GBE_REGS_LEN * (int)sizeof(u32);
160 }
161 
162 /**
163  * pch_gbe_get_drvinfo - Report driver information
164  * @netdev:  Network interface device structure
165  * @drvinfo: Driver information structure
166  */
167 static void pch_gbe_get_drvinfo(struct net_device *netdev,
168 				 struct ethtool_drvinfo *drvinfo)
169 {
170 	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
171 
172 	strlcpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
173 	strlcpy(drvinfo->version, pch_driver_version, sizeof(drvinfo->version));
174 	strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
175 		sizeof(drvinfo->bus_info));
176 }
177 
178 /**
179  * pch_gbe_get_regs - Get device registers
180  * @netdev: Network interface device structure
181  * @regs:   Ethtool register structure
182  * @p:      Buffer pointer of read device register date
183  */
184 static void pch_gbe_get_regs(struct net_device *netdev,
185 				struct ethtool_regs *regs, void *p)
186 {
187 	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
188 	struct pch_gbe_hw *hw = &adapter->hw;
189 	struct pci_dev *pdev = adapter->pdev;
190 	u32 *regs_buff = p;
191 	u16 i, tmp;
192 
193 	regs->version = 0x1000000 | (__u32)pdev->revision << 16 | pdev->device;
194 	for (i = 0; i < PCH_GBE_MAC_REGS_LEN; i++)
195 		*regs_buff++ = ioread32(&hw->reg->INT_ST + i);
196 	/* PHY register */
197 	for (i = 0; i < PCH_GBE_PHY_REGS_LEN; i++) {
198 		pch_gbe_phy_read_reg_miic(&adapter->hw, i, &tmp);
199 		*regs_buff++ = tmp;
200 	}
201 }
202 
203 /**
204  * pch_gbe_get_wol - Report whether Wake-on-Lan is enabled
205  * @netdev: Network interface device structure
206  * @wol:    Wake-on-Lan information
207  */
208 static void pch_gbe_get_wol(struct net_device *netdev,
209 				struct ethtool_wolinfo *wol)
210 {
211 	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
212 
213 	wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC;
214 	wol->wolopts = 0;
215 
216 	if ((adapter->wake_up_evt & PCH_GBE_WLC_IND))
217 		wol->wolopts |= WAKE_UCAST;
218 	if ((adapter->wake_up_evt & PCH_GBE_WLC_MLT))
219 		wol->wolopts |= WAKE_MCAST;
220 	if ((adapter->wake_up_evt & PCH_GBE_WLC_BR))
221 		wol->wolopts |= WAKE_BCAST;
222 	if ((adapter->wake_up_evt & PCH_GBE_WLC_MP))
223 		wol->wolopts |= WAKE_MAGIC;
224 }
225 
226 /**
227  * pch_gbe_set_wol - Turn Wake-on-Lan on or off
228  * @netdev: Network interface device structure
229  * @wol:    Pointer of wake-on-Lan information straucture
230  * Returns:
231  *	0:			Successful.
232  *	Negative value:		Failed.
233  */
234 static int pch_gbe_set_wol(struct net_device *netdev,
235 				struct ethtool_wolinfo *wol)
236 {
237 	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
238 
239 	if ((wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)))
240 		return -EOPNOTSUPP;
241 	/* these settings will always override what we currently have */
242 	adapter->wake_up_evt = 0;
243 
244 	if ((wol->wolopts & WAKE_UCAST))
245 		adapter->wake_up_evt |= PCH_GBE_WLC_IND;
246 	if ((wol->wolopts & WAKE_MCAST))
247 		adapter->wake_up_evt |= PCH_GBE_WLC_MLT;
248 	if ((wol->wolopts & WAKE_BCAST))
249 		adapter->wake_up_evt |= PCH_GBE_WLC_BR;
250 	if ((wol->wolopts & WAKE_MAGIC))
251 		adapter->wake_up_evt |= PCH_GBE_WLC_MP;
252 	return 0;
253 }
254 
255 /**
256  * pch_gbe_nway_reset - Restart autonegotiation
257  * @netdev: Network interface device structure
258  * Returns:
259  *	0:			Successful.
260  *	Negative value:		Failed.
261  */
262 static int pch_gbe_nway_reset(struct net_device *netdev)
263 {
264 	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
265 
266 	return mii_nway_restart(&adapter->mii);
267 }
268 
269 /**
270  * pch_gbe_get_ringparam - Report ring sizes
271  * @netdev:  Network interface device structure
272  * @ring:    Ring param structure
273  */
274 static void pch_gbe_get_ringparam(struct net_device *netdev,
275 					struct ethtool_ringparam *ring)
276 {
277 	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
278 	struct pch_gbe_tx_ring *txdr = adapter->tx_ring;
279 	struct pch_gbe_rx_ring *rxdr = adapter->rx_ring;
280 
281 	ring->rx_max_pending = PCH_GBE_MAX_RXD;
282 	ring->tx_max_pending = PCH_GBE_MAX_TXD;
283 	ring->rx_pending = rxdr->count;
284 	ring->tx_pending = txdr->count;
285 }
286 
287 /**
288  * pch_gbe_set_ringparam - Set ring sizes
289  * @netdev:  Network interface device structure
290  * @ring:    Ring param structure
291  * Returns
292  *	0:			Successful.
293  *	Negative value:		Failed.
294  */
295 static int pch_gbe_set_ringparam(struct net_device *netdev,
296 					struct ethtool_ringparam *ring)
297 {
298 	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
299 	struct pch_gbe_tx_ring *txdr, *tx_old;
300 	struct pch_gbe_rx_ring *rxdr, *rx_old;
301 	int tx_ring_size, rx_ring_size;
302 	int err = 0;
303 
304 	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
305 		return -EINVAL;
306 	tx_ring_size = (int)sizeof(struct pch_gbe_tx_ring);
307 	rx_ring_size = (int)sizeof(struct pch_gbe_rx_ring);
308 
309 	if ((netif_running(adapter->netdev)))
310 		pch_gbe_down(adapter);
311 	tx_old = adapter->tx_ring;
312 	rx_old = adapter->rx_ring;
313 
314 	txdr = kzalloc(tx_ring_size, GFP_KERNEL);
315 	if (!txdr) {
316 		err = -ENOMEM;
317 		goto err_alloc_tx;
318 	}
319 	rxdr = kzalloc(rx_ring_size, GFP_KERNEL);
320 	if (!rxdr) {
321 		err = -ENOMEM;
322 		goto err_alloc_rx;
323 	}
324 	adapter->tx_ring = txdr;
325 	adapter->rx_ring = rxdr;
326 
327 	rxdr->count =
328 		clamp_val(ring->rx_pending, PCH_GBE_MIN_RXD, PCH_GBE_MAX_RXD);
329 	rxdr->count = roundup(rxdr->count, PCH_GBE_RX_DESC_MULTIPLE);
330 
331 	txdr->count =
332 		clamp_val(ring->tx_pending, PCH_GBE_MIN_RXD, PCH_GBE_MAX_RXD);
333 	txdr->count = roundup(txdr->count, PCH_GBE_TX_DESC_MULTIPLE);
334 
335 	if ((netif_running(adapter->netdev))) {
336 		/* Try to get new resources before deleting old */
337 		err = pch_gbe_setup_rx_resources(adapter, adapter->rx_ring);
338 		if (err)
339 			goto err_setup_rx;
340 		err = pch_gbe_setup_tx_resources(adapter, adapter->tx_ring);
341 		if (err)
342 			goto err_setup_tx;
343 		pch_gbe_free_rx_resources(adapter, rx_old);
344 		pch_gbe_free_tx_resources(adapter, tx_old);
345 		kfree(tx_old);
346 		kfree(rx_old);
347 		adapter->rx_ring = rxdr;
348 		adapter->tx_ring = txdr;
349 		err = pch_gbe_up(adapter);
350 	}
351 	return err;
352 
353 err_setup_tx:
354 	pch_gbe_free_rx_resources(adapter, adapter->rx_ring);
355 err_setup_rx:
356 	adapter->rx_ring = rx_old;
357 	adapter->tx_ring = tx_old;
358 	kfree(rxdr);
359 err_alloc_rx:
360 	kfree(txdr);
361 err_alloc_tx:
362 	if (netif_running(adapter->netdev))
363 		pch_gbe_up(adapter);
364 	return err;
365 }
366 
367 /**
368  * pch_gbe_get_pauseparam - Report pause parameters
369  * @netdev:  Network interface device structure
370  * @pause:   Pause parameters structure
371  */
372 static void pch_gbe_get_pauseparam(struct net_device *netdev,
373 				       struct ethtool_pauseparam *pause)
374 {
375 	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
376 	struct pch_gbe_hw *hw = &adapter->hw;
377 
378 	pause->autoneg =
379 	    ((hw->mac.fc_autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE);
380 
381 	if (hw->mac.fc == PCH_GBE_FC_RX_PAUSE) {
382 		pause->rx_pause = 1;
383 	} else if (hw->mac.fc == PCH_GBE_FC_TX_PAUSE) {
384 		pause->tx_pause = 1;
385 	} else if (hw->mac.fc == PCH_GBE_FC_FULL) {
386 		pause->rx_pause = 1;
387 		pause->tx_pause = 1;
388 	}
389 }
390 
391 /**
392  * pch_gbe_set_pauseparam - Set pause parameters
393  * @netdev:  Network interface device structure
394  * @pause:   Pause parameters structure
395  * Returns:
396  *	0:			Successful.
397  *	Negative value:		Failed.
398  */
399 static int pch_gbe_set_pauseparam(struct net_device *netdev,
400 				       struct ethtool_pauseparam *pause)
401 {
402 	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
403 	struct pch_gbe_hw *hw = &adapter->hw;
404 	int ret = 0;
405 
406 	hw->mac.fc_autoneg = pause->autoneg;
407 	if ((pause->rx_pause) && (pause->tx_pause))
408 		hw->mac.fc = PCH_GBE_FC_FULL;
409 	else if ((pause->rx_pause) && (!pause->tx_pause))
410 		hw->mac.fc = PCH_GBE_FC_RX_PAUSE;
411 	else if ((!pause->rx_pause) && (pause->tx_pause))
412 		hw->mac.fc = PCH_GBE_FC_TX_PAUSE;
413 	else if ((!pause->rx_pause) && (!pause->tx_pause))
414 		hw->mac.fc = PCH_GBE_FC_NONE;
415 
416 	if (hw->mac.fc_autoneg == AUTONEG_ENABLE) {
417 		if ((netif_running(adapter->netdev))) {
418 			pch_gbe_down(adapter);
419 			ret = pch_gbe_up(adapter);
420 		} else {
421 			pch_gbe_reset(adapter);
422 		}
423 	} else {
424 		ret = pch_gbe_mac_force_mac_fc(hw);
425 	}
426 	return ret;
427 }
428 
429 /**
430  * pch_gbe_get_strings - Return a set of strings that describe the requested
431  *			 objects
432  * @netdev:    Network interface device structure
433  * @stringset: Select the stringset. [ETH_SS_TEST] [ETH_SS_STATS]
434  * @data:      Pointer of read string data.
435  */
436 static void pch_gbe_get_strings(struct net_device *netdev, u32 stringset,
437 					u8 *data)
438 {
439 	u8 *p = data;
440 	int i;
441 
442 	switch (stringset) {
443 	case (u32) ETH_SS_STATS:
444 		for (i = 0; i < PCH_GBE_GLOBAL_STATS_LEN; i++) {
445 			memcpy(p, pch_gbe_gstrings_stats[i].string,
446 			       ETH_GSTRING_LEN);
447 			p += ETH_GSTRING_LEN;
448 		}
449 		break;
450 	}
451 }
452 
453 /**
454  * pch_gbe_get_ethtool_stats - Return statistics about the device
455  * @netdev: Network interface device structure
456  * @stats:  Ethtool statue structure
457  * @data:   Pointer of read status area
458  */
459 static void pch_gbe_get_ethtool_stats(struct net_device *netdev,
460 				  struct ethtool_stats *stats, u64 *data)
461 {
462 	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
463 	int i;
464 	const struct pch_gbe_stats *gstats = pch_gbe_gstrings_stats;
465 	char *hw_stats = (char *)&adapter->stats;
466 
467 	pch_gbe_update_stats(adapter);
468 	for (i = 0; i < PCH_GBE_GLOBAL_STATS_LEN; i++) {
469 		char *p = hw_stats + gstats->offset;
470 		data[i] = gstats->size == sizeof(u64) ? *(u64 *)p:(*(u32 *)p);
471 		gstats++;
472 	}
473 }
474 
475 static int pch_gbe_get_sset_count(struct net_device *netdev, int sset)
476 {
477 	switch (sset) {
478 	case ETH_SS_STATS:
479 		return PCH_GBE_STATS_LEN;
480 	default:
481 		return -EOPNOTSUPP;
482 	}
483 }
484 
485 static const struct ethtool_ops pch_gbe_ethtool_ops = {
486 	.get_drvinfo = pch_gbe_get_drvinfo,
487 	.get_regs_len = pch_gbe_get_regs_len,
488 	.get_regs = pch_gbe_get_regs,
489 	.get_wol = pch_gbe_get_wol,
490 	.set_wol = pch_gbe_set_wol,
491 	.nway_reset = pch_gbe_nway_reset,
492 	.get_link = ethtool_op_get_link,
493 	.get_ringparam = pch_gbe_get_ringparam,
494 	.set_ringparam = pch_gbe_set_ringparam,
495 	.get_pauseparam = pch_gbe_get_pauseparam,
496 	.set_pauseparam = pch_gbe_set_pauseparam,
497 	.get_strings = pch_gbe_get_strings,
498 	.get_ethtool_stats = pch_gbe_get_ethtool_stats,
499 	.get_sset_count = pch_gbe_get_sset_count,
500 	.get_link_ksettings = pch_gbe_get_link_ksettings,
501 	.set_link_ksettings = pch_gbe_set_link_ksettings,
502 };
503 
504 void pch_gbe_set_ethtool_ops(struct net_device *netdev)
505 {
506 	netdev->ethtool_ops = &pch_gbe_ethtool_ops;
507 }
508