aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/Makefile3
-rw-r--r--drivers/net/pasemi_mac.c26
-rw-r--r--drivers/net/pasemi_mac.h20
-rw-r--r--drivers/net/pasemi_mac_ethtool.c159
4 files changed, 189 insertions, 19 deletions
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 3b1ea321dc05..4b442739e7bf 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -218,7 +218,8 @@ obj-$(CONFIG_SMC911X) += smc911x.o
218obj-$(CONFIG_BFIN_MAC) += bfin_mac.o 218obj-$(CONFIG_BFIN_MAC) += bfin_mac.o
219obj-$(CONFIG_DM9000) += dm9000.o 219obj-$(CONFIG_DM9000) += dm9000.o
220obj-$(CONFIG_FEC_8XX) += fec_8xx/ 220obj-$(CONFIG_FEC_8XX) += fec_8xx/
221obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o 221obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o
222pasemi_mac_driver-objs := pasemi_mac.o pasemi_mac_ethtool.o
222obj-$(CONFIG_MLX4_CORE) += mlx4/ 223obj-$(CONFIG_MLX4_CORE) += mlx4/
223obj-$(CONFIG_ENC28J60) += enc28j60.o 224obj-$(CONFIG_ENC28J60) += enc28j60.o
224 225
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index 5ee7e4a73ae0..c50f0f4de6d8 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -55,12 +55,6 @@
55 * - Multiqueue RX/TX 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#define LRO_MAX_AGGR 64 58#define LRO_MAX_AGGR 64
65 59
66#define PE_MIN_MTU 64 60#define PE_MIN_MTU 64
@@ -77,17 +71,6 @@
77 NETIF_MSG_RX_ERR | \ 71 NETIF_MSG_RX_ERR | \
78 NETIF_MSG_TX_ERR) 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
91MODULE_LICENSE("GPL"); 74MODULE_LICENSE("GPL");
92MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>"); 75MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>");
93MODULE_DESCRIPTION("PA Semi PWRficient Ethernet driver"); 76MODULE_DESCRIPTION("PA Semi PWRficient Ethernet driver");
@@ -96,6 +79,8 @@ static int debug = -1; /* -1 == use DEFAULT_MSG_ENABLE as value */
96module_param(debug, int, 0); 79module_param(debug, int, 0);
97MODULE_PARM_DESC(debug, "PA Semi MAC bitmapped debugging message enable value"); 80MODULE_PARM_DESC(debug, "PA Semi MAC bitmapped debugging message enable value");
98 81
82extern const struct ethtool_ops pasemi_mac_ethtool_ops;
83
99static int translation_enabled(void) 84static int translation_enabled(void)
100{ 85{
101#if defined(CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE) 86#if defined(CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE)
@@ -1148,7 +1133,7 @@ static int pasemi_mac_open(struct net_device *dev)
1148{ 1133{
1149 struct pasemi_mac *mac = netdev_priv(dev); 1134 struct pasemi_mac *mac = netdev_priv(dev);
1150 unsigned int flags; 1135 unsigned int flags;
1151 int ret; 1136 int i, ret;
1152 1137
1153 flags = PAS_MAC_CFG_TXP_FCE | PAS_MAC_CFG_TXP_FPC(3) | 1138 flags = PAS_MAC_CFG_TXP_FCE | PAS_MAC_CFG_TXP_FPC(3) |
1154 PAS_MAC_CFG_TXP_SL(3) | PAS_MAC_CFG_TXP_COB(0xf) | 1139 PAS_MAC_CFG_TXP_SL(3) | PAS_MAC_CFG_TXP_COB(0xf) |
@@ -1171,6 +1156,10 @@ static int pasemi_mac_open(struct net_device *dev)
1171 goto out_tx_ring; 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 /* 0x3ff with 33MHz clock is about 31us */ 1163 /* 0x3ff with 33MHz clock is about 31us */
1175 write_iob_reg(PAS_IOB_DMA_COM_TIMEOUTCFG, 1164 write_iob_reg(PAS_IOB_DMA_COM_TIMEOUTCFG,
1176 PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0x3ff)); 1165 PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0x3ff));
@@ -1812,6 +1801,7 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1812 mac->bufsz = dev->mtu + ETH_HLEN + ETH_FCS_LEN + LOCAL_SKB_ALIGN + 128; 1801 mac->bufsz = dev->mtu + ETH_HLEN + ETH_FCS_LEN + LOCAL_SKB_ALIGN + 128;
1813 1802
1814 dev->change_mtu = pasemi_mac_change_mtu; 1803 dev->change_mtu = pasemi_mac_change_mtu;
1804 dev->ethtool_ops = &pasemi_mac_ethtool_ops;
1815 1805
1816 if (err) 1806 if (err)
1817 goto out; 1807 goto out;
diff --git a/drivers/net/pasemi_mac.h b/drivers/net/pasemi_mac.h
index 90c51670a1e7..1a115ec60b53 100644
--- a/drivers/net/pasemi_mac.h
+++ b/drivers/net/pasemi_mac.h
@@ -26,6 +26,12 @@
26#include <linux/spinlock.h> 26#include <linux/spinlock.h>
27#include <linux/phy.h> 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#define MAX_LRO_DESCRIPTORS 8 35#define MAX_LRO_DESCRIPTORS 8
30#define MAX_CS 2 36#define MAX_CS 2
31 37
@@ -103,6 +109,16 @@ struct pasemi_mac_buffer {
103 dma_addr_t dma; 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)])
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))
106 122
107/* PCI register offsets and formats */ 123/* PCI register offsets and formats */
108 124
@@ -114,6 +130,7 @@ enum {
114 PAS_MAC_CFG_ADR0 = 0x8c, 130 PAS_MAC_CFG_ADR0 = 0x8c,
115 PAS_MAC_CFG_ADR1 = 0x90, 131 PAS_MAC_CFG_ADR1 = 0x90,
116 PAS_MAC_CFG_TXP = 0x98, 132 PAS_MAC_CFG_TXP = 0x98,
133 PAS_MAC_CFG_RMON = 0x100,
117 PAS_MAC_IPC_CHNL = 0x208, 134 PAS_MAC_IPC_CHNL = 0x208,
118}; 135};
119 136
@@ -185,6 +202,8 @@ enum {
185#define PAS_MAC_CFG_TXP_TIFG(x) (((x) << PAS_MAC_CFG_TXP_TIFG_S) & \ 202#define PAS_MAC_CFG_TXP_TIFG(x) (((x) << PAS_MAC_CFG_TXP_TIFG_S) & \
186 PAS_MAC_CFG_TXP_TIFG_M) 203 PAS_MAC_CFG_TXP_TIFG_M)
187 204
205#define PAS_MAC_RMON(r) (0x100+(r)*4)
206
188#define PAS_MAC_IPC_CHNL_DCHNO_M 0x003f0000 207#define PAS_MAC_IPC_CHNL_DCHNO_M 0x003f0000
189#define PAS_MAC_IPC_CHNL_DCHNO_S 16 208#define PAS_MAC_IPC_CHNL_DCHNO_S 16
190#define PAS_MAC_IPC_CHNL_DCHNO(x) (((x) << PAS_MAC_IPC_CHNL_DCHNO_S) & \ 209#define PAS_MAC_IPC_CHNL_DCHNO(x) (((x) << PAS_MAC_IPC_CHNL_DCHNO_S) & \
@@ -194,4 +213,5 @@ enum {
194#define PAS_MAC_IPC_CHNL_BCH(x) (((x) << PAS_MAC_IPC_CHNL_BCH_S) & \ 213#define PAS_MAC_IPC_CHNL_BCH(x) (((x) << PAS_MAC_IPC_CHNL_BCH_S) & \
195 PAS_MAC_IPC_CHNL_BCH_M) 214 PAS_MAC_IPC_CHNL_BCH_M)
196 215
216
197#endif /* PASEMI_MAC_H */ 217#endif /* PASEMI_MAC_H */
diff --git a/drivers/net/pasemi_mac_ethtool.c b/drivers/net/pasemi_mac_ethtool.c
new file mode 100644
index 000000000000..5e8df3afea64
--- /dev/null
+++ b/drivers/net/pasemi_mac_ethtool.c
@@ -0,0 +1,159 @@
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
29static 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
67static int
68pasemi_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
77static void
78pasemi_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
92static u32
93pasemi_mac_ethtool_get_msglevel(struct net_device *netdev)
94{
95 struct pasemi_mac *mac = netdev_priv(netdev);
96 return mac->msg_enable;
97}
98
99static void
100pasemi_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
108static void
109pasemi_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
120static 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
130static 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
142static 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
148const 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};
159