From e8b1116118d777d9851a305c2c30ce5673681fce Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 11 Jun 2019 18:37:48 +0200 Subject: s390/qeth: don't mask TX errors on IQD devices Current code suppresses debug entries when an TX buffer completes in ERROR state with no error indication set in SBALF15. This was introduced back with commit 58490f18071d ("qeth: HiperSockets SIGA retry support on CC=2."). But qeth no longer retries after CC=2, and this sort of suppression make no sense anymore. Remove it. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_main.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index b1823d75dd35..cd9e2f70d8f6 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -3236,13 +3236,6 @@ static void qeth_handle_send_error(struct qeth_card *card, int sbalf15 = buffer->buffer->element[15].sflags; QETH_CARD_TEXT(card, 6, "hdsnderr"); - if (IS_IQD(card)) { - if (sbalf15 == 0) { - qdio_err = 0; - } else { - qdio_err = 1; - } - } qeth_check_qdio_errors(card, buffer->buffer, qdio_err, "qouterr"); if (!qdio_err) -- cgit v1.2.3 From 4e2fe4edcabe50b4fe82dcae5c0daca2109df1a9 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 11 Jun 2019 18:37:49 +0200 Subject: s390/qeth: use mm helpers Slightly reduce the complexity of the core xmit path, by replacing some open-coded logic with the corresponding helpers. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_main.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index cd9e2f70d8f6..feb9e1c9d506 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -3723,8 +3724,8 @@ check_layout: __elements = 1 + qeth_count_elements(skb, proto_len); else __elements = qeth_count_elements(skb, 0); - } else if (!proto_len && qeth_get_elements_for_range(start, end) == 1) { - /* Push HW header into a new page. */ + } else if (!proto_len && PAGE_ALIGNED(skb->data)) { + /* Push HW header into preceding page, flush with skb->data. */ push_ok = true; __elements = 1 + qeth_count_elements(skb, 0); } else { @@ -3778,18 +3779,16 @@ static void __qeth_fill_buffer(struct sk_buff *skb, int element = buf->next_element_to_fill; int length = skb_headlen(skb) - offset; char *data = skb->data + offset; - int length_here, cnt; + unsigned int elem_length, cnt; /* map linear part into buffer element(s) */ while (length > 0) { - /* length_here is the remaining amount of data in this page */ - length_here = PAGE_SIZE - ((unsigned long) data % PAGE_SIZE); - if (length < length_here) - length_here = length; + elem_length = min_t(unsigned int, length, + PAGE_SIZE - offset_in_page(data)); buffer->element[element].addr = data; - buffer->element[element].length = length_here; - length -= length_here; + buffer->element[element].length = elem_length; + length -= elem_length; if (is_first_elem) { is_first_elem = false; if (length || skb_is_nonlinear(skb)) @@ -3802,7 +3801,8 @@ static void __qeth_fill_buffer(struct sk_buff *skb, buffer->element[element].eflags = SBAL_EFLAGS_MIDDLE_FRAG; } - data += length_here; + + data += elem_length; element++; } @@ -3813,17 +3813,16 @@ static void __qeth_fill_buffer(struct sk_buff *skb, data = skb_frag_address(frag); length = skb_frag_size(frag); while (length > 0) { - length_here = PAGE_SIZE - - ((unsigned long) data % PAGE_SIZE); - if (length < length_here) - length_here = length; + elem_length = min_t(unsigned int, length, + PAGE_SIZE - offset_in_page(data)); buffer->element[element].addr = data; - buffer->element[element].length = length_here; + buffer->element[element].length = elem_length; buffer->element[element].eflags = SBAL_EFLAGS_MIDDLE_FRAG; - length -= length_here; - data += length_here; + + length -= elem_length; + data += elem_length; element++; } } -- cgit v1.2.3 From ad16087222262d7e66cc1ed3838264b84997323a Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 11 Jun 2019 18:37:50 +0200 Subject: s390/qeth: simplify DOWN state handling When the tear down sequence in qeth_l?_stop_card() has finished, the card is guaranteed to be in DOWN state and we don't have to check for it again. With this insight we can also remove the redundant setting of card->state in qeth_l?_set_online()'s error path. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_l2_main.c | 7 ++----- drivers/s390/net/qeth_l3_main.c | 7 ++----- 2 files changed, 4 insertions(+), 10 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index ff8a6cd790b1..40e2f6bd0f09 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -292,11 +292,9 @@ static void qeth_l2_stop_card(struct qeth_card *card) qeth_clear_working_pool_list(card); card->state = CARD_STATE_DOWN; } - if (card->state == CARD_STATE_DOWN) { - qeth_clear_cmd_buffers(&card->read); - qeth_clear_cmd_buffers(&card->write); - } + qeth_clear_cmd_buffers(&card->read); + qeth_clear_cmd_buffers(&card->write); flush_workqueue(card->event_wq); card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; } @@ -882,7 +880,6 @@ out_remove: ccw_device_set_offline(CARD_WDEV(card)); ccw_device_set_offline(CARD_RDEV(card)); qdio_free(CARD_DDEV(card)); - card->state = CARD_STATE_DOWN; mutex_unlock(&card->conf_mutex); mutex_unlock(&card->discipline_mutex); diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 13bf3e2e9cea..99ca38164b99 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -1436,11 +1436,9 @@ static void qeth_l3_stop_card(struct qeth_card *card) qeth_clear_working_pool_list(card); card->state = CARD_STATE_DOWN; } - if (card->state == CARD_STATE_DOWN) { - qeth_clear_cmd_buffers(&card->read); - qeth_clear_cmd_buffers(&card->write); - } + qeth_clear_cmd_buffers(&card->read); + qeth_clear_cmd_buffers(&card->write); flush_workqueue(card->event_wq); } @@ -2420,7 +2418,6 @@ out_remove: ccw_device_set_offline(CARD_WDEV(card)); ccw_device_set_offline(CARD_RDEV(card)); qdio_free(CARD_DDEV(card)); - card->state = CARD_STATE_DOWN; mutex_unlock(&card->conf_mutex); mutex_unlock(&card->discipline_mutex); -- cgit v1.2.3 From 7cbc9e8fe6ccbc47604a91901620c67bc538e152 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 11 Jun 2019 18:37:51 +0200 Subject: s390/qeth: restart pending READ cmd from callback The completion of a pending READ cmd is processed via qeth_issue_next_read_cb(). Let this callback also start the next READ cmd, instead of hardcoding that step into the IRQ handler. While at it remove the check of the channel state, __qeth_issue_next_read() already does this. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_main.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index feb9e1c9d506..fade84112e80 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -851,6 +851,7 @@ out: QETH_PDU_HEADER_SEQ_NO(iob->data), QETH_SEQ_NO_LENGTH); qeth_release_buffer(channel, iob); + __qeth_issue_next_read(card); } static int qeth_set_thread_start_bit(struct qeth_card *card, @@ -1115,9 +1116,6 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, } if (channel == &card->data) return; - if (channel == &card->read && - channel->state == CH_STATE_UP) - __qeth_issue_next_read(card); if (iob && iob->callback) iob->callback(card, iob->channel, iob); -- cgit v1.2.3 From 09ac887f03608db76847f2be4a8ec72cb4323b0d Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 11 Jun 2019 18:37:52 +0200 Subject: s390/qeth: clean up setting of BLKT defaults When called from qeth_core_probe_device(), qeth_determine_capabilities() initializes the device's BLKT defaults. From all other callers, the ccw_device has already been set online and the BLKT setting is skipped. Clean this up by extracting the BLKT setting into a separate helper that gets called from the right place. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 1 + drivers/s390/net/qeth_core_main.c | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 784a2e76a1b0..5fab7b3396aa 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -665,6 +665,7 @@ struct qeth_card_info { __u16 func_level; char mcl_level[QETH_MCL_LENGTH + 1]; u8 open_when_online:1; + u8 use_v1_blkt:1; u8 is_vm_nic:1; int mac_bits; enum qeth_card_types type; diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index fade84112e80..0403a1405872 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -1633,6 +1633,8 @@ static void qeth_configure_unitaddr(struct qeth_card *card, char *prcd) card->info.cula = prcd[63]; card->info.is_vm_nic = ((prcd[0x10] == _ascebc['V']) && (prcd[0x11] == _ascebc['M'])); + card->info.use_v1_blkt = prcd[74] == 0xF0 && prcd[75] == 0xF0 && + prcd[76] >= 0xF1 && prcd[76] <= 0xF4; } static enum qeth_discipline_id qeth_vm_detect_layer(struct qeth_card *card) @@ -1716,12 +1718,11 @@ static enum qeth_discipline_id qeth_enforce_discipline(struct qeth_card *card) return disc; } -static void qeth_configure_blkt_default(struct qeth_card *card, char *prcd) +static void qeth_set_blkt_defaults(struct qeth_card *card) { QETH_DBF_TEXT(SETUP, 2, "cfgblkt"); - if (prcd[74] == 0xF0 && prcd[75] == 0xF0 && - prcd[76] >= 0xF1 && prcd[76] <= 0xF4) { + if (card->info.use_v1_blkt) { card->info.blkt.time_total = 0; card->info.blkt.inter_packet = 0; card->info.blkt.inter_packet_jumbo = 0; @@ -4761,8 +4762,6 @@ static void qeth_determine_capabilities(struct qeth_card *card) goto out_offline; } qeth_configure_unitaddr(card, prcd); - if (ddev_offline) - qeth_configure_blkt_default(card, prcd); kfree(prcd); rc = qdio_get_ssqd_desc(ddev, &card->ssqd); @@ -5660,6 +5659,8 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev) if (rc) goto err_chp_desc; qeth_determine_capabilities(card); + qeth_set_blkt_defaults(card); + enforced_disc = qeth_enforce_discipline(card); switch (enforced_disc) { case QETH_DISCIPLINE_UNDETERMINED: -- cgit v1.2.3 From 1273a800141084c73a59947f9734f46da23979e5 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 11 Jun 2019 18:37:53 +0200 Subject: s390/qeth: remove qeth_wait_for_buffer() The basic MPC initialization sequence is strictly sequential, and waiting for an available cmd buffer should never be necessary. So this change only affects the OSN path, where dangling waiters on an unbounded wait_event() are not desirable. Switch to qeth_get_buffers(), and let OSN callers deal with -ENOMEM. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 2 +- drivers/s390/net/qeth_core_main.c | 58 +++++++++++++++++++++------------------ drivers/s390/net/qeth_l2_main.c | 5 +++- 3 files changed, 37 insertions(+), 28 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 5fab7b3396aa..14e8ab34ab2f 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -998,7 +998,7 @@ void qeth_tx_timeout(struct net_device *); void qeth_release_buffer(struct qeth_channel *, struct qeth_cmd_buffer *); void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, u16 cmd_length); -struct qeth_cmd_buffer *qeth_wait_for_buffer(struct qeth_channel *); +struct qeth_cmd_buffer *qeth_get_buffer(struct qeth_channel *channel); int qeth_query_switch_attributes(struct qeth_card *card, struct qeth_switch_info *sw_info); int qeth_query_card_info(struct qeth_card *card, diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 0403a1405872..3d25cff404fe 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -65,7 +65,6 @@ static struct lock_class_key qdio_out_skb_queue_key; static void qeth_issue_next_read_cb(struct qeth_card *card, struct qeth_channel *channel, struct qeth_cmd_buffer *iob); -static struct qeth_cmd_buffer *qeth_get_buffer(struct qeth_channel *); static void qeth_free_buffer_pool(struct qeth_card *); static int qeth_qdio_establish(struct qeth_card *); static void qeth_free_qdio_queues(struct qeth_card *card); @@ -746,7 +745,7 @@ static void qeth_cancel_cmd(struct qeth_cmd_buffer *iob, int rc) qeth_release_buffer(iob->channel, iob); } -static struct qeth_cmd_buffer *qeth_get_buffer(struct qeth_channel *channel) +struct qeth_cmd_buffer *qeth_get_buffer(struct qeth_channel *channel) { struct qeth_cmd_buffer *buffer = NULL; unsigned long flags; @@ -756,15 +755,7 @@ static struct qeth_cmd_buffer *qeth_get_buffer(struct qeth_channel *channel) spin_unlock_irqrestore(&channel->iob_lock, flags); return buffer; } - -struct qeth_cmd_buffer *qeth_wait_for_buffer(struct qeth_channel *channel) -{ - struct qeth_cmd_buffer *buffer; - wait_event(channel->wait_q, - ((buffer = qeth_get_buffer(channel)) != NULL)); - return buffer; -} -EXPORT_SYMBOL_GPL(qeth_wait_for_buffer); +EXPORT_SYMBOL_GPL(qeth_get_buffer); void qeth_clear_cmd_buffers(struct qeth_channel *channel) { @@ -1794,6 +1785,16 @@ static void qeth_mpc_finalize_cmd(struct qeth_card *card, iob->callback = qeth_release_buffer_cb; } +static struct qeth_cmd_buffer *qeth_mpc_get_cmd_buffer(struct qeth_card *card) +{ + struct qeth_cmd_buffer *iob; + + iob = qeth_get_buffer(&card->write); + if (iob) + iob->finalize = qeth_mpc_finalize_cmd; + return iob; +} + /** * qeth_send_control_data() - send control command to the card * @card: qeth_card structure pointer @@ -2102,10 +2103,11 @@ static int qeth_cm_enable(struct qeth_card *card) QETH_DBF_TEXT(SETUP, 2, "cmenable"); - iob = qeth_wait_for_buffer(&card->write); - iob->finalize = qeth_mpc_finalize_cmd; - memcpy(iob->data, CM_ENABLE, CM_ENABLE_SIZE); + iob = qeth_mpc_get_cmd_buffer(card); + if (!iob) + return -ENOMEM; + memcpy(iob->data, CM_ENABLE, CM_ENABLE_SIZE); memcpy(QETH_CM_ENABLE_ISSUER_RM_TOKEN(iob->data), &card->token.issuer_rm_r, QETH_MPC_TOKEN_LENGTH); memcpy(QETH_CM_ENABLE_FILTER_TOKEN(iob->data), @@ -2137,10 +2139,11 @@ static int qeth_cm_setup(struct qeth_card *card) QETH_DBF_TEXT(SETUP, 2, "cmsetup"); - iob = qeth_wait_for_buffer(&card->write); - iob->finalize = qeth_mpc_finalize_cmd; - memcpy(iob->data, CM_SETUP, CM_SETUP_SIZE); + iob = qeth_mpc_get_cmd_buffer(card); + if (!iob) + return -ENOMEM; + memcpy(iob->data, CM_SETUP, CM_SETUP_SIZE); memcpy(QETH_CM_SETUP_DEST_ADDR(iob->data), &card->token.issuer_rm_r, QETH_MPC_TOKEN_LENGTH); memcpy(QETH_CM_SETUP_CONNECTION_TOKEN(iob->data), @@ -2256,10 +2259,11 @@ static int qeth_ulp_enable(struct qeth_card *card) /*FIXME: trace view callbacks*/ QETH_DBF_TEXT(SETUP, 2, "ulpenabl"); - iob = qeth_wait_for_buffer(&card->write); - iob->finalize = qeth_mpc_finalize_cmd; - memcpy(iob->data, ULP_ENABLE, ULP_ENABLE_SIZE); + iob = qeth_mpc_get_cmd_buffer(card); + if (!iob) + return -ENOMEM; + memcpy(iob->data, ULP_ENABLE, ULP_ENABLE_SIZE); *(QETH_ULP_ENABLE_LINKNUM(iob->data)) = (u8) card->dev->dev_port; memcpy(QETH_ULP_ENABLE_PROT_TYPE(iob->data), &prot_type, 1); memcpy(QETH_ULP_ENABLE_DEST_ADDR(iob->data), @@ -2303,10 +2307,11 @@ static int qeth_ulp_setup(struct qeth_card *card) QETH_DBF_TEXT(SETUP, 2, "ulpsetup"); - iob = qeth_wait_for_buffer(&card->write); - iob->finalize = qeth_mpc_finalize_cmd; - memcpy(iob->data, ULP_SETUP, ULP_SETUP_SIZE); + iob = qeth_mpc_get_cmd_buffer(card); + if (!iob) + return -ENOMEM; + memcpy(iob->data, ULP_SETUP, ULP_SETUP_SIZE); memcpy(QETH_ULP_SETUP_DEST_ADDR(iob->data), &card->token.cm_connection_r, QETH_MPC_TOKEN_LENGTH); memcpy(QETH_ULP_SETUP_CONNECTION_TOKEN(iob->data), @@ -2492,10 +2497,11 @@ static int qeth_dm_act(struct qeth_card *card) QETH_DBF_TEXT(SETUP, 2, "dmact"); - iob = qeth_wait_for_buffer(&card->write); - iob->finalize = qeth_mpc_finalize_cmd; - memcpy(iob->data, DM_ACT, DM_ACT_SIZE); + iob = qeth_mpc_get_cmd_buffer(card); + if (!iob) + return -ENOMEM; + memcpy(iob->data, DM_ACT, DM_ACT_SIZE); memcpy(QETH_DM_ACT_DEST_ADDR(iob->data), &card->token.cm_connection_r, QETH_MPC_TOKEN_LENGTH); memcpy(QETH_DM_ACT_CONNECTION_TOKEN(iob->data), diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 40e2f6bd0f09..5fa217382480 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -1084,7 +1084,10 @@ int qeth_osn_assist(struct net_device *dev, void *data, int data_len) QETH_CARD_TEXT(card, 2, "osnsdmc"); if (!qeth_card_hw_is_reachable(card)) return -ENODEV; - iob = qeth_wait_for_buffer(&card->write); + iob = qeth_get_buffer(&card->write); + if (!iob) + return -ENOMEM; + qeth_prepare_ipa_cmd(card, iob, (u16) data_len); memcpy(__ipa_cmd(iob), data, data_len); return qeth_osn_send_ipa_cmd(card, iob); -- cgit v1.2.3 From 0ce37ec297f68d754fa2f8e1aa4c233c897ce137 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 11 Jun 2019 18:37:54 +0200 Subject: s390/qeth: remove OSN-specific IO code OSN currently provides a custom code path to submit IPA cmds, without waiting for the cmd response. Replace it with qeth_send_ipa_cmd(), which uses the common qeth_send_control_data() IO infrastructure. By setting a custom iob->callback, we can now provide feedback to the caller about whether the cmd has been successfully submitted to HW. Since the callback then immediately wakes up the reply-waiter object, we maintain the old behaviour of returning early without waiting for the response. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 1 + drivers/s390/net/qeth_core_main.c | 3 ++- drivers/s390/net/qeth_l2_main.c | 43 +++++++-------------------------------- 3 files changed, 10 insertions(+), 37 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 14e8ab34ab2f..be50e701b744 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -996,6 +996,7 @@ void qeth_setadp_promisc_mode(struct qeth_card *); int qeth_setadpparms_change_macaddr(struct qeth_card *); void qeth_tx_timeout(struct net_device *); void qeth_release_buffer(struct qeth_channel *, struct qeth_cmd_buffer *); +void qeth_notify_reply(struct qeth_reply *reply, int reason); void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, u16 cmd_length); struct qeth_cmd_buffer *qeth_get_buffer(struct qeth_channel *channel); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 3d25cff404fe..2ad51afa6747 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -577,11 +577,12 @@ static void qeth_dequeue_reply(struct qeth_card *card, struct qeth_reply *reply) spin_unlock_irq(&card->lock); } -static void qeth_notify_reply(struct qeth_reply *reply, int reason) +void qeth_notify_reply(struct qeth_reply *reply, int reason) { reply->rc = reason; complete(&reply->received); } +EXPORT_SYMBOL_GPL(qeth_notify_reply); static void qeth_issue_ipa_msg(struct qeth_ipa_cmd *cmd, int rc, struct qeth_card *card) diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 5fa217382480..7db2c5672e02 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -1033,42 +1033,12 @@ struct qeth_discipline qeth_l2_discipline = { }; EXPORT_SYMBOL_GPL(qeth_l2_discipline); -static int qeth_osn_send_control_data(struct qeth_card *card, int len, - struct qeth_cmd_buffer *iob) +static void qeth_osn_assist_cb(struct qeth_card *card, + struct qeth_channel *channel, + struct qeth_cmd_buffer *iob) { - struct qeth_channel *channel = iob->channel; - int rc = 0; - - QETH_CARD_TEXT(card, 5, "osndctrd"); - - wait_event(card->wait_q, qeth_trylock_channel(channel)); - iob->finalize(card, iob, len); - QETH_DBF_HEX(CTRL, 2, iob->data, min(len, QETH_DBF_CTRL_LEN)); - QETH_CARD_TEXT(card, 6, "osnoirqp"); - spin_lock_irq(get_ccwdev_lock(channel->ccwdev)); - rc = ccw_device_start_timeout(channel->ccwdev, channel->ccw, - (addr_t) iob, 0, 0, iob->timeout); - spin_unlock_irq(get_ccwdev_lock(channel->ccwdev)); - if (rc) { - QETH_DBF_MESSAGE(2, "qeth_osn_send_control_data: " - "ccw_device_start rc = %i\n", rc); - QETH_CARD_TEXT_(card, 2, " err%d", rc); - qeth_release_buffer(channel, iob); - atomic_set(&channel->irq_pending, 0); - wake_up(&card->wait_q); - } - return rc; -} - -static int qeth_osn_send_ipa_cmd(struct qeth_card *card, - struct qeth_cmd_buffer *iob) -{ - u16 length; - - QETH_CARD_TEXT(card, 4, "osndipa"); - - memcpy(&length, QETH_IPA_PDU_LEN_TOTAL(iob->data), 2); - return qeth_osn_send_control_data(card, length, iob); + qeth_notify_reply(iob->reply, 0); + qeth_release_buffer(channel, iob); } int qeth_osn_assist(struct net_device *dev, void *data, int data_len) @@ -1090,7 +1060,8 @@ int qeth_osn_assist(struct net_device *dev, void *data, int data_len) qeth_prepare_ipa_cmd(card, iob, (u16) data_len); memcpy(__ipa_cmd(iob), data, data_len); - return qeth_osn_send_ipa_cmd(card, iob); + iob->callback = qeth_osn_assist_cb; + return qeth_send_ipa_cmd(card, iob, NULL, NULL); } EXPORT_SYMBOL(qeth_osn_assist); -- cgit v1.2.3 From 57a688aa22eb0ce4b1c7e9310a5d84880d1884ca Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 11 Jun 2019 18:37:55 +0200 Subject: s390/qeth: convert device-specific trace entries The vast majority of SETUP-classified trace entries can be moved to their device-specific trace file. This reduces pollution of the global SETUP file, and provides a consistent trace view of all activity on the device. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_main.c | 196 ++++++++++++++++++-------------------- drivers/s390/net/qeth_l2_main.c | 28 +++--- drivers/s390/net/qeth_l3_main.c | 35 ++++--- 3 files changed, 122 insertions(+), 137 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 2ad51afa6747..df86705bdc55 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -292,7 +292,7 @@ static int qeth_cq_init(struct qeth_card *card) int rc; if (card->options.cq == QETH_CQ_ENABLED) { - QETH_DBF_TEXT(SETUP, 2, "cqinit"); + QETH_CARD_TEXT(card, 2, "cqinit"); qdio_reset_buffers(card->qdio.c_q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q); card->qdio.c_q->next_buf_to_init = 127; @@ -300,7 +300,7 @@ static int qeth_cq_init(struct qeth_card *card) card->qdio.no_in_queues - 1, 0, 127); if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); + QETH_CARD_TEXT_(card, 2, "1err%d", rc); goto out; } } @@ -317,7 +317,7 @@ static int qeth_alloc_cq(struct qeth_card *card) int i; struct qdio_outbuf_state *outbuf_states; - QETH_DBF_TEXT(SETUP, 2, "cqon"); + QETH_CARD_TEXT(card, 2, "cqon"); card->qdio.c_q = qeth_alloc_qdio_queue(); if (!card->qdio.c_q) { rc = -1; @@ -339,11 +339,11 @@ static int qeth_alloc_cq(struct qeth_card *card) outbuf_states += QDIO_MAX_BUFFERS_PER_Q; } } else { - QETH_DBF_TEXT(SETUP, 2, "nocq"); + QETH_CARD_TEXT(card, 2, "nocq"); card->qdio.c_q = NULL; card->qdio.no_in_queues = 1; } - QETH_DBF_TEXT_(SETUP, 2, "iqc%d", card->qdio.no_in_queues); + QETH_CARD_TEXT_(card, 2, "iqc%d", card->qdio.no_in_queues); rc = 0; out: return rc; @@ -1297,7 +1297,7 @@ static int qeth_update_from_chp_desc(struct qeth_card *card) struct channel_path_desc_fmt0 *chp_dsc; int rc = 0; - QETH_DBF_TEXT(SETUP, 2, "chp_desc"); + QETH_CARD_TEXT(card, 2, "chp_desc"); ccwdev = card->data.ccwdev; chp_dsc = ccw_device_get_chp_desc(ccwdev, 0); @@ -1311,14 +1311,14 @@ static int qeth_update_from_chp_desc(struct qeth_card *card) rc = qeth_osa_set_output_queues(card, chp_dsc->chpp & 0x02); kfree(chp_dsc); - QETH_DBF_TEXT_(SETUP, 2, "nr:%x", card->qdio.no_out_queues); - QETH_DBF_TEXT_(SETUP, 2, "lvl:%02x", card->info.func_level); + QETH_CARD_TEXT_(card, 2, "nr:%x", card->qdio.no_out_queues); + QETH_CARD_TEXT_(card, 2, "lvl:%02x", card->info.func_level); return rc; } static void qeth_init_qdio_info(struct qeth_card *card) { - QETH_DBF_TEXT(SETUP, 4, "intqdinf"); + QETH_CARD_TEXT(card, 4, "intqdinf"); atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED); card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT; card->qdio.default_out_queue = QETH_DEFAULT_QUEUE; @@ -1384,8 +1384,7 @@ static void qeth_start_kernel_thread(struct work_struct *work) static void qeth_buffer_reclaim_work(struct work_struct *); static void qeth_setup_card(struct qeth_card *card) { - QETH_DBF_TEXT(SETUP, 2, "setupcrd"); - QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); + QETH_CARD_TEXT(card, 2, "setupcrd"); card->info.type = CARD_RDEV(card)->id.driver_info; card->state = CARD_STATE_DOWN; @@ -1619,7 +1618,7 @@ static int qeth_read_conf_data(struct qeth_card *card, void **buffer, static void qeth_configure_unitaddr(struct qeth_card *card, char *prcd) { - QETH_DBF_TEXT(SETUP, 2, "cfgunit"); + QETH_CARD_TEXT(card, 2, "cfgunit"); card->info.chpid = prcd[30]; card->info.unit_addr2 = prcd[31]; card->info.cula = prcd[63]; @@ -1638,7 +1637,7 @@ static enum qeth_discipline_id qeth_vm_detect_layer(struct qeth_card *card) char userid[80]; int rc = 0; - QETH_DBF_TEXT(SETUP, 2, "vmlayer"); + QETH_CARD_TEXT(card, 2, "vmlayer"); cpcmd("QUERY USERID", userid, sizeof(userid), &rc); if (rc) @@ -1681,7 +1680,7 @@ out: kfree(response); kfree(request); if (rc) - QETH_DBF_TEXT_(SETUP, 2, "err%x", rc); + QETH_CARD_TEXT_(card, 2, "err%x", rc); return disc; } @@ -1698,13 +1697,13 @@ static enum qeth_discipline_id qeth_enforce_discipline(struct qeth_card *card) switch (disc) { case QETH_DISCIPLINE_LAYER2: - QETH_DBF_TEXT(SETUP, 3, "force l2"); + QETH_CARD_TEXT(card, 3, "force l2"); break; case QETH_DISCIPLINE_LAYER3: - QETH_DBF_TEXT(SETUP, 3, "force l3"); + QETH_CARD_TEXT(card, 3, "force l3"); break; default: - QETH_DBF_TEXT(SETUP, 3, "force no"); + QETH_CARD_TEXT(card, 3, "force no"); } return disc; @@ -1712,7 +1711,7 @@ static enum qeth_discipline_id qeth_enforce_discipline(struct qeth_card *card) static void qeth_set_blkt_defaults(struct qeth_card *card) { - QETH_DBF_TEXT(SETUP, 2, "cfgblkt"); + QETH_CARD_TEXT(card, 2, "cfgblkt"); if (card->info.use_v1_blkt) { card->info.blkt.time_total = 0; @@ -1902,8 +1901,8 @@ static int qeth_idx_check_activate_response(struct qeth_card *card, return 0; /* negative reply: */ - QETH_DBF_TEXT_(SETUP, 2, "idxneg%c", - QETH_IDX_ACT_CAUSE_CODE(iob->data)); + QETH_CARD_TEXT_(card, 2, "idxneg%c", + QETH_IDX_ACT_CAUSE_CODE(iob->data)); switch (QETH_IDX_ACT_CAUSE_CODE(iob->data)) { case QETH_IDX_ACT_ERR_EXCL: @@ -1929,7 +1928,7 @@ static void qeth_idx_query_read_cb(struct qeth_card *card, u16 peer_level; int rc; - QETH_DBF_TEXT(SETUP, 2, "idxrdcb"); + QETH_CARD_TEXT(card, 2, "idxrdcb"); rc = qeth_idx_check_activate_response(card, channel, iob); if (rc) @@ -1962,7 +1961,7 @@ static void qeth_idx_query_write_cb(struct qeth_card *card, u16 peer_level; int rc; - QETH_DBF_TEXT(SETUP, 2, "idxwrcb"); + QETH_CARD_TEXT(card, 2, "idxwrcb"); rc = qeth_idx_check_activate_response(card, channel, iob); if (rc) @@ -2023,7 +2022,7 @@ static int qeth_idx_activate_read_channel(struct qeth_card *card) struct qeth_cmd_buffer *iob; int rc; - QETH_DBF_TEXT(SETUP, 2, "idxread"); + QETH_CARD_TEXT(card, 2, "idxread"); iob = qeth_get_buffer(channel); if (!iob) @@ -2056,7 +2055,7 @@ static int qeth_idx_activate_write_channel(struct qeth_card *card) struct qeth_cmd_buffer *iob; int rc; - QETH_DBF_TEXT(SETUP, 2, "idxwrite"); + QETH_CARD_TEXT(card, 2, "idxwrite"); iob = qeth_get_buffer(channel); if (!iob) @@ -2088,7 +2087,7 @@ static int qeth_cm_enable_cb(struct qeth_card *card, struct qeth_reply *reply, { struct qeth_cmd_buffer *iob; - QETH_DBF_TEXT(SETUP, 2, "cmenblcb"); + QETH_CARD_TEXT(card, 2, "cmenblcb"); iob = (struct qeth_cmd_buffer *) data; memcpy(&card->token.cm_filter_r, @@ -2102,7 +2101,7 @@ static int qeth_cm_enable(struct qeth_card *card) int rc; struct qeth_cmd_buffer *iob; - QETH_DBF_TEXT(SETUP, 2, "cmenable"); + QETH_CARD_TEXT(card, 2, "cmenable"); iob = qeth_mpc_get_cmd_buffer(card); if (!iob) @@ -2124,7 +2123,7 @@ static int qeth_cm_setup_cb(struct qeth_card *card, struct qeth_reply *reply, { struct qeth_cmd_buffer *iob; - QETH_DBF_TEXT(SETUP, 2, "cmsetpcb"); + QETH_CARD_TEXT(card, 2, "cmsetpcb"); iob = (struct qeth_cmd_buffer *) data; memcpy(&card->token.cm_connection_r, @@ -2138,7 +2137,7 @@ static int qeth_cm_setup(struct qeth_card *card) int rc; struct qeth_cmd_buffer *iob; - QETH_DBF_TEXT(SETUP, 2, "cmsetup"); + QETH_CARD_TEXT(card, 2, "cmsetup"); iob = qeth_mpc_get_cmd_buffer(card); if (!iob) @@ -2218,7 +2217,7 @@ static int qeth_ulp_enable_cb(struct qeth_card *card, struct qeth_reply *reply, __u8 link_type; struct qeth_cmd_buffer *iob; - QETH_DBF_TEXT(SETUP, 2, "ulpenacb"); + QETH_CARD_TEXT(card, 2, "ulpenacb"); iob = (struct qeth_cmd_buffer *) data; memcpy(&card->token.ulp_filter_r, @@ -2239,7 +2238,7 @@ static int qeth_ulp_enable_cb(struct qeth_card *card, struct qeth_reply *reply, card->info.link_type = link_type; } else card->info.link_type = 0; - QETH_DBF_TEXT_(SETUP, 2, "link%d", card->info.link_type); + QETH_CARD_TEXT_(card, 2, "link%d", card->info.link_type); return 0; } @@ -2257,8 +2256,7 @@ static int qeth_ulp_enable(struct qeth_card *card) u16 max_mtu; int rc; - /*FIXME: trace view callbacks*/ - QETH_DBF_TEXT(SETUP, 2, "ulpenabl"); + QETH_CARD_TEXT(card, 2, "ulpenabl"); iob = qeth_mpc_get_cmd_buffer(card); if (!iob) @@ -2283,7 +2281,7 @@ static int qeth_ulp_setup_cb(struct qeth_card *card, struct qeth_reply *reply, { struct qeth_cmd_buffer *iob; - QETH_DBF_TEXT(SETUP, 2, "ulpstpcb"); + QETH_CARD_TEXT(card, 2, "ulpstpcb"); iob = (struct qeth_cmd_buffer *) data; memcpy(&card->token.ulp_connection_r, @@ -2291,7 +2289,7 @@ static int qeth_ulp_setup_cb(struct qeth_card *card, struct qeth_reply *reply, QETH_MPC_TOKEN_LENGTH); if (!strncmp("00S", QETH_ULP_SETUP_RESP_CONNECTION_TOKEN(iob->data), 3)) { - QETH_DBF_TEXT(SETUP, 2, "olmlimit"); + QETH_CARD_TEXT(card, 2, "olmlimit"); dev_err(&card->gdev->dev, "A connection could not be " "established because of an OLM limit\n"); return -EMLINK; @@ -2306,7 +2304,7 @@ static int qeth_ulp_setup(struct qeth_card *card) struct qeth_cmd_buffer *iob; struct ccw_dev_id dev_id; - QETH_DBF_TEXT(SETUP, 2, "ulpsetup"); + QETH_CARD_TEXT(card, 2, "ulpsetup"); iob = qeth_mpc_get_cmd_buffer(card); if (!iob) @@ -2375,13 +2373,13 @@ static int qeth_alloc_qdio_queues(struct qeth_card *card) { int i, j; - QETH_DBF_TEXT(SETUP, 2, "allcqdbf"); + QETH_CARD_TEXT(card, 2, "allcqdbf"); if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED, QETH_QDIO_ALLOCATED) != QETH_QDIO_UNINITIALIZED) return 0; - QETH_DBF_TEXT(SETUP, 2, "inq"); + QETH_CARD_TEXT(card, 2, "inq"); card->qdio.in_q = qeth_alloc_qdio_queue(); if (!card->qdio.in_q) goto out_nomem; @@ -2395,8 +2393,8 @@ static int qeth_alloc_qdio_queues(struct qeth_card *card) card->qdio.out_qs[i] = qeth_alloc_output_queue(); if (!card->qdio.out_qs[i]) goto out_freeoutq; - QETH_DBF_TEXT_(SETUP, 2, "outq %i", i); - QETH_DBF_HEX(SETUP, 2, &card->qdio.out_qs[i], sizeof(void *)); + QETH_CARD_TEXT_(card, 2, "outq %i", i); + QETH_CARD_HEX(card, 2, &card->qdio.out_qs[i], sizeof(void *)); card->qdio.out_qs[i]->card = card; card->qdio.out_qs[i]->queue_no = i; /* give outbound qeth_qdio_buffers their qdio_buffers */ @@ -2487,7 +2485,7 @@ static void qeth_create_qib_param_field_blkt(struct qeth_card *card, static int qeth_qdio_activate(struct qeth_card *card) { - QETH_DBF_TEXT(SETUP, 3, "qdioact"); + QETH_CARD_TEXT(card, 3, "qdioact"); return qdio_activate(CARD_DDEV(card)); } @@ -2496,7 +2494,7 @@ static int qeth_dm_act(struct qeth_card *card) int rc; struct qeth_cmd_buffer *iob; - QETH_DBF_TEXT(SETUP, 2, "dmact"); + QETH_CARD_TEXT(card, 2, "dmact"); iob = qeth_mpc_get_cmd_buffer(card); if (!iob) @@ -2515,52 +2513,52 @@ static int qeth_mpc_initialize(struct qeth_card *card) { int rc; - QETH_DBF_TEXT(SETUP, 2, "mpcinit"); + QETH_CARD_TEXT(card, 2, "mpcinit"); rc = qeth_issue_next_read(card); if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); + QETH_CARD_TEXT_(card, 2, "1err%d", rc); return rc; } rc = qeth_cm_enable(card); if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); + QETH_CARD_TEXT_(card, 2, "2err%d", rc); goto out_qdio; } rc = qeth_cm_setup(card); if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc); + QETH_CARD_TEXT_(card, 2, "3err%d", rc); goto out_qdio; } rc = qeth_ulp_enable(card); if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc); + QETH_CARD_TEXT_(card, 2, "4err%d", rc); goto out_qdio; } rc = qeth_ulp_setup(card); if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc); + QETH_CARD_TEXT_(card, 2, "5err%d", rc); goto out_qdio; } rc = qeth_alloc_qdio_queues(card); if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc); + QETH_CARD_TEXT_(card, 2, "5err%d", rc); goto out_qdio; } rc = qeth_qdio_establish(card); if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc); + QETH_CARD_TEXT_(card, 2, "6err%d", rc); qeth_free_qdio_queues(card); goto out_qdio; } rc = qeth_qdio_activate(card); if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "7err%d", rc); + QETH_CARD_TEXT_(card, 2, "7err%d", rc); goto out_qdio; } rc = qeth_dm_act(card); if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "8err%d", rc); + QETH_CARD_TEXT_(card, 2, "8err%d", rc); goto out_qdio; } @@ -2713,7 +2711,7 @@ int qeth_init_qdio_queues(struct qeth_card *card) unsigned int i; int rc; - QETH_DBF_TEXT(SETUP, 2, "initqdqs"); + QETH_CARD_TEXT(card, 2, "initqdqs"); /* inbound queue */ qdio_reset_buffers(card->qdio.in_q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q); @@ -2727,7 +2725,7 @@ int qeth_init_qdio_queues(struct qeth_card *card) rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0, 0, card->qdio.in_buf_pool.buf_count - 1); if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); + QETH_CARD_TEXT_(card, 2, "1err%d", rc); return rc; } @@ -2885,7 +2883,7 @@ static int qeth_send_startlan(struct qeth_card *card) { struct qeth_cmd_buffer *iob; - QETH_DBF_TEXT(SETUP, 2, "strtlan"); + QETH_CARD_TEXT(card, 2, "strtlan"); iob = qeth_get_ipacmd_buffer(card, IPA_CMD_STARTLAN, 0); if (!iob) @@ -2913,7 +2911,7 @@ static int qeth_query_setadapterparms_cb(struct qeth_card *card, if (cmd->data.setadapterparms.data.query_cmds_supp.lan_type & 0x7f) { card->info.link_type = cmd->data.setadapterparms.data.query_cmds_supp.lan_type; - QETH_DBF_TEXT_(SETUP, 2, "lnk %d", card->info.link_type); + QETH_CARD_TEXT_(card, 2, "lnk %d", card->info.link_type); } card->options.adp.supported_funcs = cmd->data.setadapterparms.data.query_cmds_supp.supported_cmds; @@ -2958,7 +2956,7 @@ static int qeth_query_ipassists_cb(struct qeth_card *card, { struct qeth_ipa_cmd *cmd; - QETH_DBF_TEXT(SETUP, 2, "qipasscb"); + QETH_CARD_TEXT(card, 2, "qipasscb"); cmd = (struct qeth_ipa_cmd *) data; @@ -2967,7 +2965,7 @@ static int qeth_query_ipassists_cb(struct qeth_card *card, break; case IPA_RC_NOTSUPP: case IPA_RC_L2_UNSUPPORTED_CMD: - QETH_DBF_TEXT(SETUP, 2, "ipaunsup"); + QETH_CARD_TEXT(card, 2, "ipaunsup"); card->options.ipa4.supported_funcs |= IPA_SETADAPTERPARMS; card->options.ipa6.supported_funcs |= IPA_SETADAPTERPARMS; return -EOPNOTSUPP; @@ -2995,7 +2993,7 @@ static int qeth_query_ipassists(struct qeth_card *card, int rc; struct qeth_cmd_buffer *iob; - QETH_DBF_TEXT_(SETUP, 2, "qipassi%i", prot); + QETH_CARD_TEXT_(card, 2, "qipassi%i", prot); iob = qeth_get_ipacmd_buffer(card, IPA_CMD_QIPASSIST, prot); if (!iob) return -ENOMEM; @@ -3061,7 +3059,7 @@ static int qeth_query_setdiagass(struct qeth_card *card) struct qeth_cmd_buffer *iob; struct qeth_ipa_cmd *cmd; - QETH_DBF_TEXT(SETUP, 2, "qdiagass"); + QETH_CARD_TEXT(card, 2, "qdiagass"); iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); if (!iob) return -ENOMEM; @@ -3114,7 +3112,7 @@ int qeth_hw_trap(struct qeth_card *card, enum qeth_diags_trap_action action) struct qeth_cmd_buffer *iob; struct qeth_ipa_cmd *cmd; - QETH_DBF_TEXT(SETUP, 2, "diagtrap"); + QETH_CARD_TEXT(card, 2, "diagtrap"); iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); if (!iob) return -ENOMEM; @@ -4226,10 +4224,8 @@ static int qeth_setadpparms_set_access_ctrl_cb(struct qeth_card *card, qeth_setadpparms_inspect_rc(cmd); access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl; - QETH_DBF_TEXT_(SETUP, 2, "setaccb"); - QETH_DBF_TEXT_(SETUP, 2, "%s", card->gdev->dev.kobj.name); - QETH_DBF_TEXT_(SETUP, 2, "rc=%d", - cmd->data.setadapterparms.hdr.return_code); + QETH_CARD_TEXT_(card, 2, "rc=%d", + cmd->data.setadapterparms.hdr.return_code); if (cmd->data.setadapterparms.hdr.return_code != SET_ACCESS_CTRL_RC_SUCCESS) QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_CTRL(%#x) on device %x: %#x\n", @@ -4309,9 +4305,6 @@ static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card, QETH_CARD_TEXT(card, 4, "setacctl"); - QETH_DBF_TEXT_(SETUP, 2, "setacctl"); - QETH_DBF_TEXT_(SETUP, 2, "%s", card->gdev->dev.kobj.name); - iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_ACCESS_CONTROL, sizeof(struct qeth_ipacmd_setadpparms_hdr) + sizeof(struct qeth_set_access_ctrl)); @@ -4323,7 +4316,7 @@ static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card, rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_set_access_ctrl_cb, &fallback); - QETH_DBF_TEXT_(SETUP, 2, "rc=%d", rc); + QETH_CARD_TEXT_(card, 2, "rc=%d", rc); return rc; } @@ -4699,7 +4692,7 @@ int qeth_vm_request_mac(struct qeth_card *card) struct ccw_dev_id id; int rc; - QETH_DBF_TEXT(SETUP, 2, "vmreqmac"); + QETH_CARD_TEXT(card, 2, "vmreqmac"); request = kzalloc(sizeof(*request), GFP_KERNEL | GFP_DMA); response = kzalloc(sizeof(*response), GFP_KERNEL | GFP_DMA); @@ -4724,13 +4717,13 @@ int qeth_vm_request_mac(struct qeth_card *card) if (request->resp_buf_len < sizeof(*response) || response->version != request->resp_version) { rc = -EIO; - QETH_DBF_TEXT(SETUP, 2, "badresp"); - QETH_DBF_HEX(SETUP, 2, &request->resp_buf_len, - sizeof(request->resp_buf_len)); + QETH_CARD_TEXT(card, 2, "badresp"); + QETH_CARD_HEX(card, 2, &request->resp_buf_len, + sizeof(request->resp_buf_len)); } else if (!is_valid_ether_addr(response->mac)) { rc = -EINVAL; - QETH_DBF_TEXT(SETUP, 2, "badmac"); - QETH_DBF_HEX(SETUP, 2, response->mac, ETH_ALEN); + QETH_CARD_TEXT(card, 2, "badmac"); + QETH_CARD_HEX(card, 2, response->mac, ETH_ALEN); } else { ether_addr_copy(card->dev->dev_addr, response->mac); } @@ -4750,13 +4743,13 @@ static void qeth_determine_capabilities(struct qeth_card *card) struct ccw_device *ddev; int ddev_offline = 0; - QETH_DBF_TEXT(SETUP, 2, "detcapab"); + QETH_CARD_TEXT(card, 2, "detcapab"); ddev = CARD_DDEV(card); if (!ddev->online) { ddev_offline = 1; rc = ccw_device_set_online(ddev); if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc); + QETH_CARD_TEXT_(card, 2, "3err%d", rc); goto out; } } @@ -4765,7 +4758,7 @@ static void qeth_determine_capabilities(struct qeth_card *card) if (rc) { QETH_DBF_MESSAGE(2, "qeth_read_conf_data on device %x returned %i\n", CARD_DEVID(card), rc); - QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc); + QETH_CARD_TEXT_(card, 2, "5err%d", rc); goto out_offline; } qeth_configure_unitaddr(card, prcd); @@ -4773,13 +4766,13 @@ static void qeth_determine_capabilities(struct qeth_card *card) rc = qdio_get_ssqd_desc(ddev, &card->ssqd); if (rc) - QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc); + QETH_CARD_TEXT_(card, 2, "6err%d", rc); - QETH_DBF_TEXT_(SETUP, 2, "qfmt%d", card->ssqd.qfmt); - QETH_DBF_TEXT_(SETUP, 2, "ac1:%02x", card->ssqd.qdioac1); - QETH_DBF_TEXT_(SETUP, 2, "ac2:%04x", card->ssqd.qdioac2); - QETH_DBF_TEXT_(SETUP, 2, "ac3:%04x", card->ssqd.qdioac3); - QETH_DBF_TEXT_(SETUP, 2, "icnt%d", card->ssqd.icnt); + QETH_CARD_TEXT_(card, 2, "qfmt%d", card->ssqd.qfmt); + QETH_CARD_TEXT_(card, 2, "ac1:%02x", card->ssqd.qdioac1); + QETH_CARD_TEXT_(card, 2, "ac2:%04x", card->ssqd.qdioac2); + QETH_CARD_TEXT_(card, 2, "ac3:%04x", card->ssqd.qdioac3); + QETH_CARD_TEXT_(card, 2, "icnt%d", card->ssqd.icnt); if (!((card->ssqd.qfmt != QDIO_IQDIO_QFMT) || ((card->ssqd.qdioac1 & CHSC_AC1_INITIATE_INPUTQ) == 0) || ((card->ssqd.qdioac3 & CHSC_AC3_FORMAT2_CQ_AVAILABLE) == 0))) { @@ -4827,7 +4820,7 @@ static int qeth_qdio_establish(struct qeth_card *card) int i, j, k; int rc = 0; - QETH_DBF_TEXT(SETUP, 2, "qdioest"); + QETH_CARD_TEXT(card, 2, "qdioest"); qib_param_field = kzalloc(QDIO_MAX_BUFFERS_PER_Q, GFP_KERNEL); @@ -4931,8 +4924,7 @@ out_free_nothing: static void qeth_core_free_card(struct qeth_card *card) { - QETH_DBF_TEXT(SETUP, 2, "freecrd"); - QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); + QETH_CARD_TEXT(card, 2, "freecrd"); qeth_clean_channel(&card->read); qeth_clean_channel(&card->write); qeth_clean_channel(&card->data); @@ -4984,7 +4976,7 @@ int qeth_core_hardsetup_card(struct qeth_card *card, bool *carrier_ok) int retries = 3; int rc; - QETH_DBF_TEXT(SETUP, 2, "hrdsetup"); + QETH_CARD_TEXT(card, 2, "hrdsetup"); atomic_set(&card->force_alloc_skb, 0); rc = qeth_update_from_chp_desc(card); if (rc) @@ -5009,10 +5001,10 @@ retry: goto retriable; retriable: if (rc == -ERESTARTSYS) { - QETH_DBF_TEXT(SETUP, 2, "break1"); + QETH_CARD_TEXT(card, 2, "break1"); return rc; } else if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); + QETH_CARD_TEXT_(card, 2, "1err%d", rc); if (--retries < 0) goto out; else @@ -5024,10 +5016,10 @@ retriable: rc = qeth_idx_activate_read_channel(card); if (rc == -EINTR) { - QETH_DBF_TEXT(SETUP, 2, "break2"); + QETH_CARD_TEXT(card, 2, "break2"); return rc; } else if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc); + QETH_CARD_TEXT_(card, 2, "3err%d", rc); if (--retries < 0) goto out; else @@ -5036,10 +5028,10 @@ retriable: rc = qeth_idx_activate_write_channel(card); if (rc == -EINTR) { - QETH_DBF_TEXT(SETUP, 2, "break3"); + QETH_CARD_TEXT(card, 2, "break3"); return rc; } else if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc); + QETH_CARD_TEXT_(card, 2, "4err%d", rc); if (--retries < 0) goto out; else @@ -5048,13 +5040,13 @@ retriable: card->read_or_write_problem = 0; rc = qeth_mpc_initialize(card); if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc); + QETH_CARD_TEXT_(card, 2, "5err%d", rc); goto out; } rc = qeth_send_startlan(card); if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc); + QETH_CARD_TEXT_(card, 2, "6err%d", rc); if (rc == -ENETDOWN) { dev_warn(&card->gdev->dev, "The LAN is offline\n"); *carrier_ok = false; @@ -5081,14 +5073,14 @@ retriable: if (qeth_is_supported(card, IPA_SETADAPTERPARMS)) { rc = qeth_query_setadapterparms(card); if (rc < 0) { - QETH_DBF_TEXT_(SETUP, 2, "7err%d", rc); + QETH_CARD_TEXT_(card, 2, "7err%d", rc); goto out; } } if (qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST)) { rc = qeth_query_setdiagass(card); if (rc < 0) { - QETH_DBF_TEXT_(SETUP, 2, "8err%d", rc); + QETH_CARD_TEXT_(card, 2, "8err%d", rc); goto out; } } @@ -5705,7 +5697,7 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); - QETH_DBF_TEXT(SETUP, 2, "removedv"); + QETH_CARD_TEXT(card, 2, "removedv"); if (card->discipline) { card->discipline->remove(gdev); @@ -6102,8 +6094,8 @@ int qeth_set_features(struct net_device *dev, netdev_features_t features) netdev_features_t changed = dev->features ^ features; int rc = 0; - QETH_DBF_TEXT(SETUP, 2, "setfeat"); - QETH_DBF_HEX(SETUP, 2, &features, sizeof(features)); + QETH_CARD_TEXT(card, 2, "setfeat"); + QETH_CARD_HEX(card, 2, &features, sizeof(features)); if ((changed & NETIF_F_IP_CSUM)) { rc = qeth_set_ipa_csum(card, features & NETIF_F_IP_CSUM, @@ -6149,7 +6141,7 @@ netdev_features_t qeth_fix_features(struct net_device *dev, { struct qeth_card *card = dev->ml_priv; - QETH_DBF_TEXT(SETUP, 2, "fixfeat"); + QETH_CARD_TEXT(card, 2, "fixfeat"); if (!qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM)) features &= ~NETIF_F_IP_CSUM; if (!qeth_is_supported6(card, IPA_OUTBOUND_CHECKSUM_V6)) @@ -6162,7 +6154,7 @@ netdev_features_t qeth_fix_features(struct net_device *dev, if (!qeth_is_supported6(card, IPA_OUTBOUND_TSO)) features &= ~NETIF_F_TSO6; - QETH_DBF_HEX(SETUP, 2, &features, sizeof(features)); + QETH_CARD_HEX(card, 2, &features, sizeof(features)); return features; } EXPORT_SYMBOL_GPL(qeth_fix_features); diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 7db2c5672e02..5fc36ed20c67 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -274,8 +274,7 @@ static int qeth_l2_vlan_rx_kill_vid(struct net_device *dev, static void qeth_l2_stop_card(struct qeth_card *card) { - QETH_DBF_TEXT(SETUP , 2, "stopcard"); - QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); + QETH_CARD_TEXT(card, 2, "stopcard"); qeth_set_allowed_threads(card, 0, 1); @@ -352,8 +351,7 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card) { int rc = 0; - QETH_DBF_TEXT(SETUP, 2, "l2reqmac"); - QETH_DBF_TEXT_(SETUP, 2, "doL2%s", CARD_BUS_ID(card)); + QETH_CARD_TEXT(card, 2, "l2reqmac"); if (MACHINE_IS_VM) { rc = qeth_vm_request_mac(card); @@ -361,7 +359,7 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card) goto out; QETH_DBF_MESSAGE(2, "z/VM MAC Service failed on device %x: %#x\n", CARD_DEVID(card), rc); - QETH_DBF_TEXT_(SETUP, 2, "err%04x", rc); + QETH_CARD_TEXT_(card, 2, "err%04x", rc); /* fall back to alternative mechanism: */ } @@ -371,7 +369,7 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card) goto out; QETH_DBF_MESSAGE(2, "READ_MAC Assist failed on device %x: %#x\n", CARD_DEVID(card), rc); - QETH_DBF_TEXT_(SETUP, 2, "1err%04x", rc); + QETH_CARD_TEXT_(card, 2, "1err%04x", rc); /* fall back once more: */ } @@ -381,7 +379,7 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card) eth_hw_addr_random(card->dev); out: - QETH_DBF_HEX(SETUP, 2, card->dev->dev_addr, card->dev->addr_len); + QETH_CARD_HEX(card, 2, card->dev->dev_addr, card->dev->addr_len); return 0; } @@ -465,7 +463,7 @@ static void qeth_promisc_to_bridge(struct qeth_card *card) role = QETH_SBP_ROLE_NONE; rc = qeth_bridgeport_setrole(card, role); - QETH_DBF_TEXT_(SETUP, 2, "bpm%c%04x", + QETH_CARD_TEXT_(card, 2, "bpm%c%04x", (promisc_mode == SET_PROMISC_MODE_ON) ? '+' : '-', rc); if (!rc) { card->options.sbp.role = role; @@ -794,12 +792,11 @@ static int qeth_l2_set_online(struct ccwgroup_device *gdev) mutex_lock(&card->discipline_mutex); mutex_lock(&card->conf_mutex); - QETH_DBF_TEXT(SETUP, 2, "setonlin"); - QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); + QETH_CARD_TEXT(card, 2, "setonlin"); rc = qeth_core_hardsetup_card(card, &carrier_ok); if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc); + QETH_CARD_TEXT_(card, 2, "2err%04x", rc); rc = -ENODEV; goto out_remove; } @@ -830,7 +827,7 @@ static int qeth_l2_set_online(struct ccwgroup_device *gdev) qeth_print_status_message(card); /* softsetup */ - QETH_DBF_TEXT(SETUP, 2, "softsetp"); + QETH_CARD_TEXT(card, 2, "softsetp"); if (IS_OSD(card) || IS_OSX(card)) { rc = qeth_l2_start_ipassists(card); @@ -840,7 +837,7 @@ static int qeth_l2_set_online(struct ccwgroup_device *gdev) rc = qeth_init_qdio_queues(card); if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc); + QETH_CARD_TEXT_(card, 2, "6err%d", rc); rc = -ENODEV; goto out_remove; } @@ -894,8 +891,7 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev, mutex_lock(&card->discipline_mutex); mutex_lock(&card->conf_mutex); - QETH_DBF_TEXT(SETUP, 3, "setoffl"); - QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *)); + QETH_CARD_TEXT(card, 3, "setoffl"); if ((!recovery_mode && card->info.hwtrap) || card->info.hwtrap == 2) { qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM); @@ -916,7 +912,7 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev, if (!rc) rc = (rc2) ? rc2 : rc3; if (rc) - QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); + QETH_CARD_TEXT_(card, 2, "1err%d", rc); qdio_free(CARD_DDEV(card)); /* let user_space know that device is offline */ diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 99ca38164b99..15758f45837d 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -742,7 +742,7 @@ static int qeth_l3_setadapter_parms(struct qeth_card *card) { int rc = 0; - QETH_DBF_TEXT(SETUP, 2, "setadprm"); + QETH_CARD_TEXT(card, 2, "setadprm"); if (qeth_adp_supported(card, IPA_SETADP_ALTER_MAC_ADDRESS)) { rc = qeth_setadpparms_change_macaddr(card); @@ -979,7 +979,7 @@ static int qeth_l3_iqd_read_initial_mac(struct qeth_card *card) struct qeth_cmd_buffer *iob; struct qeth_ipa_cmd *cmd; - QETH_DBF_TEXT(SETUP, 2, "hsrmac"); + QETH_CARD_TEXT(card, 2, "hsrmac"); iob = qeth_get_ipacmd_buffer(card, IPA_CMD_CREATE_ADDR, QETH_PROT_IPV6); @@ -1017,7 +1017,7 @@ static int qeth_l3_get_unique_id(struct qeth_card *card) struct qeth_cmd_buffer *iob; struct qeth_ipa_cmd *cmd; - QETH_DBF_TEXT(SETUP, 2, "guniqeid"); + QETH_CARD_TEXT(card, 2, "guniqeid"); if (!qeth_is_supported(card, IPA_IPV6)) { card->info.unique_id = UNIQUE_ID_IF_CREATE_ADDR_FAILED | @@ -1044,7 +1044,7 @@ qeth_diags_trace_cb(struct qeth_card *card, struct qeth_reply *reply, struct qeth_ipa_cmd *cmd; __u16 rc; - QETH_DBF_TEXT(SETUP, 2, "diastrcb"); + QETH_CARD_TEXT(card, 2, "diastrcb"); cmd = (struct qeth_ipa_cmd *)data; rc = cmd->hdr.return_code; @@ -1100,7 +1100,7 @@ qeth_diags_trace(struct qeth_card *card, enum qeth_diags_trace_cmds diags_cmd) struct qeth_cmd_buffer *iob; struct qeth_ipa_cmd *cmd; - QETH_DBF_TEXT(SETUP, 2, "diagtrac"); + QETH_CARD_TEXT(card, 2, "diagtrac"); iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); if (!iob) @@ -1413,8 +1413,7 @@ static int qeth_l3_process_inbound_buffer(struct qeth_card *card, static void qeth_l3_stop_card(struct qeth_card *card) { - QETH_DBF_TEXT(SETUP, 2, "stopcard"); - QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); + QETH_CARD_TEXT(card, 2, "stopcard"); qeth_set_allowed_threads(card, 0, 1); @@ -2335,12 +2334,11 @@ static int qeth_l3_set_online(struct ccwgroup_device *gdev) mutex_lock(&card->discipline_mutex); mutex_lock(&card->conf_mutex); - QETH_DBF_TEXT(SETUP, 2, "setonlin"); - QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); + QETH_CARD_TEXT(card, 2, "setonlin"); rc = qeth_core_hardsetup_card(card, &carrier_ok); if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc); + QETH_CARD_TEXT_(card, 2, "2err%04x", rc); rc = -ENODEV; goto out_remove; } @@ -2356,28 +2354,28 @@ static int qeth_l3_set_online(struct ccwgroup_device *gdev) qeth_print_status_message(card); /* softsetup */ - QETH_DBF_TEXT(SETUP, 2, "softsetp"); + QETH_CARD_TEXT(card, 2, "softsetp"); rc = qeth_l3_setadapter_parms(card); if (rc) - QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc); + QETH_CARD_TEXT_(card, 2, "2err%04x", rc); if (!card->options.sniffer) { rc = qeth_l3_start_ipassists(card); if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc); + QETH_CARD_TEXT_(card, 2, "3err%d", rc); goto out_remove; } rc = qeth_l3_setrouting_v4(card); if (rc) - QETH_DBF_TEXT_(SETUP, 2, "4err%04x", rc); + QETH_CARD_TEXT_(card, 2, "4err%04x", rc); rc = qeth_l3_setrouting_v6(card); if (rc) - QETH_DBF_TEXT_(SETUP, 2, "5err%04x", rc); + QETH_CARD_TEXT_(card, 2, "5err%04x", rc); } rc = qeth_init_qdio_queues(card); if (rc) { - QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc); + QETH_CARD_TEXT_(card, 2, "6err%d", rc); rc = -ENODEV; goto out_remove; } @@ -2432,8 +2430,7 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev, mutex_lock(&card->discipline_mutex); mutex_lock(&card->conf_mutex); - QETH_DBF_TEXT(SETUP, 3, "setoffl"); - QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *)); + QETH_CARD_TEXT(card, 3, "setoffl"); if ((!recovery_mode && card->info.hwtrap) || card->info.hwtrap == 2) { qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM); @@ -2459,7 +2456,7 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev, if (!rc) rc = (rc2) ? rc2 : rc3; if (rc) - QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); + QETH_CARD_TEXT_(card, 2, "1err%d", rc); qdio_free(CARD_DDEV(card)); /* let user_space know that device is offline */ -- cgit v1.2.3 From fcda7f73b618d93e16c9f82fbc366ed4ea327e0e Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 11 Jun 2019 18:37:56 +0200 Subject: s390/qeth: remove 'channel' parameter from callbacks Each cmd buffer maintains a pointer to the IO channel that it was/will be issued on. So when dealing with cmd buffers, we don't need to pass around a separate channel pointer. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 5 ++--- drivers/s390/net/qeth_core_main.c | 38 +++++++++++++++++--------------------- drivers/s390/net/qeth_l2_main.c | 5 ++--- 3 files changed, 21 insertions(+), 27 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index be50e701b744..c1292d3420a2 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -585,8 +585,7 @@ struct qeth_cmd_buffer { unsigned char *data; void (*finalize)(struct qeth_card *card, struct qeth_cmd_buffer *iob, unsigned int length); - void (*callback)(struct qeth_card *card, struct qeth_channel *channel, - struct qeth_cmd_buffer *iob); + void (*callback)(struct qeth_card *card, struct qeth_cmd_buffer *iob); }; static inline struct qeth_ipa_cmd *__ipa_cmd(struct qeth_cmd_buffer *iob) @@ -995,7 +994,7 @@ void qeth_drain_output_queues(struct qeth_card *card); void qeth_setadp_promisc_mode(struct qeth_card *); int qeth_setadpparms_change_macaddr(struct qeth_card *); void qeth_tx_timeout(struct net_device *); -void qeth_release_buffer(struct qeth_channel *, struct qeth_cmd_buffer *); +void qeth_release_buffer(struct qeth_cmd_buffer *iob); void qeth_notify_reply(struct qeth_reply *reply, int reason); void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, u16 cmd_length); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index df86705bdc55..10f16ddeb71a 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -63,7 +63,6 @@ static struct device *qeth_core_root_dev; static struct lock_class_key qdio_out_skb_queue_key; static void qeth_issue_next_read_cb(struct qeth_card *card, - struct qeth_channel *channel, struct qeth_cmd_buffer *iob); static void qeth_free_buffer_pool(struct qeth_card *); static int qeth_qdio_establish(struct qeth_card *); @@ -521,7 +520,7 @@ static int __qeth_issue_next_read(struct qeth_card *card) QETH_DBF_MESSAGE(2, "error %i on device %x when starting next read ccw!\n", rc, CARD_DEVID(card)); atomic_set(&channel->irq_pending, 0); - qeth_release_buffer(channel, iob); + qeth_release_buffer(iob); card->read_or_write_problem = 1; qeth_schedule_recovery(card); wake_up(&card->wait_q); @@ -713,9 +712,9 @@ static struct qeth_cmd_buffer *__qeth_get_buffer(struct qeth_channel *channel) return NULL; } -void qeth_release_buffer(struct qeth_channel *channel, - struct qeth_cmd_buffer *iob) +void qeth_release_buffer(struct qeth_cmd_buffer *iob) { + struct qeth_channel *channel = iob->channel; unsigned long flags; spin_lock_irqsave(&channel->iob_lock, flags); @@ -731,10 +730,9 @@ void qeth_release_buffer(struct qeth_channel *channel, EXPORT_SYMBOL_GPL(qeth_release_buffer); static void qeth_release_buffer_cb(struct qeth_card *card, - struct qeth_channel *channel, struct qeth_cmd_buffer *iob) { - qeth_release_buffer(channel, iob); + qeth_release_buffer(iob); } static void qeth_cancel_cmd(struct qeth_cmd_buffer *iob, int rc) @@ -743,7 +741,7 @@ static void qeth_cancel_cmd(struct qeth_cmd_buffer *iob, int rc) if (reply) qeth_notify_reply(reply, rc); - qeth_release_buffer(iob->channel, iob); + qeth_release_buffer(iob); } struct qeth_cmd_buffer *qeth_get_buffer(struct qeth_channel *channel) @@ -763,13 +761,12 @@ void qeth_clear_cmd_buffers(struct qeth_channel *channel) int cnt; for (cnt = 0; cnt < QETH_CMD_BUFFER_NO; cnt++) - qeth_release_buffer(channel, &channel->iob[cnt]); + qeth_release_buffer(&channel->iob[cnt]); channel->io_buf_no = 0; } EXPORT_SYMBOL_GPL(qeth_clear_cmd_buffers); static void qeth_issue_next_read_cb(struct qeth_card *card, - struct qeth_channel *channel, struct qeth_cmd_buffer *iob) { struct qeth_ipa_cmd *cmd = NULL; @@ -842,7 +839,7 @@ out: memcpy(&card->seqno.pdu_hdr_ack, QETH_PDU_HEADER_SEQ_NO(iob->data), QETH_SEQ_NO_LENGTH); - qeth_release_buffer(channel, iob); + qeth_release_buffer(iob); __qeth_issue_next_read(card); } @@ -1110,7 +1107,7 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, return; if (iob && iob->callback) - iob->callback(card, iob->channel, iob); + iob->callback(card, iob); out: wake_up(&card->wait_q); @@ -1834,7 +1831,7 @@ static int qeth_send_control_data(struct qeth_card *card, int len, reply = qeth_alloc_reply(card); if (!reply) { - qeth_release_buffer(channel, iob); + qeth_release_buffer(iob); return -ENOMEM; } reply->callback = reply_cb; @@ -1849,7 +1846,7 @@ static int qeth_send_control_data(struct qeth_card *card, int len, timeout); if (timeout <= 0) { qeth_put_reply(reply); - qeth_release_buffer(channel, iob); + qeth_release_buffer(iob); return (timeout == -ERESTARTSYS) ? -EINTR : -ETIME; } @@ -1869,7 +1866,7 @@ static int qeth_send_control_data(struct qeth_card *card, int len, QETH_CARD_TEXT_(card, 2, " err%d", rc); qeth_dequeue_reply(card, reply); qeth_put_reply(reply); - qeth_release_buffer(channel, iob); + qeth_release_buffer(iob); atomic_set(&channel->irq_pending, 0); wake_up(&card->wait_q); return rc; @@ -1922,9 +1919,9 @@ static int qeth_idx_check_activate_response(struct qeth_card *card, } static void qeth_idx_query_read_cb(struct qeth_card *card, - struct qeth_channel *channel, struct qeth_cmd_buffer *iob) { + struct qeth_channel *channel = iob->channel; u16 peer_level; int rc; @@ -1951,13 +1948,13 @@ static void qeth_idx_query_read_cb(struct qeth_card *card, out: qeth_notify_reply(iob->reply, rc); - qeth_release_buffer(channel, iob); + qeth_release_buffer(iob); } static void qeth_idx_query_write_cb(struct qeth_card *card, - struct qeth_channel *channel, struct qeth_cmd_buffer *iob) { + struct qeth_channel *channel = iob->channel; u16 peer_level; int rc; @@ -1978,7 +1975,7 @@ static void qeth_idx_query_write_cb(struct qeth_card *card, out: qeth_notify_reply(iob->reply, rc); - qeth_release_buffer(channel, iob); + qeth_release_buffer(iob); } static void qeth_idx_finalize_query_cmd(struct qeth_card *card, @@ -1989,11 +1986,10 @@ static void qeth_idx_finalize_query_cmd(struct qeth_card *card, } static void qeth_idx_activate_cb(struct qeth_card *card, - struct qeth_channel *channel, struct qeth_cmd_buffer *iob) { qeth_notify_reply(iob->reply, 0); - qeth_release_buffer(channel, iob); + qeth_release_buffer(iob); } static void qeth_idx_setup_activate_cmd(struct qeth_card *card, @@ -2852,7 +2848,7 @@ int qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, QETH_CARD_TEXT(card, 4, "sendipa"); if (card->read_or_write_problem) { - qeth_release_buffer(iob->channel, iob); + qeth_release_buffer(iob); return -EIO; } diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 5fc36ed20c67..e1b25084dcd4 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -1030,11 +1030,10 @@ struct qeth_discipline qeth_l2_discipline = { EXPORT_SYMBOL_GPL(qeth_l2_discipline); static void qeth_osn_assist_cb(struct qeth_card *card, - struct qeth_channel *channel, struct qeth_cmd_buffer *iob) { qeth_notify_reply(iob->reply, 0); - qeth_release_buffer(channel, iob); + qeth_release_buffer(iob); } int qeth_osn_assist(struct net_device *dev, void *data, int data_len) @@ -1812,7 +1811,7 @@ static int qeth_l2_vnicc_request(struct qeth_card *card, req->getset_timeout.vnic_char = cbctl->param.vnic_char; break; default: - qeth_release_buffer(iob->channel, iob); + qeth_release_buffer(iob); return -EOPNOTSUPP; } -- cgit v1.2.3 From 405548959cc7e81b4ec0a88a06cc8e1060d4666f Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 11 Jun 2019 18:37:57 +0200 Subject: s390/qeth: add support for dynamically allocated cmds qeth currently uses a fixed set of statically allocated cmd buffers for the read and write IO channels. This (1) doesn't play well with the single RCD cmd we need to issue on the data channel, (2) doesn't provide the necessary flexibility for certain IDX improvements, and (3) is also rather wasteful since the buffers are idle most of the time. Add a new type of cmd buffer that is dynamically allocated, and keeps its ccw chain in the DMA data area. Since this touches most callers of qeth_setup_ccw(), also add a new CCW flags parameter for future usage. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 9 +++++++ drivers/s390/net/qeth_core_main.c | 56 ++++++++++++++++++++++++++++++++------- 2 files changed, 56 insertions(+), 9 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index c1292d3420a2..2fee41f773a1 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -560,6 +560,7 @@ enum qeth_prot_versions { enum qeth_cmd_buffer_state { BUF_STATE_FREE, BUF_STATE_LOCKED, + BUF_STATE_MALLOC, }; enum qeth_cq { @@ -579,6 +580,7 @@ struct qeth_channel; struct qeth_cmd_buffer { enum qeth_cmd_buffer_state state; + unsigned int length; struct qeth_channel *channel; struct qeth_reply *reply; long timeout; @@ -608,6 +610,13 @@ struct qeth_channel { int io_buf_no; }; +static inline struct ccw1 *__ccw_from_cmd(struct qeth_cmd_buffer *iob) +{ + if (iob->state != BUF_STATE_MALLOC) + return iob->channel->ccw; + return (struct ccw1 *)(iob->data + ALIGN(iob->length, 8)); +} + static inline bool qeth_trylock_channel(struct qeth_channel *channel) { return atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0; diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 10f16ddeb71a..e95cfc654ff8 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -485,10 +485,11 @@ static inline int qeth_is_cq(struct qeth_card *card, unsigned int queue) queue == card->qdio.no_in_queues - 1; } -static void qeth_setup_ccw(struct ccw1 *ccw, u8 cmd_code, u32 len, void *data) +static void qeth_setup_ccw(struct ccw1 *ccw, u8 cmd_code, u8 flags, u32 len, + void *data) { ccw->cmd_code = cmd_code; - ccw->flags = CCW_FLAG_SLI; + ccw->flags = flags | CCW_FLAG_SLI; ccw->count = len; ccw->cda = (__u32) __pa(data); } @@ -497,6 +498,7 @@ static int __qeth_issue_next_read(struct qeth_card *card) { struct qeth_channel *channel = &card->read; struct qeth_cmd_buffer *iob; + struct ccw1 *ccw; int rc; QETH_CARD_TEXT(card, 5, "issnxrd"); @@ -511,11 +513,11 @@ static int __qeth_issue_next_read(struct qeth_card *card) return -ENOMEM; } - qeth_setup_ccw(channel->ccw, CCW_CMD_READ, QETH_BUFSIZE, iob->data); + ccw = __ccw_from_cmd(iob); + qeth_setup_ccw(ccw, CCW_CMD_READ, 0, QETH_BUFSIZE, iob->data); iob->callback = qeth_issue_next_read_cb; QETH_CARD_TEXT(card, 6, "noirqpnd"); - rc = ccw_device_start(channel->ccwdev, channel->ccw, - (addr_t) iob, 0, 0); + rc = ccw_device_start(channel->ccwdev, ccw, (addr_t) iob, 0, 0); if (rc) { QETH_DBF_MESSAGE(2, "error %i on device %x when starting next read ccw!\n", rc, CARD_DEVID(card)); @@ -717,6 +719,14 @@ void qeth_release_buffer(struct qeth_cmd_buffer *iob) struct qeth_channel *channel = iob->channel; unsigned long flags; + if (iob->state == BUF_STATE_MALLOC) { + if (iob->reply) + qeth_put_reply(iob->reply); + kfree(iob->data); + kfree(iob); + return; + } + spin_lock_irqsave(&channel->iob_lock, flags); iob->state = BUF_STATE_FREE; iob->callback = NULL; @@ -756,6 +766,33 @@ struct qeth_cmd_buffer *qeth_get_buffer(struct qeth_channel *channel) } EXPORT_SYMBOL_GPL(qeth_get_buffer); +static struct qeth_cmd_buffer *qeth_alloc_cmd(struct qeth_channel *channel, + unsigned int length, + unsigned int ccws, long timeout) +{ + struct qeth_cmd_buffer *iob; + + if (length > QETH_BUFSIZE) + return NULL; + + iob = kzalloc(sizeof(*iob), GFP_KERNEL); + if (!iob) + return NULL; + + iob->data = kzalloc(ALIGN(length, 8) + ccws * sizeof(struct ccw1), + GFP_KERNEL | GFP_DMA); + if (!iob->data) { + kfree(iob); + return NULL; + } + + iob->state = BUF_STATE_MALLOC; + iob->channel = channel; + iob->timeout = timeout; + iob->length = length; + return iob; +} + void qeth_clear_cmd_buffers(struct qeth_channel *channel) { int cnt; @@ -1587,7 +1624,7 @@ static int qeth_read_conf_data(struct qeth_card *card, void **buffer, if (!rcd_buf) return -ENOMEM; - qeth_setup_ccw(channel->ccw, ciw->cmd, ciw->count, rcd_buf); + qeth_setup_ccw(channel->ccw, ciw->cmd, 0, ciw->count, rcd_buf); channel->state = CH_STATE_RCD; spin_lock_irq(get_ccwdev_lock(channel->ccwdev)); ret = ccw_device_start_timeout(channel->ccwdev, channel->ccw, @@ -1749,7 +1786,8 @@ static void qeth_idx_finalize_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, unsigned int length) { - qeth_setup_ccw(iob->channel->ccw, CCW_CMD_WRITE, length, iob->data); + qeth_setup_ccw(__ccw_from_cmd(iob), CCW_CMD_WRITE, 0, length, + iob->data); memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data), &card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH); @@ -1857,7 +1895,7 @@ static int qeth_send_control_data(struct qeth_card *card, int len, QETH_CARD_TEXT(card, 6, "noirqpnd"); spin_lock_irq(get_ccwdev_lock(channel->ccwdev)); - rc = ccw_device_start_timeout(channel->ccwdev, channel->ccw, + rc = ccw_device_start_timeout(channel->ccwdev, __ccw_from_cmd(iob), (addr_t) iob, 0, 0, timeout); spin_unlock_irq(get_ccwdev_lock(channel->ccwdev)); if (rc) { @@ -1982,7 +2020,7 @@ static void qeth_idx_finalize_query_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, unsigned int length) { - qeth_setup_ccw(iob->channel->ccw, CCW_CMD_READ, length, iob->data); + qeth_setup_ccw(__ccw_from_cmd(iob), CCW_CMD_READ, 0, length, iob->data); } static void qeth_idx_activate_cb(struct qeth_card *card, -- cgit v1.2.3 From 2066e1db9eef8e2057bb3a1b7cb3503a7f6725d9 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 11 Jun 2019 18:37:58 +0200 Subject: s390/qeth: convert RCD code to common IO infrastructure The RCD code is the last remaining IO path that doesn't use the qeth_send_control_data() infrastructure. Doing so allows us to remove all sorts of custom state machinery and logic in the IRQ handler. Instead of introducing statically allocated cmd buffers for this single IO on the data channel, use the new qeth_alloc_cmd() helper. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 2 - drivers/s390/net/qeth_core_main.c | 132 +++++++++++++------------------------- drivers/s390/net/qeth_core_mpc.h | 2 - 3 files changed, 46 insertions(+), 90 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 2fee41f773a1..962945a63235 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -537,8 +537,6 @@ enum qeth_channel_states { CH_STATE_DOWN, CH_STATE_HALTED, CH_STATE_STOPPED, - CH_STATE_RCD, - CH_STATE_RCD_DONE, }; /** * card state machine diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index e95cfc654ff8..671754a0e591 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -1004,7 +1004,7 @@ static int qeth_get_problem(struct qeth_card *card, struct ccw_device *cdev, } static int qeth_check_irb_error(struct qeth_card *card, struct ccw_device *cdev, - unsigned long intparm, struct irb *irb) + struct irb *irb) { if (!IS_ERR(irb)) return 0; @@ -1021,12 +1021,6 @@ static int qeth_check_irb_error(struct qeth_card *card, struct ccw_device *cdev, " on the device\n"); QETH_CARD_TEXT(card, 2, "ckirberr"); QETH_CARD_TEXT_(card, 2, " rc%d", -ETIMEDOUT); - if (intparm == QETH_RCD_PARM) { - if (card->data.ccwdev == cdev) { - card->data.state = CH_STATE_DOWN; - wake_up(&card->wait_q); - } - } return -ETIMEDOUT; default: QETH_DBF_MESSAGE(2, "unknown error %ld on channel %x\n", @@ -1069,7 +1063,7 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, if (qeth_intparm_is_iob(intparm)) iob = (struct qeth_cmd_buffer *) __va((addr_t)intparm); - rc = qeth_check_irb_error(card, cdev, intparm, irb); + rc = qeth_check_irb_error(card, cdev, irb); if (rc) { /* IO was terminated, free its resources. */ if (iob) @@ -1087,11 +1081,6 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, if (irb->scsw.cmd.fctl & (SCSW_FCTL_HALT_FUNC)) channel->state = CH_STATE_HALTED; - /*let's wake up immediately on data channel*/ - if ((channel == &card->data) && (intparm != 0) && - (intparm != QETH_RCD_PARM)) - goto out; - if (intparm == QETH_CLEAR_CHANNEL_PARM) { QETH_CARD_TEXT(card, 6, "clrchpar"); /* we don't have to handle this further */ @@ -1121,10 +1110,7 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, print_hex_dump(KERN_WARNING, "qeth: sense data ", DUMP_PREFIX_OFFSET, 16, 1, irb->ecw, 32, 1); } - if (intparm == QETH_RCD_PARM) { - channel->state = CH_STATE_DOWN; - goto out; - } + rc = qeth_get_problem(card, cdev, irb); if (rc) { card->read_or_write_problem = 1; @@ -1136,13 +1122,6 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, } } - if (intparm == QETH_RCD_PARM) { - channel->state = CH_STATE_RCD_DONE; - goto out; - } - if (channel == &card->data) - return; - if (iob && iob->callback) iob->callback(card, iob); @@ -1606,62 +1585,6 @@ int qeth_qdio_clear_card(struct qeth_card *card, int use_halt) } EXPORT_SYMBOL_GPL(qeth_qdio_clear_card); -static int qeth_read_conf_data(struct qeth_card *card, void **buffer, - int *length) -{ - struct ciw *ciw; - char *rcd_buf; - int ret; - struct qeth_channel *channel = &card->data; - - /* - * scan for RCD command in extended SenseID data - */ - ciw = ccw_device_get_ciw(channel->ccwdev, CIW_TYPE_RCD); - if (!ciw || ciw->cmd == 0) - return -EOPNOTSUPP; - rcd_buf = kzalloc(ciw->count, GFP_KERNEL | GFP_DMA); - if (!rcd_buf) - return -ENOMEM; - - qeth_setup_ccw(channel->ccw, ciw->cmd, 0, ciw->count, rcd_buf); - channel->state = CH_STATE_RCD; - spin_lock_irq(get_ccwdev_lock(channel->ccwdev)); - ret = ccw_device_start_timeout(channel->ccwdev, channel->ccw, - QETH_RCD_PARM, LPM_ANYPATH, 0, - QETH_RCD_TIMEOUT); - spin_unlock_irq(get_ccwdev_lock(channel->ccwdev)); - if (!ret) - wait_event(card->wait_q, - (channel->state == CH_STATE_RCD_DONE || - channel->state == CH_STATE_DOWN)); - if (channel->state == CH_STATE_DOWN) - ret = -EIO; - else - channel->state = CH_STATE_DOWN; - if (ret) { - kfree(rcd_buf); - *buffer = NULL; - *length = 0; - } else { - *length = ciw->count; - *buffer = rcd_buf; - } - return ret; -} - -static void qeth_configure_unitaddr(struct qeth_card *card, char *prcd) -{ - QETH_CARD_TEXT(card, 2, "cfgunit"); - card->info.chpid = prcd[30]; - card->info.unit_addr2 = prcd[31]; - card->info.cula = prcd[63]; - card->info.is_vm_nic = ((prcd[0x10] == _ascebc['V']) && - (prcd[0x11] == _ascebc['M'])); - card->info.use_v1_blkt = prcd[74] == 0xF0 && prcd[75] == 0xF0 && - prcd[76] >= 0xF1 && prcd[76] <= 0xF4; -} - static enum qeth_discipline_id qeth_vm_detect_layer(struct qeth_card *card) { enum qeth_discipline_id disc = QETH_DISCIPLINE_UNDETERMINED; @@ -1888,7 +1811,8 @@ static int qeth_send_control_data(struct qeth_card *card, int len, return (timeout == -ERESTARTSYS) ? -EINTR : -ETIME; } - iob->finalize(card, iob, len); + if (iob->finalize) + iob->finalize(card, iob, len); QETH_DBF_HEX(CTRL, 2, iob->data, min(len, QETH_DBF_CTRL_LEN)); qeth_enqueue_reply(card, reply); @@ -1922,6 +1846,46 @@ static int qeth_send_control_data(struct qeth_card *card, int len, return rc; } +static void qeth_read_conf_data_cb(struct qeth_card *card, + struct qeth_cmd_buffer *iob) +{ + unsigned char *prcd = iob->data; + + QETH_CARD_TEXT(card, 2, "cfgunit"); + card->info.chpid = prcd[30]; + card->info.unit_addr2 = prcd[31]; + card->info.cula = prcd[63]; + card->info.is_vm_nic = ((prcd[0x10] == _ascebc['V']) && + (prcd[0x11] == _ascebc['M'])); + card->info.use_v1_blkt = prcd[74] == 0xF0 && prcd[75] == 0xF0 && + prcd[76] >= 0xF1 && prcd[76] <= 0xF4; + + qeth_notify_reply(iob->reply, 0); + qeth_release_buffer(iob); +} + +static int qeth_read_conf_data(struct qeth_card *card) +{ + struct qeth_channel *channel = &card->data; + struct qeth_cmd_buffer *iob; + struct ciw *ciw; + + /* scan for RCD command in extended SenseID data */ + ciw = ccw_device_get_ciw(channel->ccwdev, CIW_TYPE_RCD); + if (!ciw || ciw->cmd == 0) + return -EOPNOTSUPP; + + iob = qeth_alloc_cmd(channel, ciw->count, 1, QETH_RCD_TIMEOUT); + if (!iob) + return -ENOMEM; + + iob->callback = qeth_read_conf_data_cb; + qeth_setup_ccw(__ccw_from_cmd(iob), ciw->cmd, 0, iob->length, + iob->data); + + return qeth_send_control_data(card, iob->length, iob, NULL, NULL); +} + static int qeth_idx_check_activate_response(struct qeth_card *card, struct qeth_channel *channel, struct qeth_cmd_buffer *iob) @@ -4772,8 +4736,6 @@ EXPORT_SYMBOL_GPL(qeth_vm_request_mac); static void qeth_determine_capabilities(struct qeth_card *card) { int rc; - int length; - char *prcd; struct ccw_device *ddev; int ddev_offline = 0; @@ -4788,15 +4750,13 @@ static void qeth_determine_capabilities(struct qeth_card *card) } } - rc = qeth_read_conf_data(card, (void **) &prcd, &length); + rc = qeth_read_conf_data(card); if (rc) { QETH_DBF_MESSAGE(2, "qeth_read_conf_data on device %x returned %i\n", CARD_DEVID(card), rc); QETH_CARD_TEXT_(card, 2, "5err%d", rc); goto out_offline; } - qeth_configure_unitaddr(card, prcd); - kfree(prcd); rc = qdio_get_ssqd_desc(ddev, &card->ssqd); if (rc) diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h index f5237b7c14c4..fadafdc0e8e4 100644 --- a/drivers/s390/net/qeth_core_mpc.h +++ b/drivers/s390/net/qeth_core_mpc.h @@ -31,14 +31,12 @@ extern unsigned char IPA_PDU_HEADER[]; #define QETH_CLEAR_CHANNEL_PARM -10 #define QETH_HALT_CHANNEL_PARM -11 -#define QETH_RCD_PARM -12 static inline bool qeth_intparm_is_iob(unsigned long intparm) { switch (intparm) { case QETH_CLEAR_CHANNEL_PARM: case QETH_HALT_CHANNEL_PARM: - case QETH_RCD_PARM: case 0: return false; } -- cgit v1.2.3 From f3b783b1d0d7d2d76e2bd8c136a80487f93dc680 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 11 Jun 2019 18:37:59 +0200 Subject: s390/qeth: command-chain the IDX sequence The current IDX sequence first sends one WRITE cmd to activate the device, and then sends a second cmd that READs the response. Using qeth_alloc_cmd(), we can combine this into a single IO with two command-chained CCWs. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_main.c | 58 ++++++++++----------------------------- 1 file changed, 14 insertions(+), 44 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 671754a0e591..11e6a3820421 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -1709,9 +1709,6 @@ static void qeth_idx_finalize_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, unsigned int length) { - qeth_setup_ccw(__ccw_from_cmd(iob), CCW_CMD_WRITE, 0, length, - iob->data); - memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data), &card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH); if (iob->channel == &card->write) @@ -1731,6 +1728,8 @@ static void qeth_mpc_finalize_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, unsigned int length) { + qeth_setup_ccw(__ccw_from_cmd(iob), CCW_CMD_WRITE, 0, length, + iob->data); qeth_idx_finalize_cmd(card, iob, length); memcpy(QETH_PDU_HEADER_SEQ_NO(iob->data), @@ -1920,8 +1919,8 @@ static int qeth_idx_check_activate_response(struct qeth_card *card, } } -static void qeth_idx_query_read_cb(struct qeth_card *card, - struct qeth_cmd_buffer *iob) +static void qeth_idx_activate_read_channel_cb(struct qeth_card *card, + struct qeth_cmd_buffer *iob) { struct qeth_channel *channel = iob->channel; u16 peer_level; @@ -1953,8 +1952,8 @@ out: qeth_release_buffer(iob); } -static void qeth_idx_query_write_cb(struct qeth_card *card, - struct qeth_cmd_buffer *iob) +static void qeth_idx_activate_write_channel_cb(struct qeth_card *card, + struct qeth_cmd_buffer *iob) { struct qeth_channel *channel = iob->channel; u16 peer_level; @@ -1980,30 +1979,19 @@ out: qeth_release_buffer(iob); } -static void qeth_idx_finalize_query_cmd(struct qeth_card *card, - struct qeth_cmd_buffer *iob, - unsigned int length) -{ - qeth_setup_ccw(__ccw_from_cmd(iob), CCW_CMD_READ, 0, length, iob->data); -} - -static void qeth_idx_activate_cb(struct qeth_card *card, - struct qeth_cmd_buffer *iob) -{ - qeth_notify_reply(iob->reply, 0); - qeth_release_buffer(iob); -} - static void qeth_idx_setup_activate_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob) { u16 addr = (card->info.cula << 8) + card->info.unit_addr2; u8 port = ((u8)card->dev->dev_port) | 0x80; + struct ccw1 *ccw = __ccw_from_cmd(iob); struct ccw_dev_id dev_id; + qeth_setup_ccw(&ccw[0], CCW_CMD_WRITE, CCW_FLAG_CC, IDX_ACTIVATE_SIZE, + iob->data); + qeth_setup_ccw(&ccw[1], CCW_CMD_READ, 0, iob->length, iob->data); ccw_device_get_id(CARD_DDEV(card), &dev_id); iob->finalize = qeth_idx_finalize_cmd; - iob->callback = qeth_idx_activate_cb; memcpy(QETH_IDX_ACT_PNO(iob->data), &port, 1); memcpy(QETH_IDX_ACT_ISSUER_RM_TOKEN(iob->data), @@ -2022,27 +2010,18 @@ static int qeth_idx_activate_read_channel(struct qeth_card *card) QETH_CARD_TEXT(card, 2, "idxread"); - iob = qeth_get_buffer(channel); + iob = qeth_alloc_cmd(channel, QETH_BUFSIZE, 2, QETH_TIMEOUT); if (!iob) return -ENOMEM; memcpy(iob->data, IDX_ACTIVATE_READ, IDX_ACTIVATE_SIZE); qeth_idx_setup_activate_cmd(card, iob); + iob->callback = qeth_idx_activate_read_channel_cb; rc = qeth_send_control_data(card, IDX_ACTIVATE_SIZE, iob, NULL, NULL); if (rc) return rc; - iob = qeth_get_buffer(channel); - if (!iob) - return -ENOMEM; - - iob->finalize = qeth_idx_finalize_query_cmd; - iob->callback = qeth_idx_query_read_cb; - rc = qeth_send_control_data(card, QETH_BUFSIZE, iob, NULL, NULL); - if (rc) - return rc; - channel->state = CH_STATE_UP; return 0; } @@ -2055,27 +2034,18 @@ static int qeth_idx_activate_write_channel(struct qeth_card *card) QETH_CARD_TEXT(card, 2, "idxwrite"); - iob = qeth_get_buffer(channel); + iob = qeth_alloc_cmd(channel, QETH_BUFSIZE, 2, QETH_TIMEOUT); if (!iob) return -ENOMEM; memcpy(iob->data, IDX_ACTIVATE_WRITE, IDX_ACTIVATE_SIZE); qeth_idx_setup_activate_cmd(card, iob); + iob->callback = qeth_idx_activate_write_channel_cb; rc = qeth_send_control_data(card, IDX_ACTIVATE_SIZE, iob, NULL, NULL); if (rc) return rc; - iob = qeth_get_buffer(channel); - if (!iob) - return -ENOMEM; - - iob->finalize = qeth_idx_finalize_query_cmd; - iob->callback = qeth_idx_query_write_cb; - rc = qeth_send_control_data(card, QETH_BUFSIZE, iob, NULL, NULL); - if (rc) - return rc; - channel->state = CH_STATE_UP; return 0; } -- cgit v1.2.3 From d9b9f40bba7db1147e8069fd3eba711b2247ee67 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Tue, 11 Jun 2019 18:38:00 +0200 Subject: s390/qeth: allocate a single cmd on read channel We statically allocate 8 cmd buffers on the read channel, when the only IO left that's still using them is the long-running READ. Replace this with a single allocated cmd, that gets restarted whenever the READ completed. This introduces refcounting for allocated cmds, so that the READ cmd can survive the IO completion. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 7 +++++ drivers/s390/net/qeth_core_main.c | 54 +++++++++++++++++++++++---------------- drivers/s390/net/qeth_l2_main.c | 1 - drivers/s390/net/qeth_l3_main.c | 1 - 4 files changed, 39 insertions(+), 24 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 962945a63235..5bcdede5e955 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -579,6 +579,7 @@ struct qeth_channel; struct qeth_cmd_buffer { enum qeth_cmd_buffer_state state; unsigned int length; + refcount_t ref_count; struct qeth_channel *channel; struct qeth_reply *reply; long timeout; @@ -588,6 +589,11 @@ struct qeth_cmd_buffer { void (*callback)(struct qeth_card *card, struct qeth_cmd_buffer *iob); }; +static inline void qeth_get_cmd(struct qeth_cmd_buffer *iob) +{ + refcount_inc(&iob->ref_count); +} + static inline struct qeth_ipa_cmd *__ipa_cmd(struct qeth_cmd_buffer *iob) { return (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE); @@ -771,6 +777,7 @@ struct qeth_card { enum qeth_card_states state; spinlock_t lock; struct ccwgroup_device *gdev; + struct qeth_cmd_buffer *read_cmd; struct qeth_channel read; struct qeth_channel write; struct qeth_channel data; diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 11e6a3820421..fe3dfeaf5ceb 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -496,26 +496,21 @@ static void qeth_setup_ccw(struct ccw1 *ccw, u8 cmd_code, u8 flags, u32 len, static int __qeth_issue_next_read(struct qeth_card *card) { - struct qeth_channel *channel = &card->read; - struct qeth_cmd_buffer *iob; - struct ccw1 *ccw; + struct qeth_cmd_buffer *iob = card->read_cmd; + struct qeth_channel *channel = iob->channel; + struct ccw1 *ccw = __ccw_from_cmd(iob); int rc; QETH_CARD_TEXT(card, 5, "issnxrd"); if (channel->state != CH_STATE_UP) return -EIO; - iob = qeth_get_buffer(channel); - if (!iob) { - dev_warn(&card->gdev->dev, "The qeth device driver " - "failed to recover an error on the device\n"); - QETH_DBF_MESSAGE(2, "issue_next_read on device %x failed: no iob available\n", - CARD_DEVID(card)); - return -ENOMEM; - } - ccw = __ccw_from_cmd(iob); - qeth_setup_ccw(ccw, CCW_CMD_READ, 0, QETH_BUFSIZE, iob->data); + memset(iob->data, 0, iob->length); + qeth_setup_ccw(ccw, CCW_CMD_READ, 0, iob->length, iob->data); iob->callback = qeth_issue_next_read_cb; + /* keep the cmd alive after completion: */ + qeth_get_cmd(iob); + QETH_CARD_TEXT(card, 6, "noirqpnd"); rc = ccw_device_start(channel->ccwdev, ccw, (addr_t) iob, 0, 0); if (rc) { @@ -694,6 +689,16 @@ static int qeth_check_idx_response(struct qeth_card *card, return 0; } +static void qeth_put_cmd(struct qeth_cmd_buffer *iob) +{ + if (refcount_dec_and_test(&iob->ref_count)) { + if (iob->reply) + qeth_put_reply(iob->reply); + kfree(iob->data); + kfree(iob); + } +} + static struct qeth_cmd_buffer *__qeth_get_buffer(struct qeth_channel *channel) { __u8 index; @@ -720,10 +725,7 @@ void qeth_release_buffer(struct qeth_cmd_buffer *iob) unsigned long flags; if (iob->state == BUF_STATE_MALLOC) { - if (iob->reply) - qeth_put_reply(iob->reply); - kfree(iob->data); - kfree(iob); + qeth_put_cmd(iob); return; } @@ -787,6 +789,7 @@ static struct qeth_cmd_buffer *qeth_alloc_cmd(struct qeth_channel *channel, } iob->state = BUF_STATE_MALLOC; + refcount_set(&iob->ref_count, 1); iob->channel = channel; iob->timeout = timeout; iob->length = length; @@ -1445,10 +1448,14 @@ static struct qeth_card *qeth_alloc_card(struct ccwgroup_device *gdev) dev_name(&gdev->dev)); if (!card->event_wq) goto out_wq; - if (qeth_setup_channel(&card->read, true)) - goto out_ip; + + card->read_cmd = qeth_alloc_cmd(&card->read, QETH_BUFSIZE, 1, 0); + if (!card->read_cmd) + goto out_read_cmd; + if (qeth_setup_channel(&card->read, false)) + goto out_read; if (qeth_setup_channel(&card->write, true)) - goto out_channel; + goto out_write; if (qeth_setup_channel(&card->data, false)) goto out_data; card->qeth_service_level.seq_print = qeth_core_sl_print; @@ -1457,9 +1464,11 @@ static struct qeth_card *qeth_alloc_card(struct ccwgroup_device *gdev) out_data: qeth_clean_channel(&card->write); -out_channel: +out_write: qeth_clean_channel(&card->read); -out_ip: +out_read: + qeth_release_buffer(card->read_cmd); +out_read_cmd: destroy_workqueue(card->event_wq); out_wq: dev_set_drvdata(&gdev->dev, NULL); @@ -4892,6 +4901,7 @@ static void qeth_core_free_card(struct qeth_card *card) qeth_clean_channel(&card->read); qeth_clean_channel(&card->write); qeth_clean_channel(&card->data); + qeth_release_buffer(card->read_cmd); destroy_workqueue(card->event_wq); qeth_free_qdio_queues(card); unregister_service_level(&card->qeth_service_level); diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index e1b25084dcd4..9565ef9747c1 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -292,7 +292,6 @@ static void qeth_l2_stop_card(struct qeth_card *card) card->state = CARD_STATE_DOWN; } - qeth_clear_cmd_buffers(&card->read); qeth_clear_cmd_buffers(&card->write); flush_workqueue(card->event_wq); card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 15758f45837d..4d66f9556451 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -1436,7 +1436,6 @@ static void qeth_l3_stop_card(struct qeth_card *card) card->state = CARD_STATE_DOWN; } - qeth_clear_cmd_buffers(&card->read); qeth_clear_cmd_buffers(&card->write); flush_workqueue(card->event_wq); } -- cgit v1.2.3 From a59d121da2394dcb84a42bf2fe436180ce2afe5c Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Thu, 27 Jun 2019 17:01:22 +0200 Subject: s390/qeth: dynamically allocate simple IPA cmds This patch reduces the usage of the write channel's static cmd buffers, by dynamically allocating all simple IPA cmds (eg. STARTLAN, SETVMAC). It also converts the OSN path. Doing so requires some changes to how we calculate the cmd length. Currently when building IPA cmds, we're quite generous in how much data we send down to the device (basically the size of the biggest cmd we know). This is no real concern at the moment, since the static cmd buffers are backed with zeroed pages. But for dynamic allocations, the exact length matters. So this patch also adds the needed length calculations to each cmd path. Commands that have multiple subtypes (eg. SETADP) of differing length will be converted with follow-up patches. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 10 +++++++++- drivers/s390/net/qeth_core_main.c | 33 ++++++++++++++++++++++++++------- drivers/s390/net/qeth_core_mpc.h | 2 ++ drivers/s390/net/qeth_l2_main.c | 12 +++++++++--- drivers/s390/net/qeth_l3_main.c | 17 ++++++++++------- 5 files changed, 56 insertions(+), 18 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 5bcdede5e955..42aa4a21a4c2 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -551,6 +551,7 @@ enum qeth_card_states { * Protocol versions */ enum qeth_prot_versions { + QETH_PROT_NONE = 0x0000, QETH_PROT_IPV4 = 0x0004, QETH_PROT_IPV6 = 0x0006, }; @@ -995,6 +996,14 @@ int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *, void *); struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *, enum qeth_ipa_cmds, enum qeth_prot_versions); +struct qeth_cmd_buffer *qeth_ipa_alloc_cmd(struct qeth_card *card, + enum qeth_ipa_cmds cmd_code, + enum qeth_prot_versions prot, + unsigned int data_length); +struct qeth_cmd_buffer *qeth_alloc_cmd(struct qeth_channel *channel, + unsigned int length, unsigned int ccws, + long timeout); + struct sk_buff *qeth_core_get_next_skb(struct qeth_card *, struct qeth_qdio_buffer *, struct qdio_buffer_element **, int *, struct qeth_hdr **); @@ -1012,7 +1021,6 @@ void qeth_release_buffer(struct qeth_cmd_buffer *iob); void qeth_notify_reply(struct qeth_reply *reply, int reason); void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, u16 cmd_length); -struct qeth_cmd_buffer *qeth_get_buffer(struct qeth_channel *channel); int qeth_query_switch_attributes(struct qeth_card *card, struct qeth_switch_info *sw_info); int qeth_query_card_info(struct qeth_card *card, diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index fe3dfeaf5ceb..84ed772bbfbd 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -756,7 +756,7 @@ static void qeth_cancel_cmd(struct qeth_cmd_buffer *iob, int rc) qeth_release_buffer(iob); } -struct qeth_cmd_buffer *qeth_get_buffer(struct qeth_channel *channel) +static struct qeth_cmd_buffer *qeth_get_buffer(struct qeth_channel *channel) { struct qeth_cmd_buffer *buffer = NULL; unsigned long flags; @@ -766,11 +766,10 @@ struct qeth_cmd_buffer *qeth_get_buffer(struct qeth_channel *channel) spin_unlock_irqrestore(&channel->iob_lock, flags); return buffer; } -EXPORT_SYMBOL_GPL(qeth_get_buffer); -static struct qeth_cmd_buffer *qeth_alloc_cmd(struct qeth_channel *channel, - unsigned int length, - unsigned int ccws, long timeout) +struct qeth_cmd_buffer *qeth_alloc_cmd(struct qeth_channel *channel, + unsigned int length, unsigned int ccws, + long timeout) { struct qeth_cmd_buffer *iob; @@ -795,6 +794,7 @@ static struct qeth_cmd_buffer *qeth_alloc_cmd(struct qeth_channel *channel, iob->length = length; return iob; } +EXPORT_SYMBOL_GPL(qeth_alloc_cmd); void qeth_clear_cmd_buffers(struct qeth_channel *channel) { @@ -2804,6 +2804,25 @@ struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *card, } EXPORT_SYMBOL_GPL(qeth_get_ipacmd_buffer); +struct qeth_cmd_buffer *qeth_ipa_alloc_cmd(struct qeth_card *card, + enum qeth_ipa_cmds cmd_code, + enum qeth_prot_versions prot, + unsigned int data_length) +{ + struct qeth_cmd_buffer *iob; + + data_length += offsetof(struct qeth_ipa_cmd, data); + iob = qeth_alloc_cmd(&card->write, IPA_PDU_HEADER_SIZE + data_length, 1, + QETH_IPA_TIMEOUT); + if (!iob) + return NULL; + + qeth_prepare_ipa_cmd(card, iob, data_length); + qeth_fill_ipacmd_header(card, __ipa_cmd(iob), cmd_code, prot); + return iob; +} +EXPORT_SYMBOL_GPL(qeth_ipa_alloc_cmd); + static int qeth_send_ipa_cmd_cb(struct qeth_card *card, struct qeth_reply *reply, unsigned long data) { @@ -2862,7 +2881,7 @@ static int qeth_send_startlan(struct qeth_card *card) QETH_CARD_TEXT(card, 2, "strtlan"); - iob = qeth_get_ipacmd_buffer(card, IPA_CMD_STARTLAN, 0); + iob = qeth_ipa_alloc_cmd(card, IPA_CMD_STARTLAN, QETH_PROT_NONE, 0); if (!iob) return -ENOMEM; return qeth_send_ipa_cmd(card, iob, qeth_send_startlan_cb, NULL); @@ -2971,7 +2990,7 @@ static int qeth_query_ipassists(struct qeth_card *card, struct qeth_cmd_buffer *iob; QETH_CARD_TEXT_(card, 2, "qipassi%i", prot); - iob = qeth_get_ipacmd_buffer(card, IPA_CMD_QIPASSIST, prot); + iob = qeth_ipa_alloc_cmd(card, IPA_CMD_QIPASSIST, prot, 0); if (!iob) return -ENOMEM; rc = qeth_send_ipa_cmd(card, iob, qeth_query_ipassists_cb, NULL); diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h index fadafdc0e8e4..e84249f8803e 100644 --- a/drivers/s390/net/qeth_core_mpc.h +++ b/drivers/s390/net/qeth_core_mpc.h @@ -806,6 +806,8 @@ struct qeth_ipa_cmd { } data; } __attribute__ ((packed)); +#define IPA_DATA_SIZEOF(field) FIELD_SIZEOF(struct qeth_ipa_cmd, data.field) + /* * special command for ARP processing. * this is not included in setassparms command before, because we get diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 9565ef9747c1..1dd8d22299c2 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -85,7 +85,8 @@ static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac, struct qeth_cmd_buffer *iob; QETH_CARD_TEXT(card, 2, "L2sdmac"); - iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4); + iob = qeth_ipa_alloc_cmd(card, ipacmd, QETH_PROT_IPV4, + IPA_DATA_SIZEOF(setdelmac)); if (!iob) return -ENOMEM; cmd = __ipa_cmd(iob); @@ -240,7 +241,8 @@ static int qeth_l2_send_setdelvlan(struct qeth_card *card, __u16 i, struct qeth_cmd_buffer *iob; QETH_CARD_TEXT_(card, 4, "L2sdv%x", ipacmd); - iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4); + iob = qeth_ipa_alloc_cmd(card, ipacmd, QETH_PROT_IPV4, + IPA_DATA_SIZEOF(setdelvlan)); if (!iob) return -ENOMEM; cmd = __ipa_cmd(iob); @@ -1040,6 +1042,8 @@ int qeth_osn_assist(struct net_device *dev, void *data, int data_len) struct qeth_cmd_buffer *iob; struct qeth_card *card; + if (data_len < 0) + return -EINVAL; if (!dev) return -ENODEV; card = dev->ml_priv; @@ -1048,7 +1052,9 @@ int qeth_osn_assist(struct net_device *dev, void *data, int data_len) QETH_CARD_TEXT(card, 2, "osnsdmc"); if (!qeth_card_hw_is_reachable(card)) return -ENODEV; - iob = qeth_get_buffer(&card->write); + + iob = qeth_alloc_cmd(&card->write, IPA_PDU_HEADER_SIZE + data_len, 1, + QETH_IPA_TIMEOUT); if (!iob) return -ENOMEM; diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 4d66f9556451..81312be8a36b 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -377,7 +377,8 @@ static int qeth_l3_send_setdelmc(struct qeth_card *card, QETH_CARD_TEXT(card, 4, "setdelmc"); - iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto); + iob = qeth_ipa_alloc_cmd(card, ipacmd, addr->proto, + IPA_DATA_SIZEOF(setdelipm)); if (!iob) return -ENOMEM; cmd = __ipa_cmd(iob); @@ -429,7 +430,8 @@ static int qeth_l3_send_setdelip(struct qeth_card *card, QETH_CARD_TEXT(card, 4, "setdelip"); - iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto); + iob = qeth_ipa_alloc_cmd(card, ipacmd, addr->proto, + IPA_DATA_SIZEOF(setdelip6)); if (!iob) return -ENOMEM; cmd = __ipa_cmd(iob); @@ -461,7 +463,8 @@ static int qeth_l3_send_setrouting(struct qeth_card *card, struct qeth_cmd_buffer *iob; QETH_CARD_TEXT(card, 4, "setroutg"); - iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETRTG, prot); + iob = qeth_ipa_alloc_cmd(card, IPA_CMD_SETRTG, prot, + IPA_DATA_SIZEOF(setrtg)); if (!iob) return -ENOMEM; cmd = __ipa_cmd(iob); @@ -981,8 +984,8 @@ static int qeth_l3_iqd_read_initial_mac(struct qeth_card *card) QETH_CARD_TEXT(card, 2, "hsrmac"); - iob = qeth_get_ipacmd_buffer(card, IPA_CMD_CREATE_ADDR, - QETH_PROT_IPV6); + iob = qeth_ipa_alloc_cmd(card, IPA_CMD_CREATE_ADDR, QETH_PROT_IPV6, + IPA_DATA_SIZEOF(create_destroy_addr)); if (!iob) return -ENOMEM; cmd = __ipa_cmd(iob); @@ -1025,8 +1028,8 @@ static int qeth_l3_get_unique_id(struct qeth_card *card) return 0; } - iob = qeth_get_ipacmd_buffer(card, IPA_CMD_CREATE_ADDR, - QETH_PROT_IPV6); + iob = qeth_ipa_alloc_cmd(card, IPA_CMD_CREATE_ADDR, QETH_PROT_IPV6, + IPA_DATA_SIZEOF(create_destroy_addr)); if (!iob) return -ENOMEM; cmd = __ipa_cmd(iob); -- cgit v1.2.3 From 1c696c896f218b12d5f92d892fffee5abd0265c9 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Thu, 27 Jun 2019 17:01:23 +0200 Subject: s390/qeth: clarify parameter for simple assist cmds For code that uses qeth_send_simple_setassparms_prot(), we currently can't differentiate whether the cmd should contain (1) no parameter, or (2) a 4-byte parameter with value 0. At the moment this doesn't cause any trouble. But when using dynamically allocated cmds, we need to know whether to allocate & transmit an additional 4 bytes of zeroes. So instead of the raw parameter value, pass a parameter pointer (or NULL) to qeth_send_simple_setassparms_prot(). Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 6 +++--- drivers/s390/net/qeth_core_main.c | 15 +++++++-------- drivers/s390/net/qeth_core_mpc.h | 2 ++ drivers/s390/net/qeth_l3_main.c | 26 ++++++++++++++------------ 4 files changed, 26 insertions(+), 23 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 42aa4a21a4c2..35d7b43f6580 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -940,12 +940,12 @@ static inline int qeth_is_diagass_supported(struct qeth_card *card, int qeth_send_simple_setassparms_prot(struct qeth_card *card, enum qeth_ipa_funcs ipa_func, - u16 cmd_code, long data, + u16 cmd_code, u32 *data, enum qeth_prot_versions prot); /* IPv4 variant */ static inline int qeth_send_simple_setassparms(struct qeth_card *card, enum qeth_ipa_funcs ipa_func, - u16 cmd_code, long data) + u16 cmd_code, u32 *data) { return qeth_send_simple_setassparms_prot(card, ipa_func, cmd_code, data, QETH_PROT_IPV4); @@ -953,7 +953,7 @@ static inline int qeth_send_simple_setassparms(struct qeth_card *card, static inline int qeth_send_simple_setassparms_v6(struct qeth_card *card, enum qeth_ipa_funcs ipa_func, - u16 cmd_code, long data) + u16 cmd_code, u32 *data) { return qeth_send_simple_setassparms_prot(card, ipa_func, cmd_code, data, QETH_PROT_IPV6); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 84ed772bbfbd..3ba91b1c1315 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -5355,20 +5355,19 @@ EXPORT_SYMBOL_GPL(qeth_get_setassparms_cmd); int qeth_send_simple_setassparms_prot(struct qeth_card *card, enum qeth_ipa_funcs ipa_func, - u16 cmd_code, long data, + u16 cmd_code, u32 *data, enum qeth_prot_versions prot) { - int length = 0; + unsigned int length = data ? SETASS_DATA_SIZEOF(flags_32bit) : 0; struct qeth_cmd_buffer *iob; QETH_CARD_TEXT_(card, 4, "simassp%i", prot); - if (data) - length = sizeof(__u32); iob = qeth_get_setassparms_cmd(card, ipa_func, cmd_code, length, prot); if (!iob) return -ENOMEM; - __ipa_cmd(iob)->data.setassparms.data.flags_32bit = (__u32) data; + if (data) + __ipa_cmd(iob)->data.setassparms.data.flags_32bit = *data; return qeth_send_ipa_cmd(card, iob, qeth_setassparms_cb, NULL); } EXPORT_SYMBOL_GPL(qeth_send_simple_setassparms_prot); @@ -5885,8 +5884,8 @@ static int qeth_start_csum_cb(struct qeth_card *card, struct qeth_reply *reply, static int qeth_set_csum_off(struct qeth_card *card, enum qeth_ipa_funcs cstype, enum qeth_prot_versions prot) { - return qeth_send_simple_setassparms_prot(card, cstype, - IPA_CMD_ASS_STOP, 0, prot); + return qeth_send_simple_setassparms_prot(card, cstype, IPA_CMD_ASS_STOP, + NULL, prot); } static int qeth_set_csum_on(struct qeth_card *card, enum qeth_ipa_funcs cstype, @@ -5974,7 +5973,7 @@ static int qeth_set_tso_off(struct qeth_card *card, enum qeth_prot_versions prot) { return qeth_send_simple_setassparms_prot(card, IPA_OUTBOUND_TSO, - IPA_CMD_ASS_STOP, 0, prot); + IPA_CMD_ASS_STOP, NULL, prot); } static int qeth_set_tso_on(struct qeth_card *card, diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h index e84249f8803e..61fc4005dd53 100644 --- a/drivers/s390/net/qeth_core_mpc.h +++ b/drivers/s390/net/qeth_core_mpc.h @@ -437,6 +437,8 @@ struct qeth_ipacmd_setassparms { } data; } __attribute__ ((packed)); +#define SETASS_DATA_SIZEOF(field) FIELD_SIZEOF(struct qeth_ipacmd_setassparms,\ + data.field) /* SETRTG IPA Command: ****************************************************/ struct qeth_set_routing { diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 81312be8a36b..3de71ed54e92 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -770,7 +770,7 @@ static int qeth_l3_start_ipa_arp_processing(struct qeth_card *card) return 0; } rc = qeth_send_simple_setassparms(card, IPA_ARP_PROCESSING, - IPA_CMD_ASS_START, 0); + IPA_CMD_ASS_START, NULL); if (rc) { dev_warn(&card->gdev->dev, "Starting ARP processing support for %s failed\n", @@ -793,7 +793,7 @@ static int qeth_l3_start_ipa_source_mac(struct qeth_card *card) } rc = qeth_send_simple_setassparms(card, IPA_SOURCE_MAC, - IPA_CMD_ASS_START, 0); + IPA_CMD_ASS_START, NULL); if (rc) dev_warn(&card->gdev->dev, "Starting source MAC-address support for %s failed\n", @@ -814,7 +814,7 @@ static int qeth_l3_start_ipa_vlan(struct qeth_card *card) } rc = qeth_send_simple_setassparms(card, IPA_VLAN_PRIO, - IPA_CMD_ASS_START, 0); + IPA_CMD_ASS_START, NULL); if (rc) { dev_warn(&card->gdev->dev, "Starting VLAN support for %s failed\n", @@ -839,7 +839,7 @@ static int qeth_l3_start_ipa_multicast(struct qeth_card *card) } rc = qeth_send_simple_setassparms(card, IPA_MULTICASTING, - IPA_CMD_ASS_START, 0); + IPA_CMD_ASS_START, NULL); if (rc) { dev_warn(&card->gdev->dev, "Starting multicast support for %s failed\n", @@ -853,6 +853,7 @@ static int qeth_l3_start_ipa_multicast(struct qeth_card *card) static int qeth_l3_softsetup_ipv6(struct qeth_card *card) { + u32 ipv6_data = 3; int rc; QETH_CARD_TEXT(card, 3, "softipv6"); @@ -860,16 +861,16 @@ static int qeth_l3_softsetup_ipv6(struct qeth_card *card) if (IS_IQD(card)) goto out; - rc = qeth_send_simple_setassparms(card, IPA_IPV6, - IPA_CMD_ASS_START, 3); + rc = qeth_send_simple_setassparms(card, IPA_IPV6, IPA_CMD_ASS_START, + &ipv6_data); if (rc) { dev_err(&card->gdev->dev, "Activating IPv6 support for %s failed\n", QETH_CARD_IFNAME(card)); return rc; } - rc = qeth_send_simple_setassparms_v6(card, IPA_IPV6, - IPA_CMD_ASS_START, 0); + rc = qeth_send_simple_setassparms_v6(card, IPA_IPV6, IPA_CMD_ASS_START, + NULL); if (rc) { dev_err(&card->gdev->dev, "Activating IPv6 support for %s failed\n", @@ -877,7 +878,7 @@ static int qeth_l3_softsetup_ipv6(struct qeth_card *card) return rc; } rc = qeth_send_simple_setassparms_v6(card, IPA_PASSTHRU, - IPA_CMD_ASS_START, 0); + IPA_CMD_ASS_START, NULL); if (rc) { dev_warn(&card->gdev->dev, "Enabling the passthrough mode for %s failed\n", @@ -903,6 +904,7 @@ static int qeth_l3_start_ipa_ipv6(struct qeth_card *card) static int qeth_l3_start_ipa_broadcast(struct qeth_card *card) { + u32 filter_data = 1; int rc; QETH_CARD_TEXT(card, 3, "stbrdcst"); @@ -915,7 +917,7 @@ static int qeth_l3_start_ipa_broadcast(struct qeth_card *card) goto out; } rc = qeth_send_simple_setassparms(card, IPA_FILTERING, - IPA_CMD_ASS_START, 0); + IPA_CMD_ASS_START, NULL); if (rc) { dev_warn(&card->gdev->dev, "Enabling broadcast filtering for " "%s failed\n", QETH_CARD_IFNAME(card)); @@ -923,7 +925,7 @@ static int qeth_l3_start_ipa_broadcast(struct qeth_card *card) } rc = qeth_send_simple_setassparms(card, IPA_FILTERING, - IPA_CMD_ASS_CONFIGURE, 1); + IPA_CMD_ASS_CONFIGURE, &filter_data); if (rc) { dev_warn(&card->gdev->dev, "Setting up broadcast filtering for %s failed\n", @@ -933,7 +935,7 @@ static int qeth_l3_start_ipa_broadcast(struct qeth_card *card) card->info.broadcast_capable = QETH_BROADCAST_WITH_ECHO; dev_info(&card->gdev->dev, "Broadcast enabled\n"); rc = qeth_send_simple_setassparms(card, IPA_FILTERING, - IPA_CMD_ASS_ENABLE, 1); + IPA_CMD_ASS_ENABLE, &filter_data); if (rc) { dev_warn(&card->gdev->dev, "Setting up broadcast echo " "filtering for %s failed\n", QETH_CARD_IFNAME(card)); -- cgit v1.2.3 From b9150461e5a6f4a78d0ef8a4d4f2a41f5a12d979 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Thu, 27 Jun 2019 17:01:24 +0200 Subject: s390/qeth: dynamically allocate various cmds with sub-types This patch converts the adapter, assist and bridgeport cmd paths to dynamic allocation. Most of the work is about re-organizing the cmd headers, calculating the correct cmd length, and filling in the right value in the sub-cmd's length field. Since we now also set the correct length for cmds that are not reflected by a fixed struct (ie SNMP), we can remove the work-around from qeth_snmp_command(). Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 9 ++-- drivers/s390/net/qeth_core_main.c | 86 ++++++++++++++++++++------------------- drivers/s390/net/qeth_core_mpc.h | 27 ++++-------- drivers/s390/net/qeth_l2_main.c | 29 ++++++------- drivers/s390/net/qeth_l3_main.c | 10 ++--- 5 files changed, 78 insertions(+), 83 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 35d7b43f6580..258756dc06c3 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -1003,6 +1003,11 @@ struct qeth_cmd_buffer *qeth_ipa_alloc_cmd(struct qeth_card *card, struct qeth_cmd_buffer *qeth_alloc_cmd(struct qeth_channel *channel, unsigned int length, unsigned int ccws, long timeout); +struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *card, + enum qeth_ipa_funcs ipa_func, + u16 cmd_code, + unsigned int data_length, + enum qeth_prot_versions prot); struct sk_buff *qeth_core_get_next_skb(struct qeth_card *, struct qeth_qdio_buffer *, struct qdio_buffer_element **, int *, @@ -1037,10 +1042,6 @@ int qeth_configure_cq(struct qeth_card *, enum qeth_cq); int qeth_hw_trap(struct qeth_card *, enum qeth_diags_trap_action); void qeth_trace_features(struct qeth_card *); int qeth_setassparms_cb(struct qeth_card *, struct qeth_reply *, unsigned long); -struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *, - enum qeth_ipa_funcs, - __u16, __u16, - enum qeth_prot_versions); int qeth_set_features(struct net_device *, netdev_features_t); void qeth_enable_hw_features(struct net_device *dev); netdev_features_t qeth_fix_features(struct net_device *, netdev_features_t); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 3ba91b1c1315..696aba566d0b 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -2915,21 +2915,24 @@ static int qeth_query_setadapterparms_cb(struct qeth_card *card, } static struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *card, - __u32 command, __u32 cmdlen) + enum qeth_ipa_setadp_cmd adp_cmd, + unsigned int data_length) { + struct qeth_ipacmd_setadpparms_hdr *hdr; struct qeth_cmd_buffer *iob; - struct qeth_ipa_cmd *cmd; - iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETADAPTERPARMS, - QETH_PROT_IPV4); - if (iob) { - cmd = __ipa_cmd(iob); - cmd->data.setadapterparms.hdr.cmdlength = cmdlen; - cmd->data.setadapterparms.hdr.command_code = command; - cmd->data.setadapterparms.hdr.used_total = 1; - cmd->data.setadapterparms.hdr.seq_no = 1; - } + iob = qeth_ipa_alloc_cmd(card, IPA_CMD_SETADAPTERPARMS, QETH_PROT_IPV4, + data_length + + offsetof(struct qeth_ipacmd_setadpparms, + data)); + if (!iob) + return NULL; + hdr = &__ipa_cmd(iob)->data.setadapterparms.hdr; + hdr->cmdlength = sizeof(*hdr) + data_length; + hdr->command_code = adp_cmd; + hdr->used_total = 1; + hdr->seq_no = 1; return iob; } @@ -2940,7 +2943,7 @@ static int qeth_query_setadapterparms(struct qeth_card *card) QETH_CARD_TEXT(card, 3, "queryadp"); iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_COMMANDS_SUPPORTED, - sizeof(struct qeth_ipacmd_setadpparms)); + SETADP_DATA_SIZEOF(query_cmds_supp)); if (!iob) return -ENOMEM; rc = qeth_send_ipa_cmd(card, iob, qeth_query_setadapterparms_cb, NULL); @@ -3027,8 +3030,7 @@ int qeth_query_switch_attributes(struct qeth_card *card, return -EOPNOTSUPP; if (!netif_carrier_ok(card->dev)) return -ENOMEDIUM; - iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_SWITCH_ATTRIBUTES, - sizeof(struct qeth_ipacmd_setadpparms_hdr)); + iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_SWITCH_ATTRIBUTES, 0); if (!iob) return -ENOMEM; return qeth_send_ipa_cmd(card, iob, @@ -4152,7 +4154,7 @@ void qeth_setadp_promisc_mode(struct qeth_card *card) QETH_CARD_TEXT_(card, 4, "mode:%x", mode); iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_PROMISC_MODE, - sizeof(struct qeth_ipacmd_setadpparms_hdr) + 8); + SETADP_DATA_SIZEOF(mode)); if (!iob) return; cmd = __ipa_cmd(iob); @@ -4192,8 +4194,7 @@ int qeth_setadpparms_change_macaddr(struct qeth_card *card) QETH_CARD_TEXT(card, 4, "chgmac"); iob = qeth_get_adapter_cmd(card, IPA_SETADP_ALTER_MAC_ADDRESS, - sizeof(struct qeth_ipacmd_setadpparms_hdr) + - sizeof(struct qeth_change_addr)); + SETADP_DATA_SIZEOF(change_addr)); if (!iob) return -ENOMEM; cmd = __ipa_cmd(iob); @@ -4302,8 +4303,7 @@ static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card, QETH_CARD_TEXT(card, 4, "setacctl"); iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_ACCESS_CONTROL, - sizeof(struct qeth_ipacmd_setadpparms_hdr) + - sizeof(struct qeth_set_access_ctrl)); + SETADP_DATA_SIZEOF(set_access_ctrl)); if (!iob) return -ENOMEM; cmd = __ipa_cmd(iob); @@ -4498,9 +4498,9 @@ static int qeth_snmp_command(struct qeth_card *card, char __user *udata) /* skip 4 bytes (data_len struct member) to get req_len */ if (copy_from_user(&req_len, udata + sizeof(int), sizeof(int))) return -EFAULT; - if (req_len > (QETH_BUFSIZE - IPA_PDU_HEADER_SIZE - - sizeof(struct qeth_ipacmd_hdr) - - sizeof(struct qeth_ipacmd_setadpparms_hdr))) + if (req_len + offsetof(struct qeth_ipacmd_setadpparms, data) + + offsetof(struct qeth_ipa_cmd, data) + IPA_PDU_HEADER_SIZE > + QETH_BUFSIZE) return -EINVAL; ureq = memdup_user(udata, req_len + sizeof(struct qeth_snmp_ureq_hdr)); if (IS_ERR(ureq)) { @@ -4515,16 +4515,12 @@ static int qeth_snmp_command(struct qeth_card *card, char __user *udata) } qinfo.udata_offset = sizeof(struct qeth_snmp_ureq_hdr); - iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_SNMP_CONTROL, - QETH_SNMP_SETADP_CMDLENGTH + req_len); + iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_SNMP_CONTROL, req_len); if (!iob) { rc = -ENOMEM; goto out; } - /* for large requests, fix-up the length fields: */ - qeth_prepare_ipa_cmd(card, iob, QETH_SETADP_BASE_LEN + req_len); - cmd = __ipa_cmd(iob); memcpy(&cmd->data.setadapterparms.data.snmp, &ureq->cmd, req_len); rc = qeth_send_ipa_cmd(card, iob, qeth_snmp_command_cb, &qinfo); @@ -4602,8 +4598,7 @@ static int qeth_query_oat_command(struct qeth_card *card, char __user *udata) } iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_OAT, - sizeof(struct qeth_ipacmd_setadpparms_hdr) + - sizeof(struct qeth_query_oat)); + SETADP_DATA_SIZEOF(query_oat)); if (!iob) { rc = -ENOMEM; goto out_free; @@ -4665,8 +4660,7 @@ int qeth_query_card_info(struct qeth_card *card, QETH_CARD_TEXT(card, 2, "qcrdinfo"); if (!qeth_adp_supported(card, IPA_SETADP_QUERY_CARD_INFO)) return -EOPNOTSUPP; - iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_CARD_INFO, - sizeof(struct qeth_ipacmd_setadpparms_hdr)); + iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_CARD_INFO, 0); if (!iob) return -ENOMEM; return qeth_send_ipa_cmd(card, iob, qeth_query_card_info_cb, @@ -5333,22 +5327,28 @@ EXPORT_SYMBOL_GPL(qeth_setassparms_cb); struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *card, enum qeth_ipa_funcs ipa_func, - __u16 cmd_code, __u16 len, + u16 cmd_code, + unsigned int data_length, enum qeth_prot_versions prot) { + struct qeth_ipacmd_setassparms *setassparms; + struct qeth_ipacmd_setassparms_hdr *hdr; struct qeth_cmd_buffer *iob; - struct qeth_ipa_cmd *cmd; QETH_CARD_TEXT(card, 4, "getasscm"); - iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETASSPARMS, prot); + iob = qeth_ipa_alloc_cmd(card, IPA_CMD_SETASSPARMS, prot, + data_length + + offsetof(struct qeth_ipacmd_setassparms, + data)); + if (!iob) + return NULL; - if (iob) { - cmd = __ipa_cmd(iob); - cmd->data.setassparms.hdr.assist_no = ipa_func; - cmd->data.setassparms.hdr.length = 8 + len; - cmd->data.setassparms.hdr.command_code = cmd_code; - } + setassparms = &__ipa_cmd(iob)->data.setassparms; + setassparms->assist_no = ipa_func; + hdr = &setassparms->hdr; + hdr->length = sizeof(*hdr) + data_length; + hdr->command_code = cmd_code; return iob; } EXPORT_SYMBOL_GPL(qeth_get_setassparms_cmd); @@ -5916,7 +5916,8 @@ static int qeth_set_csum_on(struct qeth_card *card, enum qeth_ipa_funcs cstype, return -EOPNOTSUPP; } - iob = qeth_get_setassparms_cmd(card, cstype, IPA_CMD_ASS_ENABLE, 4, + iob = qeth_get_setassparms_cmd(card, cstype, IPA_CMD_ASS_ENABLE, + SETASS_DATA_SIZEOF(flags_32bit), prot); if (!iob) { qeth_set_csum_off(card, cstype, prot); @@ -5999,7 +6000,8 @@ static int qeth_set_tso_on(struct qeth_card *card, } iob = qeth_get_setassparms_cmd(card, IPA_OUTBOUND_TSO, - IPA_CMD_ASS_ENABLE, sizeof(caps), prot); + IPA_CMD_ASS_ENABLE, + SETASS_DATA_SIZEOF(caps), prot); if (!iob) { qeth_set_tso_off(card, prot); return -ENOMEM; diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h index 61fc4005dd53..46f038580a72 100644 --- a/drivers/s390/net/qeth_core_mpc.h +++ b/drivers/s390/net/qeth_core_mpc.h @@ -379,9 +379,7 @@ struct qeth_ipacmd_layer2setdelvlan { __u16 vlan_id; } __attribute__ ((packed)); - struct qeth_ipacmd_setassparms_hdr { - __u32 assist_no; __u16 length; __u16 command_code; __u16 return_code; @@ -426,6 +424,7 @@ struct qeth_tso_start_data { /* SETASSPARMS IPA Command: */ struct qeth_ipacmd_setassparms { + u32 assist_no; struct qeth_ipacmd_setassparms_hdr hdr; union { __u32 flags_32bit; @@ -526,8 +525,6 @@ struct qeth_query_switch_attributes { #define QETH_SETADP_FLAGS_VIRTUAL_MAC 0x80 /* for CHANGE_ADDR_READ_MAC */ struct qeth_ipacmd_setadpparms_hdr { - u32 supp_hw_cmds; - u32 reserved1; u16 cmdlength; u16 reserved2; u32 command_code; @@ -539,6 +536,7 @@ struct qeth_ipacmd_setadpparms_hdr { }; struct qeth_ipacmd_setadpparms { + struct qeth_ipa_caps hw_cmds; struct qeth_ipacmd_setadpparms_hdr hdr; union { struct qeth_query_cmds_supp query_cmds_supp; @@ -552,6 +550,9 @@ struct qeth_ipacmd_setadpparms { } data; } __attribute__ ((packed)); +#define SETADP_DATA_SIZEOF(field) FIELD_SIZEOF(struct qeth_ipacmd_setadpparms,\ + data.field) + /* CREATE_ADDR IPA Command: ***********************************************/ struct qeth_create_destroy_address { __u8 unique_id[8]; @@ -688,8 +689,6 @@ struct mac_addr_lnid { } __packed; struct qeth_ipacmd_sbp_hdr { - __u32 supported_sbp_cmds; - __u32 enabled_sbp_cmds; __u16 cmdlength; __u16 reserved1; __u32 command_code; @@ -704,16 +703,10 @@ struct qeth_sbp_query_cmds_supp { __u32 reserved; } __packed; -struct qeth_sbp_reset_role { -} __packed; - struct qeth_sbp_set_primary { struct net_if_token token; } __packed; -struct qeth_sbp_set_secondary { -} __packed; - struct qeth_sbp_port_entry { __u8 role; __u8 state; @@ -739,17 +732,19 @@ struct qeth_sbp_state_change { } __packed; struct qeth_ipacmd_setbridgeport { + struct qeth_ipa_caps sbp_cmds; struct qeth_ipacmd_sbp_hdr hdr; union { struct qeth_sbp_query_cmds_supp query_cmds_supp; - struct qeth_sbp_reset_role reset_role; struct qeth_sbp_set_primary set_primary; - struct qeth_sbp_set_secondary set_secondary; struct qeth_sbp_query_ports query_ports; struct qeth_sbp_state_change state_change; } data; } __packed; +#define SBP_DATA_SIZEOF(field) FIELD_SIZEOF(struct qeth_ipacmd_setbridgeport,\ + data.field) + /* ADDRESS_CHANGE_NOTIFICATION adapter-initiated "command" *******************/ /* Bitmask for entry->change_code. Both bits may be raised. */ enum qeth_ipa_addr_change_code { @@ -827,10 +822,6 @@ enum qeth_ipa_arp_return_codes { extern const char *qeth_get_ipa_msg(enum qeth_ipa_return_codes rc); extern const char *qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd); -#define QETH_SETADP_BASE_LEN (sizeof(struct qeth_ipacmd_hdr) + \ - sizeof(struct qeth_ipacmd_setadpparms_hdr)) -#define QETH_SNMP_SETADP_CMDLENGTH 16 - /* Helper functions */ #define IS_IPA_REPLY(cmd) ((cmd->hdr.initiator == IPA_CMD_INITIATOR_HOST) || \ (cmd->hdr.initiator == IPA_CMD_INITIATOR_OSA_REPLY)) diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 1dd8d22299c2..f762d22a3272 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -1427,22 +1427,25 @@ static int qeth_bridgeport_makerc(struct qeth_card *card, static struct qeth_cmd_buffer *qeth_sbp_build_cmd(struct qeth_card *card, enum qeth_ipa_sbp_cmd sbp_cmd, - unsigned int cmd_length) + unsigned int data_length) { enum qeth_ipa_cmds ipa_cmd = IS_IQD(card) ? IPA_CMD_SETBRIDGEPORT_IQD : IPA_CMD_SETBRIDGEPORT_OSA; + struct qeth_ipacmd_sbp_hdr *hdr; struct qeth_cmd_buffer *iob; - struct qeth_ipa_cmd *cmd; - iob = qeth_get_ipacmd_buffer(card, ipa_cmd, 0); + iob = qeth_ipa_alloc_cmd(card, ipa_cmd, QETH_PROT_NONE, + data_length + + offsetof(struct qeth_ipacmd_setbridgeport, + data)); if (!iob) return iob; - cmd = __ipa_cmd(iob); - cmd->data.sbp.hdr.cmdlength = sizeof(struct qeth_ipacmd_sbp_hdr) + - cmd_length; - cmd->data.sbp.hdr.command_code = sbp_cmd; - cmd->data.sbp.hdr.used_total = 1; - cmd->data.sbp.hdr.seq_no = 1; + + hdr = &__ipa_cmd(iob)->data.sbp.hdr; + hdr->cmdlength = sizeof(*hdr) + data_length; + hdr->command_code = sbp_cmd; + hdr->used_total = 1; + hdr->seq_no = 1; return iob; } @@ -1477,7 +1480,7 @@ static void qeth_bridgeport_query_support(struct qeth_card *card) QETH_CARD_TEXT(card, 2, "brqsuppo"); iob = qeth_sbp_build_cmd(card, IPA_SBP_QUERY_COMMANDS_SUPPORTED, - sizeof(struct qeth_sbp_query_cmds_supp)); + SBP_DATA_SIZEOF(query_cmds_supp)); if (!iob) return; @@ -1569,23 +1572,21 @@ static int qeth_bridgeport_set_cb(struct qeth_card *card, */ int qeth_bridgeport_setrole(struct qeth_card *card, enum qeth_sbp_roles role) { - int cmdlength; struct qeth_cmd_buffer *iob; enum qeth_ipa_sbp_cmd setcmd; + unsigned int cmdlength = 0; QETH_CARD_TEXT(card, 2, "brsetrol"); switch (role) { case QETH_SBP_ROLE_NONE: setcmd = IPA_SBP_RESET_BRIDGE_PORT_ROLE; - cmdlength = sizeof(struct qeth_sbp_reset_role); break; case QETH_SBP_ROLE_PRIMARY: setcmd = IPA_SBP_SET_PRIMARY_BRIDGE_PORT; - cmdlength = sizeof(struct qeth_sbp_set_primary); + cmdlength = SBP_DATA_SIZEOF(set_primary); break; case QETH_SBP_ROLE_SECONDARY: setcmd = IPA_SBP_SET_SECONDARY_BRIDGE_PORT; - cmdlength = sizeof(struct qeth_sbp_set_secondary); break; default: return -EINVAL; diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 3de71ed54e92..ff4d514656f2 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -1564,7 +1564,8 @@ static int qeth_l3_arp_set_no_entries(struct qeth_card *card, int no_entries) } iob = qeth_get_setassparms_cmd(card, IPA_ARP_PROCESSING, - IPA_CMD_ASS_ARP_SET_NO_ENTRIES, 4, + IPA_CMD_ASS_ARP_SET_NO_ENTRIES, + SETASS_DATA_SIZEOF(flags_32bit), QETH_PROT_IPV4); if (!iob) return -ENOMEM; @@ -1710,9 +1711,7 @@ static int qeth_l3_query_arp_cache_info(struct qeth_card *card, iob = qeth_get_setassparms_cmd(card, IPA_ARP_PROCESSING, IPA_CMD_ASS_ARP_QUERY_INFO, - sizeof(struct qeth_arp_query_data) - - sizeof(char), - prot); + SETASS_DATA_SIZEOF(query_arp), prot); if (!iob) return -ENOMEM; cmd = __ipa_cmd(iob); @@ -1796,7 +1795,8 @@ static int qeth_l3_arp_modify_entry(struct qeth_card *card, } iob = qeth_get_setassparms_cmd(card, IPA_ARP_PROCESSING, arp_cmd, - sizeof(*cmd_entry), QETH_PROT_IPV4); + SETASS_DATA_SIZEOF(arp_entry), + QETH_PROT_IPV4); if (!iob) return -ENOMEM; -- cgit v1.2.3 From 5cfbe10a000aec92003d72061d250aa7a95bc02a Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Thu, 27 Jun 2019 17:01:25 +0200 Subject: s390/qeth: dynamically allocate diag cmds Add a new wrapper that allocates DIAG cmds of the right size, and fills in the common fields. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 3 +++ drivers/s390/net/qeth_core_main.c | 29 +++++++++++++++++++++-------- drivers/s390/net/qeth_core_mpc.h | 5 +++++ drivers/s390/net/qeth_l3_main.c | 4 +--- 4 files changed, 30 insertions(+), 11 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 258756dc06c3..b99fe6b043aa 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -1008,6 +1008,9 @@ struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *card, u16 cmd_code, unsigned int data_length, enum qeth_prot_versions prot); +struct qeth_cmd_buffer *qeth_get_diag_cmd(struct qeth_card *card, + enum qeth_diags_cmds sub_cmd, + unsigned int data_length); struct sk_buff *qeth_core_get_next_skb(struct qeth_card *, struct qeth_qdio_buffer *, struct qdio_buffer_element **, int *, diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 696aba566d0b..22074890835e 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -3037,6 +3037,25 @@ int qeth_query_switch_attributes(struct qeth_card *card, qeth_query_switch_attributes_cb, sw_info); } +struct qeth_cmd_buffer *qeth_get_diag_cmd(struct qeth_card *card, + enum qeth_diags_cmds sub_cmd, + unsigned int data_length) +{ + struct qeth_ipacmd_diagass *cmd; + struct qeth_cmd_buffer *iob; + + iob = qeth_ipa_alloc_cmd(card, IPA_CMD_SET_DIAG_ASS, QETH_PROT_NONE, + DIAG_HDR_LEN + data_length); + if (!iob) + return NULL; + + cmd = &__ipa_cmd(iob)->data.diagass; + cmd->subcmd_len = DIAG_SUB_HDR_LEN + data_length; + cmd->subcmd = sub_cmd; + return iob; +} +EXPORT_SYMBOL_GPL(qeth_get_diag_cmd); + static int qeth_query_setdiagass_cb(struct qeth_card *card, struct qeth_reply *reply, unsigned long data) { @@ -3055,15 +3074,11 @@ static int qeth_query_setdiagass_cb(struct qeth_card *card, static int qeth_query_setdiagass(struct qeth_card *card) { struct qeth_cmd_buffer *iob; - struct qeth_ipa_cmd *cmd; QETH_CARD_TEXT(card, 2, "qdiagass"); - iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); + iob = qeth_get_diag_cmd(card, QETH_DIAGS_CMD_QUERY, 0); if (!iob) return -ENOMEM; - cmd = __ipa_cmd(iob); - cmd->data.diagass.subcmd_len = 16; - cmd->data.diagass.subcmd = QETH_DIAGS_CMD_QUERY; return qeth_send_ipa_cmd(card, iob, qeth_query_setdiagass_cb, NULL); } @@ -3111,12 +3126,10 @@ int qeth_hw_trap(struct qeth_card *card, enum qeth_diags_trap_action action) struct qeth_ipa_cmd *cmd; QETH_CARD_TEXT(card, 2, "diagtrap"); - iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); + iob = qeth_get_diag_cmd(card, QETH_DIAGS_CMD_TRAP, 64); if (!iob) return -ENOMEM; cmd = __ipa_cmd(iob); - cmd->data.diagass.subcmd_len = 80; - cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRAP; cmd->data.diagass.type = 1; cmd->data.diagass.action = action; switch (action) { diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h index 46f038580a72..5cec877d972f 100644 --- a/drivers/s390/net/qeth_core_mpc.h +++ b/drivers/s390/net/qeth_core_mpc.h @@ -599,6 +599,11 @@ struct qeth_ipacmd_diagass { __u8 cdata[64]; } __attribute__ ((packed)); +#define DIAG_HDR_LEN offsetofend(struct qeth_ipacmd_diagass, ext) +#define DIAG_SUB_HDR_LEN (offsetofend(struct qeth_ipacmd_diagass, ext) -\ + offsetof(struct qeth_ipacmd_diagass, \ + subcmd_len)) + /* VNIC Characteristics IPA Command: *****************************************/ /* IPA commands/sub commands for VNICC */ #define IPA_VNICC_QUERY_CHARS 0x00000000L diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index ff4d514656f2..2e10f5be8f67 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -1107,12 +1107,10 @@ qeth_diags_trace(struct qeth_card *card, enum qeth_diags_trace_cmds diags_cmd) QETH_CARD_TEXT(card, 2, "diagtrac"); - iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0); + iob = qeth_get_diag_cmd(card, QETH_DIAGS_CMD_TRACE, 0); if (!iob) return -ENOMEM; cmd = __ipa_cmd(iob); - cmd->data.diagass.subcmd_len = 16; - cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRACE; cmd->data.diagass.type = QETH_DIAGS_TYPE_HIPERSOCKET; cmd->data.diagass.action = diags_cmd; return qeth_send_ipa_cmd(card, iob, qeth_diags_trace_cb, NULL); -- cgit v1.2.3 From 2cfb4810a3f2c7f9b20c6def45ef8a4dbb730387 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Thu, 27 Jun 2019 17:01:26 +0200 Subject: s390/qeth: dynamically allocate vnicc cmds The VNICC code is somewhat quirky in that it defers the whole cmd setup to a common helper qeth_l2_vnicc_request(). Some of the cmd specifics are then passed in via parameter, while others are simply hard-coded. Split the whole machinery up into the usual format: one helper that allocates the cmd & fills in the common fields, while all the cmd originators take care of their sub-cmd type specific work. This makes it much easier to calculate the cmd's precise length, and reduces code complexity. Signed-off-by: Julian Wiedmann Reviewed-by: Alexandra Winter Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_mpc.h | 13 ++--- drivers/s390/net/qeth_l2_main.c | 123 ++++++++++++++++++--------------------- 2 files changed, 62 insertions(+), 74 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_core_mpc.h b/drivers/s390/net/qeth_core_mpc.h index 5cec877d972f..75b5834ed28d 100644 --- a/drivers/s390/net/qeth_core_mpc.h +++ b/drivers/s390/net/qeth_core_mpc.h @@ -630,12 +630,6 @@ struct qeth_ipacmd_diagass { /* VNICC header */ struct qeth_ipacmd_vnicc_hdr { - u32 sup; - u32 cur; -}; - -/* VNICC sub command header */ -struct qeth_vnicc_sub_hdr { u16 data_length; u16 reserved; u32 sub_command; @@ -660,15 +654,18 @@ struct qeth_vnicc_getset_timeout { /* complete VNICC IPA command message */ struct qeth_ipacmd_vnicc { + struct qeth_ipa_caps vnicc_cmds; struct qeth_ipacmd_vnicc_hdr hdr; - struct qeth_vnicc_sub_hdr sub_hdr; union { struct qeth_vnicc_query_cmds query_cmds; struct qeth_vnicc_set_char set_char; struct qeth_vnicc_getset_timeout getset_timeout; - }; + } data; }; +#define VNICC_DATA_SIZEOF(field) FIELD_SIZEOF(struct qeth_ipacmd_vnicc,\ + data.field) + /* SETBRIDGEPORT IPA Command: *********************************************/ enum qeth_ipa_sbp_cmd { IPA_SBP_QUERY_COMMANDS_SUPPORTED = 0x00000000L, diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index f762d22a3272..68c6f4080745 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -1735,10 +1735,6 @@ static int qeth_l2_vnicc_makerc(struct qeth_card *card, u16 ipa_rc) /* generic VNICC request call back control */ struct _qeth_l2_vnicc_request_cbctl { u32 sub_cmd; - struct { - u32 vnic_char; - u32 timeout; - } param; struct { union{ u32 *sup_cmds; @@ -1761,80 +1757,52 @@ static int qeth_l2_vnicc_request_cb(struct qeth_card *card, if (cmd->hdr.return_code) return qeth_l2_vnicc_makerc(card, cmd->hdr.return_code); /* return results to caller */ - card->options.vnicc.sup_chars = rep->hdr.sup; - card->options.vnicc.cur_chars = rep->hdr.cur; + card->options.vnicc.sup_chars = rep->vnicc_cmds.supported; + card->options.vnicc.cur_chars = rep->vnicc_cmds.enabled; if (cbctl->sub_cmd == IPA_VNICC_QUERY_CMDS) - *cbctl->result.sup_cmds = rep->query_cmds.sup_cmds; + *cbctl->result.sup_cmds = rep->data.query_cmds.sup_cmds; if (cbctl->sub_cmd == IPA_VNICC_GET_TIMEOUT) - *cbctl->result.timeout = rep->getset_timeout.timeout; + *cbctl->result.timeout = rep->data.getset_timeout.timeout; return 0; } -/* generic VNICC request */ -static int qeth_l2_vnicc_request(struct qeth_card *card, - struct _qeth_l2_vnicc_request_cbctl *cbctl) +static struct qeth_cmd_buffer *qeth_l2_vnicc_build_cmd(struct qeth_card *card, + u32 vnicc_cmd, + unsigned int data_length) { - struct qeth_ipacmd_vnicc *req; + struct qeth_ipacmd_vnicc_hdr *hdr; struct qeth_cmd_buffer *iob; - struct qeth_ipa_cmd *cmd; - - QETH_CARD_TEXT(card, 2, "vniccreq"); - /* get new buffer for request */ - iob = qeth_get_ipacmd_buffer(card, IPA_CMD_VNICC, 0); + iob = qeth_ipa_alloc_cmd(card, IPA_CMD_VNICC, QETH_PROT_NONE, + data_length + + offsetof(struct qeth_ipacmd_vnicc, data)); if (!iob) - return -ENOMEM; - - /* create header for request */ - cmd = __ipa_cmd(iob); - req = &cmd->data.vnicc; - - /* create sub command header for request */ - req->sub_hdr.data_length = sizeof(req->sub_hdr); - req->sub_hdr.sub_command = cbctl->sub_cmd; - - /* create sub command specific request fields */ - switch (cbctl->sub_cmd) { - case IPA_VNICC_QUERY_CHARS: - break; - case IPA_VNICC_QUERY_CMDS: - req->sub_hdr.data_length += sizeof(req->query_cmds); - req->query_cmds.vnic_char = cbctl->param.vnic_char; - break; - case IPA_VNICC_ENABLE: - case IPA_VNICC_DISABLE: - req->sub_hdr.data_length += sizeof(req->set_char); - req->set_char.vnic_char = cbctl->param.vnic_char; - break; - case IPA_VNICC_SET_TIMEOUT: - req->getset_timeout.timeout = cbctl->param.timeout; - /* fallthrough */ - case IPA_VNICC_GET_TIMEOUT: - req->sub_hdr.data_length += sizeof(req->getset_timeout); - req->getset_timeout.vnic_char = cbctl->param.vnic_char; - break; - default: - qeth_release_buffer(iob); - return -EOPNOTSUPP; - } + return NULL; - /* send request */ - return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, cbctl); + hdr = &__ipa_cmd(iob)->data.vnicc.hdr; + hdr->data_length = sizeof(*hdr) + data_length; + hdr->sub_command = vnicc_cmd; + return iob; } /* VNICC query VNIC characteristics request */ static int qeth_l2_vnicc_query_chars(struct qeth_card *card) { struct _qeth_l2_vnicc_request_cbctl cbctl; + struct qeth_cmd_buffer *iob; + + QETH_CARD_TEXT(card, 2, "vniccqch"); + iob = qeth_l2_vnicc_build_cmd(card, IPA_VNICC_QUERY_CHARS, 0); + if (!iob) + return -ENOMEM; /* prepare callback control */ cbctl.sub_cmd = IPA_VNICC_QUERY_CHARS; - QETH_CARD_TEXT(card, 2, "vniccqch"); - return qeth_l2_vnicc_request(card, &cbctl); + return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, &cbctl); } /* VNICC query sub commands request */ @@ -1842,14 +1810,21 @@ static int qeth_l2_vnicc_query_cmds(struct qeth_card *card, u32 vnic_char, u32 *sup_cmds) { struct _qeth_l2_vnicc_request_cbctl cbctl; + struct qeth_cmd_buffer *iob; + + QETH_CARD_TEXT(card, 2, "vniccqcm"); + iob = qeth_l2_vnicc_build_cmd(card, IPA_VNICC_QUERY_CMDS, + VNICC_DATA_SIZEOF(query_cmds)); + if (!iob) + return -ENOMEM; + + __ipa_cmd(iob)->data.vnicc.data.query_cmds.vnic_char = vnic_char; /* prepare callback control */ cbctl.sub_cmd = IPA_VNICC_QUERY_CMDS; - cbctl.param.vnic_char = vnic_char; cbctl.result.sup_cmds = sup_cmds; - QETH_CARD_TEXT(card, 2, "vniccqcm"); - return qeth_l2_vnicc_request(card, &cbctl); + return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, &cbctl); } /* VNICC enable/disable characteristic request */ @@ -1857,31 +1832,47 @@ static int qeth_l2_vnicc_set_char(struct qeth_card *card, u32 vnic_char, u32 cmd) { struct _qeth_l2_vnicc_request_cbctl cbctl; + struct qeth_cmd_buffer *iob; + + QETH_CARD_TEXT(card, 2, "vniccedc"); + iob = qeth_l2_vnicc_build_cmd(card, cmd, VNICC_DATA_SIZEOF(set_char)); + if (!iob) + return -ENOMEM; + + __ipa_cmd(iob)->data.vnicc.data.set_char.vnic_char = vnic_char; /* prepare callback control */ cbctl.sub_cmd = cmd; - cbctl.param.vnic_char = vnic_char; - QETH_CARD_TEXT(card, 2, "vniccedc"); - return qeth_l2_vnicc_request(card, &cbctl); + return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, &cbctl); } /* VNICC get/set timeout for characteristic request */ static int qeth_l2_vnicc_getset_timeout(struct qeth_card *card, u32 vnicc, u32 cmd, u32 *timeout) { + struct qeth_vnicc_getset_timeout *getset_timeout; struct _qeth_l2_vnicc_request_cbctl cbctl; + struct qeth_cmd_buffer *iob; + + QETH_CARD_TEXT(card, 2, "vniccgst"); + iob = qeth_l2_vnicc_build_cmd(card, cmd, + VNICC_DATA_SIZEOF(getset_timeout)); + if (!iob) + return -ENOMEM; + + getset_timeout = &__ipa_cmd(iob)->data.vnicc.data.getset_timeout; + getset_timeout->vnic_char = vnicc; + + if (cmd == IPA_VNICC_SET_TIMEOUT) + getset_timeout->timeout = *timeout; /* prepare callback control */ cbctl.sub_cmd = cmd; - cbctl.param.vnic_char = vnicc; - if (cmd == IPA_VNICC_SET_TIMEOUT) - cbctl.param.timeout = *timeout; if (cmd == IPA_VNICC_GET_TIMEOUT) cbctl.result.timeout = timeout; - QETH_CARD_TEXT(card, 2, "vniccgst"); - return qeth_l2_vnicc_request(card, &cbctl); + return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, &cbctl); } /* set current VNICC flag state; called from sysfs store function */ -- cgit v1.2.3 From f19f8fd2df7c5929313984a5d83e9fb280bfd75f Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Thu, 27 Jun 2019 17:01:27 +0200 Subject: s390/qeth: dynamically allocate MPC cmds The base MPC cmds are the last remaining user of the static cmd buffers. Port them over to use dynamic allocation, and stop backing the write channel's cmd buffers with pages. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_main.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 22074890835e..b4c200eec707 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -1454,7 +1454,7 @@ static struct qeth_card *qeth_alloc_card(struct ccwgroup_device *gdev) goto out_read_cmd; if (qeth_setup_channel(&card->read, false)) goto out_read; - if (qeth_setup_channel(&card->write, true)) + if (qeth_setup_channel(&card->write, false)) goto out_write; if (qeth_setup_channel(&card->data, false)) goto out_data; @@ -1737,8 +1737,6 @@ static void qeth_mpc_finalize_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, unsigned int length) { - qeth_setup_ccw(__ccw_from_cmd(iob), CCW_CMD_WRITE, 0, length, - iob->data); qeth_idx_finalize_cmd(card, iob, length); memcpy(QETH_PDU_HEADER_SEQ_NO(iob->data), @@ -1751,13 +1749,20 @@ static void qeth_mpc_finalize_cmd(struct qeth_card *card, iob->callback = qeth_release_buffer_cb; } -static struct qeth_cmd_buffer *qeth_mpc_get_cmd_buffer(struct qeth_card *card) +static struct qeth_cmd_buffer *qeth_mpc_alloc_cmd(struct qeth_card *card, + void *data, + unsigned int data_length) { struct qeth_cmd_buffer *iob; - iob = qeth_get_buffer(&card->write); - if (iob) - iob->finalize = qeth_mpc_finalize_cmd; + iob = qeth_alloc_cmd(&card->write, data_length, 1, QETH_TIMEOUT); + if (!iob) + return NULL; + + memcpy(iob->data, data, data_length); + qeth_setup_ccw(__ccw_from_cmd(iob), CCW_CMD_WRITE, 0, data_length, + iob->data); + iob->finalize = qeth_mpc_finalize_cmd; return iob; } @@ -2080,11 +2085,10 @@ static int qeth_cm_enable(struct qeth_card *card) QETH_CARD_TEXT(card, 2, "cmenable"); - iob = qeth_mpc_get_cmd_buffer(card); + iob = qeth_mpc_alloc_cmd(card, CM_ENABLE, CM_ENABLE_SIZE); if (!iob) return -ENOMEM; - memcpy(iob->data, CM_ENABLE, CM_ENABLE_SIZE); memcpy(QETH_CM_ENABLE_ISSUER_RM_TOKEN(iob->data), &card->token.issuer_rm_r, QETH_MPC_TOKEN_LENGTH); memcpy(QETH_CM_ENABLE_FILTER_TOKEN(iob->data), @@ -2116,11 +2120,10 @@ static int qeth_cm_setup(struct qeth_card *card) QETH_CARD_TEXT(card, 2, "cmsetup"); - iob = qeth_mpc_get_cmd_buffer(card); + iob = qeth_mpc_alloc_cmd(card, CM_SETUP, CM_SETUP_SIZE); if (!iob) return -ENOMEM; - memcpy(iob->data, CM_SETUP, CM_SETUP_SIZE); memcpy(QETH_CM_SETUP_DEST_ADDR(iob->data), &card->token.issuer_rm_r, QETH_MPC_TOKEN_LENGTH); memcpy(QETH_CM_SETUP_CONNECTION_TOKEN(iob->data), @@ -2235,11 +2238,10 @@ static int qeth_ulp_enable(struct qeth_card *card) QETH_CARD_TEXT(card, 2, "ulpenabl"); - iob = qeth_mpc_get_cmd_buffer(card); + iob = qeth_mpc_alloc_cmd(card, ULP_ENABLE, ULP_ENABLE_SIZE); if (!iob) return -ENOMEM; - memcpy(iob->data, ULP_ENABLE, ULP_ENABLE_SIZE); *(QETH_ULP_ENABLE_LINKNUM(iob->data)) = (u8) card->dev->dev_port; memcpy(QETH_ULP_ENABLE_PROT_TYPE(iob->data), &prot_type, 1); memcpy(QETH_ULP_ENABLE_DEST_ADDR(iob->data), @@ -2283,11 +2285,10 @@ static int qeth_ulp_setup(struct qeth_card *card) QETH_CARD_TEXT(card, 2, "ulpsetup"); - iob = qeth_mpc_get_cmd_buffer(card); + iob = qeth_mpc_alloc_cmd(card, ULP_SETUP, ULP_SETUP_SIZE); if (!iob) return -ENOMEM; - memcpy(iob->data, ULP_SETUP, ULP_SETUP_SIZE); memcpy(QETH_ULP_SETUP_DEST_ADDR(iob->data), &card->token.cm_connection_r, QETH_MPC_TOKEN_LENGTH); memcpy(QETH_ULP_SETUP_CONNECTION_TOKEN(iob->data), @@ -2473,11 +2474,10 @@ static int qeth_dm_act(struct qeth_card *card) QETH_CARD_TEXT(card, 2, "dmact"); - iob = qeth_mpc_get_cmd_buffer(card); + iob = qeth_mpc_alloc_cmd(card, DM_ACT, DM_ACT_SIZE); if (!iob) return -ENOMEM; - memcpy(iob->data, DM_ACT, DM_ACT_SIZE); memcpy(QETH_DM_ACT_DEST_ADDR(iob->data), &card->token.cm_connection_r, QETH_MPC_TOKEN_LENGTH); memcpy(QETH_DM_ACT_CONNECTION_TOKEN(iob->data), @@ -2770,6 +2770,8 @@ void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, u16 total_length = IPA_PDU_HEADER_SIZE + cmd_length; u8 prot_type = qeth_mpc_select_prot_type(card); + qeth_setup_ccw(__ccw_from_cmd(iob), CCW_CMD_WRITE, 0, total_length, + iob->data); iob->finalize = qeth_ipa_finalize_cmd; iob->timeout = QETH_IPA_TIMEOUT; -- cgit v1.2.3 From c3b2218d3170178b2e5539bca3623f9519386d04 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Thu, 27 Jun 2019 17:01:28 +0200 Subject: s390/qeth: remove static cmd buffer infrastructure Now that all cmds are dynamically allocated, the code for static cmd buffers can go away entirely. Resulting in a nice reduction of code/data size & complexity, while removing the risk that qeth_clear_cmd_buffers() releases cmds that are still in-flight. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 45 ++----- drivers/s390/net/qeth_core_main.c | 254 ++++++++------------------------------ drivers/s390/net/qeth_l2_main.c | 3 +- drivers/s390/net/qeth_l3_main.c | 1 - 4 files changed, 59 insertions(+), 244 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index b99fe6b043aa..715bff28d48e 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -60,7 +60,7 @@ struct qeth_dbf_info { debug_info_t *id; }; -#define QETH_DBF_CTRL_LEN 256 +#define QETH_DBF_CTRL_LEN 256U #define QETH_DBF_TEXT(name, level, text) \ debug_text_event(qeth_dbf[QETH_DBF_##name].id, level, text) @@ -524,11 +524,6 @@ struct qeth_qdio_info { int default_out_queue; }; -/** - * buffer stuff for read channel - */ -#define QETH_CMD_BUFFER_NO 8 - /** * channel state machine */ @@ -556,12 +551,6 @@ enum qeth_prot_versions { QETH_PROT_IPV6 = 0x0006, }; -enum qeth_cmd_buffer_state { - BUF_STATE_FREE, - BUF_STATE_LOCKED, - BUF_STATE_MALLOC, -}; - enum qeth_cq { QETH_CQ_DISABLED = 0, QETH_CQ_ENABLED = 1, @@ -575,18 +564,20 @@ struct qeth_ipato { struct list_head entries; }; -struct qeth_channel; +struct qeth_channel { + struct ccw_device *ccwdev; + enum qeth_channel_states state; + atomic_t irq_pending; +}; struct qeth_cmd_buffer { - enum qeth_cmd_buffer_state state; unsigned int length; refcount_t ref_count; struct qeth_channel *channel; struct qeth_reply *reply; long timeout; unsigned char *data; - void (*finalize)(struct qeth_card *card, struct qeth_cmd_buffer *iob, - unsigned int length); + void (*finalize)(struct qeth_card *card, struct qeth_cmd_buffer *iob); void (*callback)(struct qeth_card *card, struct qeth_cmd_buffer *iob); }; @@ -600,25 +591,8 @@ static inline struct qeth_ipa_cmd *__ipa_cmd(struct qeth_cmd_buffer *iob) return (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE); } -/** - * definition of a qeth channel, used for read and write - */ -struct qeth_channel { - enum qeth_channel_states state; - struct ccw1 *ccw; - spinlock_t iob_lock; - wait_queue_head_t wait_q; - struct ccw_device *ccwdev; -/*command buffer for control data*/ - struct qeth_cmd_buffer iob[QETH_CMD_BUFFER_NO]; - atomic_t irq_pending; - int io_buf_no; -}; - static inline struct ccw1 *__ccw_from_cmd(struct qeth_cmd_buffer *iob) { - if (iob->state != BUF_STATE_MALLOC) - return iob->channel->ccw; return (struct ccw1 *)(iob->data + ALIGN(iob->length, 8)); } @@ -994,8 +968,6 @@ int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *, int (*reply_cb) (struct qeth_card *, struct qeth_reply *, unsigned long), void *); -struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *, - enum qeth_ipa_cmds, enum qeth_prot_versions); struct qeth_cmd_buffer *qeth_ipa_alloc_cmd(struct qeth_card *card, enum qeth_ipa_cmds cmd_code, enum qeth_prot_versions prot, @@ -1011,6 +983,7 @@ struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *card, struct qeth_cmd_buffer *qeth_get_diag_cmd(struct qeth_card *card, enum qeth_diags_cmds sub_cmd, unsigned int data_length); +void qeth_put_cmd(struct qeth_cmd_buffer *iob); struct sk_buff *qeth_core_get_next_skb(struct qeth_card *, struct qeth_qdio_buffer *, struct qdio_buffer_element **, int *, @@ -1020,12 +993,10 @@ int qeth_poll(struct napi_struct *napi, int budget); void qeth_clear_ipacmd_list(struct qeth_card *); int qeth_qdio_clear_card(struct qeth_card *, int); void qeth_clear_working_pool_list(struct qeth_card *); -void qeth_clear_cmd_buffers(struct qeth_channel *); void qeth_drain_output_queues(struct qeth_card *card); void qeth_setadp_promisc_mode(struct qeth_card *); int qeth_setadpparms_change_macaddr(struct qeth_card *); void qeth_tx_timeout(struct net_device *); -void qeth_release_buffer(struct qeth_cmd_buffer *iob); void qeth_notify_reply(struct qeth_reply *reply, int reason); void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, u16 cmd_length); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index b4c200eec707..3875f70118e4 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -517,7 +517,7 @@ static int __qeth_issue_next_read(struct qeth_card *card) QETH_DBF_MESSAGE(2, "error %i on device %x when starting next read ccw!\n", rc, CARD_DEVID(card)); atomic_set(&channel->irq_pending, 0); - qeth_release_buffer(iob); + qeth_put_cmd(iob); card->read_or_write_problem = 1; qeth_schedule_recovery(card); wake_up(&card->wait_q); @@ -689,7 +689,7 @@ static int qeth_check_idx_response(struct qeth_card *card, return 0; } -static void qeth_put_cmd(struct qeth_cmd_buffer *iob) +void qeth_put_cmd(struct qeth_cmd_buffer *iob) { if (refcount_dec_and_test(&iob->ref_count)) { if (iob->reply) @@ -698,53 +698,12 @@ static void qeth_put_cmd(struct qeth_cmd_buffer *iob) kfree(iob); } } - -static struct qeth_cmd_buffer *__qeth_get_buffer(struct qeth_channel *channel) -{ - __u8 index; - - index = channel->io_buf_no; - do { - if (channel->iob[index].state == BUF_STATE_FREE) { - channel->iob[index].state = BUF_STATE_LOCKED; - channel->iob[index].timeout = QETH_TIMEOUT; - channel->io_buf_no = (channel->io_buf_no + 1) % - QETH_CMD_BUFFER_NO; - memset(channel->iob[index].data, 0, QETH_BUFSIZE); - return channel->iob + index; - } - index = (index + 1) % QETH_CMD_BUFFER_NO; - } while (index != channel->io_buf_no); - - return NULL; -} - -void qeth_release_buffer(struct qeth_cmd_buffer *iob) -{ - struct qeth_channel *channel = iob->channel; - unsigned long flags; - - if (iob->state == BUF_STATE_MALLOC) { - qeth_put_cmd(iob); - return; - } - - spin_lock_irqsave(&channel->iob_lock, flags); - iob->state = BUF_STATE_FREE; - iob->callback = NULL; - if (iob->reply) { - qeth_put_reply(iob->reply); - iob->reply = NULL; - } - spin_unlock_irqrestore(&channel->iob_lock, flags); - wake_up(&channel->wait_q); -} -EXPORT_SYMBOL_GPL(qeth_release_buffer); +EXPORT_SYMBOL_GPL(qeth_put_cmd); static void qeth_release_buffer_cb(struct qeth_card *card, struct qeth_cmd_buffer *iob) { - qeth_release_buffer(iob); + qeth_put_cmd(iob); } static void qeth_cancel_cmd(struct qeth_cmd_buffer *iob, int rc) @@ -753,18 +712,7 @@ static void qeth_cancel_cmd(struct qeth_cmd_buffer *iob, int rc) if (reply) qeth_notify_reply(reply, rc); - qeth_release_buffer(iob); -} - -static struct qeth_cmd_buffer *qeth_get_buffer(struct qeth_channel *channel) -{ - struct qeth_cmd_buffer *buffer = NULL; - unsigned long flags; - - spin_lock_irqsave(&channel->iob_lock, flags); - buffer = __qeth_get_buffer(channel); - spin_unlock_irqrestore(&channel->iob_lock, flags); - return buffer; + qeth_put_cmd(iob); } struct qeth_cmd_buffer *qeth_alloc_cmd(struct qeth_channel *channel, @@ -787,7 +735,6 @@ struct qeth_cmd_buffer *qeth_alloc_cmd(struct qeth_channel *channel, return NULL; } - iob->state = BUF_STATE_MALLOC; refcount_set(&iob->ref_count, 1); iob->channel = channel; iob->timeout = timeout; @@ -796,16 +743,6 @@ struct qeth_cmd_buffer *qeth_alloc_cmd(struct qeth_channel *channel, } EXPORT_SYMBOL_GPL(qeth_alloc_cmd); -void qeth_clear_cmd_buffers(struct qeth_channel *channel) -{ - int cnt; - - for (cnt = 0; cnt < QETH_CMD_BUFFER_NO; cnt++) - qeth_release_buffer(&channel->iob[cnt]); - channel->io_buf_no = 0; -} -EXPORT_SYMBOL_GPL(qeth_clear_cmd_buffers); - static void qeth_issue_next_read_cb(struct qeth_card *card, struct qeth_cmd_buffer *iob) { @@ -879,7 +816,7 @@ out: memcpy(&card->seqno.pdu_hdr_ack, QETH_PDU_HEADER_SEQ_NO(iob->data), QETH_SEQ_NO_LENGTH); - qeth_release_buffer(iob); + qeth_put_cmd(iob); __qeth_issue_next_read(card); } @@ -1229,56 +1166,26 @@ static void qeth_free_buffer_pool(struct qeth_card *card) static void qeth_clean_channel(struct qeth_channel *channel) { struct ccw_device *cdev = channel->ccwdev; - int cnt; QETH_DBF_TEXT(SETUP, 2, "freech"); spin_lock_irq(get_ccwdev_lock(cdev)); cdev->handler = NULL; spin_unlock_irq(get_ccwdev_lock(cdev)); - - for (cnt = 0; cnt < QETH_CMD_BUFFER_NO; cnt++) - kfree(channel->iob[cnt].data); - kfree(channel->ccw); } -static int qeth_setup_channel(struct qeth_channel *channel, bool alloc_buffers) +static void qeth_setup_channel(struct qeth_channel *channel) { struct ccw_device *cdev = channel->ccwdev; - int cnt; QETH_DBF_TEXT(SETUP, 2, "setupch"); - channel->ccw = kmalloc(sizeof(struct ccw1), GFP_KERNEL | GFP_DMA); - if (!channel->ccw) - return -ENOMEM; channel->state = CH_STATE_DOWN; atomic_set(&channel->irq_pending, 0); - init_waitqueue_head(&channel->wait_q); spin_lock_irq(get_ccwdev_lock(cdev)); cdev->handler = qeth_irq; spin_unlock_irq(get_ccwdev_lock(cdev)); - - if (!alloc_buffers) - return 0; - - for (cnt = 0; cnt < QETH_CMD_BUFFER_NO; cnt++) { - channel->iob[cnt].data = kmalloc(QETH_BUFSIZE, - GFP_KERNEL | GFP_DMA); - if (channel->iob[cnt].data == NULL) - break; - channel->iob[cnt].state = BUF_STATE_FREE; - channel->iob[cnt].channel = channel; - } - if (cnt < QETH_CMD_BUFFER_NO) { - qeth_clean_channel(channel); - return -ENOMEM; - } - channel->io_buf_no = 0; - spin_lock_init(&channel->iob_lock); - - return 0; } static int qeth_osa_set_output_queues(struct qeth_card *card, bool single) @@ -1452,22 +1359,14 @@ static struct qeth_card *qeth_alloc_card(struct ccwgroup_device *gdev) card->read_cmd = qeth_alloc_cmd(&card->read, QETH_BUFSIZE, 1, 0); if (!card->read_cmd) goto out_read_cmd; - if (qeth_setup_channel(&card->read, false)) - goto out_read; - if (qeth_setup_channel(&card->write, false)) - goto out_write; - if (qeth_setup_channel(&card->data, false)) - goto out_data; + + qeth_setup_channel(&card->read); + qeth_setup_channel(&card->write); + qeth_setup_channel(&card->data); card->qeth_service_level.seq_print = qeth_core_sl_print; register_service_level(&card->qeth_service_level); return card; -out_data: - qeth_clean_channel(&card->write); -out_write: - qeth_clean_channel(&card->read); -out_read: - qeth_release_buffer(card->read_cmd); out_read_cmd: destroy_workqueue(card->event_wq); out_wq: @@ -1715,8 +1614,7 @@ static void qeth_init_func_level(struct qeth_card *card) } static void qeth_idx_finalize_cmd(struct qeth_card *card, - struct qeth_cmd_buffer *iob, - unsigned int length) + struct qeth_cmd_buffer *iob) { memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data), &card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH); @@ -1734,10 +1632,9 @@ static int qeth_peer_func_level(int level) } static void qeth_mpc_finalize_cmd(struct qeth_card *card, - struct qeth_cmd_buffer *iob, - unsigned int length) + struct qeth_cmd_buffer *iob) { - qeth_idx_finalize_cmd(card, iob, length); + qeth_idx_finalize_cmd(card, iob); memcpy(QETH_PDU_HEADER_SEQ_NO(iob->data), &card->seqno.pdu_hdr, QETH_SEQ_NO_LENGTH); @@ -1769,7 +1666,6 @@ static struct qeth_cmd_buffer *qeth_mpc_alloc_cmd(struct qeth_card *card, /** * qeth_send_control_data() - send control command to the card * @card: qeth_card structure pointer - * @len: size of the command buffer * @iob: qeth_cmd_buffer pointer * @reply_cb: callback function pointer * @cb_card: pointer to the qeth_card structure @@ -1789,7 +1685,7 @@ static struct qeth_cmd_buffer *qeth_mpc_alloc_cmd(struct qeth_card *card, * field 'param' of the structure qeth_reply. */ -static int qeth_send_control_data(struct qeth_card *card, int len, +static int qeth_send_control_data(struct qeth_card *card, struct qeth_cmd_buffer *iob, int (*reply_cb)(struct qeth_card *cb_card, struct qeth_reply *cb_reply, @@ -1805,13 +1701,13 @@ static int qeth_send_control_data(struct qeth_card *card, int len, reply = qeth_alloc_reply(card); if (!reply) { - qeth_release_buffer(iob); + qeth_put_cmd(iob); return -ENOMEM; } reply->callback = reply_cb; reply->param = reply_param; - /* pairs with qeth_release_buffer(): */ + /* pairs with qeth_put_cmd(): */ qeth_get_reply(reply); iob->reply = reply; @@ -1820,13 +1716,13 @@ static int qeth_send_control_data(struct qeth_card *card, int len, timeout); if (timeout <= 0) { qeth_put_reply(reply); - qeth_release_buffer(iob); + qeth_put_cmd(iob); return (timeout == -ERESTARTSYS) ? -EINTR : -ETIME; } if (iob->finalize) - iob->finalize(card, iob, len); - QETH_DBF_HEX(CTRL, 2, iob->data, min(len, QETH_DBF_CTRL_LEN)); + iob->finalize(card, iob); + QETH_DBF_HEX(CTRL, 2, iob->data, min(iob->length, QETH_DBF_CTRL_LEN)); qeth_enqueue_reply(card, reply); @@ -1841,7 +1737,7 @@ static int qeth_send_control_data(struct qeth_card *card, int len, QETH_CARD_TEXT_(card, 2, " err%d", rc); qeth_dequeue_reply(card, reply); qeth_put_reply(reply); - qeth_release_buffer(iob); + qeth_put_cmd(iob); atomic_set(&channel->irq_pending, 0); wake_up(&card->wait_q); return rc; @@ -1874,7 +1770,7 @@ static void qeth_read_conf_data_cb(struct qeth_card *card, prcd[76] >= 0xF1 && prcd[76] <= 0xF4; qeth_notify_reply(iob->reply, 0); - qeth_release_buffer(iob); + qeth_put_cmd(iob); } static int qeth_read_conf_data(struct qeth_card *card) @@ -1896,7 +1792,7 @@ static int qeth_read_conf_data(struct qeth_card *card) qeth_setup_ccw(__ccw_from_cmd(iob), ciw->cmd, 0, iob->length, iob->data); - return qeth_send_control_data(card, iob->length, iob, NULL, NULL); + return qeth_send_control_data(card, iob, NULL, NULL); } static int qeth_idx_check_activate_response(struct qeth_card *card, @@ -1963,7 +1859,7 @@ static void qeth_idx_activate_read_channel_cb(struct qeth_card *card, out: qeth_notify_reply(iob->reply, rc); - qeth_release_buffer(iob); + qeth_put_cmd(iob); } static void qeth_idx_activate_write_channel_cb(struct qeth_card *card, @@ -1990,7 +1886,7 @@ static void qeth_idx_activate_write_channel_cb(struct qeth_card *card, out: qeth_notify_reply(iob->reply, rc); - qeth_release_buffer(iob); + qeth_put_cmd(iob); } static void qeth_idx_setup_activate_cmd(struct qeth_card *card, @@ -2032,7 +1928,7 @@ static int qeth_idx_activate_read_channel(struct qeth_card *card) qeth_idx_setup_activate_cmd(card, iob); iob->callback = qeth_idx_activate_read_channel_cb; - rc = qeth_send_control_data(card, IDX_ACTIVATE_SIZE, iob, NULL, NULL); + rc = qeth_send_control_data(card, iob, NULL, NULL); if (rc) return rc; @@ -2056,7 +1952,7 @@ static int qeth_idx_activate_write_channel(struct qeth_card *card) qeth_idx_setup_activate_cmd(card, iob); iob->callback = qeth_idx_activate_write_channel_cb; - rc = qeth_send_control_data(card, IDX_ACTIVATE_SIZE, iob, NULL, NULL); + rc = qeth_send_control_data(card, iob, NULL, NULL); if (rc) return rc; @@ -2080,7 +1976,6 @@ static int qeth_cm_enable_cb(struct qeth_card *card, struct qeth_reply *reply, static int qeth_cm_enable(struct qeth_card *card) { - int rc; struct qeth_cmd_buffer *iob; QETH_CARD_TEXT(card, 2, "cmenable"); @@ -2094,9 +1989,7 @@ static int qeth_cm_enable(struct qeth_card *card) memcpy(QETH_CM_ENABLE_FILTER_TOKEN(iob->data), &card->token.cm_filter_w, QETH_MPC_TOKEN_LENGTH); - rc = qeth_send_control_data(card, CM_ENABLE_SIZE, iob, - qeth_cm_enable_cb, NULL); - return rc; + return qeth_send_control_data(card, iob, qeth_cm_enable_cb, NULL); } static int qeth_cm_setup_cb(struct qeth_card *card, struct qeth_reply *reply, @@ -2115,7 +2008,6 @@ static int qeth_cm_setup_cb(struct qeth_card *card, struct qeth_reply *reply, static int qeth_cm_setup(struct qeth_card *card) { - int rc; struct qeth_cmd_buffer *iob; QETH_CARD_TEXT(card, 2, "cmsetup"); @@ -2130,9 +2022,7 @@ static int qeth_cm_setup(struct qeth_card *card) &card->token.cm_connection_w, QETH_MPC_TOKEN_LENGTH); memcpy(QETH_CM_SETUP_FILTER_TOKEN(iob->data), &card->token.cm_filter_r, QETH_MPC_TOKEN_LENGTH); - rc = qeth_send_control_data(card, CM_SETUP_SIZE, iob, - qeth_cm_setup_cb, NULL); - return rc; + return qeth_send_control_data(card, iob, qeth_cm_setup_cb, NULL); } static int qeth_update_max_mtu(struct qeth_card *card, unsigned int max_mtu) @@ -2248,8 +2138,7 @@ static int qeth_ulp_enable(struct qeth_card *card) &card->token.cm_connection_r, QETH_MPC_TOKEN_LENGTH); memcpy(QETH_ULP_ENABLE_FILTER_TOKEN(iob->data), &card->token.ulp_filter_w, QETH_MPC_TOKEN_LENGTH); - rc = qeth_send_control_data(card, ULP_ENABLE_SIZE, iob, - qeth_ulp_enable_cb, &max_mtu); + rc = qeth_send_control_data(card, iob, qeth_ulp_enable_cb, &max_mtu); if (rc) return rc; return qeth_update_max_mtu(card, max_mtu); @@ -2278,7 +2167,6 @@ static int qeth_ulp_setup_cb(struct qeth_card *card, struct qeth_reply *reply, static int qeth_ulp_setup(struct qeth_card *card) { - int rc; __u16 temp; struct qeth_cmd_buffer *iob; struct ccw_dev_id dev_id; @@ -2300,9 +2188,7 @@ static int qeth_ulp_setup(struct qeth_card *card) memcpy(QETH_ULP_SETUP_CUA(iob->data), &dev_id.devno, 2); temp = (card->info.cula << 8) + card->info.unit_addr2; memcpy(QETH_ULP_SETUP_REAL_DEVADDR(iob->data), &temp, 2); - rc = qeth_send_control_data(card, ULP_SETUP_SIZE, iob, - qeth_ulp_setup_cb, NULL); - return rc; + return qeth_send_control_data(card, iob, qeth_ulp_setup_cb, NULL); } static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *q, int bidx) @@ -2469,7 +2355,6 @@ static int qeth_qdio_activate(struct qeth_card *card) static int qeth_dm_act(struct qeth_card *card) { - int rc; struct qeth_cmd_buffer *iob; QETH_CARD_TEXT(card, 2, "dmact"); @@ -2482,8 +2367,7 @@ static int qeth_dm_act(struct qeth_card *card) &card->token.cm_connection_r, QETH_MPC_TOKEN_LENGTH); memcpy(QETH_DM_ACT_CONNECTION_TOKEN(iob->data), &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH); - rc = qeth_send_control_data(card, DM_ACT_SIZE, iob, NULL, NULL); - return rc; + return qeth_send_control_data(card, iob, NULL, NULL); } static int qeth_mpc_initialize(struct qeth_card *card) @@ -2728,36 +2612,10 @@ int qeth_init_qdio_queues(struct qeth_card *card) } EXPORT_SYMBOL_GPL(qeth_init_qdio_queues); -static __u8 qeth_get_ipa_adp_type(enum qeth_link_types link_type) -{ - switch (link_type) { - case QETH_LINK_TYPE_HSTR: - return 2; - default: - return 1; - } -} - -static void qeth_fill_ipacmd_header(struct qeth_card *card, - struct qeth_ipa_cmd *cmd, - enum qeth_ipa_cmds command, - enum qeth_prot_versions prot) -{ - cmd->hdr.command = command; - cmd->hdr.initiator = IPA_CMD_INITIATOR_HOST; - /* cmd->hdr.seqno is set by qeth_send_control_data() */ - cmd->hdr.adapter_type = qeth_get_ipa_adp_type(card->info.link_type); - cmd->hdr.rel_adapter_no = (u8) card->dev->dev_port; - cmd->hdr.prim_version_no = IS_LAYER2(card) ? 2 : 1; - cmd->hdr.param_count = 1; - cmd->hdr.prot_version = prot; -} - static void qeth_ipa_finalize_cmd(struct qeth_card *card, - struct qeth_cmd_buffer *iob, - unsigned int length) + struct qeth_cmd_buffer *iob) { - qeth_mpc_finalize_cmd(card, iob, length); + qeth_mpc_finalize_cmd(card, iob); /* override with IPA-specific values: */ __ipa_cmd(iob)->hdr.seqno = card->seqno.ipa; @@ -2767,13 +2625,12 @@ static void qeth_ipa_finalize_cmd(struct qeth_card *card, void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, u16 cmd_length) { - u16 total_length = IPA_PDU_HEADER_SIZE + cmd_length; u8 prot_type = qeth_mpc_select_prot_type(card); + u16 total_length = iob->length; qeth_setup_ccw(__ccw_from_cmd(iob), CCW_CMD_WRITE, 0, total_length, iob->data); iob->finalize = qeth_ipa_finalize_cmd; - iob->timeout = QETH_IPA_TIMEOUT; memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE); memcpy(QETH_IPA_PDU_LEN_TOTAL(iob->data), &total_length, 2); @@ -2786,32 +2643,14 @@ void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, } EXPORT_SYMBOL_GPL(qeth_prepare_ipa_cmd); -struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *card, - enum qeth_ipa_cmds ipacmd, enum qeth_prot_versions prot) -{ - struct qeth_cmd_buffer *iob; - - iob = qeth_get_buffer(&card->write); - if (iob) { - qeth_prepare_ipa_cmd(card, iob, sizeof(struct qeth_ipa_cmd)); - qeth_fill_ipacmd_header(card, __ipa_cmd(iob), ipacmd, prot); - } else { - dev_warn(&card->gdev->dev, - "The qeth driver ran out of channel command buffers\n"); - QETH_DBF_MESSAGE(1, "device %x ran out of channel command buffers", - CARD_DEVID(card)); - } - - return iob; -} -EXPORT_SYMBOL_GPL(qeth_get_ipacmd_buffer); - struct qeth_cmd_buffer *qeth_ipa_alloc_cmd(struct qeth_card *card, enum qeth_ipa_cmds cmd_code, enum qeth_prot_versions prot, unsigned int data_length) { + enum qeth_link_types link_type = card->info.link_type; struct qeth_cmd_buffer *iob; + struct qeth_ipacmd_hdr *hdr; data_length += offsetof(struct qeth_ipa_cmd, data); iob = qeth_alloc_cmd(&card->write, IPA_PDU_HEADER_SIZE + data_length, 1, @@ -2820,7 +2659,16 @@ struct qeth_cmd_buffer *qeth_ipa_alloc_cmd(struct qeth_card *card, return NULL; qeth_prepare_ipa_cmd(card, iob, data_length); - qeth_fill_ipacmd_header(card, __ipa_cmd(iob), cmd_code, prot); + + hdr = &__ipa_cmd(iob)->hdr; + hdr->command = cmd_code; + hdr->initiator = IPA_CMD_INITIATOR_HOST; + /* hdr->seqno is set by qeth_send_control_data() */ + hdr->adapter_type = (link_type == QETH_LINK_TYPE_HSTR) ? 2 : 1; + hdr->rel_adapter_no = (u8) card->dev->dev_port; + hdr->prim_version_no = IS_LAYER2(card) ? 2 : 1; + hdr->param_count = 1; + hdr->prot_version = prot; return iob; } EXPORT_SYMBOL_GPL(qeth_ipa_alloc_cmd); @@ -2844,20 +2692,18 @@ int qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, unsigned long), void *reply_param) { - u16 length; int rc; QETH_CARD_TEXT(card, 4, "sendipa"); if (card->read_or_write_problem) { - qeth_release_buffer(iob); + qeth_put_cmd(iob); return -EIO; } if (reply_cb == NULL) reply_cb = qeth_send_ipa_cmd_cb; - memcpy(&length, QETH_IPA_PDU_LEN_TOTAL(iob->data), 2); - rc = qeth_send_control_data(card, length, iob, reply_cb, reply_param); + rc = qeth_send_control_data(card, iob, reply_cb, reply_param); if (rc == -ETIME) { qeth_clear_ipacmd_list(card); qeth_schedule_recovery(card); @@ -4929,7 +4775,7 @@ static void qeth_core_free_card(struct qeth_card *card) qeth_clean_channel(&card->read); qeth_clean_channel(&card->write); qeth_clean_channel(&card->data); - qeth_release_buffer(card->read_cmd); + qeth_put_cmd(card->read_cmd); destroy_workqueue(card->event_wq); qeth_free_qdio_queues(card); unregister_service_level(&card->qeth_service_level); diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 68c6f4080745..03e1cd4a282a 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -294,7 +294,6 @@ static void qeth_l2_stop_card(struct qeth_card *card) card->state = CARD_STATE_DOWN; } - qeth_clear_cmd_buffers(&card->write); flush_workqueue(card->event_wq); card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; } @@ -1034,7 +1033,7 @@ static void qeth_osn_assist_cb(struct qeth_card *card, struct qeth_cmd_buffer *iob) { qeth_notify_reply(iob->reply, 0); - qeth_release_buffer(iob); + qeth_put_cmd(iob); } int qeth_osn_assist(struct net_device *dev, void *data, int data_len) diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 2e10f5be8f67..c36f368336a0 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -1439,7 +1439,6 @@ static void qeth_l3_stop_card(struct qeth_card *card) card->state = CARD_STATE_DOWN; } - qeth_clear_cmd_buffers(&card->write); flush_workqueue(card->event_wq); } -- cgit v1.2.3 From d4c08afafa0469a24771b14528ee179f72861ea3 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Thu, 27 Jun 2019 17:01:29 +0200 Subject: s390/qeth: streamline SNMP cmd code Apply some cleanups to qeth_snmp_command() and its callback: 1. when accessing the user data, use the proper struct instead of hard-coded offsets. Also copy the request data straight into the allocated cmd, skipping the extra memdup_user() to a tmp buffer. 2. capping the request length is no longer needed, the same check gets applied at a base level in qeth_alloc_cmd(). 3. clean up some duplicated (and misindented) trace statements. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_main.c | 49 ++++++++++++++------------------------- 1 file changed, 18 insertions(+), 31 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 3875f70118e4..efb9a27b916e 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -4320,18 +4320,13 @@ static int qeth_snmp_command_cb(struct qeth_card *card, return -ENOSPC; } QETH_CARD_TEXT_(card, 4, "snore%i", - cmd->data.setadapterparms.hdr.used_total); + cmd->data.setadapterparms.hdr.used_total); QETH_CARD_TEXT_(card, 4, "sseqn%i", - cmd->data.setadapterparms.hdr.seq_no); + cmd->data.setadapterparms.hdr.seq_no); /*copy entries to user buffer*/ memcpy(qinfo->udata + qinfo->udata_offset, snmp_data, data_len); qinfo->udata_offset += data_len; - /* check if all replies received ... */ - QETH_CARD_TEXT_(card, 4, "srtot%i", - cmd->data.setadapterparms.hdr.used_total); - QETH_CARD_TEXT_(card, 4, "srseq%i", - cmd->data.setadapterparms.hdr.seq_no); if (cmd->data.setadapterparms.hdr.seq_no < cmd->data.setadapterparms.hdr.used_total) return 1; @@ -4340,9 +4335,8 @@ static int qeth_snmp_command_cb(struct qeth_card *card, static int qeth_snmp_command(struct qeth_card *card, char __user *udata) { + struct qeth_snmp_ureq __user *ureq; struct qeth_cmd_buffer *iob; - struct qeth_ipa_cmd *cmd; - struct qeth_snmp_ureq *ureq; unsigned int req_len; struct qeth_arp_query_info qinfo = {0, }; int rc = 0; @@ -4356,34 +4350,28 @@ static int qeth_snmp_command(struct qeth_card *card, char __user *udata) IS_LAYER3(card)) return -EOPNOTSUPP; - /* skip 4 bytes (data_len struct member) to get req_len */ - if (copy_from_user(&req_len, udata + sizeof(int), sizeof(int))) + ureq = (struct qeth_snmp_ureq __user *) udata; + if (get_user(qinfo.udata_len, &ureq->hdr.data_len) || + get_user(req_len, &ureq->hdr.req_len)) + return -EFAULT; + + iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_SNMP_CONTROL, req_len); + if (!iob) + return -ENOMEM; + + if (copy_from_user(&__ipa_cmd(iob)->data.setadapterparms.data.snmp, + &ureq->cmd, req_len)) { + qeth_put_cmd(iob); return -EFAULT; - if (req_len + offsetof(struct qeth_ipacmd_setadpparms, data) + - offsetof(struct qeth_ipa_cmd, data) + IPA_PDU_HEADER_SIZE > - QETH_BUFSIZE) - return -EINVAL; - ureq = memdup_user(udata, req_len + sizeof(struct qeth_snmp_ureq_hdr)); - if (IS_ERR(ureq)) { - QETH_CARD_TEXT(card, 2, "snmpnome"); - return PTR_ERR(ureq); } - qinfo.udata_len = ureq->hdr.data_len; + qinfo.udata = kzalloc(qinfo.udata_len, GFP_KERNEL); if (!qinfo.udata) { - kfree(ureq); + qeth_put_cmd(iob); return -ENOMEM; } qinfo.udata_offset = sizeof(struct qeth_snmp_ureq_hdr); - iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_SNMP_CONTROL, req_len); - if (!iob) { - rc = -ENOMEM; - goto out; - } - - cmd = __ipa_cmd(iob); - memcpy(&cmd->data.setadapterparms.data.snmp, &ureq->cmd, req_len); rc = qeth_send_ipa_cmd(card, iob, qeth_snmp_command_cb, &qinfo); if (rc) QETH_DBF_MESSAGE(2, "SNMP command failed on device %x: (%#x)\n", @@ -4392,8 +4380,7 @@ static int qeth_snmp_command(struct qeth_card *card, char __user *udata) if (copy_to_user(udata, qinfo.udata, qinfo.udata_len)) rc = -EFAULT; } -out: - kfree(ureq); + kfree(qinfo.udata); return rc; } -- cgit v1.2.3 From c4733c32ca2272b8c11663fc1ad6264d2ee42384 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Thu, 27 Jun 2019 17:01:30 +0200 Subject: s390/qeth: consolidate pm code De-duplicate the pm callback implementations from the two sub-drivers, replacing them with core helpers that delegate to the .set_online and .set_offline callbacks. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 3 --- drivers/s390/net/qeth_core_main.c | 36 +++++++++++++++++++----------------- drivers/s390/net/qeth_l2_main.c | 30 ------------------------------ drivers/s390/net/qeth_l3_main.c | 30 ------------------------------ 4 files changed, 19 insertions(+), 80 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index 715bff28d48e..c81d5ec26803 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -713,9 +713,6 @@ struct qeth_discipline { void (*remove) (struct ccwgroup_device *); int (*set_online) (struct ccwgroup_device *); int (*set_offline) (struct ccwgroup_device *); - int (*freeze)(struct ccwgroup_device *); - int (*thaw) (struct ccwgroup_device *); - int (*restore)(struct ccwgroup_device *); int (*do_ioctl)(struct net_device *dev, struct ifreq *rq, int cmd); int (*control_event_handler)(struct qeth_card *card, struct qeth_ipa_cmd *cmd); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index efb9a27b916e..3011cae00391 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -5589,28 +5589,30 @@ static void qeth_core_shutdown(struct ccwgroup_device *gdev) qdio_free(CARD_DDEV(card)); } -static int qeth_core_freeze(struct ccwgroup_device *gdev) +static int qeth_suspend(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); - if (card->discipline && card->discipline->freeze) - return card->discipline->freeze(gdev); - return 0; -} -static int qeth_core_thaw(struct ccwgroup_device *gdev) -{ - struct qeth_card *card = dev_get_drvdata(&gdev->dev); - if (card->discipline && card->discipline->thaw) - return card->discipline->thaw(gdev); + qeth_set_allowed_threads(card, 0, 1); + wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); + if (gdev->state == CCWGROUP_OFFLINE) + return 0; + + card->discipline->set_offline(gdev); return 0; } -static int qeth_core_restore(struct ccwgroup_device *gdev) +static int qeth_resume(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); - if (card->discipline && card->discipline->restore) - return card->discipline->restore(gdev); - return 0; + int rc; + + rc = card->discipline->set_online(gdev); + + qeth_set_allowed_threads(card, 0xffffffff, 0); + if (rc) + dev_warn(&card->gdev->dev, "The qeth device driver failed to recover an error on the device\n"); + return rc; } static ssize_t group_store(struct device_driver *ddrv, const char *buf, @@ -5651,9 +5653,9 @@ static struct ccwgroup_driver qeth_core_ccwgroup_driver = { .shutdown = qeth_core_shutdown, .prepare = NULL, .complete = NULL, - .freeze = qeth_core_freeze, - .thaw = qeth_core_thaw, - .restore = qeth_core_restore, + .freeze = qeth_suspend, + .thaw = qeth_resume, + .restore = qeth_resume, }; struct qeth_card *qeth_get_card_by_busid(char *bus_id) diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 03e1cd4a282a..4a2ff9d8aa5f 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -965,33 +965,6 @@ static void __exit qeth_l2_exit(void) pr_info("unregister layer 2 discipline\n"); } -static int qeth_l2_pm_suspend(struct ccwgroup_device *gdev) -{ - struct qeth_card *card = dev_get_drvdata(&gdev->dev); - - qeth_set_allowed_threads(card, 0, 1); - wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); - if (gdev->state == CCWGROUP_OFFLINE) - return 0; - - qeth_l2_set_offline(gdev); - return 0; -} - -static int qeth_l2_pm_resume(struct ccwgroup_device *gdev) -{ - struct qeth_card *card = dev_get_drvdata(&gdev->dev); - int rc; - - rc = qeth_l2_set_online(gdev); - - qeth_set_allowed_threads(card, 0xffffffff, 0); - if (rc) - dev_warn(&card->gdev->dev, "The qeth device driver " - "failed to recover an error on the device\n"); - return rc; -} - /* Returns zero if the command is successfully "consumed" */ static int qeth_l2_control_event(struct qeth_card *card, struct qeth_ipa_cmd *cmd) @@ -1021,9 +994,6 @@ struct qeth_discipline qeth_l2_discipline = { .remove = qeth_l2_remove_device, .set_online = qeth_l2_set_online, .set_offline = qeth_l2_set_offline, - .freeze = qeth_l2_pm_suspend, - .thaw = qeth_l2_pm_resume, - .restore = qeth_l2_pm_resume, .do_ioctl = NULL, .control_event_handler = qeth_l2_control_event, }; diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index c36f368336a0..44a602aa12ec 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2500,33 +2500,6 @@ static int qeth_l3_recover(void *ptr) return 0; } -static int qeth_l3_pm_suspend(struct ccwgroup_device *gdev) -{ - struct qeth_card *card = dev_get_drvdata(&gdev->dev); - - qeth_set_allowed_threads(card, 0, 1); - wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); - if (gdev->state == CCWGROUP_OFFLINE) - return 0; - - qeth_l3_set_offline(gdev); - return 0; -} - -static int qeth_l3_pm_resume(struct ccwgroup_device *gdev) -{ - struct qeth_card *card = dev_get_drvdata(&gdev->dev); - int rc; - - rc = qeth_l3_set_online(gdev); - - qeth_set_allowed_threads(card, 0xffffffff, 0); - if (rc) - dev_warn(&card->gdev->dev, "The qeth device driver " - "failed to recover an error on the device\n"); - return rc; -} - /* Returns zero if the command is successfully "consumed" */ static int qeth_l3_control_event(struct qeth_card *card, struct qeth_ipa_cmd *cmd) @@ -2542,9 +2515,6 @@ struct qeth_discipline qeth_l3_discipline = { .remove = qeth_l3_remove_device, .set_online = qeth_l3_set_online, .set_offline = qeth_l3_set_offline, - .freeze = qeth_l3_pm_suspend, - .thaw = qeth_l3_pm_resume, - .restore = qeth_l3_pm_resume, .do_ioctl = qeth_l3_do_ioctl, .control_event_handler = qeth_l3_control_event, }; -- cgit v1.2.3 From c097cc9228193ac624633058737d2bfc32c8c3d3 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Thu, 27 Jun 2019 17:01:31 +0200 Subject: s390/qeth: consolidate skb RX processing in L3 driver Use napi_gro_receive() to pass up all types of packets that a L3 device may receive. 1) For proper L2 packets received by the IQD sniffer, this is the obvious thing to do. 2) For af_iucv (which doesn't provide a GRO assist), the GRO code will transparently fall back to netif_receive_skb(). So there's no need to special-case this traffic in our code. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_l3_main.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 44a602aa12ec..15351922b209 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -1312,6 +1312,15 @@ static int qeth_l3_vlan_rx_kill_vid(struct net_device *dev, static void qeth_l3_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, struct qeth_hdr *hdr) { + struct af_iucv_trans_hdr *iucv = (struct af_iucv_trans_hdr *) skb->data; + struct net_device *dev = skb->dev; + + if (IS_IQD(card) && iucv->magic == ETH_P_AF_IUCV) { + dev_hard_header(skb, dev, ETH_P_AF_IUCV, dev->dev_addr, + "FAKELL", skb->len); + return; + } + if (!(hdr->hdr.l3.flags & QETH_HDR_PASSTHRU)) { u16 prot = (hdr->hdr.l3.flags & QETH_HDR_IPV6) ? ETH_P_IPV6 : ETH_P_IP; @@ -1345,8 +1354,6 @@ static void qeth_l3_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, tg_addr, "FAKELL", skb->len); } - skb->protocol = eth_type_trans(skb, card->dev); - /* copy VLAN tag from hdr into skb */ if (!card->options.sniffer && (hdr->hdr.l3.ext_flags & (QETH_HDR_EXT_VLAN_FRAME | @@ -1363,12 +1370,10 @@ static void qeth_l3_rebuild_skb(struct qeth_card *card, struct sk_buff *skb, static int qeth_l3_process_inbound_buffer(struct qeth_card *card, int budget, int *done) { - struct net_device *dev = card->dev; int work_done = 0; struct sk_buff *skb; struct qeth_hdr *hdr; unsigned int len; - __u16 magic; *done = 0; WARN_ON_ONCE(!budget); @@ -1382,23 +1387,12 @@ static int qeth_l3_process_inbound_buffer(struct qeth_card *card, } switch (hdr->hdr.l3.id) { case QETH_HEADER_TYPE_LAYER3: - magic = *(__u16 *)skb->data; - if (IS_IQD(card) && magic == ETH_P_AF_IUCV) { - len = skb->len; - dev_hard_header(skb, dev, ETH_P_AF_IUCV, - dev->dev_addr, "FAKELL", len); - skb->protocol = eth_type_trans(skb, dev); - netif_receive_skb(skb); - } else { - qeth_l3_rebuild_skb(card, skb, hdr); - len = skb->len; - napi_gro_receive(&card->napi, skb); - } - break; + qeth_l3_rebuild_skb(card, skb, hdr); + /* fall through */ case QETH_HEADER_TYPE_LAYER2: /* for HiperSockets sniffer */ skb->protocol = eth_type_trans(skb, skb->dev); len = skb->len; - netif_receive_skb(skb); + napi_gro_receive(&card->napi, skb); break; default: dev_kfree_skb_any(skb); -- cgit v1.2.3 From 980f4568fa32736b1dec69db2cc7c947b767e52e Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Thu, 27 Jun 2019 17:01:32 +0200 Subject: s390/qeth: extract helper for route validation As follow-up to commit 0cd6783d3c7d ("s390/qeth: check dst entry before use"), consolidate the dst_check() logic into a single helper and add a wrapper around the cast type selection. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 13 +++++++++++ drivers/s390/net/qeth_l3_main.c | 49 ++++++++++++++++++----------------------- 2 files changed, 34 insertions(+), 28 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index c81d5ec26803..d354b39cdf4b 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -25,6 +25,8 @@ #include #include +#include +#include #include #include #include @@ -877,6 +879,17 @@ static inline int qeth_get_ether_cast_type(struct sk_buff *skb) return RTN_UNICAST; } +static inline struct dst_entry *qeth_dst_check_rcu(struct sk_buff *skb, int ipv) +{ + struct dst_entry *dst = skb_dst(skb); + struct rt6_info *rt; + + rt = (struct rt6_info *) dst; + if (dst) + dst = dst_check(dst, (ipv == 6) ? rt6_get_cookie(rt) : 0); + return dst; +} + static inline void qeth_rx_csum(struct qeth_card *card, struct sk_buff *skb, u8 flags) { diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 15351922b209..5bf5129ddcd4 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include @@ -1878,26 +1877,17 @@ static int qeth_l3_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) return rc; } -static int qeth_l3_get_cast_type(struct sk_buff *skb) +static int qeth_l3_get_cast_type_rcu(struct sk_buff *skb, struct dst_entry *dst, + int ipv) { - int ipv = qeth_get_ip_version(skb); struct neighbour *n = NULL; - struct dst_entry *dst; - rcu_read_lock(); - dst = skb_dst(skb); - if (dst) { - struct rt6_info *rt = (struct rt6_info *) dst; - - dst = dst_check(dst, (ipv == 6) ? rt6_get_cookie(rt) : 0); - if (dst) - n = dst_neigh_lookup_skb(dst, skb); - } + if (dst) + n = dst_neigh_lookup_skb(dst, skb); if (n) { int cast_type = n->type; - rcu_read_unlock(); neigh_release(n); if ((cast_type == RTN_BROADCAST) || (cast_type == RTN_MULTICAST) || @@ -1905,7 +1895,6 @@ static int qeth_l3_get_cast_type(struct sk_buff *skb) return cast_type; return RTN_UNICAST; } - rcu_read_unlock(); /* no neighbour (eg AF_PACKET), fall back to target's IP address ... */ switch (ipv) { @@ -1923,6 +1912,20 @@ static int qeth_l3_get_cast_type(struct sk_buff *skb) } } +static int qeth_l3_get_cast_type(struct sk_buff *skb) +{ + int ipv = qeth_get_ip_version(skb); + struct dst_entry *dst; + int cast_type; + + rcu_read_lock(); + dst = qeth_dst_check_rcu(skb, ipv); + cast_type = qeth_l3_get_cast_type_rcu(skb, dst, ipv); + rcu_read_unlock(); + + return cast_type; +} + static u8 qeth_l3_cast_type_to_flag(int cast_type) { if (cast_type == RTN_MULTICAST) @@ -1987,27 +1990,17 @@ static void qeth_l3_fill_header(struct qeth_qdio_out_q *queue, } rcu_read_lock(); - dst = skb_dst(skb); + dst = qeth_dst_check_rcu(skb, ipv); if (ipv == 4) { - struct rtable *rt; - - if (dst) - dst = dst_check(dst, 0); - rt = (struct rtable *) dst; + struct rtable *rt = (struct rtable *) dst; *((__be32 *) &hdr->hdr.l3.next_hop.ipv4.addr) = (rt) ? rt_nexthop(rt, ip_hdr(skb)->daddr) : ip_hdr(skb)->daddr; } else { /* IPv6 */ - struct rt6_info *rt; - - if (dst) { - rt = (struct rt6_info *) dst; - dst = dst_check(dst, rt6_get_cookie(rt)); - } - rt = (struct rt6_info *) dst; + struct rt6_info *rt = (struct rt6_info *) dst; if (rt && !ipv6_addr_any(&rt->rt6i_gateway)) l3_hdr->next_hop.ipv6_addr = rt->rt6i_gateway; -- cgit v1.2.3 From eca1d5c22da19abf14d27f599e787dc98b1702a3 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Thu, 27 Jun 2019 17:01:33 +0200 Subject: s390/qeth: move cast type selection into fill_header() The cast type currently gets selected in .ndo_start_xmit, and is then piped through several layers until it's stored into the HW header. Push the selection down into qeth_l?_fill_header() to (1) reduce the number of xmit-wide parameters, and (2) merge the two route validation checks into just one. Signed-off-by: Julian Wiedmann Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 5 ++--- drivers/s390/net/qeth_core_main.c | 7 +++---- drivers/s390/net/qeth_l2_main.c | 4 ++-- drivers/s390/net/qeth_l3_main.c | 43 +++++++++++++++++---------------------- 4 files changed, 26 insertions(+), 33 deletions(-) (limited to 'drivers/s390/net') diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index d354b39cdf4b..c7ee07ce3615 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -1040,11 +1040,10 @@ int qeth_stop(struct net_device *dev); int qeth_vm_request_mac(struct qeth_card *card); int qeth_xmit(struct qeth_card *card, struct sk_buff *skb, - struct qeth_qdio_out_q *queue, int ipv, int cast_type, + struct qeth_qdio_out_q *queue, int ipv, void (*fill_header)(struct qeth_qdio_out_q *queue, struct qeth_hdr *hdr, struct sk_buff *skb, - int ipv, int cast_type, - unsigned int data_len)); + int ipv, unsigned int data_len)); /* 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 3011cae00391..4d0caeebc802 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -3908,11 +3908,10 @@ static void qeth_fill_tso_ext(struct qeth_hdr_tso *hdr, } int qeth_xmit(struct qeth_card *card, struct sk_buff *skb, - struct qeth_qdio_out_q *queue, int ipv, int cast_type, + struct qeth_qdio_out_q *queue, int ipv, void (*fill_header)(struct qeth_qdio_out_q *queue, struct qeth_hdr *hdr, struct sk_buff *skb, - int ipv, int cast_type, - unsigned int data_len)) + int ipv, unsigned int data_len)) { unsigned int proto_len, hw_hdr_len; unsigned int frame_len = skb->len; @@ -3946,7 +3945,7 @@ int qeth_xmit(struct qeth_card *card, struct sk_buff *skb, data_offset = push_len + proto_len; } memset(hdr, 0, hw_hdr_len); - fill_header(queue, hdr, skb, ipv, cast_type, frame_len); + fill_header(queue, hdr, skb, ipv, frame_len); if (is_tso) qeth_fill_tso_ext((struct qeth_hdr_tso *) hdr, frame_len - proto_len, skb, proto_len); diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 4a2ff9d8aa5f..fd64bc3f4062 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -164,8 +164,9 @@ static void qeth_l2_drain_rx_mode_cache(struct qeth_card *card) static void qeth_l2_fill_header(struct qeth_qdio_out_q *queue, struct qeth_hdr *hdr, struct sk_buff *skb, - int ipv, int cast_type, unsigned int data_len) + int ipv, unsigned int data_len) { + int cast_type = qeth_get_ether_cast_type(skb); struct vlan_ethhdr *veth = vlan_eth_hdr(skb); hdr->hdr.l2.pkt_length = data_len; @@ -598,7 +599,6 @@ static netdev_tx_t qeth_l2_hard_start_xmit(struct sk_buff *skb, rc = qeth_l2_xmit_osn(card, skb, queue); else rc = qeth_xmit(card, skb, queue, qeth_get_ip_version(skb), - qeth_get_ether_cast_type(skb), qeth_l2_fill_header); if (!rc) { diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 5bf5129ddcd4..2dd99f103671 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -1939,12 +1939,13 @@ static u8 qeth_l3_cast_type_to_flag(int cast_type) static void qeth_l3_fill_header(struct qeth_qdio_out_q *queue, struct qeth_hdr *hdr, struct sk_buff *skb, - int ipv, int cast_type, unsigned int data_len) + int ipv, unsigned int data_len) { struct qeth_hdr_layer3 *l3_hdr = &hdr->hdr.l3; struct vlan_ethhdr *veth = vlan_eth_hdr(skb); struct qeth_card *card = queue->card; struct dst_entry *dst; + int cast_type; hdr->hdr.l3.length = data_len; @@ -1981,25 +1982,22 @@ static void qeth_l3_fill_header(struct qeth_qdio_out_q *queue, hdr->hdr.l3.vlan_id = ntohs(veth->h_vlan_TCI); } - l3_hdr->flags = qeth_l3_cast_type_to_flag(cast_type); - - /* OSA only: */ - if (!ipv) { - l3_hdr->flags |= QETH_HDR_PASSTHRU; - return; - } - rcu_read_lock(); dst = qeth_dst_check_rcu(skb, ipv); + if (IS_IQD(card) && skb_get_queue_mapping(skb) != QETH_IQD_MCAST_TXQ) + cast_type = RTN_UNICAST; + else + cast_type = qeth_l3_get_cast_type_rcu(skb, dst, ipv); + l3_hdr->flags |= qeth_l3_cast_type_to_flag(cast_type); + if (ipv == 4) { struct rtable *rt = (struct rtable *) dst; *((__be32 *) &hdr->hdr.l3.next_hop.ipv4.addr) = (rt) ? rt_nexthop(rt, ip_hdr(skb)->daddr) : ip_hdr(skb)->daddr; - } else { - /* IPv6 */ + } else if (ipv == 6) { struct rt6_info *rt = (struct rt6_info *) dst; if (rt && !ipv6_addr_any(&rt->rt6i_gateway)) @@ -2010,6 +2008,9 @@ static void qeth_l3_fill_header(struct qeth_qdio_out_q *queue, hdr->hdr.l3.flags |= QETH_HDR_IPV6; if (!IS_IQD(card)) hdr->hdr.l3.flags |= QETH_HDR_PASSTHRU; + } else { + /* OSA only: */ + l3_hdr->flags |= QETH_HDR_PASSTHRU; } rcu_read_unlock(); } @@ -2029,7 +2030,7 @@ static void qeth_l3_fixup_headers(struct sk_buff *skb) } static int qeth_l3_xmit(struct qeth_card *card, struct sk_buff *skb, - struct qeth_qdio_out_q *queue, int ipv, int cast_type) + struct qeth_qdio_out_q *queue, int ipv) { unsigned int hw_hdr_len; int rc; @@ -2043,7 +2044,7 @@ static int qeth_l3_xmit(struct qeth_card *card, struct sk_buff *skb, skb_pull(skb, ETH_HLEN); qeth_l3_fixup_headers(skb); - return qeth_xmit(card, skb, queue, ipv, cast_type, qeth_l3_fill_header); + return qeth_xmit(card, skb, queue, ipv, qeth_l3_fill_header); } static netdev_tx_t qeth_l3_hard_start_xmit(struct sk_buff *skb, @@ -2054,7 +2055,7 @@ static netdev_tx_t qeth_l3_hard_start_xmit(struct sk_buff *skb, int ipv = qeth_get_ip_version(skb); struct qeth_qdio_out_q *queue; int tx_bytes = skb->len; - int cast_type, rc; + int rc; if (IS_IQD(card)) { queue = card->qdio.out_qs[qeth_iqd_translate_txq(dev, txq)]; @@ -2065,24 +2066,18 @@ static netdev_tx_t qeth_l3_hard_start_xmit(struct sk_buff *skb, (card->options.cq == QETH_CQ_ENABLED && skb->protocol != htons(ETH_P_AF_IUCV))) goto tx_drop; - - if (txq == QETH_IQD_MCAST_TXQ) - cast_type = qeth_l3_get_cast_type(skb); - else - cast_type = RTN_UNICAST; } else { queue = card->qdio.out_qs[txq]; - cast_type = qeth_l3_get_cast_type(skb); } - if (cast_type == RTN_BROADCAST && !card->info.broadcast_capable) + if (!(dev->flags & IFF_BROADCAST) && + qeth_l3_get_cast_type(skb) == RTN_BROADCAST) goto tx_drop; if (ipv == 4 || IS_IQD(card)) - rc = qeth_l3_xmit(card, skb, queue, ipv, cast_type); + rc = qeth_l3_xmit(card, skb, queue, ipv); else - rc = qeth_xmit(card, skb, queue, ipv, cast_type, - qeth_l3_fill_header); + rc = qeth_xmit(card, skb, queue, ipv, qeth_l3_fill_header); if (!rc) { QETH_TXQ_STAT_INC(queue, tx_packets); -- cgit v1.2.3