OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [net/] [ucc_geth_ethtool.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * Copyright (c) 2007 Freescale Semiconductor, Inc. All rights reserved.
3
 *
4
 * Description: QE UCC Gigabit Ethernet Ethtool API Set
5
 *
6
 * Author: Li Yang <leoli@freescale.com>
7
 *
8
 * Limitation:
9
 * Can only get/set setttings of the first queue.
10
 * Need to re-open the interface manually after changing some paramters.
11
 *
12
 * This program is free software; you can redistribute  it and/or modify it
13
 * under  the terms of  the GNU General  Public License as published by the
14
 * Free Software Foundation;  either version 2 of the  License, or (at your
15
 * option) any later version.
16
 */
17
 
18
#include <linux/kernel.h>
19
#include <linux/init.h>
20
#include <linux/errno.h>
21
#include <linux/slab.h>
22
#include <linux/stddef.h>
23
#include <linux/interrupt.h>
24
#include <linux/netdevice.h>
25
#include <linux/etherdevice.h>
26
#include <linux/skbuff.h>
27
#include <linux/spinlock.h>
28
#include <linux/mm.h>
29
#include <linux/delay.h>
30
#include <linux/dma-mapping.h>
31
#include <linux/fsl_devices.h>
32
#include <linux/ethtool.h>
33
#include <linux/mii.h>
34
#include <linux/phy.h>
35
 
36
#include <asm/io.h>
37
#include <asm/irq.h>
38
#include <asm/uaccess.h>
39
#include <asm/types.h>
40
#include <asm/uaccess.h>
41
 
42
#include "ucc_geth.h"
43
#include "ucc_geth_mii.h"
44
 
45
static char hw_stat_gstrings[][ETH_GSTRING_LEN] = {
46
        "tx-64-frames",
47
        "tx-65-127-frames",
48
        "tx-128-255-frames",
49
        "rx-64-frames",
50
        "rx-65-127-frames",
51
        "rx-128-255-frames",
52
        "tx-bytes-ok",
53
        "tx-pause-frames",
54
        "tx-multicast-frames",
55
        "tx-broadcast-frames",
56
        "rx-frames",
57
        "rx-bytes-ok",
58
        "rx-bytes-all",
59
        "rx-multicast-frames",
60
        "rx-broadcast-frames",
61
        "stats-counter-carry",
62
        "stats-counter-mask",
63
        "rx-dropped-frames",
64
};
65
 
66
static char tx_fw_stat_gstrings[][ETH_GSTRING_LEN] = {
67
        "tx-single-collision",
68
        "tx-multiple-collision",
69
        "tx-late-collsion",
70
        "tx-aborted-frames",
71
        "tx-lost-frames",
72
        "tx-carrier-sense-errors",
73
        "tx-frames-ok",
74
        "tx-excessive-differ-frames",
75
        "tx-256-511-frames",
76
        "tx-1024-1518-frames",
77
        "tx-jumbo-frames",
78
};
79
 
80
static char rx_fw_stat_gstrings[][ETH_GSTRING_LEN] = {
81
        "rx-crc-errors",
82
        "rx-alignment-errors",
83
        "rx-in-range-length-errors",
84
        "rx-out-of-range-length-errors",
85
        "rx-too-long-frames",
86
        "rx-runt",
87
        "rx-very-long-event",
88
        "rx-symbol-errors",
89
        "rx-busy-drop-frames",
90
        "reserved",
91
        "reserved",
92
        "rx-mismatch-drop-frames",
93
        "rx-small-than-64",
94
        "rx-256-511-frames",
95
        "rx-512-1023-frames",
96
        "rx-1024-1518-frames",
97
        "rx-jumbo-frames",
98
        "rx-mac-error-loss",
99
        "rx-pause-frames",
100
        "reserved",
101
        "rx-vlan-removed",
102
        "rx-vlan-replaced",
103
        "rx-vlan-inserted",
104
        "rx-ip-checksum-errors",
105
};
106
 
107
#define UEC_HW_STATS_LEN ARRAY_SIZE(hw_stat_gstrings)
108
#define UEC_TX_FW_STATS_LEN ARRAY_SIZE(tx_fw_stat_gstrings)
109
#define UEC_RX_FW_STATS_LEN ARRAY_SIZE(rx_fw_stat_gstrings)
110
 
111
extern int init_flow_control_params(u32 automatic_flow_control_mode,
112
                int rx_flow_control_enable,
113
                int tx_flow_control_enable, u16 pause_period,
114
                u16 extension_field, volatile u32 *upsmr_register,
115
                volatile u32 *uempr_register, volatile u32 *maccfg1_register);
116
 
117
static int
118
uec_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
119
{
120
        struct ucc_geth_private *ugeth = netdev_priv(netdev);
121
        struct phy_device *phydev = ugeth->phydev;
122
        struct ucc_geth_info *ug_info = ugeth->ug_info;
123
 
124
        if (!phydev)
125
                return -ENODEV;
126
 
127
        ecmd->maxtxpkt = 1;
128
        ecmd->maxrxpkt = ug_info->interruptcoalescingmaxvalue[0];
129
 
130
        return phy_ethtool_gset(phydev, ecmd);
131
}
132
 
133
static int
134
uec_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
135
{
136
        struct ucc_geth_private *ugeth = netdev_priv(netdev);
137
        struct phy_device *phydev = ugeth->phydev;
138
 
139
        if (!phydev)
140
                return -ENODEV;
141
 
142
        return phy_ethtool_sset(phydev, ecmd);
143
}
144
 
145
static void
146
uec_get_pauseparam(struct net_device *netdev,
147
                     struct ethtool_pauseparam *pause)
148
{
149
        struct ucc_geth_private *ugeth = netdev_priv(netdev);
150
 
151
        pause->autoneg = ugeth->phydev->autoneg;
152
 
153
        if (ugeth->ug_info->receiveFlowControl)
154
                pause->rx_pause = 1;
155
        if (ugeth->ug_info->transmitFlowControl)
156
                pause->tx_pause = 1;
157
}
158
 
159
static int
160
uec_set_pauseparam(struct net_device *netdev,
161
                     struct ethtool_pauseparam *pause)
162
{
163
        struct ucc_geth_private *ugeth = netdev_priv(netdev);
164
        int ret = 0;
165
 
166
        ugeth->ug_info->receiveFlowControl = pause->rx_pause;
167
        ugeth->ug_info->transmitFlowControl = pause->tx_pause;
168
 
169
        if (ugeth->phydev->autoneg) {
170
                if (netif_running(netdev)) {
171
                        /* FIXME: automatically restart */
172
                        printk(KERN_INFO
173
                                "Please re-open the interface.\n");
174
                }
175
        } else {
176
                struct ucc_geth_info *ug_info = ugeth->ug_info;
177
 
178
                ret = init_flow_control_params(ug_info->aufc,
179
                                        ug_info->receiveFlowControl,
180
                                        ug_info->transmitFlowControl,
181
                                        ug_info->pausePeriod,
182
                                        ug_info->extensionField,
183
                                        &ugeth->uccf->uf_regs->upsmr,
184
                                        &ugeth->ug_regs->uempr,
185
                                        &ugeth->ug_regs->maccfg1);
186
        }
187
 
188
        return ret;
189
}
190
 
191
static uint32_t
192
uec_get_msglevel(struct net_device *netdev)
193
{
194
        struct ucc_geth_private *ugeth = netdev_priv(netdev);
195
        return ugeth->msg_enable;
196
}
197
 
198
static void
199
uec_set_msglevel(struct net_device *netdev, uint32_t data)
200
{
201
        struct ucc_geth_private *ugeth = netdev_priv(netdev);
202
        ugeth->msg_enable = data;
203
}
204
 
205
static int
206
uec_get_regs_len(struct net_device *netdev)
207
{
208
        return sizeof(struct ucc_geth);
209
}
210
 
211
static void
212
uec_get_regs(struct net_device *netdev,
213
               struct ethtool_regs *regs, void *p)
214
{
215
        int i;
216
        struct ucc_geth_private *ugeth = netdev_priv(netdev);
217
        u32 __iomem *ug_regs = (u32 __iomem *)ugeth->ug_regs;
218
        u32 *buff = p;
219
 
220
        for (i = 0; i < sizeof(struct ucc_geth) / sizeof(u32); i++)
221
                buff[i] = in_be32(&ug_regs[i]);
222
}
223
 
224
static void
225
uec_get_ringparam(struct net_device *netdev,
226
                    struct ethtool_ringparam *ring)
227
{
228
        struct ucc_geth_private *ugeth = netdev_priv(netdev);
229
        struct ucc_geth_info *ug_info = ugeth->ug_info;
230
        int queue = 0;
231
 
232
        ring->rx_max_pending = UCC_GETH_BD_RING_SIZE_MAX;
233
        ring->rx_mini_max_pending = UCC_GETH_BD_RING_SIZE_MAX;
234
        ring->rx_jumbo_max_pending = UCC_GETH_BD_RING_SIZE_MAX;
235
        ring->tx_max_pending = UCC_GETH_BD_RING_SIZE_MAX;
236
 
237
        ring->rx_pending = ug_info->bdRingLenRx[queue];
238
        ring->rx_mini_pending = ug_info->bdRingLenRx[queue];
239
        ring->rx_jumbo_pending = ug_info->bdRingLenRx[queue];
240
        ring->tx_pending = ug_info->bdRingLenTx[queue];
241
}
242
 
243
static int
244
uec_set_ringparam(struct net_device *netdev,
245
                    struct ethtool_ringparam *ring)
246
{
247
        struct ucc_geth_private *ugeth = netdev_priv(netdev);
248
        struct ucc_geth_info *ug_info = ugeth->ug_info;
249
        int queue = 0, ret = 0;
250
 
251
        if (ring->rx_pending < UCC_GETH_RX_BD_RING_SIZE_MIN) {
252
                printk("%s: RxBD ring size must be no smaller than %d.\n",
253
                                netdev->name, UCC_GETH_RX_BD_RING_SIZE_MIN);
254
                return -EINVAL;
255
        }
256
        if (ring->rx_pending % UCC_GETH_RX_BD_RING_SIZE_ALIGNMENT) {
257
                printk("%s: RxBD ring size must be multiple of %d.\n",
258
                        netdev->name, UCC_GETH_RX_BD_RING_SIZE_ALIGNMENT);
259
                return -EINVAL;
260
        }
261
        if (ring->tx_pending < UCC_GETH_TX_BD_RING_SIZE_MIN) {
262
                printk("%s: TxBD ring size must be no smaller than %d.\n",
263
                                netdev->name, UCC_GETH_TX_BD_RING_SIZE_MIN);
264
                return -EINVAL;
265
        }
266
 
267
        ug_info->bdRingLenRx[queue] = ring->rx_pending;
268
        ug_info->bdRingLenTx[queue] = ring->tx_pending;
269
 
270
        if (netif_running(netdev)) {
271
                /* FIXME: restart automatically */
272
                printk(KERN_INFO
273
                        "Please re-open the interface.\n");
274
        }
275
 
276
        return ret;
277
}
278
 
279
static int uec_get_sset_count(struct net_device *netdev, int sset)
280
{
281
        struct ucc_geth_private *ugeth = netdev_priv(netdev);
282
        u32 stats_mode = ugeth->ug_info->statisticsMode;
283
        int len = 0;
284
 
285
        switch (sset) {
286
        case ETH_SS_STATS:
287
                if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_HARDWARE)
288
                        len += UEC_HW_STATS_LEN;
289
                if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX)
290
                        len += UEC_TX_FW_STATS_LEN;
291
                if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX)
292
                        len += UEC_RX_FW_STATS_LEN;
293
 
294
                return len;
295
 
296
        default:
297
                return -EOPNOTSUPP;
298
        }
299
}
300
 
301
static void uec_get_strings(struct net_device *netdev, u32 stringset, u8 *buf)
302
{
303
        struct ucc_geth_private *ugeth = netdev_priv(netdev);
304
        u32 stats_mode = ugeth->ug_info->statisticsMode;
305
 
306
        if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_HARDWARE) {
307
                memcpy(buf, hw_stat_gstrings, UEC_HW_STATS_LEN *
308
                                ETH_GSTRING_LEN);
309
                buf += UEC_HW_STATS_LEN * ETH_GSTRING_LEN;
310
        }
311
        if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX) {
312
                memcpy(buf, tx_fw_stat_gstrings, UEC_TX_FW_STATS_LEN *
313
                                ETH_GSTRING_LEN);
314
                buf += UEC_TX_FW_STATS_LEN * ETH_GSTRING_LEN;
315
        }
316
        if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX)
317
                memcpy(buf, tx_fw_stat_gstrings, UEC_RX_FW_STATS_LEN *
318
                                ETH_GSTRING_LEN);
319
}
320
 
321
static void uec_get_ethtool_stats(struct net_device *netdev,
322
                struct ethtool_stats *stats, uint64_t *data)
323
{
324
        struct ucc_geth_private *ugeth = netdev_priv(netdev);
325
        u32 stats_mode = ugeth->ug_info->statisticsMode;
326
        u32 __iomem *base;
327
        int i, j = 0;
328
 
329
        if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_HARDWARE) {
330
                base = (u32 __iomem *)&ugeth->ug_regs->tx64;
331
                for (i = 0; i < UEC_HW_STATS_LEN; i++)
332
                        data[j++] = (u64)in_be32(&base[i]);
333
        }
334
        if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX) {
335
                base = (u32 __iomem *)ugeth->p_tx_fw_statistics_pram;
336
                for (i = 0; i < UEC_TX_FW_STATS_LEN; i++)
337
                        data[j++] = (u64)in_be32(&base[i]);
338
        }
339
        if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX) {
340
                base = (u32 __iomem *)ugeth->p_rx_fw_statistics_pram;
341
                for (i = 0; i < UEC_RX_FW_STATS_LEN; i++)
342
                        data[j++] = (u64)in_be32(&base[i]);
343
        }
344
}
345
 
346
static int uec_nway_reset(struct net_device *netdev)
347
{
348
        struct ucc_geth_private *ugeth = netdev_priv(netdev);
349
 
350
        return phy_start_aneg(ugeth->phydev);
351
}
352
 
353
/* Report driver information */
354
static void
355
uec_get_drvinfo(struct net_device *netdev,
356
                       struct ethtool_drvinfo *drvinfo)
357
{
358
        strncpy(drvinfo->driver, DRV_NAME, 32);
359
        strncpy(drvinfo->version, DRV_VERSION, 32);
360
        strncpy(drvinfo->fw_version, "N/A", 32);
361
        strncpy(drvinfo->bus_info, "QUICC ENGINE", 32);
362
        drvinfo->eedump_len = 0;
363
        drvinfo->regdump_len = uec_get_regs_len(netdev);
364
}
365
 
366
static const struct ethtool_ops uec_ethtool_ops = {
367
        .get_settings           = uec_get_settings,
368
        .set_settings           = uec_set_settings,
369
        .get_drvinfo            = uec_get_drvinfo,
370
        .get_regs_len           = uec_get_regs_len,
371
        .get_regs               = uec_get_regs,
372
        .get_msglevel           = uec_get_msglevel,
373
        .set_msglevel           = uec_set_msglevel,
374
        .nway_reset             = uec_nway_reset,
375
        .get_link               = ethtool_op_get_link,
376
        .get_ringparam          = uec_get_ringparam,
377
        .set_ringparam          = uec_set_ringparam,
378
        .get_pauseparam         = uec_get_pauseparam,
379
        .set_pauseparam         = uec_set_pauseparam,
380
        .set_sg                 = ethtool_op_set_sg,
381
        .get_sset_count         = uec_get_sset_count,
382
        .get_strings            = uec_get_strings,
383
        .get_ethtool_stats      = uec_get_ethtool_stats,
384
};
385
 
386
void uec_set_ethtool_ops(struct net_device *netdev)
387
{
388
        SET_ETHTOOL_OPS(netdev, &uec_ethtool_ops);
389
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.