~ubuntu-branches/ubuntu/trusty/linux-armadaxp/trusty

« back to all changes in this revision

Viewing changes to drivers/net/pch_gbe/pch_gbe_ethtool.c

  • Committer: Package Import Robot
  • Author(s): Michael Casadevall, Bryan Wu, Dann Frazier, Michael Casadeall
  • Date: 2012-03-10 15:00:54 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120310150054-flugb39zon8vvgwe
Tags: 3.2.0-1600.1
[ Bryan Wu ]
* UBUNTU: import debian/debian.env and debian.armadaxp

[ Dann Frazier ]
* ARM: Armada XP: remove trailing '/' in dirnames in mvRules.mk

[ Michael Casadeall ]
* tools: add some tools for Marvell Armada XP processor
* kernel: timer tick hacking from Marvell
* kernel: Sheeva Errata: add delay on Sheeva when powering down
* net: add Marvell NFP netfilter
* net: socket and skb modifications made by Marvell
* miscdevice: add minor IDs for some Marvell Armada drivers
* fs: introduce memory pool for splice()
* video: EDID detection updates from Marvell Armada XP patchset
* video: backlight: add Marvell Dove LCD backlight driver
* video: display: add THS8200 display driver
* video: framebuffer: add Marvell Dove and Armada XP processor onchip LCD controller driver
* usbtest: add Interrupt transfer testing by Marvell Armada XP code
* usb: ehci: add support for Marvell EHCI controler
* tty/serial: 8250: add support for Marvell Armada XP processor and DeviceTree work
* rtc: add support for Marvell Armada XP onchip RTC controller
* net: pppoe: add Marvell ethernet NFP hook in PPPoE networking driver
* mtd: nand: add support for Marvell Armada XP Nand Flash Controller
* mtd: maps: add Marvell Armada XP specific map driver
* mmc: add support for Marvell Armada XP MMC/SD host controller
* i2c: add support for Marvell Armada XP onchip i2c bus controller
* hwmon: add Kconfig option for Armada XP onchip thermal sensor driver
* dmaengine: add Net DMA support for splice and update Marvell XOR DMA engine driver
* ata: add support for Marvell Armada XP SATA controller and update some quirks
* ARM: add Marvell Armada XP machine to mach-types
* ARM: oprofile: add support for Marvell PJ4B core
* ARM: mm: more ARMv6 switches for Marvell Armada XP
* ARM: remove static declaration to allow compilation
* ARM: alignment access fault trick
* ARM: mm: skip some fault fixing when run on NONE SMP ARMv6 mode during early abort event
* ARM: mm: add Marvell Sheeva CPU Architecture for PJ4B
* ARM: introduce optimized copy operation for Marvell Armada XP
* ARM: SAUCE: hardware breakpoint trick for Marvell Armada XP
* ARM: big endian and little endian tricks for Marvell Armada XP
* ARM: SAUCE: Add Marvell Armada XP build rules to arch/arm/kernel/Makefile
* ARM: vfp: add special handling for Marvell Armada XP
* ARM: add support for Marvell U-Boot
* ARM: add mv_controller_num for ARM PCI drivers
* ARM: add support for local PMUs, general SMP tweaks and cache flushing
* ARM: add Marvell device identifies in glue-proc.h
* ARM: add IPC driver support for Marvell platforms
* ARM: add DMA mapping for Marvell platforms
* ARM: add Sheeva errata and PJ4B code for booting
* ARM: update Kconfig and Makefile to include Marvell Armada XP platforms
* ARM: Armada XP: import LSP from Marvell for Armada XP 3.2 kernel enablement

Show diffs side-by-side

added added

removed removed

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