From 93ad37d94d0b42e493d95b8a79181112c76ab459 Mon Sep 17 00:00:00 2001 From: "Klaus D. Wacker" Date: Thu, 24 Apr 2008 10:15:18 +0200 Subject: lcs: CCL-sequ. numbers required for protocol 802.2 only. Sequence numbers in skbs (Receive path) are assigned only to 802.2 packets. Signed-off-by: Klaus D. Wacker Signed-off-by: Frank Blaschka Signed-off-by: Jeff Garzik --- drivers/s390/net/lcs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/s390') diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index f51ed997258..dd22f4b3703 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -1793,7 +1793,8 @@ lcs_get_skb(struct lcs_card *card, char *skb_data, unsigned int skb_len) skb->protocol = card->lan_type_trans(skb, card->dev); card->stats.rx_bytes += skb_len; card->stats.rx_packets++; - *((__u32 *)skb->cb) = ++card->pkt_seq; + if (skb->protocol == htons(ETH_P_802_2)) + *((__u32 *)skb->cb) = ++card->pkt_seq; netif_rx(skb); } -- cgit v1.2.3-70-g09d2 From 8bbf84404b02f193c5422c252264d7b82ffe4443 Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Thu, 24 Apr 2008 10:15:19 +0200 Subject: netiucv: get rid of in_atomic() use There is no urgent need to restart a netiucv connection automatically, if packets are sent while the netiucv device is not up and running. Signed-off-by: Ursula Braun Signed-off-by: Frank Blaschka Signed-off-by: Jeff Garzik --- drivers/s390/net/netiucv.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index 8f876f6ab36..0fb780e35fa 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c @@ -1313,8 +1313,6 @@ static int netiucv_tx(struct sk_buff *skb, struct net_device *dev) * and throw away packet. */ if (fsm_getstate(privptr->fsm) != DEV_STATE_RUNNING) { - if (!in_atomic()) - fsm_event(privptr->fsm, DEV_EVENT_START, dev); dev_kfree_skb(skb); privptr->stats.tx_dropped++; privptr->stats.tx_errors++; -- cgit v1.2.3-70-g09d2 From 022b660ae5d075ed9eaddef6f6fb7abb48bdf63b Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Thu, 24 Apr 2008 10:15:20 +0200 Subject: ccwgroup: Unify parsing for group attribute. Instead of having each driver for ccwgroup slave device parsing the input itself and calling ccwgroup_create(), introduce a new function ccwgroup_create_from_string() and handle parsing inside the ccwgroup core. Signed-off-by: Ursula Braun Signed-off-by: Frank Blaschka Signed-off-by: Jeff Garzik --- drivers/s390/cio/ccwgroup.c | 96 ++++++++++++++++++++++++++++++--------- drivers/s390/net/cu3088.c | 20 +------- drivers/s390/net/qeth_core_main.c | 23 +--------- include/asm-s390/ccwgroup.h | 7 ++- 4 files changed, 82 insertions(+), 64 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index 03914fa8117..f38923e38e9 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c @@ -153,44 +153,89 @@ __ccwgroup_create_symlinks(struct ccwgroup_device *gdev) return 0; } +static int __get_next_bus_id(const char **buf, char *bus_id) +{ + int rc, len; + char *start, *end; + + start = (char *)*buf; + end = strchr(start, ','); + if (!end) { + /* Last entry. Strip trailing newline, if applicable. */ + end = strchr(start, '\n'); + if (end) + *end = '\0'; + len = strlen(start) + 1; + } else { + len = end - start + 1; + end++; + } + if (len < BUS_ID_SIZE) { + strlcpy(bus_id, start, len); + rc = 0; + } else + rc = -EINVAL; + *buf = end; + return rc; +} + +static int __is_valid_bus_id(char bus_id[BUS_ID_SIZE]) +{ + int cssid, ssid, devno; + + /* Must be of form %x.%x.%04x */ + if (sscanf(bus_id, "%x.%1x.%04x", &cssid, &ssid, &devno) != 3) + return 0; + return 1; +} + /** - * ccwgroup_create() - create and register a ccw group device + * ccwgroup_create_from_string() - create and register a ccw group device * @root: parent device for the new device * @creator_id: identifier of creating driver * @cdrv: ccw driver of slave devices - * @argc: number of slave devices - * @argv: bus ids of slave devices + * @num_devices: number of slave devices + * @buf: buffer containing comma separated bus ids of slave devices * * Create and register a new ccw group device as a child of @root. Slave - * devices are obtained from the list of bus ids given in @argv[] and must all + * devices are obtained from the list of bus ids given in @buf and must all * belong to @cdrv. * Returns: * %0 on success and an error code on failure. * Context: * non-atomic */ -int ccwgroup_create(struct device *root, unsigned int creator_id, - struct ccw_driver *cdrv, int argc, char *argv[]) +int ccwgroup_create_from_string(struct device *root, unsigned int creator_id, + struct ccw_driver *cdrv, int num_devices, + const char *buf) { struct ccwgroup_device *gdev; - int i; - int rc; + int rc, i; + char tmp_bus_id[BUS_ID_SIZE]; + const char *curr_buf; - if (argc > 256) /* disallow dumb users */ - return -EINVAL; - - gdev = kzalloc(sizeof(*gdev) + argc*sizeof(gdev->cdev[0]), GFP_KERNEL); + gdev = kzalloc(sizeof(*gdev) + num_devices * sizeof(gdev->cdev[0]), + GFP_KERNEL); if (!gdev) return -ENOMEM; atomic_set(&gdev->onoff, 0); mutex_init(&gdev->reg_mutex); mutex_lock(&gdev->reg_mutex); - for (i = 0; i < argc; i++) { - gdev->cdev[i] = get_ccwdev_by_busid(cdrv, argv[i]); - - /* all devices have to be of the same type in - * order to be grouped */ + curr_buf = buf; + for (i = 0; i < num_devices && curr_buf; i++) { + rc = __get_next_bus_id(&curr_buf, tmp_bus_id); + if (rc != 0) + goto error; + if (!__is_valid_bus_id(tmp_bus_id)) { + rc = -EINVAL; + goto error; + } + gdev->cdev[i] = get_ccwdev_by_busid(cdrv, tmp_bus_id); + /* + * All devices have to be of the same type in + * order to be grouped. + */ if (!gdev->cdev[i] || gdev->cdev[i]->id.driver_info != gdev->cdev[0]->id.driver_info) { @@ -204,9 +249,18 @@ int ccwgroup_create(struct device *root, unsigned int creator_id, } dev_set_drvdata(&gdev->cdev[i]->dev, gdev); } - + /* Check for sufficient number of bus ids. */ + if (i < num_devices && !curr_buf) { + rc = -EINVAL; + goto error; + } + /* Check for trailing stuff. */ + if (i == num_devices && strlen(curr_buf) > 0) { + rc = -EINVAL; + goto error; + } gdev->creator_id = creator_id; - gdev->count = argc; + gdev->count = num_devices; gdev->dev.bus = &ccwgroup_bus_type; gdev->dev.parent = root; gdev->dev.release = ccwgroup_release; @@ -234,7 +288,7 @@ int ccwgroup_create(struct device *root, unsigned int creator_id, device_remove_file(&gdev->dev, &dev_attr_ungroup); device_unregister(&gdev->dev); error: - for (i = 0; i < argc; i++) + for (i = 0; i < num_devices; i++) if (gdev->cdev[i]) { if (dev_get_drvdata(&gdev->cdev[i]->dev) == gdev) dev_set_drvdata(&gdev->cdev[i]->dev, NULL); @@ -244,6 +298,7 @@ error: put_device(&gdev->dev); return rc; } +EXPORT_SYMBOL(ccwgroup_create_from_string); static int __init init_ccwgroup (void) @@ -519,6 +574,5 @@ void ccwgroup_remove_ccwdev(struct ccw_device *cdev) MODULE_LICENSE("GPL"); EXPORT_SYMBOL(ccwgroup_driver_register); EXPORT_SYMBOL(ccwgroup_driver_unregister); -EXPORT_SYMBOL(ccwgroup_create); EXPORT_SYMBOL(ccwgroup_probe_ccwdev); EXPORT_SYMBOL(ccwgroup_remove_ccwdev); diff --git a/drivers/s390/net/cu3088.c b/drivers/s390/net/cu3088.c index 76728ae4b84..8e7697305a4 100644 --- a/drivers/s390/net/cu3088.c +++ b/drivers/s390/net/cu3088.c @@ -62,30 +62,14 @@ static struct device *cu3088_root_dev; static ssize_t group_write(struct device_driver *drv, const char *buf, size_t count) { - const char *start, *end; - char bus_ids[2][BUS_ID_SIZE], *argv[2]; - int i; int ret; struct ccwgroup_driver *cdrv; cdrv = to_ccwgroupdrv(drv); if (!cdrv) return -EINVAL; - start = buf; - for (i=0; i<2; i++) { - static const char delim[] = {',', '\n'}; - int len; - - if (!(end = strchr(start, delim[i]))) - return -EINVAL; - len = min_t(ptrdiff_t, BUS_ID_SIZE, end - start + 1); - strlcpy (bus_ids[i], start, len); - argv[i] = bus_ids[i]; - start = end + 1; - } - - ret = ccwgroup_create(cu3088_root_dev, cdrv->driver_id, - &cu3088_driver, 2, argv); + ret = ccwgroup_create_from_string(cu3088_root_dev, cdrv->driver_id, + &cu3088_driver, 2, buf); return (ret == 0) ? count : ret; } diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 055f5c3e7b5..231d18c3b6f 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -3827,27 +3827,8 @@ static struct ccw_driver qeth_ccw_driver = { static int qeth_core_driver_group(const char *buf, struct device *root_dev, unsigned long driver_id) { - const char *start, *end; - char bus_ids[3][BUS_ID_SIZE], *argv[3]; - int i; - - start = buf; - for (i = 0; i < 3; i++) { - static const char delim[] = { ',', ',', '\n' }; - int len; - - end = strchr(start, delim[i]); - if (!end) - return -EINVAL; - len = min_t(ptrdiff_t, BUS_ID_SIZE, end - start); - strncpy(bus_ids[i], start, len); - bus_ids[i][len] = '\0'; - start = end + 1; - argv[i] = bus_ids[i]; - } - - return (ccwgroup_create(root_dev, driver_id, - &qeth_ccw_driver, 3, argv)); + return ccwgroup_create_from_string(root_dev, driver_id, + &qeth_ccw_driver, 3, buf); } int qeth_core_hardsetup_card(struct qeth_card *card) diff --git a/include/asm-s390/ccwgroup.h b/include/asm-s390/ccwgroup.h index 289053ef5e6..a27f68985a7 100644 --- a/include/asm-s390/ccwgroup.h +++ b/include/asm-s390/ccwgroup.h @@ -57,10 +57,9 @@ struct ccwgroup_driver { extern int ccwgroup_driver_register (struct ccwgroup_driver *cdriver); extern void ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver); -extern int ccwgroup_create (struct device *root, - unsigned int creator_id, - struct ccw_driver *gdrv, - int argc, char *argv[]); +int ccwgroup_create_from_string(struct device *root, unsigned int creator_id, + struct ccw_driver *cdrv, int num_devices, + const char *buf); extern int ccwgroup_probe_ccwdev(struct ccw_device *cdev); extern void ccwgroup_remove_ccwdev(struct ccw_device *cdev); -- cgit v1.2.3-70-g09d2 From cd023216e64cc0359ec51312bef14ef2449535dd Mon Sep 17 00:00:00 2001 From: Peter Tiedemann Date: Thu, 24 Apr 2008 10:15:21 +0200 Subject: qeth module size reduction. Replace complex macro for s390dbf calls by equivalent function. This reduces module size about 10% without visible performance impact. Signed-off-by: Peter Tiedemann Signed-off-by: Frank Blaschka Signed-off-by: Jeff Garzik --- drivers/s390/net/qeth_core.h | 18 ++---------------- drivers/s390/net/qeth_core_main.c | 15 ++++++++++++--- drivers/s390/net/qeth_l2_main.c | 3 --- drivers/s390/net/qeth_l3.h | 3 --- drivers/s390/net/qeth_l3_main.c | 2 -- 5 files changed, 14 insertions(+), 27 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 66f4f12503c..b7bb0ff87c1 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -72,22 +72,7 @@ struct qeth_dbf_info { debug_sprintf_event(qeth_dbf[QETH_DBF_MSG].id, level, text) #define QETH_DBF_TEXT_(name, level, text...) \ - do { \ - if (qeth_dbf_passes(qeth_dbf[QETH_DBF_##name].id, level)) { \ - char *dbf_txt_buf = \ - get_cpu_var(QETH_DBF_TXT_BUF); \ - sprintf(dbf_txt_buf, text); \ - debug_text_event(qeth_dbf[QETH_DBF_##name].id, \ - level, dbf_txt_buf); \ - put_cpu_var(QETH_DBF_TXT_BUF); \ - } \ - } while (0) - -/* Allow to sort out low debug levels early to avoid wasted sprints */ -static inline int qeth_dbf_passes(debug_info_t *dbf_grp, int level) -{ - return (level <= dbf_grp->level); -} + qeth_dbf_longtext(QETH_DBF_##name, level, text) /** * some more debug stuff @@ -894,6 +879,7 @@ void qeth_core_get_ethtool_stats(struct net_device *, struct ethtool_stats *, u64 *); void qeth_core_get_strings(struct net_device *, u32, u8 *); void qeth_core_get_drvinfo(struct net_device *, struct ethtool_drvinfo *); +void qeth_dbf_longtext(enum qeth_dbf_names dbf_nix, int level, char *text, ...); /* exports for OSN */ int qeth_osn_assist(struct net_device *, void *, int); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 231d18c3b6f..18323250a33 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -26,9 +26,6 @@ #include "qeth_core.h" #include "qeth_core_offl.h" -static DEFINE_PER_CPU(char[256], qeth_core_dbf_txt_buf); -#define QETH_DBF_TXT_BUF qeth_core_dbf_txt_buf - struct qeth_dbf_info qeth_dbf[QETH_DBF_INFOS] = { /* define dbf - Name, Pages, Areas, Maxlen, Level, View, Handle */ /* N P A M L V H */ @@ -4067,6 +4064,18 @@ static void qeth_unregister_dbf_views(void) } } +void qeth_dbf_longtext(enum qeth_dbf_names dbf_nix, int level, char *text, ...) +{ + char dbf_txt_buf[32]; + + if (level > (qeth_dbf[dbf_nix].id)->level) + return; + snprintf(dbf_txt_buf, sizeof(dbf_txt_buf), text); + debug_text_event(qeth_dbf[dbf_nix].id, level, dbf_txt_buf); + +} +EXPORT_SYMBOL_GPL(qeth_dbf_longtext); + static int qeth_register_dbf_views(void) { int ret; diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 3921d1631a7..7e8f6396509 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -22,9 +22,6 @@ #include "qeth_core.h" #include "qeth_core_offl.h" -#define QETH_DBF_TXT_BUF qeth_l2_dbf_txt_buf -static DEFINE_PER_CPU(char[256], qeth_l2_dbf_txt_buf); - static int qeth_l2_set_offline(struct ccwgroup_device *); static int qeth_l2_stop(struct net_device *); static int qeth_l2_send_delmac(struct qeth_card *, __u8 *); diff --git a/drivers/s390/net/qeth_l3.h b/drivers/s390/net/qeth_l3.h index 1be353593a5..9f143c83bba 100644 --- a/drivers/s390/net/qeth_l3.h +++ b/drivers/s390/net/qeth_l3.h @@ -13,9 +13,6 @@ #include "qeth_core.h" -#define QETH_DBF_TXT_BUF qeth_l3_dbf_txt_buf -DECLARE_PER_CPU(char[256], qeth_l3_dbf_txt_buf); - struct qeth_ipaddr { struct list_head entry; enum qeth_ip_types type; diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index e1bfe56087d..62a54364a51 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -28,8 +28,6 @@ #include "qeth_l3.h" #include "qeth_core_offl.h" -DEFINE_PER_CPU(char[256], qeth_l3_dbf_txt_buf); - static int qeth_l3_set_offline(struct ccwgroup_device *); static int qeth_l3_recover(void *); static int qeth_l3_stop(struct net_device *); -- cgit v1.2.3-70-g09d2 From 213298f862d10ade909bdb7d833493d4bdad683d Mon Sep 17 00:00:00 2001 From: Frank Blaschka Date: Thu, 24 Apr 2008 10:15:22 +0200 Subject: qeth: layer 3 support vlan IPv6 on hiper socket hiper socket require the QETH_HDR_EXT_VLAN_FRAME flag in the qdio header to handle vlan tagged frames. Signed-off-by: Frank Blaschka Signed-off-by: Jeff Garzik --- drivers/s390/net/qeth_l3_main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 62a54364a51..f385e93d757 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2568,9 +2568,10 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, * v6 uses passthrough, v4 sets the tag in the QDIO header. */ if (card->vlangrp && vlan_tx_tag_present(skb)) { - hdr->hdr.l3.ext_flags = (ipv == 4) ? - QETH_HDR_EXT_VLAN_FRAME : - QETH_HDR_EXT_INCLUDE_VLAN_TAG; + if ((ipv == 4) || (card->info.type == QETH_CARD_TYPE_IQD)) + hdr->hdr.l3.ext_flags = QETH_HDR_EXT_VLAN_FRAME; + else + hdr->hdr.l3.ext_flags = QETH_HDR_EXT_INCLUDE_VLAN_TAG; hdr->hdr.l3.vlan_id = vlan_tx_tag_get(skb); } -- cgit v1.2.3-70-g09d2 From 3f9975aa4d5b3c614eef8785ec63da13fbd55b51 Mon Sep 17 00:00:00 2001 From: Frank Blaschka Date: Thu, 24 Apr 2008 10:15:23 +0200 Subject: qeth: provide get ethtool settings Load balancing bonding queries the speed of the slave interfaces. To support a bond consisting of different slave speeds we have to report the speed by ethtool settings. Signed-off-by: Frank Blaschka Signed-off-by: Jeff Garzik --- drivers/s390/net/qeth_core.h | 1 + drivers/s390/net/qeth_core_main.c | 90 +++++++++++++++++++++++++++++++++++++++ drivers/s390/net/qeth_l2_main.c | 1 + drivers/s390/net/qeth_l3_main.c | 1 + 4 files changed, 93 insertions(+) (limited to 'drivers/s390') diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index b7bb0ff87c1..8dd83d92098 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -880,6 +880,7 @@ void qeth_core_get_ethtool_stats(struct net_device *, void qeth_core_get_strings(struct net_device *, u32, u8 *); void qeth_core_get_drvinfo(struct net_device *, struct ethtool_drvinfo *); void qeth_dbf_longtext(enum qeth_dbf_names dbf_nix, int level, char *text, ...); +int qeth_core_ethtool_get_settings(struct net_device *, struct ethtool_cmd *); /* exports for OSN */ int qeth_osn_assist(struct net_device *, void *, int); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 18323250a33..23a46340ffa 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -4423,6 +4423,96 @@ void qeth_core_get_drvinfo(struct net_device *dev, } EXPORT_SYMBOL_GPL(qeth_core_get_drvinfo); +int qeth_core_ethtool_get_settings(struct net_device *netdev, + struct ethtool_cmd *ecmd) +{ + struct qeth_card *card = netdev_priv(netdev); + enum qeth_link_types link_type; + + if ((card->info.type == QETH_CARD_TYPE_IQD) || (card->info.guestlan)) + link_type = QETH_LINK_TYPE_10GBIT_ETH; + else + link_type = card->info.link_type; + + ecmd->transceiver = XCVR_INTERNAL; + ecmd->supported = SUPPORTED_Autoneg; + ecmd->advertising = ADVERTISED_Autoneg; + ecmd->duplex = DUPLEX_FULL; + ecmd->autoneg = AUTONEG_ENABLE; + + switch (link_type) { + case QETH_LINK_TYPE_FAST_ETH: + case QETH_LINK_TYPE_LANE_ETH100: + ecmd->supported |= SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_TP; + ecmd->advertising |= ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full | + ADVERTISED_TP; + ecmd->speed = SPEED_100; + ecmd->port = PORT_TP; + break; + + case QETH_LINK_TYPE_GBIT_ETH: + case QETH_LINK_TYPE_LANE_ETH1000: + ecmd->supported |= SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Half | + SUPPORTED_1000baseT_Full | + SUPPORTED_FIBRE; + ecmd->advertising |= ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full | + ADVERTISED_1000baseT_Half | + ADVERTISED_1000baseT_Full | + ADVERTISED_FIBRE; + ecmd->speed = SPEED_1000; + ecmd->port = PORT_FIBRE; + break; + + case QETH_LINK_TYPE_10GBIT_ETH: + ecmd->supported |= SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Half | + SUPPORTED_1000baseT_Full | + SUPPORTED_10000baseT_Full | + SUPPORTED_FIBRE; + ecmd->advertising |= ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full | + ADVERTISED_1000baseT_Half | + ADVERTISED_1000baseT_Full | + ADVERTISED_10000baseT_Full | + ADVERTISED_FIBRE; + ecmd->speed = SPEED_10000; + ecmd->port = PORT_FIBRE; + break; + + default: + ecmd->supported |= SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_TP; + ecmd->advertising |= ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_TP; + ecmd->speed = SPEED_10; + ecmd->port = PORT_TP; + } + + return 0; +} +EXPORT_SYMBOL_GPL(qeth_core_ethtool_get_settings); + static int __init qeth_core_init(void) { int rc; diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 7e8f6396509..e6092829a5a 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -861,6 +861,7 @@ static struct ethtool_ops qeth_l2_ethtool_ops = { .get_ethtool_stats = qeth_core_get_ethtool_stats, .get_stats_count = qeth_core_get_stats_count, .get_drvinfo = qeth_core_get_drvinfo, + .get_settings = qeth_core_ethtool_get_settings, }; static struct ethtool_ops qeth_l2_osn_ops = { diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index f385e93d757..ce23169587e 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2889,6 +2889,7 @@ static struct ethtool_ops qeth_l3_ethtool_ops = { .get_ethtool_stats = qeth_core_get_ethtool_stats, .get_stats_count = qeth_core_get_stats_count, .get_drvinfo = qeth_core_get_drvinfo, + .get_settings = qeth_core_ethtool_get_settings, }; /* -- cgit v1.2.3-70-g09d2 From f90b744eb8ead0af7a7aa2f78ff861dff4863f2c Mon Sep 17 00:00:00 2001 From: Frank Blaschka Date: Thu, 24 Apr 2008 10:15:24 +0200 Subject: qeth: rework fast path Remove unnecessary traces. Remove unnecessary wrappers for skb functions. Signed-off-by: Frank Blaschka Signed-off-by: Jeff Garzik --- drivers/s390/net/qeth_core.h | 31 ++++-------------- drivers/s390/net/qeth_core_main.c | 67 ++------------------------------------- drivers/s390/net/qeth_l2_main.c | 8 ++--- drivers/s390/net/qeth_l3_main.c | 5 --- 4 files changed, 13 insertions(+), 98 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 8dd83d92098..699ac11debd 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -758,27 +758,6 @@ static inline int qeth_get_micros(void) return (int) (get_clock() >> 12); } -static inline void *qeth_push_skb(struct qeth_card *card, struct sk_buff *skb, - int size) -{ - void *hdr; - - hdr = (void *) skb_push(skb, size); - /* - * sanity check, the Linux memory allocation scheme should - * never present us cases like this one (the qdio header size plus - * the first 40 bytes of the paket cross a 4k boundary) - */ - if ((((unsigned long) hdr) & (~(PAGE_SIZE - 1))) != - (((unsigned long) hdr + size + - QETH_IP_HEADER_SIZE) & (~(PAGE_SIZE - 1)))) { - PRINT_ERR("Misaligned packet on interface %s. Discarded.", - QETH_CARD_IFNAME(card)); - return NULL; - } - return hdr; -} - static inline int qeth_get_ip_version(struct sk_buff *skb) { switch (skb->protocol) { @@ -791,6 +770,12 @@ static inline int qeth_get_ip_version(struct sk_buff *skb) } } +static inline void qeth_put_buffer_pool_entry(struct qeth_card *card, + struct qeth_buffer_pool_entry *entry) +{ + list_add_tail(&entry->list, &card->qdio.in_buf_pool.entry_list); +} + struct qeth_eddp_context; extern struct ccwgroup_driver qeth_l2_ccwgroup_driver; extern struct ccwgroup_driver qeth_l3_ccwgroup_driver; @@ -828,8 +813,6 @@ struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *, int qeth_query_setadapterparms(struct qeth_card *); int qeth_check_qdio_errors(struct qdio_buffer *, unsigned int, unsigned int, const char *); -void qeth_put_buffer_pool_entry(struct qeth_card *, - struct qeth_buffer_pool_entry *); void qeth_queue_input_buffer(struct qeth_card *, int); struct sk_buff *qeth_core_get_next_skb(struct qeth_card *, struct qdio_buffer *, struct qdio_buffer_element **, int *, @@ -865,8 +848,6 @@ int qeth_send_control_data(struct qeth_card *, int, struct qeth_cmd_buffer *, void *reply_param); int qeth_get_cast_type(struct qeth_card *, struct sk_buff *); int qeth_get_priority_queue(struct qeth_card *, struct sk_buff *, int, int); -struct sk_buff *qeth_prepare_skb(struct qeth_card *, struct sk_buff *, - struct qeth_hdr **); int qeth_get_elements_no(struct qeth_card *, void *, struct sk_buff *, int); int qeth_do_send_packet_fast(struct qeth_card *, struct qeth_qdio_out_q *, struct sk_buff *, struct qeth_hdr *, int, diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 23a46340ffa..820c332096e 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -2252,14 +2252,6 @@ void qeth_print_status_message(struct qeth_card *card) } EXPORT_SYMBOL_GPL(qeth_print_status_message); -void qeth_put_buffer_pool_entry(struct qeth_card *card, - struct qeth_buffer_pool_entry *entry) -{ - QETH_DBF_TEXT(TRACE, 6, "ptbfplen"); - list_add_tail(&entry->list, &card->qdio.in_buf_pool.entry_list); -} -EXPORT_SYMBOL_GPL(qeth_put_buffer_pool_entry); - static void qeth_initialize_working_pool_list(struct qeth_card *card) { struct qeth_buffer_pool_entry *entry; @@ -2600,7 +2592,6 @@ void qeth_queue_input_buffer(struct qeth_card *card, int index) int rc; int newcount = 0; - QETH_DBF_TEXT(TRACE, 6, "queinbuf"); count = (index < queue->next_buf_to_init)? card->qdio.in_buf_pool.buf_count - (queue->next_buf_to_init - index) : @@ -2789,8 +2780,6 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int, int i; unsigned int qdio_flags; - QETH_DBF_TEXT(TRACE, 6, "flushbuf"); - for (i = index; i < index + count; ++i) { buf = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q]; buf->buffer->element[buf->next_element_to_fill - 1].flags |= @@ -3034,49 +3023,6 @@ int qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb, } EXPORT_SYMBOL_GPL(qeth_get_priority_queue); -static void __qeth_free_new_skb(struct sk_buff *orig_skb, - struct sk_buff *new_skb) -{ - if (orig_skb != new_skb) - dev_kfree_skb_any(new_skb); -} - -static inline struct sk_buff *qeth_realloc_headroom(struct qeth_card *card, - struct sk_buff *skb, int size) -{ - struct sk_buff *new_skb = skb; - - if (skb_headroom(skb) >= size) - return skb; - new_skb = skb_realloc_headroom(skb, size); - if (!new_skb) - PRINT_ERR("Could not realloc headroom for qeth_hdr " - "on interface %s", QETH_CARD_IFNAME(card)); - return new_skb; -} - -struct sk_buff *qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb, - struct qeth_hdr **hdr) -{ - struct sk_buff *new_skb; - - QETH_DBF_TEXT(TRACE, 6, "prepskb"); - - new_skb = qeth_realloc_headroom(card, skb, - sizeof(struct qeth_hdr)); - if (!new_skb) - return NULL; - - *hdr = ((struct qeth_hdr *)qeth_push_skb(card, new_skb, - sizeof(struct qeth_hdr))); - if (*hdr == NULL) { - __qeth_free_new_skb(skb, new_skb); - return NULL; - } - return new_skb; -} -EXPORT_SYMBOL_GPL(qeth_prepare_skb); - int qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb, int elems) { @@ -3097,8 +3043,8 @@ int qeth_get_elements_no(struct qeth_card *card, void *hdr, } EXPORT_SYMBOL_GPL(qeth_get_elements_no); -static void __qeth_fill_buffer(struct sk_buff *skb, struct qdio_buffer *buffer, - int is_tso, int *next_element_to_fill) +static inline void __qeth_fill_buffer(struct sk_buff *skb, + struct qdio_buffer *buffer, int is_tso, int *next_element_to_fill) { int length = skb->len; int length_here; @@ -3140,15 +3086,13 @@ static void __qeth_fill_buffer(struct sk_buff *skb, struct qdio_buffer *buffer, *next_element_to_fill = element; } -static int qeth_fill_buffer(struct qeth_qdio_out_q *queue, +static inline int qeth_fill_buffer(struct qeth_qdio_out_q *queue, struct qeth_qdio_out_buffer *buf, struct sk_buff *skb) { struct qdio_buffer *buffer; struct qeth_hdr_tso *hdr; int flush_cnt = 0, hdr_len, large_send = 0; - QETH_DBF_TEXT(TRACE, 6, "qdfillbf"); - buffer = buf->buffer; atomic_inc(&skb->users); skb_queue_tail(&buf->skb_list, skb); @@ -3207,8 +3151,6 @@ int qeth_do_send_packet_fast(struct qeth_card *card, int flush_cnt = 0; int index; - QETH_DBF_TEXT(TRACE, 6, "dosndpfa"); - /* spin until we get the queue ... */ while (atomic_cmpxchg(&queue->state, QETH_OUT_Q_UNLOCKED, QETH_OUT_Q_LOCKED) != QETH_OUT_Q_UNLOCKED); @@ -3260,8 +3202,6 @@ int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue, int tmp; int rc = 0; - QETH_DBF_TEXT(TRACE, 6, "dosndpkt"); - /* spin until we get the queue ... */ while (atomic_cmpxchg(&queue->state, QETH_OUT_Q_UNLOCKED, QETH_OUT_Q_LOCKED) != QETH_OUT_Q_UNLOCKED); @@ -3958,7 +3898,6 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card, int use_rx_sg = 0; int frag = 0; - QETH_DBF_TEXT(TRACE, 6, "nextskb"); /* qeth_hdr must not cross element boundaries */ if (element->length < offset + sizeof(struct qeth_hdr)) { if (qeth_is_last_sbale(element)) diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index e6092829a5a..ef07e9cadfc 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -632,8 +632,6 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO; struct qeth_eddp_context *ctx = NULL; - QETH_DBF_TEXT(TRACE, 6, "l2xmit"); - if ((card->state != CARD_STATE_UP) || !card->lan_online) { card->stats.tx_carrier_errors++; goto tx_drop; @@ -655,9 +653,12 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) if (card->info.type == QETH_CARD_TYPE_OSN) hdr = (struct qeth_hdr *)skb->data; else { - new_skb = qeth_prepare_skb(card, skb, &hdr); + /* create a clone with writeable headroom */ + new_skb = skb_realloc_headroom(skb, sizeof(struct qeth_hdr)); if (!new_skb) goto tx_drop; + hdr = (struct qeth_hdr *)skb_push(new_skb, + sizeof(struct qeth_hdr)); qeth_l2_fill_header(card, hdr, new_skb, ipv, cast_type); } @@ -744,7 +745,6 @@ static void qeth_l2_qdio_input_handler(struct ccw_device *ccwdev, int index; int i; - QETH_DBF_TEXT(TRACE, 6, "qdinput"); card = (struct qeth_card *) card_ptr; net_dev = card->dev; if (card->options.performance_stats) { diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index ce23169587e..50545a1f6b3 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2557,8 +2557,6 @@ static int qeth_l3_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, struct sk_buff *skb, int ipv, int cast_type) { - QETH_DBF_TEXT(TRACE, 6, "fillhdr"); - memset(hdr, 0, sizeof(struct qeth_hdr)); hdr->hdr.l3.id = QETH_HEADER_TYPE_LAYER3; hdr->hdr.l3.ext_flags = 0; @@ -2637,8 +2635,6 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO; struct qeth_eddp_context *ctx = NULL; - QETH_DBF_TEXT(TRACE, 6, "l3xmit"); - if ((card->info.type == QETH_CARD_TYPE_IQD) && (skb->protocol != htons(ETH_P_IPV6)) && (skb->protocol != htons(ETH_P_IP))) @@ -2982,7 +2978,6 @@ static void qeth_l3_qdio_input_handler(struct ccw_device *ccwdev, int index; int i; - QETH_DBF_TEXT(TRACE, 6, "qdinput"); card = (struct qeth_card *) card_ptr; net_dev = card->dev; if (card->options.performance_stats) { -- cgit v1.2.3-70-g09d2 From 8af7c5aebc9a7b46f6ea55ee5a216dce4005f538 Mon Sep 17 00:00:00 2001 From: Frank Blaschka Date: Thu, 24 Apr 2008 10:15:25 +0200 Subject: qeth: layer 3 add missing dev_open/close to ccwgroup handler In case the ccwgroup device is set online/offline we have to run the corresponding dev_open/close for the netdevice. Signed-off-by: Frank Blaschka Signed-off-by: Jeff Garzik --- drivers/s390/net/qeth_l3_main.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 50545a1f6b3..94a8ead64ed 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2091,6 +2091,11 @@ static int qeth_l3_stop_card(struct qeth_card *card, int recovery_mode) (card->state == CARD_STATE_UP)) { if (recovery_mode) qeth_l3_stop(card->dev); + else { + rtnl_lock(); + dev_close(card->dev); + rtnl_unlock(); + } if (!card->use_hard_stop) { rc = qeth_send_stoplan(card); if (rc) @@ -3135,9 +3140,15 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) netif_carrier_on(card->dev); qeth_set_allowed_threads(card, 0xffffffff, 0); - if ((recover_flag == CARD_STATE_RECOVER) && recovery_mode) { + if (recover_flag == CARD_STATE_RECOVER) { + if (recovery_mode) qeth_l3_open(card->dev); - qeth_l3_set_multicast_list(card->dev); + else { + rtnl_lock(); + dev_open(card->dev); + rtnl_unlock(); + } + qeth_l3_set_multicast_list(card->dev); } /* let user_space know that device is online */ kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); -- cgit v1.2.3-70-g09d2 From a74b08c7fcfc49727cb9e4409ec0410674410c93 Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Thu, 24 Apr 2008 10:15:26 +0200 Subject: qeth: read number of ports from card Read out number of ports from the hardware. Signed-off-by: Ursula Braun Signed-off-by: Frank Blaschka Signed-off-by: Jeff Garzik --- drivers/s390/net/qeth_core_main.c | 5 +++-- include/asm-s390/qdio.h | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 820c332096e..436bf1f6d4a 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -3803,8 +3803,9 @@ retry: QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); return rc; } - - mpno = QETH_MAX_PORTNO; + mpno = qdio_get_ssqd_pct(CARD_DDEV(card)); + if (mpno) + mpno = min(mpno - 1, QETH_MAX_PORTNO); if (card->info.portno > mpno) { PRINT_ERR("Device %s does not offer port number %d \n.", CARD_BUS_ID(card), card->info.portno); diff --git a/include/asm-s390/qdio.h b/include/asm-s390/qdio.h index 4b8ff55f680..11240342a0f 100644 --- a/include/asm-s390/qdio.h +++ b/include/asm-s390/qdio.h @@ -127,6 +127,7 @@ extern int do_QDIO(struct ccw_device*, unsigned int flags, unsigned int qidx,unsigned int count, struct qdio_buffer *buffers); +extern int qdio_get_ssqd_pct(struct ccw_device*); extern int qdio_synchronize(struct ccw_device*, unsigned int flags, unsigned int queue_number); -- cgit v1.2.3-70-g09d2 From efe3df6f6cfb587e662aa6f0cf9a9fde93d8af0b Mon Sep 17 00:00:00 2001 From: Frank Blaschka Date: Thu, 24 Apr 2008 10:15:27 +0200 Subject: qeth: layer 2 allow ethtool to set TSO Allow ethtool to turn on/off EDDP via ethtool TSO interface. Signed-off-by: Frank Blaschka Signed-off-by: Jeff Garzik --- drivers/s390/net/qeth_l2_main.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers/s390') diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index ef07e9cadfc..86ec50ddae1 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -849,6 +849,22 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev) return; } +static int qeth_l2_ethtool_set_tso(struct net_device *dev, u32 data) +{ + struct qeth_card *card = netdev_priv(dev); + + if (data) { + if (card->options.large_send == QETH_LARGE_SEND_NO) { + card->options.large_send = QETH_LARGE_SEND_EDDP; + dev->features |= NETIF_F_TSO; + } + } else { + dev->features &= ~NETIF_F_TSO; + card->options.large_send = QETH_LARGE_SEND_NO; + } + return 0; +} + static struct ethtool_ops qeth_l2_ethtool_ops = { .get_link = ethtool_op_get_link, .get_tx_csum = ethtool_op_get_tx_csum, @@ -856,7 +872,7 @@ static struct ethtool_ops qeth_l2_ethtool_ops = { .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, .get_tso = ethtool_op_get_tso, - .set_tso = ethtool_op_set_tso, + .set_tso = qeth_l2_ethtool_set_tso, .get_strings = qeth_core_get_strings, .get_ethtool_stats = qeth_core_get_ethtool_stats, .get_stats_count = qeth_core_get_stats_count, -- cgit v1.2.3-70-g09d2 From 0a0a83107c01a8dba04fa40ddb29ff021d4f8112 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Thu, 24 Apr 2008 10:15:28 +0200 Subject: netiucv: Fix missing driver attributes. Signed-off-by: Cornelia Huck Signed-off-by: Frank Blaschka Signed-off-by: Jeff Garzik --- drivers/s390/net/netiucv.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/s390') diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index 0fb780e35fa..e4ba6a0372a 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c @@ -2145,6 +2145,7 @@ static int __init netiucv_init(void) if (rc) goto out_dbf; IUCV_DBF_TEXT(trace, 3, __func__); + netiucv_driver.groups = netiucv_drv_attr_groups; rc = driver_register(&netiucv_driver); if (rc) { PRINT_ERR("NETIUCV: failed to register driver.\n"); -- cgit v1.2.3-70-g09d2