Commit e37c772e36a7943b2e0bd8f48312e78474c0df15

Authored by Olof Johansson
1 parent 251567848f

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 +};