Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+189 -19
+2 -1
drivers/net/Makefile
··· 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
+8 -18
drivers/net/pasemi_mac.c
··· 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 ··· 71 77 NETIF_MSG_RX_ERR | \ 72 78 NETIF_MSG_TX_ERR) 73 79 74 - #define TX_DESC(tx, num) ((tx)->chan.ring_virt[(num) & (TX_RING_SIZE-1)]) 75 - #define TX_DESC_INFO(tx, num) ((tx)->ring_info[(num) & (TX_RING_SIZE-1)]) 76 - #define RX_DESC(rx, num) ((rx)->chan.ring_virt[(num) & (RX_RING_SIZE-1)]) 77 - #define RX_DESC_INFO(rx, num) ((rx)->ring_info[(num) & (RX_RING_SIZE-1)]) 78 - #define RX_BUFF(rx, num) ((rx)->buffers[(num) & (RX_RING_SIZE-1)]) 79 - #define CS_DESC(cs, num) ((cs)->chan.ring_virt[(num) & (CS_RING_SIZE-1)]) 80 - 81 - #define RING_USED(ring) (((ring)->next_to_fill - (ring)->next_to_clean) \ 82 - & ((ring)->size - 1)) 83 - #define RING_AVAIL(ring) ((ring->size) - RING_USED(ring)) 84 - 85 80 MODULE_LICENSE("GPL"); 86 81 MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>"); 87 82 MODULE_DESCRIPTION("PA Semi PWRficient Ethernet driver"); ··· 78 95 static int debug = -1; /* -1 == use DEFAULT_MSG_ENABLE as value */ 79 96 module_param(debug, int, 0); 80 97 MODULE_PARM_DESC(debug, "PA Semi MAC bitmapped debugging message enable value"); 98 + 99 + extern const struct ethtool_ops pasemi_mac_ethtool_ops; 81 100 82 101 static int translation_enabled(void) 83 102 { ··· 1133 1148 { 1134 1149 struct pasemi_mac *mac = netdev_priv(dev); 1135 1150 unsigned int flags; 1136 - int ret; 1151 + int i, ret; 1137 1152 1138 1153 flags = PAS_MAC_CFG_TXP_FCE | PAS_MAC_CFG_TXP_FPC(3) | 1139 1154 PAS_MAC_CFG_TXP_SL(3) | PAS_MAC_CFG_TXP_COB(0xf) | ··· 1155 1170 if (!mac->num_cs) 1156 1171 goto out_tx_ring; 1157 1172 } 1173 + 1174 + /* Zero out rmon counters */ 1175 + for (i = 0; i < 32; i++) 1176 + write_mac_reg(mac, PAS_MAC_RMON(i), 0); 1158 1177 1159 1178 /* 0x3ff with 33MHz clock is about 31us */ 1160 1179 write_iob_reg(PAS_IOB_DMA_COM_TIMEOUTCFG, ··· 1801 1812 mac->bufsz = dev->mtu + ETH_HLEN + ETH_FCS_LEN + LOCAL_SKB_ALIGN + 128; 1802 1813 1803 1814 dev->change_mtu = pasemi_mac_change_mtu; 1815 + dev->ethtool_ops = &pasemi_mac_ethtool_ops; 1804 1816 1805 1817 if (err) 1806 1818 goto out;
+20
drivers/net/pasemi_mac.h
··· 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 ··· 109 103 dma_addr_t dma; 110 104 }; 111 105 106 + #define TX_DESC(tx, num) ((tx)->chan.ring_virt[(num) & (TX_RING_SIZE-1)]) 107 + #define TX_DESC_INFO(tx, num) ((tx)->ring_info[(num) & (TX_RING_SIZE-1)]) 108 + #define RX_DESC(rx, num) ((rx)->chan.ring_virt[(num) & (RX_RING_SIZE-1)]) 109 + #define RX_DESC_INFO(rx, num) ((rx)->ring_info[(num) & (RX_RING_SIZE-1)]) 110 + #define RX_BUFF(rx, num) ((rx)->buffers[(num) & (RX_RING_SIZE-1)]) 111 + #define CS_DESC(cs, num) ((cs)->chan.ring_virt[(num) & (CS_RING_SIZE-1)]) 112 + 113 + #define RING_USED(ring) (((ring)->next_to_fill - (ring)->next_to_clean) \ 114 + & ((ring)->size - 1)) 115 + #define RING_AVAIL(ring) ((ring->size) - RING_USED(ring)) 112 116 113 117 /* PCI register offsets and formats */ 114 118 ··· 130 114 PAS_MAC_CFG_ADR0 = 0x8c, 131 115 PAS_MAC_CFG_ADR1 = 0x90, 132 116 PAS_MAC_CFG_TXP = 0x98, 117 + PAS_MAC_CFG_RMON = 0x100, 133 118 PAS_MAC_IPC_CHNL = 0x208, 134 119 }; 135 120 ··· 202 185 #define PAS_MAC_CFG_TXP_TIFG(x) (((x) << PAS_MAC_CFG_TXP_TIFG_S) & \ 203 186 PAS_MAC_CFG_TXP_TIFG_M) 204 187 188 + #define PAS_MAC_RMON(r) (0x100+(r)*4) 189 + 205 190 #define PAS_MAC_IPC_CHNL_DCHNO_M 0x003f0000 206 191 #define PAS_MAC_IPC_CHNL_DCHNO_S 16 207 192 #define PAS_MAC_IPC_CHNL_DCHNO(x) (((x) << PAS_MAC_IPC_CHNL_DCHNO_S) & \ ··· 212 193 #define PAS_MAC_IPC_CHNL_BCH_S 0 213 194 #define PAS_MAC_IPC_CHNL_BCH(x) (((x) << PAS_MAC_IPC_CHNL_BCH_S) & \ 214 195 PAS_MAC_IPC_CHNL_BCH_M) 196 + 215 197 216 198 #endif /* PASEMI_MAC_H */
+159
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 + }; 159 +