diff options
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/net/claw.c | 2 | ||||
-rw-r--r-- | drivers/s390/net/ctcm_main.c | 2 | ||||
-rw-r--r-- | drivers/s390/net/ctcm_sysfs.c | 14 | ||||
-rw-r--r-- | drivers/s390/net/lcs.c | 15 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core.h | 6 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_main.c | 100 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_sys.c | 22 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l2_main.c | 18 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l3_main.c | 21 |
9 files changed, 124 insertions, 76 deletions
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c index fd7b3bd80789..d837c3c5330f 100644 --- a/drivers/s390/net/claw.c +++ b/drivers/s390/net/claw.c @@ -3348,7 +3348,7 @@ static int __init claw_init(void) } CLAW_DBF_TEXT(2, setup, "init_mod"); claw_root_dev = root_device_register("claw"); - ret = PTR_RET(claw_root_dev); + ret = PTR_ERR_OR_ZERO(claw_root_dev); if (ret) goto register_err; ret = ccw_driver_register(&claw_ccw_driver); diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c index 70b3a023100e..03b6ad035577 100644 --- a/drivers/s390/net/ctcm_main.c +++ b/drivers/s390/net/ctcm_main.c @@ -1837,7 +1837,7 @@ static int __init ctcm_init(void) if (ret) goto out_err; ctcm_root_dev = root_device_register("ctcm"); - ret = PTR_RET(ctcm_root_dev); + ret = PTR_ERR_OR_ZERO(ctcm_root_dev); if (ret) goto register_err; ret = ccw_driver_register(&ctcm_ccw_driver); diff --git a/drivers/s390/net/ctcm_sysfs.c b/drivers/s390/net/ctcm_sysfs.c index 985b5dcbdac8..6bcfbbb20f04 100644 --- a/drivers/s390/net/ctcm_sysfs.c +++ b/drivers/s390/net/ctcm_sysfs.c @@ -34,8 +34,9 @@ static ssize_t ctcm_buffer_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct net_device *ndev; - int bs1; + unsigned int bs1; struct ctcm_priv *priv = dev_get_drvdata(dev); + int rc; ndev = priv->channel[CTCM_READ]->netdev; if (!(priv && priv->channel[CTCM_READ] && ndev)) { @@ -43,7 +44,9 @@ static ssize_t ctcm_buffer_write(struct device *dev, return -ENODEV; } - sscanf(buf, "%u", &bs1); + rc = sscanf(buf, "%u", &bs1); + if (rc != 1) + goto einval; if (bs1 > CTCM_BUFSIZE_LIMIT) goto einval; if (bs1 < (576 + LL_HEADER_LENGTH + 2)) @@ -143,13 +146,14 @@ static ssize_t ctcm_proto_show(struct device *dev, static ssize_t ctcm_proto_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - int value; + int value, rc; struct ctcm_priv *priv = dev_get_drvdata(dev); if (!priv) return -ENODEV; - sscanf(buf, "%u", &value); - if (!((value == CTCM_PROTO_S390) || + rc = sscanf(buf, "%d", &value); + if ((rc != 1) || + !((value == CTCM_PROTO_S390) || (value == CTCM_PROTO_LINUX) || (value == CTCM_PROTO_MPC) || (value == CTCM_PROTO_OS390))) diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index c461f2aac610..0a7d87c372b8 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -1943,14 +1943,16 @@ static ssize_t lcs_portno_store (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct lcs_card *card; - int value; + int value, rc; card = dev_get_drvdata(dev); if (!card) return 0; - sscanf(buf, "%u", &value); + rc = sscanf(buf, "%d", &value); + if (rc != 1) + return -EINVAL; /* TODO: sanity checks */ card->portno = value; @@ -1997,14 +1999,17 @@ static ssize_t lcs_timeout_store (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct lcs_card *card; - int value; + unsigned int value; + int rc; card = dev_get_drvdata(dev); if (!card) return 0; - sscanf(buf, "%u", &value); + rc = sscanf(buf, "%u", &value); + if (rc != 1) + return -EINVAL; /* TODO: sanity checks */ card->lancmd_timeout = value; @@ -2442,7 +2447,7 @@ __init lcs_init_module(void) if (rc) goto out_err; lcs_root_dev = root_device_register("lcs"); - rc = PTR_RET(lcs_root_dev); + rc = PTR_ERR_OR_ZERO(lcs_root_dev); if (rc) goto register_err; rc = ccw_driver_register(&lcs_ccw_driver); diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 5333b2c018e7..a2088af51cc5 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -268,10 +268,8 @@ static inline int qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, #define QETH_NO_PRIO_QUEUEING 0 #define QETH_PRIO_Q_ING_PREC 1 #define QETH_PRIO_Q_ING_TOS 2 -#define IP_TOS_LOWDELAY 0x10 -#define IP_TOS_HIGHTHROUGHPUT 0x08 -#define IP_TOS_HIGHRELIABILITY 0x04 -#define IP_TOS_NOTIMPORTANT 0x02 +#define QETH_PRIO_Q_ING_SKB 3 +#define QETH_PRIO_Q_ING_VLAN 4 /* Packing */ #define QETH_LOW_WATERMARK_PACK 2 diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index e89f38c31176..f54bec54d677 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -20,6 +20,7 @@ #include <linux/kthread.h> #include <linux/slab.h> #include <net/iucv/af_iucv.h> +#include <net/dsfield.h> #include <asm/ebcdic.h> #include <asm/chpid.h> @@ -1013,7 +1014,7 @@ static long __qeth_check_irb_error(struct ccw_device *cdev, card = CARD_FROM_CDEV(cdev); - if (!IS_ERR(irb)) + if (!card || !IS_ERR(irb)) return 0; switch (PTR_ERR(irb)) { @@ -1029,7 +1030,7 @@ static long __qeth_check_irb_error(struct ccw_device *cdev, QETH_CARD_TEXT(card, 2, "ckirberr"); QETH_CARD_TEXT_(card, 2, " rc%d", -ETIMEDOUT); if (intparm == QETH_RCD_PARM) { - if (card && (card->data.ccwdev == cdev)) { + if (card->data.ccwdev == cdev) { card->data.state = CH_STATE_DOWN; wake_up(&card->wait_q); } @@ -3662,42 +3663,56 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev, } EXPORT_SYMBOL_GPL(qeth_qdio_output_handler); +/** + * Note: Function assumes that we have 4 outbound queues. + */ int qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb, int ipv, int cast_type) { - if (!ipv && (card->info.type == QETH_CARD_TYPE_OSD || - card->info.type == QETH_CARD_TYPE_OSX)) - return card->qdio.default_out_queue; - switch (card->qdio.no_out_queues) { - case 4: - if (cast_type && card->info.is_multicast_different) - return card->info.is_multicast_different & - (card->qdio.no_out_queues - 1); - if (card->qdio.do_prio_queueing && (ipv == 4)) { - const u8 tos = ip_hdr(skb)->tos; - - if (card->qdio.do_prio_queueing == - QETH_PRIO_Q_ING_TOS) { - if (tos & IP_TOS_NOTIMPORTANT) - return 3; - if (tos & IP_TOS_HIGHRELIABILITY) - return 2; - if (tos & IP_TOS_HIGHTHROUGHPUT) - return 1; - if (tos & IP_TOS_LOWDELAY) - return 0; - } - if (card->qdio.do_prio_queueing == - QETH_PRIO_Q_ING_PREC) - return 3 - (tos >> 6); - } else if (card->qdio.do_prio_queueing && (ipv == 6)) { - /* TODO: IPv6!!! */ + __be16 *tci; + u8 tos; + + if (cast_type && card->info.is_multicast_different) + return card->info.is_multicast_different & + (card->qdio.no_out_queues - 1); + + switch (card->qdio.do_prio_queueing) { + case QETH_PRIO_Q_ING_TOS: + case QETH_PRIO_Q_ING_PREC: + switch (ipv) { + case 4: + tos = ipv4_get_dsfield(ip_hdr(skb)); + break; + case 6: + tos = ipv6_get_dsfield(ipv6_hdr(skb)); + break; + default: + return card->qdio.default_out_queue; } - return card->qdio.default_out_queue; - case 1: /* fallthrough for single-out-queue 1920-device */ + if (card->qdio.do_prio_queueing == QETH_PRIO_Q_ING_PREC) + return ~tos >> 6 & 3; + if (tos & IPTOS_MINCOST) + return 3; + if (tos & IPTOS_RELIABILITY) + return 2; + if (tos & IPTOS_THROUGHPUT) + return 1; + if (tos & IPTOS_LOWDELAY) + return 0; + break; + case QETH_PRIO_Q_ING_SKB: + if (skb->priority > 5) + return 0; + return ~skb->priority >> 1 & 3; + case QETH_PRIO_Q_ING_VLAN: + tci = &((struct ethhdr *)skb->data)->h_proto; + if (*tci == ETH_P_8021Q) + return ~*(tci + 1) >> (VLAN_PRIO_SHIFT + 1) & 3; + break; default: - return card->qdio.default_out_queue; + break; } + return card->qdio.default_out_queue; } EXPORT_SYMBOL_GPL(qeth_get_priority_queue); @@ -5703,6 +5718,7 @@ int qeth_core_ethtool_get_settings(struct net_device *netdev, struct qeth_card *card = netdev->ml_priv; enum qeth_link_types link_type; struct carrier_info carrier_info; + u32 speed; if ((card->info.type == QETH_CARD_TYPE_IQD) || (card->info.guestlan)) link_type = QETH_LINK_TYPE_10GBIT_ETH; @@ -5717,28 +5733,29 @@ int qeth_core_ethtool_get_settings(struct net_device *netdev, case QETH_LINK_TYPE_FAST_ETH: case QETH_LINK_TYPE_LANE_ETH100: qeth_set_ecmd_adv_sup(ecmd, SPEED_100, PORT_TP); - ecmd->speed = SPEED_100; + speed = SPEED_100; ecmd->port = PORT_TP; break; case QETH_LINK_TYPE_GBIT_ETH: case QETH_LINK_TYPE_LANE_ETH1000: qeth_set_ecmd_adv_sup(ecmd, SPEED_1000, PORT_FIBRE); - ecmd->speed = SPEED_1000; + speed = SPEED_1000; ecmd->port = PORT_FIBRE; break; case QETH_LINK_TYPE_10GBIT_ETH: qeth_set_ecmd_adv_sup(ecmd, SPEED_10000, PORT_FIBRE); - ecmd->speed = SPEED_10000; + speed = SPEED_10000; ecmd->port = PORT_FIBRE; break; default: qeth_set_ecmd_adv_sup(ecmd, SPEED_10, PORT_TP); - ecmd->speed = SPEED_10; + speed = SPEED_10; ecmd->port = PORT_TP; } + ethtool_cmd_speed_set(ecmd, speed); /* Check if we can obtain more accurate information. */ /* If QUERY_CARD_INFO command is not supported or fails, */ @@ -5783,18 +5800,19 @@ int qeth_core_ethtool_get_settings(struct net_device *netdev, switch (carrier_info.port_speed) { case CARD_INFO_PORTS_10M: - ecmd->speed = SPEED_10; + speed = SPEED_10; break; case CARD_INFO_PORTS_100M: - ecmd->speed = SPEED_100; + speed = SPEED_100; break; case CARD_INFO_PORTS_1G: - ecmd->speed = SPEED_1000; + speed = SPEED_1000; break; case CARD_INFO_PORTS_10G: - ecmd->speed = SPEED_10000; + speed = SPEED_10000; break; } + ethtool_cmd_speed_set(ecmd, speed); return 0; } @@ -5816,7 +5834,7 @@ static int __init qeth_core_init(void) if (rc) goto out_err; qeth_core_root_dev = root_device_register("qeth"); - rc = PTR_RET(qeth_core_root_dev); + rc = PTR_ERR_OR_ZERO(qeth_core_root_dev); if (rc) goto register_err; qeth_core_header_cache = kmem_cache_create("qeth_hdr", diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c index 425c0ecf1f3b..8a25a2be9890 100644 --- a/drivers/s390/net/qeth_core_sys.c +++ b/drivers/s390/net/qeth_core_sys.c @@ -217,6 +217,10 @@ static ssize_t qeth_dev_prioqing_show(struct device *dev, return sprintf(buf, "%s\n", "by precedence"); case QETH_PRIO_Q_ING_TOS: return sprintf(buf, "%s\n", "by type of service"); + case QETH_PRIO_Q_ING_SKB: + return sprintf(buf, "%s\n", "by skb-priority"); + case QETH_PRIO_Q_ING_VLAN: + return sprintf(buf, "%s\n", "by VLAN headers"); default: return sprintf(buf, "always queue %i\n", card->qdio.default_out_queue); @@ -250,11 +254,23 @@ static ssize_t qeth_dev_prioqing_store(struct device *dev, } tmp = strsep((char **) &buf, "\n"); - if (!strcmp(tmp, "prio_queueing_prec")) + if (!strcmp(tmp, "prio_queueing_prec")) { card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_PREC; - else if (!strcmp(tmp, "prio_queueing_tos")) + card->qdio.default_out_queue = QETH_DEFAULT_QUEUE; + } else if (!strcmp(tmp, "prio_queueing_skb")) { + card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_SKB; + card->qdio.default_out_queue = QETH_DEFAULT_QUEUE; + } else if (!strcmp(tmp, "prio_queueing_tos")) { card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_TOS; - else if (!strcmp(tmp, "no_prio_queueing:0")) { + card->qdio.default_out_queue = QETH_DEFAULT_QUEUE; + } else if (!strcmp(tmp, "prio_queueing_vlan")) { + if (!card->options.layer2) { + rc = -ENOTSUPP; + goto out; + } + card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_VLAN; + card->qdio.default_out_queue = QETH_DEFAULT_QUEUE; + } else if (!strcmp(tmp, "no_prio_queueing:0")) { card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING; card->qdio.default_out_queue = 0; } else if (!strcmp(tmp, "no_prio_queueing:1")) { diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 8dea3f12ccc1..5ef5b4f45758 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -725,15 +725,20 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) int elements = 0; struct qeth_card *card = dev->ml_priv; struct sk_buff *new_skb = skb; - int ipv = qeth_get_ip_version(skb); int cast_type = qeth_l2_get_cast_type(card, skb); - struct qeth_qdio_out_q *queue = card->qdio.out_qs - [qeth_get_priority_queue(card, skb, ipv, cast_type)]; + struct qeth_qdio_out_q *queue; int tx_bytes = skb->len; int data_offset = -1; int elements_needed = 0; int hd_len = 0; + if (card->qdio.do_prio_queueing || (cast_type && + card->info.is_multicast_different)) + queue = card->qdio.out_qs[qeth_get_priority_queue(card, skb, + qeth_get_ip_version(skb), cast_type)]; + else + queue = card->qdio.out_qs[card->qdio.default_out_queue]; + if ((card->state != CARD_STATE_UP) || !card->lan_online) { card->stats.tx_carrier_errors++; goto tx_drop; @@ -964,10 +969,9 @@ static int qeth_l2_setup_netdev(struct qeth_card *card) card->dev->watchdog_timeo = QETH_TX_TIMEOUT; card->dev->mtu = card->info.initial_mtu; card->dev->netdev_ops = &qeth_l2_netdev_ops; - if (card->info.type != QETH_CARD_TYPE_OSN) - SET_ETHTOOL_OPS(card->dev, &qeth_l2_ethtool_ops); - else - SET_ETHTOOL_OPS(card->dev, &qeth_l2_osn_ops); + card->dev->ethtool_ops = + (card->info.type != QETH_CARD_TYPE_OSN) ? + &qeth_l2_ethtool_ops : &qeth_l2_osn_ops; card->dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; card->info.broadcast_capable = 1; qeth_l2_request_initial_mac(card); diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 3524d34ff694..14e0b5810e8c 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -63,7 +63,7 @@ void qeth_l3_ipaddr4_to_string(const __u8 *addr, char *buf) int qeth_l3_string_to_ipaddr4(const char *buf, __u8 *addr) { int count = 0, rc = 0; - int in[4]; + unsigned int in[4]; char c; rc = sscanf(buf, "%u.%u.%u.%u%c", @@ -1659,7 +1659,7 @@ static void qeth_l3_add_vlan_mc(struct qeth_card *card) for_each_set_bit(vid, card->active_vlans, VLAN_N_VID) { struct net_device *netdev; - netdev = __vlan_find_dev_deep(card->dev, htons(ETH_P_8021Q), + netdev = __vlan_find_dev_deep_rcu(card->dev, htons(ETH_P_8021Q), vid); if (netdev == NULL || !(netdev->flags & IFF_UP)) @@ -1721,7 +1721,7 @@ static void qeth_l3_add_vlan_mc6(struct qeth_card *card) for_each_set_bit(vid, card->active_vlans, VLAN_N_VID) { struct net_device *netdev; - netdev = __vlan_find_dev_deep(card->dev, htons(ETH_P_8021Q), + netdev = __vlan_find_dev_deep_rcu(card->dev, htons(ETH_P_8021Q), vid); if (netdev == NULL || !(netdev->flags & IFF_UP)) @@ -1766,7 +1766,7 @@ static void qeth_l3_free_vlan_addresses4(struct qeth_card *card, QETH_CARD_TEXT(card, 4, "frvaddr4"); - netdev = __vlan_find_dev_deep(card->dev, htons(ETH_P_8021Q), vid); + netdev = __vlan_find_dev_deep_rcu(card->dev, htons(ETH_P_8021Q), vid); if (!netdev) return; in_dev = in_dev_get(netdev); @@ -1796,7 +1796,7 @@ static void qeth_l3_free_vlan_addresses6(struct qeth_card *card, QETH_CARD_TEXT(card, 4, "frvaddr6"); - netdev = __vlan_find_dev_deep(card->dev, htons(ETH_P_8021Q), vid); + netdev = __vlan_find_dev_deep_rcu(card->dev, htons(ETH_P_8021Q), vid); if (!netdev) return; in6_dev = in6_dev_get(netdev); @@ -2089,7 +2089,7 @@ static int qeth_l3_verify_vlan_dev(struct net_device *dev, struct net_device *netdev; rcu_read_lock(); - netdev = __vlan_find_dev_deep(card->dev, htons(ETH_P_8021Q), + netdev = __vlan_find_dev_deep_rcu(card->dev, htons(ETH_P_8021Q), vid); rcu_read_unlock(); if (netdev == dev) { @@ -2926,8 +2926,11 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) struct sk_buff *new_skb = NULL; int ipv = qeth_get_ip_version(skb); int cast_type = qeth_l3_get_cast_type(card, skb); - struct qeth_qdio_out_q *queue = card->qdio.out_qs - [qeth_get_priority_queue(card, skb, ipv, cast_type)]; + struct qeth_qdio_out_q *queue = + card->qdio.out_qs[card->qdio.do_prio_queueing + || (cast_type && card->info.is_multicast_different) ? + qeth_get_priority_queue(card, skb, ipv, cast_type) : + card->qdio.default_out_queue]; int tx_bytes = skb->len; bool large_send; int data_offset = -1; @@ -3298,7 +3301,7 @@ static int qeth_l3_setup_netdev(struct qeth_card *card) card->dev->ml_priv = card; card->dev->watchdog_timeo = QETH_TX_TIMEOUT; card->dev->mtu = card->info.initial_mtu; - SET_ETHTOOL_OPS(card->dev, &qeth_l3_ethtool_ops); + card->dev->ethtool_ops = &qeth_l3_ethtool_ops; card->dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_FILTER; |