Commit c2153277 authored by Julian Wiedmann's avatar Julian Wiedmann Committed by David S. Miller

s390/qeth: consolidate filling of low-level cmd length fields

The code to fill the IPA length fields is duplicated three times across
the driver:
1. qeth_send_ipa_cmd() sets IPA_CMD_LENGTH, which matches the defaults
   in the IPA_PDU_HEADER template.
2. for OSN, qeth_osn_send_ipa_cmd() bypasses this logic and inserts the
   length passed by the caller.
3. SNMP commands (that can outgrow IPA_CMD_LENGTH) have their own way
   of setting the length fields, via qeth_send_ipa_snmp_cmd().

Consolidate this into qeth_prepare_ipa_cmd(), which all originators of
IPA cmds already call during setup of their cmd. Let qeth_send_ipa_cmd()
pull the length from the cmd instead of hard-coding IPA_CMD_LENGTH.

For now, the SNMP code still needs to fix-up its length fields manually.
Signed-off-by: default avatarJulian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 84dbea46
...@@ -1000,7 +1000,8 @@ void qeth_tx_timeout(struct net_device *); ...@@ -1000,7 +1000,8 @@ void qeth_tx_timeout(struct net_device *);
void qeth_prepare_control_data(struct qeth_card *, int, void qeth_prepare_control_data(struct qeth_card *, int,
struct qeth_cmd_buffer *); struct qeth_cmd_buffer *);
void qeth_release_buffer(struct qeth_channel *, struct qeth_cmd_buffer *); 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); 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_wait_for_buffer(struct qeth_channel *);
int qeth_query_switch_attributes(struct qeth_card *card, int qeth_query_switch_attributes(struct qeth_card *card,
struct qeth_switch_info *sw_info); struct qeth_switch_info *sw_info);
......
...@@ -2815,14 +2815,20 @@ static void qeth_fill_ipacmd_header(struct qeth_card *card, ...@@ -2815,14 +2815,20 @@ static void qeth_fill_ipacmd_header(struct qeth_card *card,
cmd->hdr.prot_version = prot; cmd->hdr.prot_version = prot;
} }
void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob) 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); u8 prot_type = qeth_mpc_select_prot_type(card);
memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE); memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
memcpy(QETH_IPA_PDU_LEN_TOTAL(iob->data), &total_length, 2);
memcpy(QETH_IPA_CMD_PROT_TYPE(iob->data), &prot_type, 1); memcpy(QETH_IPA_CMD_PROT_TYPE(iob->data), &prot_type, 1);
memcpy(QETH_IPA_PDU_LEN_PDU1(iob->data), &cmd_length, 2);
memcpy(QETH_IPA_PDU_LEN_PDU2(iob->data), &cmd_length, 2);
memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data), memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
&card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH); &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
memcpy(QETH_IPA_PDU_LEN_PDU3(iob->data), &cmd_length, 2);
} }
EXPORT_SYMBOL_GPL(qeth_prepare_ipa_cmd); EXPORT_SYMBOL_GPL(qeth_prepare_ipa_cmd);
...@@ -2833,7 +2839,7 @@ struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *card, ...@@ -2833,7 +2839,7 @@ struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *card,
iob = qeth_get_buffer(&card->write); iob = qeth_get_buffer(&card->write);
if (iob) { if (iob) {
qeth_prepare_ipa_cmd(card, iob); qeth_prepare_ipa_cmd(card, iob, sizeof(struct qeth_ipa_cmd));
qeth_fill_ipacmd_header(card, __ipa_cmd(iob), ipacmd, prot); qeth_fill_ipacmd_header(card, __ipa_cmd(iob), ipacmd, prot);
} else { } else {
dev_warn(&card->gdev->dev, dev_warn(&card->gdev->dev,
...@@ -2857,11 +2863,12 @@ int qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob, ...@@ -2857,11 +2863,12 @@ int qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
unsigned long), unsigned long),
void *reply_param) void *reply_param)
{ {
u16 length;
int rc; int rc;
QETH_CARD_TEXT(card, 4, "sendipa"); QETH_CARD_TEXT(card, 4, "sendipa");
rc = qeth_send_control_data(card, IPA_CMD_LENGTH, memcpy(&length, QETH_IPA_PDU_LEN_TOTAL(iob->data), 2);
iob, reply_cb, reply_param); rc = qeth_send_control_data(card, length, iob, reply_cb, reply_param);
if (rc == -ETIME) { if (rc == -ETIME) {
qeth_clear_ipacmd_list(card); qeth_clear_ipacmd_list(card);
qeth_schedule_recovery(card); qeth_schedule_recovery(card);
...@@ -4460,27 +4467,6 @@ static int qeth_mdio_read(struct net_device *dev, int phy_id, int regnum) ...@@ -4460,27 +4467,6 @@ static int qeth_mdio_read(struct net_device *dev, int phy_id, int regnum)
return rc; return rc;
} }
static int qeth_send_ipa_snmp_cmd(struct qeth_card *card,
struct qeth_cmd_buffer *iob, int len,
int (*reply_cb)(struct qeth_card *, struct qeth_reply *,
unsigned long),
void *reply_param)
{
u16 s1, s2;
QETH_CARD_TEXT(card, 4, "sendsnmp");
/* adjust PDU length fields in IPA_PDU_HEADER */
s1 = (u32) IPA_PDU_HEADER_SIZE + len;
s2 = (u32) len;
memcpy(QETH_IPA_PDU_LEN_TOTAL(iob->data), &s1, 2);
memcpy(QETH_IPA_PDU_LEN_PDU1(iob->data), &s2, 2);
memcpy(QETH_IPA_PDU_LEN_PDU2(iob->data), &s2, 2);
memcpy(QETH_IPA_PDU_LEN_PDU3(iob->data), &s2, 2);
return qeth_send_control_data(card, IPA_PDU_HEADER_SIZE + len, iob,
reply_cb, reply_param);
}
static int qeth_snmp_command_cb(struct qeth_card *card, static int qeth_snmp_command_cb(struct qeth_card *card,
struct qeth_reply *reply, unsigned long sdata) struct qeth_reply *reply, unsigned long sdata)
{ {
...@@ -4586,10 +4572,13 @@ static int qeth_snmp_command(struct qeth_card *card, char __user *udata) ...@@ -4586,10 +4572,13 @@ static int qeth_snmp_command(struct qeth_card *card, char __user *udata)
rc = -ENOMEM; rc = -ENOMEM;
goto out; 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); cmd = __ipa_cmd(iob);
memcpy(&cmd->data.setadapterparms.data.snmp, &ureq->cmd, req_len); memcpy(&cmd->data.setadapterparms.data.snmp, &ureq->cmd, req_len);
rc = qeth_send_ipa_snmp_cmd(card, iob, QETH_SETADP_BASE_LEN + req_len, rc = qeth_send_ipa_cmd(card, iob, qeth_snmp_command_cb, &qinfo);
qeth_snmp_command_cb, (void *)&qinfo);
if (rc) if (rc)
QETH_DBF_MESSAGE(2, "SNMP command failed on device %x: (%#x)\n", QETH_DBF_MESSAGE(2, "SNMP command failed on device %x: (%#x)\n",
CARD_DEVID(card), rc); CARD_DEVID(card), rc);
......
...@@ -125,24 +125,13 @@ unsigned char DM_ACT[] = { ...@@ -125,24 +125,13 @@ unsigned char DM_ACT[] = {
unsigned char IPA_PDU_HEADER[] = { unsigned char IPA_PDU_HEADER[] = {
0x00, 0xe0, 0x00, 0x00, 0x77, 0x77, 0x77, 0x77, 0x00, 0xe0, 0x00, 0x00, 0x77, 0x77, 0x77, 0x77,
0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00,
(IPA_PDU_HEADER_SIZE+sizeof(struct qeth_ipa_cmd)) / 256,
(IPA_PDU_HEADER_SIZE+sizeof(struct qeth_ipa_cmd)) % 256,
0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0xc1, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00,
sizeof(struct qeth_ipa_cmd) / 256, 0x00, 0x00, 0x00, 0x05, 0x77, 0x77, 0x77, 0x77,
sizeof(struct qeth_ipa_cmd) % 256,
0x00,
sizeof(struct qeth_ipa_cmd) / 256,
sizeof(struct qeth_ipa_cmd) % 256,
0x05,
0x77, 0x77, 0x77, 0x77,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
sizeof(struct qeth_ipa_cmd) / 256,
sizeof(struct qeth_ipa_cmd) % 256,
0x00, 0x00, 0x00, 0x40,
}; };
struct ipa_rc_msg { struct ipa_rc_msg {
......
...@@ -21,8 +21,6 @@ ...@@ -21,8 +21,6 @@
extern unsigned char IPA_PDU_HEADER[]; extern unsigned char IPA_PDU_HEADER[];
#define QETH_IPA_CMD_DEST_ADDR(buffer) (buffer + 0x2c) #define QETH_IPA_CMD_DEST_ADDR(buffer) (buffer + 0x2c)
#define IPA_CMD_LENGTH (IPA_PDU_HEADER_SIZE + sizeof(struct qeth_ipa_cmd))
#define QETH_SEQ_NO_LENGTH 4 #define QETH_SEQ_NO_LENGTH 4
#define QETH_MPC_TOKEN_LENGTH 4 #define QETH_MPC_TOKEN_LENGTH 4
#define QETH_MCL_LENGTH 4 #define QETH_MCL_LENGTH 4
......
...@@ -1124,20 +1124,14 @@ static int qeth_osn_send_control_data(struct qeth_card *card, int len, ...@@ -1124,20 +1124,14 @@ static int qeth_osn_send_control_data(struct qeth_card *card, int len,
} }
static int qeth_osn_send_ipa_cmd(struct qeth_card *card, static int qeth_osn_send_ipa_cmd(struct qeth_card *card,
struct qeth_cmd_buffer *iob, int data_len) struct qeth_cmd_buffer *iob)
{ {
u16 s1, s2; u16 length;
QETH_CARD_TEXT(card, 4, "osndipa"); QETH_CARD_TEXT(card, 4, "osndipa");
qeth_prepare_ipa_cmd(card, iob); memcpy(&length, QETH_IPA_PDU_LEN_TOTAL(iob->data), 2);
s1 = (u16)(IPA_PDU_HEADER_SIZE + data_len); return qeth_osn_send_control_data(card, length, iob);
s2 = (u16)data_len;
memcpy(QETH_IPA_PDU_LEN_TOTAL(iob->data), &s1, 2);
memcpy(QETH_IPA_PDU_LEN_PDU1(iob->data), &s2, 2);
memcpy(QETH_IPA_PDU_LEN_PDU2(iob->data), &s2, 2);
memcpy(QETH_IPA_PDU_LEN_PDU3(iob->data), &s2, 2);
return qeth_osn_send_control_data(card, s1, iob);
} }
int qeth_osn_assist(struct net_device *dev, void *data, int data_len) int qeth_osn_assist(struct net_device *dev, void *data, int data_len)
...@@ -1154,8 +1148,9 @@ int qeth_osn_assist(struct net_device *dev, void *data, int data_len) ...@@ -1154,8 +1148,9 @@ int qeth_osn_assist(struct net_device *dev, void *data, int data_len)
if (!qeth_card_hw_is_reachable(card)) if (!qeth_card_hw_is_reachable(card))
return -ENODEV; return -ENODEV;
iob = qeth_wait_for_buffer(&card->write); iob = qeth_wait_for_buffer(&card->write);
qeth_prepare_ipa_cmd(card, iob, (u16) data_len);
memcpy(__ipa_cmd(iob), data, data_len); memcpy(__ipa_cmd(iob), data, data_len);
return qeth_osn_send_ipa_cmd(card, iob, data_len); return qeth_osn_send_ipa_cmd(card, iob);
} }
EXPORT_SYMBOL(qeth_osn_assist); EXPORT_SYMBOL(qeth_osn_assist);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment