diff options
Diffstat (limited to 'drivers/s390/net')
-rw-r--r-- | drivers/s390/net/qeth_core.h | 1 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_main.c | 57 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l2_main.c | 8 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l3_main.c | 26 |
4 files changed, 63 insertions, 29 deletions
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index d5ccce1..e0c4557 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -643,7 +643,6 @@ struct qeth_card_options { int macaddr_mode; int fake_broadcast; int add_hhlen; - int fake_ll; int layer2; enum qeth_large_send_types large_send; int performance_stats; diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index e783644..6811dd5 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -287,8 +287,15 @@ int qeth_set_large_send(struct qeth_card *card, card->options.large_send = type; switch (card->options.large_send) { case QETH_LARGE_SEND_EDDP: - card->dev->features |= NETIF_F_TSO | NETIF_F_SG | + if (card->info.type != QETH_CARD_TYPE_IQD) { + card->dev->features |= NETIF_F_TSO | NETIF_F_SG | NETIF_F_HW_CSUM; + } else { + card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG | + NETIF_F_HW_CSUM); + card->options.large_send = QETH_LARGE_SEND_NO; + rc = -EOPNOTSUPP; + } break; case QETH_LARGE_SEND_TSO: if (qeth_is_supported(card, IPA_OUTBOUND_TSO)) { @@ -572,6 +579,10 @@ static void qeth_send_control_data_cb(struct qeth_channel *channel, card = CARD_FROM_CDEV(channel->ccwdev); if (qeth_check_idx_response(iob->data)) { qeth_clear_ipacmd_list(card); + if (((iob->data[2] & 0xc0) == 0xc0) && iob->data[4] == 0xf6) + dev_err(&card->gdev->dev, + "The qeth device is not configured " + "for the OSI layer required by z/VM\n"); qeth_schedule_recovery(card); goto out; } @@ -1072,7 +1083,6 @@ static void qeth_set_intial_options(struct qeth_card *card) card->options.macaddr_mode = QETH_TR_MACADDR_NONCANONICAL; card->options.fake_broadcast = 0; card->options.add_hhlen = DEFAULT_ADD_HHLEN; - card->options.fake_ll = 0; card->options.performance_stats = 0; card->options.rx_sg_cb = QETH_RX_SG_CB; } @@ -1682,6 +1692,7 @@ int qeth_send_control_data(struct qeth_card *card, int len, unsigned long flags; struct qeth_reply *reply = NULL; unsigned long timeout; + struct qeth_ipa_cmd *cmd; QETH_DBF_TEXT(TRACE, 2, "sendctl"); @@ -1728,17 +1739,34 @@ int qeth_send_control_data(struct qeth_card *card, int len, wake_up(&card->wait_q); return rc; } - while (!atomic_read(&reply->received)) { - if (time_after(jiffies, timeout)) { - spin_lock_irqsave(&reply->card->lock, flags); - list_del_init(&reply->list); - spin_unlock_irqrestore(&reply->card->lock, flags); - reply->rc = -ETIME; - atomic_inc(&reply->received); - wake_up(&reply->wait_q); - } - cpu_relax(); - }; + + /* we have only one long running ipassist, since we can ensure + process context of this command we can sleep */ + cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); + if ((cmd->hdr.command == IPA_CMD_SETIP) && + (cmd->hdr.prot_version == QETH_PROT_IPV4)) { + if (!wait_event_timeout(reply->wait_q, + atomic_read(&reply->received), timeout)) + goto time_err; + } else { + while (!atomic_read(&reply->received)) { + if (time_after(jiffies, timeout)) + goto time_err; + cpu_relax(); + }; + } + + rc = reply->rc; + qeth_put_reply(reply); + return rc; + +time_err: + spin_lock_irqsave(&reply->card->lock, flags); + list_del_init(&reply->list); + spin_unlock_irqrestore(&reply->card->lock, flags); + reply->rc = -ETIME; + atomic_inc(&reply->received); + wake_up(&reply->wait_q); rc = reply->rc; qeth_put_reply(reply); return rc; @@ -2250,7 +2278,8 @@ void qeth_print_status_message(struct qeth_card *card) } /* fallthrough */ case QETH_CARD_TYPE_IQD: - if (card->info.guestlan) { + if ((card->info.guestlan) || + (card->info.mcl_level[0] & 0x80)) { card->info.mcl_level[0] = (char) _ebcasc[(__u8) card->info.mcl_level[0]]; card->info.mcl_level[1] = (char) _ebcasc[(__u8) diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 2c48591..21627ba 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -1126,9 +1126,11 @@ static int qeth_l2_recover(void *ptr) dev_info(&card->gdev->dev, "Device successfully recovered!\n"); else { - rtnl_lock(); - dev_close(card->dev); - rtnl_unlock(); + if (card->dev) { + rtnl_lock(); + dev_close(card->dev); + rtnl_unlock(); + } dev_warn(&card->gdev->dev, "The qeth device driver " "failed to recover an error on the device\n"); } diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index c0b30b2..cfda1ec 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -1047,7 +1047,7 @@ static int qeth_l3_setadapter_parms(struct qeth_card *card) rc = qeth_setadpparms_change_macaddr(card); if (rc) dev_warn(&card->gdev->dev, "Reading the adapter MAC" - " address failed\n", rc); + " address failed\n"); } if ((card->info.link_type == QETH_LINK_TYPE_HSTR) || @@ -1207,12 +1207,9 @@ static int qeth_l3_start_ipa_source_mac(struct qeth_card *card) QETH_DBF_TEXT(TRACE, 3, "stsrcmac"); - if (!card->options.fake_ll) - return -EOPNOTSUPP; - if (!qeth_is_supported(card, IPA_SOURCE_MAC)) { dev_info(&card->gdev->dev, - "Inbound source address not supported on %s\n", + "Inbound source MAC-address not supported on %s\n", QETH_CARD_IFNAME(card)); return -EOPNOTSUPP; } @@ -1221,7 +1218,7 @@ static int qeth_l3_start_ipa_source_mac(struct qeth_card *card) IPA_CMD_ASS_START, 0); if (rc) dev_warn(&card->gdev->dev, - "Starting proxy ARP support for %s failed\n", + "Starting source MAC-address support for %s failed\n", QETH_CARD_IFNAME(card)); return rc; } @@ -1921,8 +1918,13 @@ static inline __u16 qeth_l3_rebuild_skb(struct qeth_card *card, memcpy(tg_addr, card->dev->dev_addr, card->dev->addr_len); } - card->dev->header_ops->create(skb, card->dev, prot, tg_addr, - "FAKELL", card->dev->addr_len); + if (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_SRC_MAC_ADDR) + card->dev->header_ops->create(skb, card->dev, prot, + tg_addr, &hdr->hdr.l3.dest_addr[2], + card->dev->addr_len); + else + card->dev->header_ops->create(skb, card->dev, prot, + tg_addr, "FAKELL", card->dev->addr_len); } #ifdef CONFIG_TR @@ -2080,9 +2082,11 @@ static int qeth_l3_stop_card(struct qeth_card *card, int recovery_mode) if (recovery_mode) qeth_l3_stop(card->dev); else { - rtnl_lock(); - dev_close(card->dev); - rtnl_unlock(); + if (card->dev) { + rtnl_lock(); + dev_close(card->dev); + rtnl_unlock(); + } } if (!card->use_hard_stop) { rc = qeth_send_stoplan(card); |