2 * Copyright (C) 1999 - 2010 Intel Corporation.
3 * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD.
5 * This code was derived from the Intel e1000e Linux driver.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include "pch_gbe_api.h"
23 * pch_gbe_stats - Stats item information
25 struct pch_gbe_stats
{
26 char string
[ETH_GSTRING_LEN
];
31 #define PCH_GBE_STAT(m) \
34 .size = FIELD_SIZEOF(struct pch_gbe_hw_stats, m), \
35 .offset = offsetof(struct pch_gbe_hw_stats, m), \
39 * pch_gbe_gstrings_stats - ethtool information status name list
41 static const struct pch_gbe_stats pch_gbe_gstrings_stats
[] = {
42 PCH_GBE_STAT(rx_packets
),
43 PCH_GBE_STAT(tx_packets
),
44 PCH_GBE_STAT(rx_bytes
),
45 PCH_GBE_STAT(tx_bytes
),
46 PCH_GBE_STAT(rx_errors
),
47 PCH_GBE_STAT(tx_errors
),
48 PCH_GBE_STAT(rx_dropped
),
49 PCH_GBE_STAT(tx_dropped
),
50 PCH_GBE_STAT(multicast
),
51 PCH_GBE_STAT(collisions
),
52 PCH_GBE_STAT(rx_crc_errors
),
53 PCH_GBE_STAT(rx_frame_errors
),
54 PCH_GBE_STAT(rx_alloc_buff_failed
),
55 PCH_GBE_STAT(tx_length_errors
),
56 PCH_GBE_STAT(tx_aborted_errors
),
57 PCH_GBE_STAT(tx_carrier_errors
),
58 PCH_GBE_STAT(tx_timeout_count
),
59 PCH_GBE_STAT(tx_restart_count
),
60 PCH_GBE_STAT(intr_rx_dsc_empty_count
),
61 PCH_GBE_STAT(intr_rx_frame_err_count
),
62 PCH_GBE_STAT(intr_rx_fifo_err_count
),
63 PCH_GBE_STAT(intr_rx_dma_err_count
),
64 PCH_GBE_STAT(intr_tx_fifo_err_count
),
65 PCH_GBE_STAT(intr_tx_dma_err_count
),
66 PCH_GBE_STAT(intr_tcpip_err_count
)
69 #define PCH_GBE_QUEUE_STATS_LEN 0
70 #define PCH_GBE_GLOBAL_STATS_LEN ARRAY_SIZE(pch_gbe_gstrings_stats)
71 #define PCH_GBE_STATS_LEN (PCH_GBE_GLOBAL_STATS_LEN + PCH_GBE_QUEUE_STATS_LEN)
73 #define PCH_GBE_MAC_REGS_LEN (sizeof(struct pch_gbe_regs) / 4)
74 #define PCH_GBE_REGS_LEN (PCH_GBE_MAC_REGS_LEN + PCH_GBE_PHY_REGS_LEN)
76 * pch_gbe_get_link_ksettings - Get device-specific settings
77 * @netdev: Network interface device structure
78 * @ecmd: Ethtool command
81 * Negative value: Failed.
83 static int pch_gbe_get_link_ksettings(struct net_device
*netdev
,
84 struct ethtool_link_ksettings
*ecmd
)
86 struct pch_gbe_adapter
*adapter
= netdev_priv(netdev
);
87 u32 supported
, advertising
;
89 mii_ethtool_get_link_ksettings(&adapter
->mii
, ecmd
);
91 ethtool_convert_link_mode_to_legacy_u32(&supported
,
92 ecmd
->link_modes
.supported
);
93 ethtool_convert_link_mode_to_legacy_u32(&advertising
,
94 ecmd
->link_modes
.advertising
);
96 supported
&= ~(SUPPORTED_TP
| SUPPORTED_1000baseT_Half
);
97 advertising
&= ~(ADVERTISED_TP
| ADVERTISED_1000baseT_Half
);
99 ethtool_convert_legacy_u32_to_link_mode(ecmd
->link_modes
.supported
,
101 ethtool_convert_legacy_u32_to_link_mode(ecmd
->link_modes
.advertising
,
104 if (!netif_carrier_ok(adapter
->netdev
))
105 ecmd
->base
.speed
= SPEED_UNKNOWN
;
111 * pch_gbe_set_link_ksettings - Set device-specific settings
112 * @netdev: Network interface device structure
113 * @ecmd: Ethtool command
116 * Negative value: Failed.
118 static int pch_gbe_set_link_ksettings(struct net_device
*netdev
,
119 const struct ethtool_link_ksettings
*ecmd
)
121 struct pch_gbe_adapter
*adapter
= netdev_priv(netdev
);
122 struct pch_gbe_hw
*hw
= &adapter
->hw
;
123 struct ethtool_link_ksettings copy_ecmd
;
124 u32 speed
= ecmd
->base
.speed
;
128 pch_gbe_hal_write_phy_reg(hw
, MII_BMCR
, BMCR_RESET
);
130 memcpy(©_ecmd
, ecmd
, sizeof(*ecmd
));
132 /* when set_settings() is called with a ethtool_cmd previously
133 * filled by get_settings() on a down link, speed is -1: */
134 if (speed
== UINT_MAX
) {
136 copy_ecmd
.base
.speed
= speed
;
137 copy_ecmd
.base
.duplex
= DUPLEX_FULL
;
139 ret
= mii_ethtool_set_link_ksettings(&adapter
->mii
, ©_ecmd
);
141 netdev_err(netdev
, "Error: mii_ethtool_set_link_ksettings\n");
144 hw
->mac
.link_speed
= speed
;
145 hw
->mac
.link_duplex
= copy_ecmd
.base
.duplex
;
146 ethtool_convert_link_mode_to_legacy_u32(
147 &advertising
, copy_ecmd
.link_modes
.advertising
);
148 hw
->phy
.autoneg_advertised
= advertising
;
149 hw
->mac
.autoneg
= copy_ecmd
.base
.autoneg
;
152 if (netif_running(adapter
->netdev
)) {
153 pch_gbe_down(adapter
);
154 ret
= pch_gbe_up(adapter
);
156 pch_gbe_reset(adapter
);
162 * pch_gbe_get_regs_len - Report the size of device registers
163 * @netdev: Network interface device structure
164 * Returns: the size of device registers.
166 static int pch_gbe_get_regs_len(struct net_device
*netdev
)
168 return PCH_GBE_REGS_LEN
* (int)sizeof(u32
);
172 * pch_gbe_get_drvinfo - Report driver information
173 * @netdev: Network interface device structure
174 * @drvinfo: Driver information structure
176 static void pch_gbe_get_drvinfo(struct net_device
*netdev
,
177 struct ethtool_drvinfo
*drvinfo
)
179 struct pch_gbe_adapter
*adapter
= netdev_priv(netdev
);
181 strlcpy(drvinfo
->driver
, KBUILD_MODNAME
, sizeof(drvinfo
->driver
));
182 strlcpy(drvinfo
->version
, pch_driver_version
, sizeof(drvinfo
->version
));
183 strlcpy(drvinfo
->bus_info
, pci_name(adapter
->pdev
),
184 sizeof(drvinfo
->bus_info
));
188 * pch_gbe_get_regs - Get device registers
189 * @netdev: Network interface device structure
190 * @regs: Ethtool register structure
191 * @p: Buffer pointer of read device register date
193 static void pch_gbe_get_regs(struct net_device
*netdev
,
194 struct ethtool_regs
*regs
, void *p
)
196 struct pch_gbe_adapter
*adapter
= netdev_priv(netdev
);
197 struct pch_gbe_hw
*hw
= &adapter
->hw
;
198 struct pci_dev
*pdev
= adapter
->pdev
;
202 regs
->version
= 0x1000000 | (__u32
)pdev
->revision
<< 16 | pdev
->device
;
203 for (i
= 0; i
< PCH_GBE_MAC_REGS_LEN
; i
++)
204 *regs_buff
++ = ioread32(&hw
->reg
->INT_ST
+ i
);
206 for (i
= 0; i
< PCH_GBE_PHY_REGS_LEN
; i
++) {
207 pch_gbe_hal_read_phy_reg(&adapter
->hw
, i
, &tmp
);
213 * pch_gbe_get_wol - Report whether Wake-on-Lan is enabled
214 * @netdev: Network interface device structure
215 * @wol: Wake-on-Lan information
217 static void pch_gbe_get_wol(struct net_device
*netdev
,
218 struct ethtool_wolinfo
*wol
)
220 struct pch_gbe_adapter
*adapter
= netdev_priv(netdev
);
222 wol
->supported
= WAKE_UCAST
| WAKE_MCAST
| WAKE_BCAST
| WAKE_MAGIC
;
225 if ((adapter
->wake_up_evt
& PCH_GBE_WLC_IND
))
226 wol
->wolopts
|= WAKE_UCAST
;
227 if ((adapter
->wake_up_evt
& PCH_GBE_WLC_MLT
))
228 wol
->wolopts
|= WAKE_MCAST
;
229 if ((adapter
->wake_up_evt
& PCH_GBE_WLC_BR
))
230 wol
->wolopts
|= WAKE_BCAST
;
231 if ((adapter
->wake_up_evt
& PCH_GBE_WLC_MP
))
232 wol
->wolopts
|= WAKE_MAGIC
;
236 * pch_gbe_set_wol - Turn Wake-on-Lan on or off
237 * @netdev: Network interface device structure
238 * @wol: Pointer of wake-on-Lan information straucture
241 * Negative value: Failed.
243 static int pch_gbe_set_wol(struct net_device
*netdev
,
244 struct ethtool_wolinfo
*wol
)
246 struct pch_gbe_adapter
*adapter
= netdev_priv(netdev
);
248 if ((wol
->wolopts
& (WAKE_PHY
| WAKE_ARP
| WAKE_MAGICSECURE
)))
250 /* these settings will always override what we currently have */
251 adapter
->wake_up_evt
= 0;
253 if ((wol
->wolopts
& WAKE_UCAST
))
254 adapter
->wake_up_evt
|= PCH_GBE_WLC_IND
;
255 if ((wol
->wolopts
& WAKE_MCAST
))
256 adapter
->wake_up_evt
|= PCH_GBE_WLC_MLT
;
257 if ((wol
->wolopts
& WAKE_BCAST
))
258 adapter
->wake_up_evt
|= PCH_GBE_WLC_BR
;
259 if ((wol
->wolopts
& WAKE_MAGIC
))
260 adapter
->wake_up_evt
|= PCH_GBE_WLC_MP
;
265 * pch_gbe_nway_reset - Restart autonegotiation
266 * @netdev: Network interface device structure
269 * Negative value: Failed.
271 static int pch_gbe_nway_reset(struct net_device
*netdev
)
273 struct pch_gbe_adapter
*adapter
= netdev_priv(netdev
);
275 return mii_nway_restart(&adapter
->mii
);
279 * pch_gbe_get_ringparam - Report ring sizes
280 * @netdev: Network interface device structure
281 * @ring: Ring param structure
283 static void pch_gbe_get_ringparam(struct net_device
*netdev
,
284 struct ethtool_ringparam
*ring
)
286 struct pch_gbe_adapter
*adapter
= netdev_priv(netdev
);
287 struct pch_gbe_tx_ring
*txdr
= adapter
->tx_ring
;
288 struct pch_gbe_rx_ring
*rxdr
= adapter
->rx_ring
;
290 ring
->rx_max_pending
= PCH_GBE_MAX_RXD
;
291 ring
->tx_max_pending
= PCH_GBE_MAX_TXD
;
292 ring
->rx_pending
= rxdr
->count
;
293 ring
->tx_pending
= txdr
->count
;
297 * pch_gbe_set_ringparam - Set ring sizes
298 * @netdev: Network interface device structure
299 * @ring: Ring param structure
302 * Negative value: Failed.
304 static int pch_gbe_set_ringparam(struct net_device
*netdev
,
305 struct ethtool_ringparam
*ring
)
307 struct pch_gbe_adapter
*adapter
= netdev_priv(netdev
);
308 struct pch_gbe_tx_ring
*txdr
, *tx_old
;
309 struct pch_gbe_rx_ring
*rxdr
, *rx_old
;
310 int tx_ring_size
, rx_ring_size
;
313 if ((ring
->rx_mini_pending
) || (ring
->rx_jumbo_pending
))
315 tx_ring_size
= (int)sizeof(struct pch_gbe_tx_ring
);
316 rx_ring_size
= (int)sizeof(struct pch_gbe_rx_ring
);
318 if ((netif_running(adapter
->netdev
)))
319 pch_gbe_down(adapter
);
320 tx_old
= adapter
->tx_ring
;
321 rx_old
= adapter
->rx_ring
;
323 txdr
= kzalloc(tx_ring_size
, GFP_KERNEL
);
328 rxdr
= kzalloc(rx_ring_size
, GFP_KERNEL
);
333 adapter
->tx_ring
= txdr
;
334 adapter
->rx_ring
= rxdr
;
337 clamp_val(ring
->rx_pending
, PCH_GBE_MIN_RXD
, PCH_GBE_MAX_RXD
);
338 rxdr
->count
= roundup(rxdr
->count
, PCH_GBE_RX_DESC_MULTIPLE
);
341 clamp_val(ring
->tx_pending
, PCH_GBE_MIN_RXD
, PCH_GBE_MAX_RXD
);
342 txdr
->count
= roundup(txdr
->count
, PCH_GBE_TX_DESC_MULTIPLE
);
344 if ((netif_running(adapter
->netdev
))) {
345 /* Try to get new resources before deleting old */
346 err
= pch_gbe_setup_rx_resources(adapter
, adapter
->rx_ring
);
349 err
= pch_gbe_setup_tx_resources(adapter
, adapter
->tx_ring
);
352 /* save the new, restore the old in order to free it,
353 * then restore the new back again */
355 adapter
->rx_ring
= rx_old
;
356 adapter
->tx_ring
= tx_old
;
357 pch_gbe_free_rx_resources(adapter
, adapter
->rx_ring
);
358 pch_gbe_free_tx_resources(adapter
, adapter
->tx_ring
);
361 adapter
->rx_ring
= rxdr
;
362 adapter
->tx_ring
= txdr
;
364 pch_gbe_free_rx_resources(adapter
, rx_old
);
365 pch_gbe_free_tx_resources(adapter
, tx_old
);
368 adapter
->rx_ring
= rxdr
;
369 adapter
->tx_ring
= txdr
;
371 err
= pch_gbe_up(adapter
);
376 pch_gbe_free_rx_resources(adapter
, adapter
->rx_ring
);
378 adapter
->rx_ring
= rx_old
;
379 adapter
->tx_ring
= tx_old
;
384 if (netif_running(adapter
->netdev
))
390 * pch_gbe_get_pauseparam - Report pause parameters
391 * @netdev: Network interface device structure
392 * @pause: Pause parameters structure
394 static void pch_gbe_get_pauseparam(struct net_device
*netdev
,
395 struct ethtool_pauseparam
*pause
)
397 struct pch_gbe_adapter
*adapter
= netdev_priv(netdev
);
398 struct pch_gbe_hw
*hw
= &adapter
->hw
;
401 ((hw
->mac
.fc_autoneg
) ? AUTONEG_ENABLE
: AUTONEG_DISABLE
);
403 if (hw
->mac
.fc
== PCH_GBE_FC_RX_PAUSE
) {
405 } else if (hw
->mac
.fc
== PCH_GBE_FC_TX_PAUSE
) {
407 } else if (hw
->mac
.fc
== PCH_GBE_FC_FULL
) {
414 * pch_gbe_set_pauseparam - Set pause parameters
415 * @netdev: Network interface device structure
416 * @pause: Pause parameters structure
419 * Negative value: Failed.
421 static int pch_gbe_set_pauseparam(struct net_device
*netdev
,
422 struct ethtool_pauseparam
*pause
)
424 struct pch_gbe_adapter
*adapter
= netdev_priv(netdev
);
425 struct pch_gbe_hw
*hw
= &adapter
->hw
;
428 hw
->mac
.fc_autoneg
= pause
->autoneg
;
429 if ((pause
->rx_pause
) && (pause
->tx_pause
))
430 hw
->mac
.fc
= PCH_GBE_FC_FULL
;
431 else if ((pause
->rx_pause
) && (!pause
->tx_pause
))
432 hw
->mac
.fc
= PCH_GBE_FC_RX_PAUSE
;
433 else if ((!pause
->rx_pause
) && (pause
->tx_pause
))
434 hw
->mac
.fc
= PCH_GBE_FC_TX_PAUSE
;
435 else if ((!pause
->rx_pause
) && (!pause
->tx_pause
))
436 hw
->mac
.fc
= PCH_GBE_FC_NONE
;
438 if (hw
->mac
.fc_autoneg
== AUTONEG_ENABLE
) {
439 if ((netif_running(adapter
->netdev
))) {
440 pch_gbe_down(adapter
);
441 ret
= pch_gbe_up(adapter
);
443 pch_gbe_reset(adapter
);
446 ret
= pch_gbe_mac_force_mac_fc(hw
);
452 * pch_gbe_get_strings - Return a set of strings that describe the requested
454 * @netdev: Network interface device structure
455 * @stringset: Select the stringset. [ETH_SS_TEST] [ETH_SS_STATS]
456 * @data: Pointer of read string data.
458 static void pch_gbe_get_strings(struct net_device
*netdev
, u32 stringset
,
465 case (u32
) ETH_SS_STATS
:
466 for (i
= 0; i
< PCH_GBE_GLOBAL_STATS_LEN
; i
++) {
467 memcpy(p
, pch_gbe_gstrings_stats
[i
].string
,
469 p
+= ETH_GSTRING_LEN
;
476 * pch_gbe_get_ethtool_stats - Return statistics about the device
477 * @netdev: Network interface device structure
478 * @stats: Ethtool statue structure
479 * @data: Pointer of read status area
481 static void pch_gbe_get_ethtool_stats(struct net_device
*netdev
,
482 struct ethtool_stats
*stats
, u64
*data
)
484 struct pch_gbe_adapter
*adapter
= netdev_priv(netdev
);
486 const struct pch_gbe_stats
*gstats
= pch_gbe_gstrings_stats
;
487 char *hw_stats
= (char *)&adapter
->stats
;
489 pch_gbe_update_stats(adapter
);
490 for (i
= 0; i
< PCH_GBE_GLOBAL_STATS_LEN
; i
++) {
491 char *p
= hw_stats
+ gstats
->offset
;
492 data
[i
] = gstats
->size
== sizeof(u64
) ? *(u64
*)p
:(*(u32
*)p
);
497 static int pch_gbe_get_sset_count(struct net_device
*netdev
, int sset
)
501 return PCH_GBE_STATS_LEN
;
507 static const struct ethtool_ops pch_gbe_ethtool_ops
= {
508 .get_drvinfo
= pch_gbe_get_drvinfo
,
509 .get_regs_len
= pch_gbe_get_regs_len
,
510 .get_regs
= pch_gbe_get_regs
,
511 .get_wol
= pch_gbe_get_wol
,
512 .set_wol
= pch_gbe_set_wol
,
513 .nway_reset
= pch_gbe_nway_reset
,
514 .get_link
= ethtool_op_get_link
,
515 .get_ringparam
= pch_gbe_get_ringparam
,
516 .set_ringparam
= pch_gbe_set_ringparam
,
517 .get_pauseparam
= pch_gbe_get_pauseparam
,
518 .set_pauseparam
= pch_gbe_set_pauseparam
,
519 .get_strings
= pch_gbe_get_strings
,
520 .get_ethtool_stats
= pch_gbe_get_ethtool_stats
,
521 .get_sset_count
= pch_gbe_get_sset_count
,
522 .get_link_ksettings
= pch_gbe_get_link_ksettings
,
523 .set_link_ksettings
= pch_gbe_set_link_ksettings
,
526 void pch_gbe_set_ethtool_ops(struct net_device
*netdev
)
528 netdev
->ethtool_ops
= &pch_gbe_ethtool_ops
;