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

s390/qeth: move ethtool code into its own file

Most of this is self-contained code.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Julian Wiedmann and committed by
David S. Miller
d896ac62 4326b5b4

+346 -351
+1 -1
drivers/s390/net/Makefile
··· 9 9 obj-$(CONFIG_SMSGIUCV) += smsgiucv.o 10 10 obj-$(CONFIG_SMSGIUCV_EVENT) += smsgiucv_app.o 11 11 obj-$(CONFIG_LCS) += lcs.o 12 - qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o 12 + qeth-y += qeth_core_sys.o qeth_core_main.o qeth_core_mpc.o qeth_ethtool.o 13 13 obj-$(CONFIG_QETH) += qeth.o 14 14 qeth_l2-y += qeth_l2_main.o qeth_l2_sys.o 15 15 obj-$(CONFIG_QETH_L2) += qeth_l2.o
+4 -8
drivers/s390/net/qeth_core.h
··· 18 18 #include <linux/in6.h> 19 19 #include <linux/bitops.h> 20 20 #include <linux/seq_file.h> 21 - #include <linux/ethtool.h> 22 21 #include <linux/hashtable.h> 23 22 #include <linux/ip.h> 24 23 #include <linux/refcount.h> ··· 921 922 922 923 extern struct qeth_discipline qeth_l2_discipline; 923 924 extern struct qeth_discipline qeth_l3_discipline; 925 + extern const struct ethtool_ops qeth_ethtool_ops; 926 + extern const struct ethtool_ops qeth_osn_ethtool_ops; 924 927 extern const struct attribute_group *qeth_generic_attr_groups[]; 925 928 extern const struct attribute_group *qeth_osn_attr_groups[]; 926 929 extern const struct attribute_group qeth_device_attr_group; ··· 977 976 struct qeth_cmd_buffer *qeth_wait_for_buffer(struct qeth_channel *); 978 977 int qeth_query_switch_attributes(struct qeth_card *card, 979 978 struct qeth_switch_info *sw_info); 979 + int qeth_query_card_info(struct qeth_card *card, 980 + struct carrier_info *carrier_info); 980 981 unsigned int qeth_count_elements(struct sk_buff *skb, unsigned int data_offset); 981 982 int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue, 982 983 struct sk_buff *skb, struct qeth_hdr *hdr, 983 984 unsigned int offset, unsigned int hd_len, 984 985 int elements_needed); 985 986 int qeth_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); 986 - int qeth_core_get_sset_count(struct net_device *, int); 987 - void qeth_core_get_ethtool_stats(struct net_device *, 988 - struct ethtool_stats *, u64 *); 989 - void qeth_core_get_strings(struct net_device *, u32, u8 *); 990 - void qeth_core_get_drvinfo(struct net_device *, struct ethtool_drvinfo *); 991 987 void qeth_dbf_longtext(debug_info_t *id, int level, char *text, ...); 992 - int qeth_core_ethtool_get_link_ksettings(struct net_device *netdev, 993 - struct ethtool_link_ksettings *cmd); 994 988 int qeth_set_access_ctrl_online(struct qeth_card *card, int fallback); 995 989 int qeth_configure_cq(struct qeth_card *, enum qeth_cq); 996 990 int qeth_hw_trap(struct qeth_card *, enum qeth_diags_trap_action);
+6 -311
drivers/s390/net/qeth_core_main.c
··· 4698 4698 return 0; 4699 4699 } 4700 4700 4701 - static int qeth_query_card_info(struct qeth_card *card, 4702 - struct carrier_info *carrier_info) 4701 + int qeth_query_card_info(struct qeth_card *card, 4702 + struct carrier_info *carrier_info) 4703 4703 { 4704 4704 struct qeth_cmd_buffer *iob; 4705 4705 ··· 5623 5623 SET_NETDEV_DEV(dev, &card->gdev->dev); 5624 5624 netif_carrier_off(dev); 5625 5625 5626 - if (!IS_OSN(card)) { 5626 + if (IS_OSN(card)) { 5627 + dev->ethtool_ops = &qeth_osn_ethtool_ops; 5628 + } else { 5629 + dev->ethtool_ops = &qeth_ethtool_ops; 5627 5630 dev->priv_flags &= ~IFF_TX_SKB_SHARING; 5628 5631 dev->hw_features |= NETIF_F_SG; 5629 5632 dev->vlan_features |= NETIF_F_SG; ··· 5913 5910 return rc; 5914 5911 } 5915 5912 EXPORT_SYMBOL_GPL(qeth_do_ioctl); 5916 - 5917 - static struct { 5918 - const char str[ETH_GSTRING_LEN]; 5919 - } qeth_ethtool_stats_keys[] = { 5920 - /* 0 */{"rx skbs"}, 5921 - {"rx buffers"}, 5922 - {"tx skbs"}, 5923 - {"tx buffers"}, 5924 - {"tx skbs no packing"}, 5925 - {"tx buffers no packing"}, 5926 - {"tx skbs packing"}, 5927 - {"tx buffers packing"}, 5928 - {"tx sg skbs"}, 5929 - {"tx buffer elements"}, 5930 - /* 10 */{"rx sg skbs"}, 5931 - {"rx sg frags"}, 5932 - {"rx sg page allocs"}, 5933 - {"tx large kbytes"}, 5934 - {"tx large count"}, 5935 - {"tx pk state ch n->p"}, 5936 - {"tx pk state ch p->n"}, 5937 - {"tx pk watermark low"}, 5938 - {"tx pk watermark high"}, 5939 - {"queue 0 buffer usage"}, 5940 - /* 20 */{"queue 1 buffer usage"}, 5941 - {"queue 2 buffer usage"}, 5942 - {"queue 3 buffer usage"}, 5943 - {"tx csum"}, 5944 - {"tx lin"}, 5945 - {"tx linfail"}, 5946 - {"rx csum"} 5947 - }; 5948 - 5949 - int qeth_core_get_sset_count(struct net_device *dev, int stringset) 5950 - { 5951 - switch (stringset) { 5952 - case ETH_SS_STATS: 5953 - return (sizeof(qeth_ethtool_stats_keys) / ETH_GSTRING_LEN); 5954 - default: 5955 - return -EINVAL; 5956 - } 5957 - } 5958 - EXPORT_SYMBOL_GPL(qeth_core_get_sset_count); 5959 - 5960 - void qeth_core_get_ethtool_stats(struct net_device *dev, 5961 - struct ethtool_stats *stats, u64 *data) 5962 - { 5963 - struct qeth_card *card = dev->ml_priv; 5964 - data[0] = card->stats.rx_packets - 5965 - card->perf_stats.initial_rx_packets; 5966 - data[1] = card->perf_stats.bufs_rec; 5967 - data[2] = card->stats.tx_packets - 5968 - card->perf_stats.initial_tx_packets; 5969 - data[3] = card->perf_stats.bufs_sent; 5970 - data[4] = card->stats.tx_packets - card->perf_stats.initial_tx_packets 5971 - - card->perf_stats.skbs_sent_pack; 5972 - data[5] = card->perf_stats.bufs_sent - card->perf_stats.bufs_sent_pack; 5973 - data[6] = card->perf_stats.skbs_sent_pack; 5974 - data[7] = card->perf_stats.bufs_sent_pack; 5975 - data[8] = card->perf_stats.sg_skbs_sent; 5976 - data[9] = card->perf_stats.buf_elements_sent; 5977 - data[10] = card->perf_stats.sg_skbs_rx; 5978 - data[11] = card->perf_stats.sg_frags_rx; 5979 - data[12] = card->perf_stats.sg_alloc_page_rx; 5980 - data[13] = (card->perf_stats.large_send_bytes >> 10); 5981 - data[14] = card->perf_stats.large_send_cnt; 5982 - data[15] = card->perf_stats.sc_dp_p; 5983 - data[16] = card->perf_stats.sc_p_dp; 5984 - data[17] = QETH_LOW_WATERMARK_PACK; 5985 - data[18] = QETH_HIGH_WATERMARK_PACK; 5986 - data[19] = atomic_read(&card->qdio.out_qs[0]->used_buffers); 5987 - data[20] = (card->qdio.no_out_queues > 1) ? 5988 - atomic_read(&card->qdio.out_qs[1]->used_buffers) : 0; 5989 - data[21] = (card->qdio.no_out_queues > 2) ? 5990 - atomic_read(&card->qdio.out_qs[2]->used_buffers) : 0; 5991 - data[22] = (card->qdio.no_out_queues > 3) ? 5992 - atomic_read(&card->qdio.out_qs[3]->used_buffers) : 0; 5993 - data[23] = card->perf_stats.tx_csum; 5994 - data[24] = card->perf_stats.tx_lin; 5995 - data[25] = card->perf_stats.tx_linfail; 5996 - data[26] = card->perf_stats.rx_csum; 5997 - } 5998 - EXPORT_SYMBOL_GPL(qeth_core_get_ethtool_stats); 5999 - 6000 - void qeth_core_get_strings(struct net_device *dev, u32 stringset, u8 *data) 6001 - { 6002 - switch (stringset) { 6003 - case ETH_SS_STATS: 6004 - memcpy(data, &qeth_ethtool_stats_keys, 6005 - sizeof(qeth_ethtool_stats_keys)); 6006 - break; 6007 - default: 6008 - WARN_ON(1); 6009 - break; 6010 - } 6011 - } 6012 - EXPORT_SYMBOL_GPL(qeth_core_get_strings); 6013 - 6014 - void qeth_core_get_drvinfo(struct net_device *dev, 6015 - struct ethtool_drvinfo *info) 6016 - { 6017 - struct qeth_card *card = dev->ml_priv; 6018 - 6019 - strlcpy(info->driver, IS_LAYER2(card) ? "qeth_l2" : "qeth_l3", 6020 - sizeof(info->driver)); 6021 - strlcpy(info->version, "1.0", sizeof(info->version)); 6022 - strlcpy(info->fw_version, card->info.mcl_level, 6023 - sizeof(info->fw_version)); 6024 - snprintf(info->bus_info, sizeof(info->bus_info), "%s/%s/%s", 6025 - CARD_RDEV_ID(card), CARD_WDEV_ID(card), CARD_DDEV_ID(card)); 6026 - } 6027 - EXPORT_SYMBOL_GPL(qeth_core_get_drvinfo); 6028 - 6029 - /* Helper function to fill 'advertising' and 'supported' which are the same. */ 6030 - /* Autoneg and full-duplex are supported and advertised unconditionally. */ 6031 - /* Always advertise and support all speeds up to specified, and only one */ 6032 - /* specified port type. */ 6033 - static void qeth_set_cmd_adv_sup(struct ethtool_link_ksettings *cmd, 6034 - int maxspeed, int porttype) 6035 - { 6036 - ethtool_link_ksettings_zero_link_mode(cmd, supported); 6037 - ethtool_link_ksettings_zero_link_mode(cmd, advertising); 6038 - ethtool_link_ksettings_zero_link_mode(cmd, lp_advertising); 6039 - 6040 - ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg); 6041 - ethtool_link_ksettings_add_link_mode(cmd, advertising, Autoneg); 6042 - 6043 - switch (porttype) { 6044 - case PORT_TP: 6045 - ethtool_link_ksettings_add_link_mode(cmd, supported, TP); 6046 - ethtool_link_ksettings_add_link_mode(cmd, advertising, TP); 6047 - break; 6048 - case PORT_FIBRE: 6049 - ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE); 6050 - ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE); 6051 - break; 6052 - default: 6053 - ethtool_link_ksettings_add_link_mode(cmd, supported, TP); 6054 - ethtool_link_ksettings_add_link_mode(cmd, advertising, TP); 6055 - WARN_ON_ONCE(1); 6056 - } 6057 - 6058 - /* partially does fall through, to also select lower speeds */ 6059 - switch (maxspeed) { 6060 - case SPEED_25000: 6061 - ethtool_link_ksettings_add_link_mode(cmd, supported, 6062 - 25000baseSR_Full); 6063 - ethtool_link_ksettings_add_link_mode(cmd, advertising, 6064 - 25000baseSR_Full); 6065 - break; 6066 - case SPEED_10000: 6067 - ethtool_link_ksettings_add_link_mode(cmd, supported, 6068 - 10000baseT_Full); 6069 - ethtool_link_ksettings_add_link_mode(cmd, advertising, 6070 - 10000baseT_Full); 6071 - case SPEED_1000: 6072 - ethtool_link_ksettings_add_link_mode(cmd, supported, 6073 - 1000baseT_Full); 6074 - ethtool_link_ksettings_add_link_mode(cmd, advertising, 6075 - 1000baseT_Full); 6076 - ethtool_link_ksettings_add_link_mode(cmd, supported, 6077 - 1000baseT_Half); 6078 - ethtool_link_ksettings_add_link_mode(cmd, advertising, 6079 - 1000baseT_Half); 6080 - case SPEED_100: 6081 - ethtool_link_ksettings_add_link_mode(cmd, supported, 6082 - 100baseT_Full); 6083 - ethtool_link_ksettings_add_link_mode(cmd, advertising, 6084 - 100baseT_Full); 6085 - ethtool_link_ksettings_add_link_mode(cmd, supported, 6086 - 100baseT_Half); 6087 - ethtool_link_ksettings_add_link_mode(cmd, advertising, 6088 - 100baseT_Half); 6089 - case SPEED_10: 6090 - ethtool_link_ksettings_add_link_mode(cmd, supported, 6091 - 10baseT_Full); 6092 - ethtool_link_ksettings_add_link_mode(cmd, advertising, 6093 - 10baseT_Full); 6094 - ethtool_link_ksettings_add_link_mode(cmd, supported, 6095 - 10baseT_Half); 6096 - ethtool_link_ksettings_add_link_mode(cmd, advertising, 6097 - 10baseT_Half); 6098 - /* end fallthrough */ 6099 - break; 6100 - default: 6101 - ethtool_link_ksettings_add_link_mode(cmd, supported, 6102 - 10baseT_Full); 6103 - ethtool_link_ksettings_add_link_mode(cmd, advertising, 6104 - 10baseT_Full); 6105 - ethtool_link_ksettings_add_link_mode(cmd, supported, 6106 - 10baseT_Half); 6107 - ethtool_link_ksettings_add_link_mode(cmd, advertising, 6108 - 10baseT_Half); 6109 - WARN_ON_ONCE(1); 6110 - } 6111 - } 6112 - 6113 - int qeth_core_ethtool_get_link_ksettings(struct net_device *netdev, 6114 - struct ethtool_link_ksettings *cmd) 6115 - { 6116 - struct qeth_card *card = netdev->ml_priv; 6117 - enum qeth_link_types link_type; 6118 - struct carrier_info carrier_info; 6119 - int rc; 6120 - 6121 - if ((card->info.type == QETH_CARD_TYPE_IQD) || (card->info.guestlan)) 6122 - link_type = QETH_LINK_TYPE_10GBIT_ETH; 6123 - else 6124 - link_type = card->info.link_type; 6125 - 6126 - cmd->base.duplex = DUPLEX_FULL; 6127 - cmd->base.autoneg = AUTONEG_ENABLE; 6128 - cmd->base.phy_address = 0; 6129 - cmd->base.mdio_support = 0; 6130 - cmd->base.eth_tp_mdix = ETH_TP_MDI_INVALID; 6131 - cmd->base.eth_tp_mdix_ctrl = ETH_TP_MDI_INVALID; 6132 - 6133 - switch (link_type) { 6134 - case QETH_LINK_TYPE_FAST_ETH: 6135 - case QETH_LINK_TYPE_LANE_ETH100: 6136 - cmd->base.speed = SPEED_100; 6137 - cmd->base.port = PORT_TP; 6138 - break; 6139 - case QETH_LINK_TYPE_GBIT_ETH: 6140 - case QETH_LINK_TYPE_LANE_ETH1000: 6141 - cmd->base.speed = SPEED_1000; 6142 - cmd->base.port = PORT_FIBRE; 6143 - break; 6144 - case QETH_LINK_TYPE_10GBIT_ETH: 6145 - cmd->base.speed = SPEED_10000; 6146 - cmd->base.port = PORT_FIBRE; 6147 - break; 6148 - case QETH_LINK_TYPE_25GBIT_ETH: 6149 - cmd->base.speed = SPEED_25000; 6150 - cmd->base.port = PORT_FIBRE; 6151 - break; 6152 - default: 6153 - cmd->base.speed = SPEED_10; 6154 - cmd->base.port = PORT_TP; 6155 - } 6156 - qeth_set_cmd_adv_sup(cmd, cmd->base.speed, cmd->base.port); 6157 - 6158 - /* Check if we can obtain more accurate information. */ 6159 - /* If QUERY_CARD_INFO command is not supported or fails, */ 6160 - /* just return the heuristics that was filled above. */ 6161 - rc = qeth_query_card_info(card, &carrier_info); 6162 - if (rc == -EOPNOTSUPP) /* for old hardware, return heuristic */ 6163 - return 0; 6164 - if (rc) /* report error from the hardware operation */ 6165 - return rc; 6166 - /* on success, fill in the information got from the hardware */ 6167 - 6168 - netdev_dbg(netdev, 6169 - "card info: card_type=0x%02x, port_mode=0x%04x, port_speed=0x%08x\n", 6170 - carrier_info.card_type, 6171 - carrier_info.port_mode, 6172 - carrier_info.port_speed); 6173 - 6174 - /* Update attributes for which we've obtained more authoritative */ 6175 - /* information, leave the rest the way they where filled above. */ 6176 - switch (carrier_info.card_type) { 6177 - case CARD_INFO_TYPE_1G_COPPER_A: 6178 - case CARD_INFO_TYPE_1G_COPPER_B: 6179 - cmd->base.port = PORT_TP; 6180 - qeth_set_cmd_adv_sup(cmd, SPEED_1000, cmd->base.port); 6181 - break; 6182 - case CARD_INFO_TYPE_1G_FIBRE_A: 6183 - case CARD_INFO_TYPE_1G_FIBRE_B: 6184 - cmd->base.port = PORT_FIBRE; 6185 - qeth_set_cmd_adv_sup(cmd, SPEED_1000, cmd->base.port); 6186 - break; 6187 - case CARD_INFO_TYPE_10G_FIBRE_A: 6188 - case CARD_INFO_TYPE_10G_FIBRE_B: 6189 - cmd->base.port = PORT_FIBRE; 6190 - qeth_set_cmd_adv_sup(cmd, SPEED_10000, cmd->base.port); 6191 - break; 6192 - } 6193 - 6194 - switch (carrier_info.port_mode) { 6195 - case CARD_INFO_PORTM_FULLDUPLEX: 6196 - cmd->base.duplex = DUPLEX_FULL; 6197 - break; 6198 - case CARD_INFO_PORTM_HALFDUPLEX: 6199 - cmd->base.duplex = DUPLEX_HALF; 6200 - break; 6201 - } 6202 - 6203 - switch (carrier_info.port_speed) { 6204 - case CARD_INFO_PORTS_10M: 6205 - cmd->base.speed = SPEED_10; 6206 - break; 6207 - case CARD_INFO_PORTS_100M: 6208 - cmd->base.speed = SPEED_100; 6209 - break; 6210 - case CARD_INFO_PORTS_1G: 6211 - cmd->base.speed = SPEED_1000; 6212 - break; 6213 - case CARD_INFO_PORTS_10G: 6214 - cmd->base.speed = SPEED_10000; 6215 - break; 6216 - case CARD_INFO_PORTS_25G: 6217 - cmd->base.speed = SPEED_25000; 6218 - break; 6219 - } 6220 - 6221 - return 0; 6222 - } 6223 - EXPORT_SYMBOL_GPL(qeth_core_ethtool_get_link_ksettings); 6224 5913 6225 5914 static int qeth_start_csum_cb(struct qeth_card *card, struct qeth_reply *reply, 6226 5915 unsigned long data)
+333
drivers/s390/net/qeth_ethtool.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright IBM Corp. 2018 4 + */ 5 + 6 + #define KMSG_COMPONENT "qeth" 7 + #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 8 + 9 + #include <linux/ethtool.h> 10 + #include "qeth_core.h" 11 + 12 + static struct { 13 + const char str[ETH_GSTRING_LEN]; 14 + } qeth_ethtool_stats_keys[] = { 15 + /* 0 */{"rx skbs"}, 16 + {"rx buffers"}, 17 + {"tx skbs"}, 18 + {"tx buffers"}, 19 + {"tx skbs no packing"}, 20 + {"tx buffers no packing"}, 21 + {"tx skbs packing"}, 22 + {"tx buffers packing"}, 23 + {"tx sg skbs"}, 24 + {"tx buffer elements"}, 25 + /* 10 */{"rx sg skbs"}, 26 + {"rx sg frags"}, 27 + {"rx sg page allocs"}, 28 + {"tx large kbytes"}, 29 + {"tx large count"}, 30 + {"tx pk state ch n->p"}, 31 + {"tx pk state ch p->n"}, 32 + {"tx pk watermark low"}, 33 + {"tx pk watermark high"}, 34 + {"queue 0 buffer usage"}, 35 + /* 20 */{"queue 1 buffer usage"}, 36 + {"queue 2 buffer usage"}, 37 + {"queue 3 buffer usage"}, 38 + {"tx csum"}, 39 + {"tx lin"}, 40 + {"tx linfail"}, 41 + {"rx csum"} 42 + }; 43 + 44 + static int qeth_get_sset_count(struct net_device *dev, int stringset) 45 + { 46 + switch (stringset) { 47 + case ETH_SS_STATS: 48 + return (sizeof(qeth_ethtool_stats_keys) / ETH_GSTRING_LEN); 49 + default: 50 + return -EINVAL; 51 + } 52 + } 53 + 54 + static void qeth_get_ethtool_stats(struct net_device *dev, 55 + struct ethtool_stats *stats, u64 *data) 56 + { 57 + struct qeth_card *card = dev->ml_priv; 58 + 59 + data[0] = card->stats.rx_packets - 60 + card->perf_stats.initial_rx_packets; 61 + data[1] = card->perf_stats.bufs_rec; 62 + data[2] = card->stats.tx_packets - 63 + card->perf_stats.initial_tx_packets; 64 + data[3] = card->perf_stats.bufs_sent; 65 + data[4] = card->stats.tx_packets - card->perf_stats.initial_tx_packets 66 + - card->perf_stats.skbs_sent_pack; 67 + data[5] = card->perf_stats.bufs_sent - card->perf_stats.bufs_sent_pack; 68 + data[6] = card->perf_stats.skbs_sent_pack; 69 + data[7] = card->perf_stats.bufs_sent_pack; 70 + data[8] = card->perf_stats.sg_skbs_sent; 71 + data[9] = card->perf_stats.buf_elements_sent; 72 + data[10] = card->perf_stats.sg_skbs_rx; 73 + data[11] = card->perf_stats.sg_frags_rx; 74 + data[12] = card->perf_stats.sg_alloc_page_rx; 75 + data[13] = (card->perf_stats.large_send_bytes >> 10); 76 + data[14] = card->perf_stats.large_send_cnt; 77 + data[15] = card->perf_stats.sc_dp_p; 78 + data[16] = card->perf_stats.sc_p_dp; 79 + data[17] = QETH_LOW_WATERMARK_PACK; 80 + data[18] = QETH_HIGH_WATERMARK_PACK; 81 + data[19] = atomic_read(&card->qdio.out_qs[0]->used_buffers); 82 + data[20] = (card->qdio.no_out_queues > 1) ? 83 + atomic_read(&card->qdio.out_qs[1]->used_buffers) : 0; 84 + data[21] = (card->qdio.no_out_queues > 2) ? 85 + atomic_read(&card->qdio.out_qs[2]->used_buffers) : 0; 86 + data[22] = (card->qdio.no_out_queues > 3) ? 87 + atomic_read(&card->qdio.out_qs[3]->used_buffers) : 0; 88 + data[23] = card->perf_stats.tx_csum; 89 + data[24] = card->perf_stats.tx_lin; 90 + data[25] = card->perf_stats.tx_linfail; 91 + data[26] = card->perf_stats.rx_csum; 92 + } 93 + 94 + static void qeth_get_strings(struct net_device *dev, u32 stringset, u8 *data) 95 + { 96 + switch (stringset) { 97 + case ETH_SS_STATS: 98 + memcpy(data, &qeth_ethtool_stats_keys, 99 + sizeof(qeth_ethtool_stats_keys)); 100 + break; 101 + default: 102 + WARN_ON(1); 103 + break; 104 + } 105 + } 106 + 107 + static void qeth_get_drvinfo(struct net_device *dev, 108 + struct ethtool_drvinfo *info) 109 + { 110 + struct qeth_card *card = dev->ml_priv; 111 + 112 + strlcpy(info->driver, IS_LAYER2(card) ? "qeth_l2" : "qeth_l3", 113 + sizeof(info->driver)); 114 + strlcpy(info->version, "1.0", sizeof(info->version)); 115 + strlcpy(info->fw_version, card->info.mcl_level, 116 + sizeof(info->fw_version)); 117 + snprintf(info->bus_info, sizeof(info->bus_info), "%s/%s/%s", 118 + CARD_RDEV_ID(card), CARD_WDEV_ID(card), CARD_DDEV_ID(card)); 119 + } 120 + 121 + /* Helper function to fill 'advertising' and 'supported' which are the same. */ 122 + /* Autoneg and full-duplex are supported and advertised unconditionally. */ 123 + /* Always advertise and support all speeds up to specified, and only one */ 124 + /* specified port type. */ 125 + static void qeth_set_cmd_adv_sup(struct ethtool_link_ksettings *cmd, 126 + int maxspeed, int porttype) 127 + { 128 + ethtool_link_ksettings_zero_link_mode(cmd, supported); 129 + ethtool_link_ksettings_zero_link_mode(cmd, advertising); 130 + ethtool_link_ksettings_zero_link_mode(cmd, lp_advertising); 131 + 132 + ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg); 133 + ethtool_link_ksettings_add_link_mode(cmd, advertising, Autoneg); 134 + 135 + switch (porttype) { 136 + case PORT_TP: 137 + ethtool_link_ksettings_add_link_mode(cmd, supported, TP); 138 + ethtool_link_ksettings_add_link_mode(cmd, advertising, TP); 139 + break; 140 + case PORT_FIBRE: 141 + ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE); 142 + ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE); 143 + break; 144 + default: 145 + ethtool_link_ksettings_add_link_mode(cmd, supported, TP); 146 + ethtool_link_ksettings_add_link_mode(cmd, advertising, TP); 147 + WARN_ON_ONCE(1); 148 + } 149 + 150 + /* partially does fall through, to also select lower speeds */ 151 + switch (maxspeed) { 152 + case SPEED_25000: 153 + ethtool_link_ksettings_add_link_mode(cmd, supported, 154 + 25000baseSR_Full); 155 + ethtool_link_ksettings_add_link_mode(cmd, advertising, 156 + 25000baseSR_Full); 157 + break; 158 + case SPEED_10000: 159 + ethtool_link_ksettings_add_link_mode(cmd, supported, 160 + 10000baseT_Full); 161 + ethtool_link_ksettings_add_link_mode(cmd, advertising, 162 + 10000baseT_Full); 163 + /* fall through */ 164 + case SPEED_1000: 165 + ethtool_link_ksettings_add_link_mode(cmd, supported, 166 + 1000baseT_Full); 167 + ethtool_link_ksettings_add_link_mode(cmd, advertising, 168 + 1000baseT_Full); 169 + ethtool_link_ksettings_add_link_mode(cmd, supported, 170 + 1000baseT_Half); 171 + ethtool_link_ksettings_add_link_mode(cmd, advertising, 172 + 1000baseT_Half); 173 + /* fall through */ 174 + case SPEED_100: 175 + ethtool_link_ksettings_add_link_mode(cmd, supported, 176 + 100baseT_Full); 177 + ethtool_link_ksettings_add_link_mode(cmd, advertising, 178 + 100baseT_Full); 179 + ethtool_link_ksettings_add_link_mode(cmd, supported, 180 + 100baseT_Half); 181 + ethtool_link_ksettings_add_link_mode(cmd, advertising, 182 + 100baseT_Half); 183 + /* fall through */ 184 + case SPEED_10: 185 + ethtool_link_ksettings_add_link_mode(cmd, supported, 186 + 10baseT_Full); 187 + ethtool_link_ksettings_add_link_mode(cmd, advertising, 188 + 10baseT_Full); 189 + ethtool_link_ksettings_add_link_mode(cmd, supported, 190 + 10baseT_Half); 191 + ethtool_link_ksettings_add_link_mode(cmd, advertising, 192 + 10baseT_Half); 193 + break; 194 + default: 195 + ethtool_link_ksettings_add_link_mode(cmd, supported, 196 + 10baseT_Full); 197 + ethtool_link_ksettings_add_link_mode(cmd, advertising, 198 + 10baseT_Full); 199 + ethtool_link_ksettings_add_link_mode(cmd, supported, 200 + 10baseT_Half); 201 + ethtool_link_ksettings_add_link_mode(cmd, advertising, 202 + 10baseT_Half); 203 + WARN_ON_ONCE(1); 204 + } 205 + } 206 + 207 + 208 + static int qeth_get_link_ksettings(struct net_device *netdev, 209 + struct ethtool_link_ksettings *cmd) 210 + { 211 + struct qeth_card *card = netdev->ml_priv; 212 + enum qeth_link_types link_type; 213 + struct carrier_info carrier_info; 214 + int rc; 215 + 216 + if (IS_IQD(card) || IS_VM_NIC(card)) 217 + link_type = QETH_LINK_TYPE_10GBIT_ETH; 218 + else 219 + link_type = card->info.link_type; 220 + 221 + cmd->base.duplex = DUPLEX_FULL; 222 + cmd->base.autoneg = AUTONEG_ENABLE; 223 + cmd->base.phy_address = 0; 224 + cmd->base.mdio_support = 0; 225 + cmd->base.eth_tp_mdix = ETH_TP_MDI_INVALID; 226 + cmd->base.eth_tp_mdix_ctrl = ETH_TP_MDI_INVALID; 227 + 228 + switch (link_type) { 229 + case QETH_LINK_TYPE_FAST_ETH: 230 + case QETH_LINK_TYPE_LANE_ETH100: 231 + cmd->base.speed = SPEED_100; 232 + cmd->base.port = PORT_TP; 233 + break; 234 + case QETH_LINK_TYPE_GBIT_ETH: 235 + case QETH_LINK_TYPE_LANE_ETH1000: 236 + cmd->base.speed = SPEED_1000; 237 + cmd->base.port = PORT_FIBRE; 238 + break; 239 + case QETH_LINK_TYPE_10GBIT_ETH: 240 + cmd->base.speed = SPEED_10000; 241 + cmd->base.port = PORT_FIBRE; 242 + break; 243 + case QETH_LINK_TYPE_25GBIT_ETH: 244 + cmd->base.speed = SPEED_25000; 245 + cmd->base.port = PORT_FIBRE; 246 + break; 247 + default: 248 + cmd->base.speed = SPEED_10; 249 + cmd->base.port = PORT_TP; 250 + } 251 + qeth_set_cmd_adv_sup(cmd, cmd->base.speed, cmd->base.port); 252 + 253 + /* Check if we can obtain more accurate information. */ 254 + /* If QUERY_CARD_INFO command is not supported or fails, */ 255 + /* just return the heuristics that was filled above. */ 256 + rc = qeth_query_card_info(card, &carrier_info); 257 + if (rc == -EOPNOTSUPP) /* for old hardware, return heuristic */ 258 + return 0; 259 + if (rc) /* report error from the hardware operation */ 260 + return rc; 261 + /* on success, fill in the information got from the hardware */ 262 + 263 + netdev_dbg(netdev, 264 + "card info: card_type=0x%02x, port_mode=0x%04x, port_speed=0x%08x\n", 265 + carrier_info.card_type, 266 + carrier_info.port_mode, 267 + carrier_info.port_speed); 268 + 269 + /* Update attributes for which we've obtained more authoritative */ 270 + /* information, leave the rest the way they where filled above. */ 271 + switch (carrier_info.card_type) { 272 + case CARD_INFO_TYPE_1G_COPPER_A: 273 + case CARD_INFO_TYPE_1G_COPPER_B: 274 + cmd->base.port = PORT_TP; 275 + qeth_set_cmd_adv_sup(cmd, SPEED_1000, cmd->base.port); 276 + break; 277 + case CARD_INFO_TYPE_1G_FIBRE_A: 278 + case CARD_INFO_TYPE_1G_FIBRE_B: 279 + cmd->base.port = PORT_FIBRE; 280 + qeth_set_cmd_adv_sup(cmd, SPEED_1000, cmd->base.port); 281 + break; 282 + case CARD_INFO_TYPE_10G_FIBRE_A: 283 + case CARD_INFO_TYPE_10G_FIBRE_B: 284 + cmd->base.port = PORT_FIBRE; 285 + qeth_set_cmd_adv_sup(cmd, SPEED_10000, cmd->base.port); 286 + break; 287 + } 288 + 289 + switch (carrier_info.port_mode) { 290 + case CARD_INFO_PORTM_FULLDUPLEX: 291 + cmd->base.duplex = DUPLEX_FULL; 292 + break; 293 + case CARD_INFO_PORTM_HALFDUPLEX: 294 + cmd->base.duplex = DUPLEX_HALF; 295 + break; 296 + } 297 + 298 + switch (carrier_info.port_speed) { 299 + case CARD_INFO_PORTS_10M: 300 + cmd->base.speed = SPEED_10; 301 + break; 302 + case CARD_INFO_PORTS_100M: 303 + cmd->base.speed = SPEED_100; 304 + break; 305 + case CARD_INFO_PORTS_1G: 306 + cmd->base.speed = SPEED_1000; 307 + break; 308 + case CARD_INFO_PORTS_10G: 309 + cmd->base.speed = SPEED_10000; 310 + break; 311 + case CARD_INFO_PORTS_25G: 312 + cmd->base.speed = SPEED_25000; 313 + break; 314 + } 315 + 316 + return 0; 317 + } 318 + 319 + const struct ethtool_ops qeth_ethtool_ops = { 320 + .get_link = ethtool_op_get_link, 321 + .get_strings = qeth_get_strings, 322 + .get_ethtool_stats = qeth_get_ethtool_stats, 323 + .get_sset_count = qeth_get_sset_count, 324 + .get_drvinfo = qeth_get_drvinfo, 325 + .get_link_ksettings = qeth_get_link_ksettings, 326 + }; 327 + 328 + const struct ethtool_ops qeth_osn_ethtool_ops = { 329 + .get_strings = qeth_get_strings, 330 + .get_ethtool_stats = qeth_get_ethtool_stats, 331 + .get_sset_count = qeth_get_sset_count, 332 + .get_drvinfo = qeth_get_drvinfo, 333 + };
+2 -21
drivers/s390/net/qeth_l2_main.c
··· 696 696 unregister_netdev(card->dev); 697 697 } 698 698 699 - static const struct ethtool_ops qeth_l2_ethtool_ops = { 700 - .get_link = ethtool_op_get_link, 701 - .get_strings = qeth_core_get_strings, 702 - .get_ethtool_stats = qeth_core_get_ethtool_stats, 703 - .get_sset_count = qeth_core_get_sset_count, 704 - .get_drvinfo = qeth_core_get_drvinfo, 705 - .get_link_ksettings = qeth_core_ethtool_get_link_ksettings, 706 - }; 707 - 708 - static const struct ethtool_ops qeth_l2_osn_ops = { 709 - .get_strings = qeth_core_get_strings, 710 - .get_ethtool_stats = qeth_core_get_ethtool_stats, 711 - .get_sset_count = qeth_core_get_sset_count, 712 - .get_drvinfo = qeth_core_get_drvinfo, 713 - }; 714 - 715 699 static const struct net_device_ops qeth_l2_netdev_ops = { 716 700 .ndo_open = qeth_open, 717 701 .ndo_stop = qeth_stop, ··· 719 735 720 736 card->dev->priv_flags |= IFF_UNICAST_FLT; 721 737 card->dev->netdev_ops = &qeth_l2_netdev_ops; 722 - if (card->info.type == QETH_CARD_TYPE_OSN) { 723 - card->dev->ethtool_ops = &qeth_l2_osn_ops; 738 + if (IS_OSN(card)) 724 739 card->dev->flags |= IFF_NOARP; 725 - } else { 726 - card->dev->ethtool_ops = &qeth_l2_ethtool_ops; 740 + else 727 741 card->dev->needed_headroom = sizeof(struct qeth_hdr); 728 - } 729 742 730 743 if (IS_OSM(card)) { 731 744 card->dev->features |= NETIF_F_VLAN_CHALLENGED;
-10
drivers/s390/net/qeth_l3_main.c
··· 2117 2117 return NETDEV_TX_OK; 2118 2118 } 2119 2119 2120 - static const struct ethtool_ops qeth_l3_ethtool_ops = { 2121 - .get_link = ethtool_op_get_link, 2122 - .get_strings = qeth_core_get_strings, 2123 - .get_ethtool_stats = qeth_core_get_ethtool_stats, 2124 - .get_sset_count = qeth_core_get_sset_count, 2125 - .get_drvinfo = qeth_core_get_drvinfo, 2126 - .get_link_ksettings = qeth_core_ethtool_get_link_ksettings, 2127 - }; 2128 - 2129 2120 /* 2130 2121 * we need NOARP for IPv4 but we want neighbor solicitation for IPv6. Setting 2131 2122 * NOARP on the netdevice is no option because it also turns off neighbor ··· 2238 2247 return -ENODEV; 2239 2248 2240 2249 card->dev->needed_headroom = headroom; 2241 - card->dev->ethtool_ops = &qeth_l3_ethtool_ops; 2242 2250 card->dev->features |= NETIF_F_HW_VLAN_CTAG_TX | 2243 2251 NETIF_F_HW_VLAN_CTAG_RX | 2244 2252 NETIF_F_HW_VLAN_CTAG_FILTER;