diff options
| author | Vince Bridgers <vbridgers2013@gmail.com> | 2014-03-17 18:52:37 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2014-03-17 21:26:57 -0400 |
| commit | 6c3324a96b4991d91c25d9fe6b52f5024e2cb8c5 (patch) | |
| tree | d24eadf0b4493b97ddf4e2535a203186020bc92a /drivers/net/ethernet/altera | |
| parent | f64f8808bcb9965e7e935bfab17951726750654b (diff) | |
Altera TSE: Add Miscellaneous Files for Altera Ethernet Driver
This patch adds miscellaneous files for the Altera Ethernet Driver,
including ethtool support.
Signed-off-by: Vince Bridgers <vbridgers2013@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/altera')
| -rw-r--r-- | drivers/net/ethernet/altera/altera_tse_ethtool.c | 227 | ||||
| -rw-r--r-- | drivers/net/ethernet/altera/altera_utils.c | 44 | ||||
| -rw-r--r-- | drivers/net/ethernet/altera/altera_utils.h | 27 |
3 files changed, 298 insertions, 0 deletions
diff --git a/drivers/net/ethernet/altera/altera_tse_ethtool.c b/drivers/net/ethernet/altera/altera_tse_ethtool.c new file mode 100644 index 000000000000..63ac5f4960e4 --- /dev/null +++ b/drivers/net/ethernet/altera/altera_tse_ethtool.c | |||
| @@ -0,0 +1,227 @@ | |||
| 1 | /* Ethtool support for Altera Triple-Speed Ethernet MAC driver | ||
| 2 | * Copyright (C) 2008-2014 Altera Corporation. All rights reserved | ||
| 3 | * | ||
| 4 | * Contributors: | ||
| 5 | * Dalon Westergreen | ||
| 6 | * Thomas Chou | ||
| 7 | * Ian Abbott | ||
| 8 | * Yuriy Kozlov | ||
| 9 | * Tobias Klauser | ||
| 10 | * Andriy Smolskyy | ||
| 11 | * Roman Bulgakov | ||
| 12 | * Dmytro Mytarchuk | ||
| 13 | * | ||
| 14 | * Original driver contributed by SLS. | ||
| 15 | * Major updates contributed by GlobalLogic | ||
| 16 | * | ||
| 17 | * This program is free software; you can redistribute it and/or modify it | ||
| 18 | * under the terms and conditions of the GNU General Public License, | ||
| 19 | * version 2, as published by the Free Software Foundation. | ||
| 20 | * | ||
| 21 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 22 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 23 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 24 | * more details. | ||
| 25 | * | ||
| 26 | * You should have received a copy of the GNU General Public License along with | ||
| 27 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 28 | */ | ||
| 29 | |||
| 30 | #include <linux/ethtool.h> | ||
| 31 | #include <linux/kernel.h> | ||
| 32 | #include <linux/netdevice.h> | ||
| 33 | #include <linux/phy.h> | ||
| 34 | |||
| 35 | #include "altera_tse.h" | ||
| 36 | |||
| 37 | #define TSE_STATS_LEN 31 | ||
| 38 | #define TSE_NUM_REGS 128 | ||
| 39 | |||
| 40 | static char const stat_gstrings[][ETH_GSTRING_LEN] = { | ||
| 41 | "tx_packets", | ||
| 42 | "rx_packets", | ||
| 43 | "rx_crc_errors", | ||
| 44 | "rx_align_errors", | ||
| 45 | "tx_bytes", | ||
| 46 | "rx_bytes", | ||
| 47 | "tx_pause", | ||
| 48 | "rx_pause", | ||
| 49 | "rx_errors", | ||
| 50 | "tx_errors", | ||
| 51 | "rx_unicast", | ||
| 52 | "rx_multicast", | ||
| 53 | "rx_broadcast", | ||
| 54 | "tx_discards", | ||
| 55 | "tx_unicast", | ||
| 56 | "tx_multicast", | ||
| 57 | "tx_broadcast", | ||
| 58 | "ether_drops", | ||
| 59 | "rx_total_bytes", | ||
| 60 | "rx_total_packets", | ||
| 61 | "rx_undersize", | ||
| 62 | "rx_oversize", | ||
| 63 | "rx_64_bytes", | ||
| 64 | "rx_65_127_bytes", | ||
| 65 | "rx_128_255_bytes", | ||
| 66 | "rx_256_511_bytes", | ||
| 67 | "rx_512_1023_bytes", | ||
| 68 | "rx_1024_1518_bytes", | ||
| 69 | "rx_gte_1519_bytes", | ||
| 70 | "rx_jabbers", | ||
| 71 | "rx_runts", | ||
| 72 | }; | ||
| 73 | |||
| 74 | static void tse_get_drvinfo(struct net_device *dev, | ||
| 75 | struct ethtool_drvinfo *info) | ||
| 76 | { | ||
| 77 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 78 | u32 rev = ioread32(&priv->mac_dev->megacore_revision); | ||
| 79 | |||
| 80 | strcpy(info->driver, "Altera TSE MAC IP Driver"); | ||
| 81 | strcpy(info->version, "v8.0"); | ||
| 82 | snprintf(info->fw_version, ETHTOOL_FWVERS_LEN, "v%d.%d", | ||
| 83 | rev & 0xFFFF, (rev & 0xFFFF0000) >> 16); | ||
| 84 | sprintf(info->bus_info, "platform"); | ||
| 85 | } | ||
| 86 | |||
| 87 | /* Fill in a buffer with the strings which correspond to the | ||
| 88 | * stats | ||
| 89 | */ | ||
| 90 | static void tse_gstrings(struct net_device *dev, u32 stringset, u8 *buf) | ||
| 91 | { | ||
| 92 | memcpy(buf, stat_gstrings, TSE_STATS_LEN * ETH_GSTRING_LEN); | ||
| 93 | } | ||
| 94 | |||
| 95 | static void tse_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, | ||
| 96 | u64 *buf) | ||
| 97 | { | ||
| 98 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 99 | struct altera_tse_mac *mac = priv->mac_dev; | ||
| 100 | u64 ext; | ||
| 101 | |||
| 102 | buf[0] = ioread32(&mac->frames_transmitted_ok); | ||
| 103 | buf[1] = ioread32(&mac->frames_received_ok); | ||
| 104 | buf[2] = ioread32(&mac->frames_check_sequence_errors); | ||
| 105 | buf[3] = ioread32(&mac->alignment_errors); | ||
| 106 | |||
| 107 | /* Extended aOctetsTransmittedOK counter */ | ||
| 108 | ext = (u64) ioread32(&mac->msb_octets_transmitted_ok) << 32; | ||
| 109 | ext |= ioread32(&mac->octets_transmitted_ok); | ||
| 110 | buf[4] = ext; | ||
| 111 | |||
| 112 | /* Extended aOctetsReceivedOK counter */ | ||
| 113 | ext = (u64) ioread32(&mac->msb_octets_received_ok) << 32; | ||
| 114 | ext |= ioread32(&mac->octets_received_ok); | ||
| 115 | buf[5] = ext; | ||
| 116 | |||
| 117 | buf[6] = ioread32(&mac->tx_pause_mac_ctrl_frames); | ||
| 118 | buf[7] = ioread32(&mac->rx_pause_mac_ctrl_frames); | ||
| 119 | buf[8] = ioread32(&mac->if_in_errors); | ||
| 120 | buf[9] = ioread32(&mac->if_out_errors); | ||
| 121 | buf[10] = ioread32(&mac->if_in_ucast_pkts); | ||
| 122 | buf[11] = ioread32(&mac->if_in_multicast_pkts); | ||
| 123 | buf[12] = ioread32(&mac->if_in_broadcast_pkts); | ||
| 124 | buf[13] = ioread32(&mac->if_out_discards); | ||
| 125 | buf[14] = ioread32(&mac->if_out_ucast_pkts); | ||
| 126 | buf[15] = ioread32(&mac->if_out_multicast_pkts); | ||
| 127 | buf[16] = ioread32(&mac->if_out_broadcast_pkts); | ||
| 128 | buf[17] = ioread32(&mac->ether_stats_drop_events); | ||
| 129 | |||
| 130 | /* Extended etherStatsOctets counter */ | ||
| 131 | ext = (u64) ioread32(&mac->msb_ether_stats_octets) << 32; | ||
| 132 | ext |= ioread32(&mac->ether_stats_octets); | ||
| 133 | buf[18] = ext; | ||
| 134 | |||
| 135 | buf[19] = ioread32(&mac->ether_stats_pkts); | ||
| 136 | buf[20] = ioread32(&mac->ether_stats_undersize_pkts); | ||
| 137 | buf[21] = ioread32(&mac->ether_stats_oversize_pkts); | ||
| 138 | buf[22] = ioread32(&mac->ether_stats_pkts_64_octets); | ||
| 139 | buf[23] = ioread32(&mac->ether_stats_pkts_65to127_octets); | ||
| 140 | buf[24] = ioread32(&mac->ether_stats_pkts_128to255_octets); | ||
| 141 | buf[25] = ioread32(&mac->ether_stats_pkts_256to511_octets); | ||
| 142 | buf[26] = ioread32(&mac->ether_stats_pkts_512to1023_octets); | ||
| 143 | buf[27] = ioread32(&mac->ether_stats_pkts_1024to1518_octets); | ||
| 144 | buf[28] = ioread32(&mac->ether_stats_pkts_1519tox_octets); | ||
| 145 | buf[29] = ioread32(&mac->ether_stats_jabbers); | ||
| 146 | buf[30] = ioread32(&mac->ether_stats_fragments); | ||
| 147 | } | ||
| 148 | |||
| 149 | static int tse_sset_count(struct net_device *dev, int sset) | ||
| 150 | { | ||
| 151 | switch (sset) { | ||
| 152 | case ETH_SS_STATS: | ||
| 153 | return TSE_STATS_LEN; | ||
| 154 | default: | ||
| 155 | return -EOPNOTSUPP; | ||
| 156 | } | ||
| 157 | } | ||
| 158 | |||
| 159 | static u32 tse_get_msglevel(struct net_device *dev) | ||
| 160 | { | ||
| 161 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 162 | return priv->msg_enable; | ||
| 163 | } | ||
| 164 | |||
| 165 | static void tse_set_msglevel(struct net_device *dev, uint32_t data) | ||
| 166 | { | ||
| 167 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 168 | priv->msg_enable = data; | ||
| 169 | } | ||
| 170 | |||
| 171 | static int tse_reglen(struct net_device *dev) | ||
| 172 | { | ||
| 173 | return TSE_NUM_REGS * sizeof(u32); | ||
| 174 | } | ||
| 175 | |||
| 176 | static void tse_get_regs(struct net_device *dev, struct ethtool_regs *regs, | ||
| 177 | void *regbuf) | ||
| 178 | { | ||
| 179 | int i; | ||
| 180 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 181 | u32 *tse_mac_regs = (u32 *)priv->mac_dev; | ||
| 182 | u32 *buf = regbuf; | ||
| 183 | |||
| 184 | for (i = 0; i < TSE_NUM_REGS; i++) | ||
| 185 | buf[i] = ioread32(&tse_mac_regs[i]); | ||
| 186 | } | ||
| 187 | |||
| 188 | static int tse_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
| 189 | { | ||
| 190 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 191 | struct phy_device *phydev = priv->phydev; | ||
| 192 | |||
| 193 | if (phydev == NULL) | ||
| 194 | return -ENODEV; | ||
| 195 | |||
| 196 | return phy_ethtool_gset(phydev, cmd); | ||
| 197 | } | ||
| 198 | |||
| 199 | static int tse_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
| 200 | { | ||
| 201 | struct altera_tse_private *priv = netdev_priv(dev); | ||
| 202 | struct phy_device *phydev = priv->phydev; | ||
| 203 | |||
| 204 | if (phydev == NULL) | ||
| 205 | return -ENODEV; | ||
| 206 | |||
| 207 | return phy_ethtool_sset(phydev, cmd); | ||
| 208 | } | ||
| 209 | |||
| 210 | static const struct ethtool_ops tse_ethtool_ops = { | ||
| 211 | .get_drvinfo = tse_get_drvinfo, | ||
| 212 | .get_regs_len = tse_reglen, | ||
| 213 | .get_regs = tse_get_regs, | ||
| 214 | .get_link = ethtool_op_get_link, | ||
| 215 | .get_settings = tse_get_settings, | ||
| 216 | .set_settings = tse_set_settings, | ||
| 217 | .get_strings = tse_gstrings, | ||
| 218 | .get_sset_count = tse_sset_count, | ||
| 219 | .get_ethtool_stats = tse_fill_stats, | ||
| 220 | .get_msglevel = tse_get_msglevel, | ||
| 221 | .set_msglevel = tse_set_msglevel, | ||
| 222 | }; | ||
| 223 | |||
| 224 | void altera_tse_set_ethtool_ops(struct net_device *netdev) | ||
| 225 | { | ||
| 226 | SET_ETHTOOL_OPS(netdev, &tse_ethtool_ops); | ||
| 227 | } | ||
diff --git a/drivers/net/ethernet/altera/altera_utils.c b/drivers/net/ethernet/altera/altera_utils.c new file mode 100644 index 000000000000..70fa13f486b2 --- /dev/null +++ b/drivers/net/ethernet/altera/altera_utils.c | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | /* Altera TSE SGDMA and MSGDMA Linux driver | ||
| 2 | * Copyright (C) 2014 Altera Corporation. All rights reserved | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms and conditions of the GNU General Public License, | ||
| 6 | * version 2, as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 11 | * more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License along with | ||
| 14 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include "altera_tse.h" | ||
| 18 | #include "altera_utils.h" | ||
| 19 | |||
| 20 | void tse_set_bit(void __iomem *ioaddr, u32 bit_mask) | ||
| 21 | { | ||
| 22 | u32 value = ioread32(ioaddr); | ||
| 23 | value |= bit_mask; | ||
| 24 | iowrite32(value, ioaddr); | ||
| 25 | } | ||
| 26 | |||
| 27 | void tse_clear_bit(void __iomem *ioaddr, u32 bit_mask) | ||
| 28 | { | ||
| 29 | u32 value = ioread32(ioaddr); | ||
| 30 | value &= ~bit_mask; | ||
| 31 | iowrite32(value, ioaddr); | ||
| 32 | } | ||
| 33 | |||
| 34 | int tse_bit_is_set(void __iomem *ioaddr, u32 bit_mask) | ||
| 35 | { | ||
| 36 | u32 value = ioread32(ioaddr); | ||
| 37 | return (value & bit_mask) ? 1 : 0; | ||
| 38 | } | ||
| 39 | |||
| 40 | int tse_bit_is_clear(void __iomem *ioaddr, u32 bit_mask) | ||
| 41 | { | ||
| 42 | u32 value = ioread32(ioaddr); | ||
| 43 | return (value & bit_mask) ? 0 : 1; | ||
| 44 | } | ||
diff --git a/drivers/net/ethernet/altera/altera_utils.h b/drivers/net/ethernet/altera/altera_utils.h new file mode 100644 index 000000000000..ce1db36d3583 --- /dev/null +++ b/drivers/net/ethernet/altera/altera_utils.h | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | /* Altera TSE SGDMA and MSGDMA Linux driver | ||
| 2 | * Copyright (C) 2014 Altera Corporation. All rights reserved | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms and conditions of the GNU General Public License, | ||
| 6 | * version 2, as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 11 | * more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License along with | ||
| 14 | * this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/kernel.h> | ||
| 18 | |||
| 19 | #ifndef __ALTERA_UTILS_H__ | ||
| 20 | #define __ALTERA_UTILS_H__ | ||
| 21 | |||
| 22 | void tse_set_bit(void __iomem *ioaddr, u32 bit_mask); | ||
| 23 | void tse_clear_bit(void __iomem *ioaddr, u32 bit_mask); | ||
| 24 | int tse_bit_is_set(void __iomem *ioaddr, u32 bit_mask); | ||
| 25 | int tse_bit_is_clear(void __iomem *ioaddr, u32 bit_mask); | ||
| 26 | |||
| 27 | #endif /* __ALTERA_UTILS_H__*/ | ||
