Commit e37c772e36a7943b2e0bd8f48312e78474c0df15
1 parent
251567848f
Exists in
master
and in
7 other branches
pasemi_mac: basic ethtool support
First cut at ethtool support, to be completed over time. Signed-off-by: Olof Johansson <olof@lixom.net> Acked-by: Jeff Garzik <jgarzik@pobox.com>
Showing 4 changed files with 189 additions and 19 deletions Side-by-side Diff
drivers/net/Makefile
... | ... | @@ -218,7 +218,8 @@ |
218 | 218 | obj-$(CONFIG_BFIN_MAC) += bfin_mac.o |
219 | 219 | obj-$(CONFIG_DM9000) += dm9000.o |
220 | 220 | obj-$(CONFIG_FEC_8XX) += fec_8xx/ |
221 | -obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o | |
221 | +obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o | |
222 | +pasemi_mac_driver-objs := pasemi_mac.o pasemi_mac_ethtool.o | |
222 | 223 | obj-$(CONFIG_MLX4_CORE) += mlx4/ |
223 | 224 | obj-$(CONFIG_ENC28J60) += enc28j60.o |
224 | 225 |
drivers/net/pasemi_mac.c
... | ... | @@ -55,12 +55,6 @@ |
55 | 55 | * - Multiqueue RX/TX |
56 | 56 | */ |
57 | 57 | |
58 | - | |
59 | -/* Must be a power of two */ | |
60 | -#define RX_RING_SIZE 2048 | |
61 | -#define TX_RING_SIZE 4096 | |
62 | -#define CS_RING_SIZE (TX_RING_SIZE*2) | |
63 | - | |
64 | 58 | #define LRO_MAX_AGGR 64 |
65 | 59 | |
66 | 60 | #define PE_MIN_MTU 64 |
... | ... | @@ -77,17 +71,6 @@ |
77 | 71 | NETIF_MSG_RX_ERR | \ |
78 | 72 | NETIF_MSG_TX_ERR) |
79 | 73 | |
80 | -#define TX_DESC(tx, num) ((tx)->chan.ring_virt[(num) & (TX_RING_SIZE-1)]) | |
81 | -#define TX_DESC_INFO(tx, num) ((tx)->ring_info[(num) & (TX_RING_SIZE-1)]) | |
82 | -#define RX_DESC(rx, num) ((rx)->chan.ring_virt[(num) & (RX_RING_SIZE-1)]) | |
83 | -#define RX_DESC_INFO(rx, num) ((rx)->ring_info[(num) & (RX_RING_SIZE-1)]) | |
84 | -#define RX_BUFF(rx, num) ((rx)->buffers[(num) & (RX_RING_SIZE-1)]) | |
85 | -#define CS_DESC(cs, num) ((cs)->chan.ring_virt[(num) & (CS_RING_SIZE-1)]) | |
86 | - | |
87 | -#define RING_USED(ring) (((ring)->next_to_fill - (ring)->next_to_clean) \ | |
88 | - & ((ring)->size - 1)) | |
89 | -#define RING_AVAIL(ring) ((ring->size) - RING_USED(ring)) | |
90 | - | |
91 | 74 | MODULE_LICENSE("GPL"); |
92 | 75 | MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>"); |
93 | 76 | MODULE_DESCRIPTION("PA Semi PWRficient Ethernet driver"); |
... | ... | @@ -96,6 +79,8 @@ |
96 | 79 | module_param(debug, int, 0); |
97 | 80 | MODULE_PARM_DESC(debug, "PA Semi MAC bitmapped debugging message enable value"); |
98 | 81 | |
82 | +extern const struct ethtool_ops pasemi_mac_ethtool_ops; | |
83 | + | |
99 | 84 | static int translation_enabled(void) |
100 | 85 | { |
101 | 86 | #if defined(CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE) |
... | ... | @@ -1148,7 +1133,7 @@ |
1148 | 1133 | { |
1149 | 1134 | struct pasemi_mac *mac = netdev_priv(dev); |
1150 | 1135 | unsigned int flags; |
1151 | - int ret; | |
1136 | + int i, ret; | |
1152 | 1137 | |
1153 | 1138 | flags = PAS_MAC_CFG_TXP_FCE | PAS_MAC_CFG_TXP_FPC(3) | |
1154 | 1139 | PAS_MAC_CFG_TXP_SL(3) | PAS_MAC_CFG_TXP_COB(0xf) | |
... | ... | @@ -1171,6 +1156,10 @@ |
1171 | 1156 | goto out_tx_ring; |
1172 | 1157 | } |
1173 | 1158 | |
1159 | + /* Zero out rmon counters */ | |
1160 | + for (i = 0; i < 32; i++) | |
1161 | + write_mac_reg(mac, PAS_MAC_RMON(i), 0); | |
1162 | + | |
1174 | 1163 | /* 0x3ff with 33MHz clock is about 31us */ |
1175 | 1164 | write_iob_reg(PAS_IOB_DMA_COM_TIMEOUTCFG, |
1176 | 1165 | PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0x3ff)); |
... | ... | @@ -1812,6 +1801,7 @@ |
1812 | 1801 | mac->bufsz = dev->mtu + ETH_HLEN + ETH_FCS_LEN + LOCAL_SKB_ALIGN + 128; |
1813 | 1802 | |
1814 | 1803 | dev->change_mtu = pasemi_mac_change_mtu; |
1804 | + dev->ethtool_ops = &pasemi_mac_ethtool_ops; | |
1815 | 1805 | |
1816 | 1806 | if (err) |
1817 | 1807 | goto out; |
drivers/net/pasemi_mac.h
... | ... | @@ -26,6 +26,12 @@ |
26 | 26 | #include <linux/spinlock.h> |
27 | 27 | #include <linux/phy.h> |
28 | 28 | |
29 | +/* Must be a power of two */ | |
30 | +#define RX_RING_SIZE 2048 | |
31 | +#define TX_RING_SIZE 4096 | |
32 | +#define CS_RING_SIZE (TX_RING_SIZE*2) | |
33 | + | |
34 | + | |
29 | 35 | #define MAX_LRO_DESCRIPTORS 8 |
30 | 36 | #define MAX_CS 2 |
31 | 37 | |
32 | 38 | |
... | ... | @@ -103,7 +109,17 @@ |
103 | 109 | dma_addr_t dma; |
104 | 110 | }; |
105 | 111 | |
112 | +#define TX_DESC(tx, num) ((tx)->chan.ring_virt[(num) & (TX_RING_SIZE-1)]) | |
113 | +#define TX_DESC_INFO(tx, num) ((tx)->ring_info[(num) & (TX_RING_SIZE-1)]) | |
114 | +#define RX_DESC(rx, num) ((rx)->chan.ring_virt[(num) & (RX_RING_SIZE-1)]) | |
115 | +#define RX_DESC_INFO(rx, num) ((rx)->ring_info[(num) & (RX_RING_SIZE-1)]) | |
116 | +#define RX_BUFF(rx, num) ((rx)->buffers[(num) & (RX_RING_SIZE-1)]) | |
117 | +#define CS_DESC(cs, num) ((cs)->chan.ring_virt[(num) & (CS_RING_SIZE-1)]) | |
106 | 118 | |
119 | +#define RING_USED(ring) (((ring)->next_to_fill - (ring)->next_to_clean) \ | |
120 | + & ((ring)->size - 1)) | |
121 | +#define RING_AVAIL(ring) ((ring->size) - RING_USED(ring)) | |
122 | + | |
107 | 123 | /* PCI register offsets and formats */ |
108 | 124 | |
109 | 125 | |
... | ... | @@ -114,6 +130,7 @@ |
114 | 130 | PAS_MAC_CFG_ADR0 = 0x8c, |
115 | 131 | PAS_MAC_CFG_ADR1 = 0x90, |
116 | 132 | PAS_MAC_CFG_TXP = 0x98, |
133 | + PAS_MAC_CFG_RMON = 0x100, | |
117 | 134 | PAS_MAC_IPC_CHNL = 0x208, |
118 | 135 | }; |
119 | 136 | |
... | ... | @@ -185,6 +202,8 @@ |
185 | 202 | #define PAS_MAC_CFG_TXP_TIFG(x) (((x) << PAS_MAC_CFG_TXP_TIFG_S) & \ |
186 | 203 | PAS_MAC_CFG_TXP_TIFG_M) |
187 | 204 | |
205 | +#define PAS_MAC_RMON(r) (0x100+(r)*4) | |
206 | + | |
188 | 207 | #define PAS_MAC_IPC_CHNL_DCHNO_M 0x003f0000 |
189 | 208 | #define PAS_MAC_IPC_CHNL_DCHNO_S 16 |
190 | 209 | #define PAS_MAC_IPC_CHNL_DCHNO(x) (((x) << PAS_MAC_IPC_CHNL_DCHNO_S) & \ |
... | ... | @@ -193,6 +212,7 @@ |
193 | 212 | #define PAS_MAC_IPC_CHNL_BCH_S 0 |
194 | 213 | #define PAS_MAC_IPC_CHNL_BCH(x) (((x) << PAS_MAC_IPC_CHNL_BCH_S) & \ |
195 | 214 | PAS_MAC_IPC_CHNL_BCH_M) |
215 | + | |
196 | 216 | |
197 | 217 | #endif /* PASEMI_MAC_H */ |
drivers/net/pasemi_mac_ethtool.c
1 | +/* | |
2 | + * Copyright (C) 2006-2008 PA Semi, Inc | |
3 | + * | |
4 | + * Ethtool hooks for the PA Semi PWRficient onchip 1G/10G Ethernet MACs | |
5 | + * | |
6 | + * This program is free software; you can redistribute it and/or modify | |
7 | + * it under the terms of the GNU General Public License version 2 as | |
8 | + * published by the Free Software Foundation. | |
9 | + * | |
10 | + * This program is distributed in the hope that it will be useful, | |
11 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | + * GNU General Public License for more details. | |
14 | + * | |
15 | + * You should have received a copy of the GNU General Public License | |
16 | + * along with this program; if not, write to the Free Software | |
17 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | + */ | |
19 | + | |
20 | + | |
21 | +#include <linux/netdevice.h> | |
22 | +#include <linux/ethtool.h> | |
23 | +#include <linux/pci.h> | |
24 | +#include <linux/inet_lro.h> | |
25 | + | |
26 | +#include <asm/pasemi_dma.h> | |
27 | +#include "pasemi_mac.h" | |
28 | + | |
29 | +static struct { | |
30 | + const char str[ETH_GSTRING_LEN]; | |
31 | +} ethtool_stats_keys[] = { | |
32 | + { "rx-drops" }, | |
33 | + { "rx-bytes" }, | |
34 | + { "rx-packets" }, | |
35 | + { "rx-broadcast-packets" }, | |
36 | + { "rx-multicast-packets" }, | |
37 | + { "rx-crc-errors" }, | |
38 | + { "rx-undersize-errors" }, | |
39 | + { "rx-oversize-errors" }, | |
40 | + { "rx-short-fragment-errors" }, | |
41 | + { "rx-jabber-errors" }, | |
42 | + { "rx-64-byte-packets" }, | |
43 | + { "rx-65-127-byte-packets" }, | |
44 | + { "rx-128-255-byte-packets" }, | |
45 | + { "rx-256-511-byte-packets" }, | |
46 | + { "rx-512-1023-byte-packets" }, | |
47 | + { "rx-1024-1518-byte-packets" }, | |
48 | + { "rx-pause-frames" }, | |
49 | + { "tx-bytes" }, | |
50 | + { "tx-packets" }, | |
51 | + { "tx-broadcast-packets" }, | |
52 | + { "tx-multicast-packets" }, | |
53 | + { "tx-collisions" }, | |
54 | + { "tx-late-collisions" }, | |
55 | + { "tx-excessive-collisions" }, | |
56 | + { "tx-crc-errors" }, | |
57 | + { "tx-undersize-errors" }, | |
58 | + { "tx-oversize-errors" }, | |
59 | + { "tx-64-byte-packets" }, | |
60 | + { "tx-65-127-byte-packets" }, | |
61 | + { "tx-128-255-byte-packets" }, | |
62 | + { "tx-256-511-byte-packets" }, | |
63 | + { "tx-512-1023-byte-packets" }, | |
64 | + { "tx-1024-1518-byte-packets" }, | |
65 | +}; | |
66 | + | |
67 | +static int | |
68 | +pasemi_mac_ethtool_get_settings(struct net_device *netdev, | |
69 | + struct ethtool_cmd *cmd) | |
70 | +{ | |
71 | + struct pasemi_mac *mac = netdev_priv(netdev); | |
72 | + struct phy_device *phydev = mac->phydev; | |
73 | + | |
74 | + return phy_ethtool_gset(phydev, cmd); | |
75 | +} | |
76 | + | |
77 | +static void | |
78 | +pasemi_mac_ethtool_get_drvinfo(struct net_device *netdev, | |
79 | + struct ethtool_drvinfo *drvinfo) | |
80 | +{ | |
81 | + struct pasemi_mac *mac; | |
82 | + mac = netdev_priv(netdev); | |
83 | + | |
84 | + /* clear and fill out info */ | |
85 | + memset(drvinfo, 0, sizeof(struct ethtool_drvinfo)); | |
86 | + strncpy(drvinfo->driver, "pasemi_mac", 12); | |
87 | + strcpy(drvinfo->version, "N/A"); | |
88 | + strcpy(drvinfo->fw_version, "N/A"); | |
89 | + strncpy(drvinfo->bus_info, pci_name(mac->pdev), 32); | |
90 | +} | |
91 | + | |
92 | +static u32 | |
93 | +pasemi_mac_ethtool_get_msglevel(struct net_device *netdev) | |
94 | +{ | |
95 | + struct pasemi_mac *mac = netdev_priv(netdev); | |
96 | + return mac->msg_enable; | |
97 | +} | |
98 | + | |
99 | +static void | |
100 | +pasemi_mac_ethtool_set_msglevel(struct net_device *netdev, | |
101 | + u32 level) | |
102 | +{ | |
103 | + struct pasemi_mac *mac = netdev_priv(netdev); | |
104 | + mac->msg_enable = level; | |
105 | +} | |
106 | + | |
107 | + | |
108 | +static void | |
109 | +pasemi_mac_ethtool_get_ringparam(struct net_device *netdev, | |
110 | + struct ethtool_ringparam *ering) | |
111 | +{ | |
112 | + struct pasemi_mac *mac = netdev->priv; | |
113 | + | |
114 | + ering->tx_max_pending = TX_RING_SIZE/2; | |
115 | + ering->tx_pending = RING_USED(mac->tx)/2; | |
116 | + ering->rx_max_pending = RX_RING_SIZE/4; | |
117 | + ering->rx_pending = RING_USED(mac->rx)/4; | |
118 | +} | |
119 | + | |
120 | +static int pasemi_mac_get_sset_count(struct net_device *netdev, int sset) | |
121 | +{ | |
122 | + switch (sset) { | |
123 | + case ETH_SS_STATS: | |
124 | + return ARRAY_SIZE(ethtool_stats_keys); | |
125 | + default: | |
126 | + return -EOPNOTSUPP; | |
127 | + } | |
128 | +} | |
129 | + | |
130 | +static void pasemi_mac_get_ethtool_stats(struct net_device *netdev, | |
131 | + struct ethtool_stats *stats, u64 *data) | |
132 | +{ | |
133 | + struct pasemi_mac *mac = netdev->priv; | |
134 | + int i; | |
135 | + | |
136 | + data[0] = pasemi_read_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if)) | |
137 | + >> PAS_DMA_RXINT_RCMDSTA_DROPS_S; | |
138 | + for (i = 0; i < 32; i++) | |
139 | + data[1+i] = pasemi_read_mac_reg(mac->dma_if, PAS_MAC_RMON(i)); | |
140 | +} | |
141 | + | |
142 | +static void pasemi_mac_get_strings(struct net_device *netdev, u32 stringset, | |
143 | + u8 *data) | |
144 | +{ | |
145 | + memcpy(data, ethtool_stats_keys, sizeof(ethtool_stats_keys)); | |
146 | +} | |
147 | + | |
148 | +const struct ethtool_ops pasemi_mac_ethtool_ops = { | |
149 | + .get_settings = pasemi_mac_ethtool_get_settings, | |
150 | + .get_drvinfo = pasemi_mac_ethtool_get_drvinfo, | |
151 | + .get_msglevel = pasemi_mac_ethtool_get_msglevel, | |
152 | + .set_msglevel = pasemi_mac_ethtool_set_msglevel, | |
153 | + .get_link = ethtool_op_get_link, | |
154 | + .get_ringparam = pasemi_mac_ethtool_get_ringparam, | |
155 | + .get_strings = pasemi_mac_get_strings, | |
156 | + .get_sset_count = pasemi_mac_get_sset_count, | |
157 | + .get_ethtool_stats = pasemi_mac_get_ethtool_stats, | |
158 | +}; |