Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5df285f6 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 's390-qeth-next'



Ursula Braun says:

====================
s390: qeth patches

yesterday I came up with 13 qeth patches. Since you have not been
happy with the 13th patch, I want to make sure that at least the
remaining 12 qeth patches can be applied to net-next. Here is the
resend of them.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents fcefa42f e48b9eaa
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -281,8 +281,6 @@ static inline int qeth_is_ipa_enabled(struct qeth_ipa_info *ipa,
#define QETH_HIGH_WATERMARK_PACK 5
#define QETH_WATERMARK_PACK_FUZZ 1

#define QETH_IP_HEADER_SIZE 40

/* large receive scatter gather copy break */
#define QETH_RX_SG_CB (PAGE_SIZE >> 1)
#define QETH_RX_PULL_LEN 256
@@ -674,8 +672,6 @@ struct qeth_card_info {
	int broadcast_capable;
	int unique_id;
	struct qeth_card_blkt blkt;
	__u32 csum_mask;
	__u32 tx_csum_mask;
	enum qeth_ipa_promisc_modes promisc_mode;
	__u32 diagass_support;
	__u32 hwtrap;
@@ -917,7 +913,6 @@ void qeth_clear_thread_running_bit(struct qeth_card *, unsigned long);
int qeth_core_hardsetup_card(struct qeth_card *);
void qeth_print_status_message(struct qeth_card *);
int qeth_init_qdio_queues(struct qeth_card *);
int qeth_send_startlan(struct qeth_card *);
int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *,
		  int (*reply_cb)
		  (struct qeth_card *, struct qeth_reply *, unsigned long),
+100 −35
Original line number Diff line number Diff line
@@ -2944,7 +2944,7 @@ int qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
}
EXPORT_SYMBOL_GPL(qeth_send_ipa_cmd);

int qeth_send_startlan(struct qeth_card *card)
static int qeth_send_startlan(struct qeth_card *card)
{
	int rc;
	struct qeth_cmd_buffer *iob;
@@ -2957,7 +2957,6 @@ int qeth_send_startlan(struct qeth_card *card)
	rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);
	return rc;
}
EXPORT_SYMBOL_GPL(qeth_send_startlan);

static int qeth_default_setadapterparms_cb(struct qeth_card *card,
		struct qeth_reply *reply, unsigned long data)
@@ -5087,6 +5086,20 @@ int qeth_core_hardsetup_card(struct qeth_card *card)
		goto out;
	}

	rc = qeth_send_startlan(card);
	if (rc) {
		QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc);
		if (rc == IPA_RC_LAN_OFFLINE) {
			dev_warn(&card->gdev->dev,
				"The LAN is offline\n");
			card->lan_online = 0;
		} else {
			rc = -ENODEV;
			goto out;
		}
	} else
		card->lan_online = 1;

	card->options.ipa4.supported_funcs = 0;
	card->options.ipa6.supported_funcs = 0;
	card->options.adp.supported_funcs = 0;
@@ -5098,14 +5111,14 @@ int qeth_core_hardsetup_card(struct qeth_card *card)
	if (qeth_is_supported(card, IPA_SETADAPTERPARMS)) {
		rc = qeth_query_setadapterparms(card);
		if (rc < 0) {
			QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc);
			QETH_DBF_TEXT_(SETUP, 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, "7err%d", rc);
			QETH_DBF_TEXT_(SETUP, 2, "8err%d", rc);
			goto out;
		}
	}
@@ -5289,18 +5302,6 @@ int qeth_setassparms_cb(struct qeth_card *card,
		if (cmd->hdr.prot_version == QETH_PROT_IPV6)
			card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
	}
	if (cmd->data.setassparms.hdr.assist_no == IPA_INBOUND_CHECKSUM &&
	    cmd->data.setassparms.hdr.command_code == IPA_CMD_ASS_START) {
		card->info.csum_mask = cmd->data.setassparms.data.flags_32bit;
		QETH_CARD_TEXT_(card, 3, "csum:%d", card->info.csum_mask);
	}
	if (cmd->data.setassparms.hdr.assist_no == IPA_OUTBOUND_CHECKSUM &&
	    cmd->data.setassparms.hdr.command_code == IPA_CMD_ASS_START) {
		card->info.tx_csum_mask =
			cmd->data.setassparms.data.flags_32bit;
		QETH_CARD_TEXT_(card, 3, "tcsu:%d", card->info.tx_csum_mask);
	}

	return 0;
}
EXPORT_SYMBOL_GPL(qeth_setassparms_cb);
@@ -6060,23 +6061,96 @@ int qeth_core_ethtool_get_settings(struct net_device *netdev,
}
EXPORT_SYMBOL_GPL(qeth_core_ethtool_get_settings);

/* Callback to handle checksum offload command reply from OSA card.
 * Verify that required features have been enabled on the card.
 * Return error in hdr->return_code as this value is checked by caller.
 *
 * Always returns zero to indicate no further messages from the OSA card.
 */
static int qeth_ipa_checksum_run_cmd_cb(struct qeth_card *card,
					struct qeth_reply *reply,
					unsigned long data)
{
	struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
	struct qeth_checksum_cmd *chksum_cb =
				(struct qeth_checksum_cmd *)reply->param;

	QETH_CARD_TEXT(card, 4, "chkdoccb");
	if (cmd->hdr.return_code)
		return 0;

	memset(chksum_cb, 0, sizeof(*chksum_cb));
	if (cmd->data.setassparms.hdr.command_code == IPA_CMD_ASS_START) {
		chksum_cb->supported =
				cmd->data.setassparms.data.chksum.supported;
		QETH_CARD_TEXT_(card, 3, "strt:%x", chksum_cb->supported);
	}
	if (cmd->data.setassparms.hdr.command_code == IPA_CMD_ASS_ENABLE) {
		chksum_cb->supported =
				cmd->data.setassparms.data.chksum.supported;
		chksum_cb->enabled =
				cmd->data.setassparms.data.chksum.enabled;
		QETH_CARD_TEXT_(card, 3, "supp:%x", chksum_cb->supported);
		QETH_CARD_TEXT_(card, 3, "enab:%x", chksum_cb->enabled);
	}
	return 0;
}

/* Send command to OSA card and check results. */
static int qeth_ipa_checksum_run_cmd(struct qeth_card *card,
				     enum qeth_ipa_funcs ipa_func,
				     __u16 cmd_code, long data,
				     struct qeth_checksum_cmd *chksum_cb)
{
	struct qeth_cmd_buffer *iob;
	int rc = -ENOMEM;

	QETH_CARD_TEXT(card, 4, "chkdocmd");
	iob = qeth_get_setassparms_cmd(card, ipa_func, cmd_code,
				       sizeof(__u32), QETH_PROT_IPV4);
	if (iob)
		rc = qeth_send_setassparms(card, iob, sizeof(__u32), data,
					   qeth_ipa_checksum_run_cmd_cb,
					   chksum_cb);
	return rc;
}

static int qeth_send_checksum_on(struct qeth_card *card, int cstype)
{
	long rxtx_arg;
	const __u32 required_features = QETH_IPA_CHECKSUM_IP_HDR |
					QETH_IPA_CHECKSUM_UDP |
					QETH_IPA_CHECKSUM_TCP;
	struct qeth_checksum_cmd chksum_cb;
	int rc;

	rc = qeth_send_simple_setassparms(card, cstype, IPA_CMD_ASS_START, 0);
	rc = qeth_ipa_checksum_run_cmd(card, cstype, IPA_CMD_ASS_START, 0,
				       &chksum_cb);
	if (!rc) {
		if ((required_features & chksum_cb.supported) !=
		    required_features)
			rc = -EIO;
		else if (!(QETH_IPA_CHECKSUM_LP2LP & chksum_cb.supported) &&
			 cstype == IPA_INBOUND_CHECKSUM)
			dev_warn(&card->gdev->dev,
				 "Hardware checksumming is performed only if %s and its peer use different OSA Express 3 ports\n",
				 QETH_CARD_IFNAME(card));
	}
	if (rc) {
		qeth_send_simple_setassparms(card, cstype, IPA_CMD_ASS_STOP, 0);
		dev_warn(&card->gdev->dev,
			 "Starting HW checksumming for %s failed, using SW checksumming\n",
			 QETH_CARD_IFNAME(card));
		return rc;
	}
	rxtx_arg = (cstype == IPA_OUTBOUND_CHECKSUM) ? card->info.tx_csum_mask
						     : card->info.csum_mask;
	rc = qeth_send_simple_setassparms(card, cstype, IPA_CMD_ASS_ENABLE,
					  rxtx_arg);
	rc = qeth_ipa_checksum_run_cmd(card, cstype, IPA_CMD_ASS_ENABLE,
				       chksum_cb.supported, &chksum_cb);
	if (!rc) {
		if ((required_features & chksum_cb.enabled) !=
		    required_features)
			rc = -EIO;
	}
	if (rc) {
		qeth_send_simple_setassparms(card, cstype, IPA_CMD_ASS_STOP, 0);
		dev_warn(&card->gdev->dev,
			 "Enabling HW checksumming for %s failed, using SW checksumming\n",
			 QETH_CARD_IFNAME(card));
@@ -6090,19 +6164,10 @@ static int qeth_send_checksum_on(struct qeth_card *card, int cstype)

static int qeth_set_ipa_csum(struct qeth_card *card, int on, int cstype)
{
	int rc;

	if (on) {
		rc = qeth_send_checksum_on(card, cstype);
		if (rc)
			return -EIO;
	} else {
		rc = qeth_send_simple_setassparms(card, cstype,
	int rc = (on) ? qeth_send_checksum_on(card, cstype)
		      : qeth_send_simple_setassparms(card, cstype,
						     IPA_CMD_ASS_STOP, 0);
		if (rc)
			return -EIO;
	}
	return 0;
	return rc ? -EIO : 0;
}

static int qeth_set_ipa_tso(struct qeth_card *card, int on)
+17 −0
Original line number Diff line number Diff line
@@ -352,11 +352,28 @@ struct qeth_arp_query_info {
	char *udata;
};

/* IPA set assist segmentation bit definitions for receive and
 * transmit checksum offloading.
 */
enum qeth_ipa_checksum_bits {
	QETH_IPA_CHECKSUM_IP_HDR	= 0x0002,
	QETH_IPA_CHECKSUM_UDP		= 0x0008,
	QETH_IPA_CHECKSUM_TCP		= 0x0010,
	QETH_IPA_CHECKSUM_LP2LP		= 0x0020
};

/* IPA Assist checksum offload reply layout. */
struct qeth_checksum_cmd {
	__u32 supported;
	__u32 enabled;
} __packed;

/* SETASSPARMS IPA Command: */
struct qeth_ipacmd_setassparms {
	struct qeth_ipacmd_setassparms_hdr hdr;
	union {
		__u32 flags_32bit;
		struct qeth_checksum_cmd chksum;
		struct qeth_arp_cache_entry add_arp_entry;
		struct qeth_arp_query_data query_arp;
		__u8 ip[16];
+79 −110
Original line number Diff line number Diff line
@@ -27,9 +27,6 @@

static int qeth_l2_set_offline(struct ccwgroup_device *);
static int qeth_l2_stop(struct net_device *);
static int qeth_l2_send_delmac(struct qeth_card *, __u8 *);
static int qeth_l2_send_setdelmac(struct qeth_card *, __u8 *,
			   enum qeth_ipa_cmds);
static void qeth_l2_set_rx_mode(struct net_device *);
static int qeth_l2_recover(void *);
static void qeth_bridgeport_query_support(struct qeth_card *card);
@@ -165,13 +162,70 @@ static int qeth_setdel_makerc(struct qeth_card *card, int retcode)
	return rc;
}

static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac,
			   enum qeth_ipa_cmds ipacmd)
{
	struct qeth_ipa_cmd *cmd;
	struct qeth_cmd_buffer *iob;

	QETH_CARD_TEXT(card, 2, "L2sdmac");
	iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
	if (!iob)
		return -ENOMEM;
	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
	cmd->data.setdelmac.mac_length = OSA_ADDR_LEN;
	memcpy(&cmd->data.setdelmac.mac, mac, OSA_ADDR_LEN);
	return qeth_setdel_makerc(card, qeth_send_ipa_cmd(card, iob,
					NULL, NULL));
}

static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac)
{
	int rc;

	QETH_CARD_TEXT(card, 2, "L2Setmac");
	rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC);
	if (rc == 0) {
		card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;
		memcpy(card->dev->dev_addr, mac, OSA_ADDR_LEN);
		dev_info(&card->gdev->dev,
			"MAC address %pM successfully registered on device %s\n",
			card->dev->dev_addr, card->dev->name);
	} else {
		card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
		switch (rc) {
		case -EEXIST:
			dev_warn(&card->gdev->dev,
				"MAC address %pM already exists\n", mac);
			break;
		case -EPERM:
			dev_warn(&card->gdev->dev,
				"MAC address %pM is not authorized\n", mac);
			break;
		}
	}
	return rc;
}

static int qeth_l2_send_delmac(struct qeth_card *card, __u8 *mac)
{
	int rc;

	QETH_CARD_TEXT(card, 2, "L2Delmac");
	if (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))
		return 0;
	rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_DELVMAC);
	if (rc == 0)
		card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
	return rc;
}

static int qeth_l2_send_setgroupmac(struct qeth_card *card, __u8 *mac)
{
	int rc;

	QETH_CARD_TEXT(card, 2, "L2Sgmac");
	rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac,
					IPA_CMD_SETGMAC));
	rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETGMAC);
	if (rc == -EEXIST)
		QETH_DBF_MESSAGE(2, "Group MAC %pM already existing on %s\n",
			mac, QETH_CARD_IFNAME(card));
@@ -186,8 +240,7 @@ static int qeth_l2_send_delgroupmac(struct qeth_card *card, __u8 *mac)
	int rc;

	QETH_CARD_TEXT(card, 2, "L2Dgmac");
	rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac,
					IPA_CMD_DELGMAC));
	rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_DELGMAC);
	if (rc)
		QETH_DBF_MESSAGE(2,
			"Could not delete group MAC %pM on %s: %d\n",
@@ -195,28 +248,27 @@ static int qeth_l2_send_delgroupmac(struct qeth_card *card, __u8 *mac)
	return rc;
}

static inline u32 qeth_l2_mac_hash(const u8 *addr)
static int qeth_l2_write_mac(struct qeth_card *card, struct qeth_mac *mac)
{
	return get_unaligned((u32 *)(&addr[2]));
	if (mac->is_uc) {
		return qeth_l2_send_setdelmac(card, mac->mac_addr,
						IPA_CMD_SETVMAC);
	} else {
		return qeth_l2_send_setgroupmac(card, mac->mac_addr);
	}
}

static int qeth_l2_write_mac(struct qeth_card *card, struct qeth_mac *mac)
static int qeth_l2_remove_mac(struct qeth_card *card, struct qeth_mac *mac)
{

	int rc;

	if (mac->is_uc) {
		rc = qeth_setdel_makerc(card,
				qeth_l2_send_setdelmac(card, mac->mac_addr,
						IPA_CMD_SETVMAC));
		return qeth_l2_send_setdelmac(card, mac->mac_addr,
						IPA_CMD_DELVMAC);
	} else {
		rc = qeth_setdel_makerc(card,
				qeth_l2_send_setgroupmac(card, mac->mac_addr));
		return qeth_l2_send_delgroupmac(card, mac->mac_addr);
	}
	return rc;
}

static void qeth_l2_del_all_macs(struct qeth_card *card, int del)
static void qeth_l2_del_all_macs(struct qeth_card *card)
{
	struct qeth_mac *mac;
	struct hlist_node *tmp;
@@ -224,19 +276,17 @@ static void qeth_l2_del_all_macs(struct qeth_card *card, int del)

	spin_lock_bh(&card->mclock);
	hash_for_each_safe(card->mac_htable, i, tmp, mac, hnode) {
		if (del) {
			if (mac->is_uc)
				qeth_l2_send_setdelmac(card, mac->mac_addr,
						IPA_CMD_DELVMAC);
			else
				qeth_l2_send_delgroupmac(card, mac->mac_addr);
		}
		hash_del(&mac->hnode);
		kfree(mac);
	}
	spin_unlock_bh(&card->mclock);
}

static inline u32 qeth_l2_mac_hash(const u8 *addr)
{
	return get_unaligned((u32 *)(&addr[2]));
}

static inline int qeth_l2_get_cast_type(struct qeth_card *card,
			struct sk_buff *skb)
{
@@ -425,7 +475,7 @@ static void qeth_l2_stop_card(struct qeth_card *card, int recovery_mode)
		card->state = CARD_STATE_SOFTSETUP;
	}
	if (card->state == CARD_STATE_SOFTSETUP) {
		qeth_l2_del_all_macs(card, 0);
		qeth_l2_del_all_macs(card);
		qeth_clear_ipacmd_list(card);
		card->state = CARD_STATE_HARDSETUP;
	}
@@ -577,65 +627,6 @@ static int qeth_l2_poll(struct napi_struct *napi, int budget)
	return work_done;
}

static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac,
			   enum qeth_ipa_cmds ipacmd)
{
	struct qeth_ipa_cmd *cmd;
	struct qeth_cmd_buffer *iob;

	QETH_CARD_TEXT(card, 2, "L2sdmac");
	iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
	if (!iob)
		return -ENOMEM;
	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
	cmd->data.setdelmac.mac_length = OSA_ADDR_LEN;
	memcpy(&cmd->data.setdelmac.mac, mac, OSA_ADDR_LEN);
	return qeth_send_ipa_cmd(card, iob, NULL, NULL);
}

static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac)
{
	int rc;

	QETH_CARD_TEXT(card, 2, "L2Setmac");
	rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac,
					IPA_CMD_SETVMAC));
	if (rc == 0) {
		card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;
		memcpy(card->dev->dev_addr, mac, OSA_ADDR_LEN);
		dev_info(&card->gdev->dev,
			"MAC address %pM successfully registered on device %s\n",
			card->dev->dev_addr, card->dev->name);
	} else {
		card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
		switch (rc) {
		case -EEXIST:
			dev_warn(&card->gdev->dev,
				"MAC address %pM already exists\n", mac);
			break;
		case -EPERM:
			dev_warn(&card->gdev->dev,
				"MAC address %pM is not authorized\n", mac);
			break;
		}
	}
	return rc;
}

static int qeth_l2_send_delmac(struct qeth_card *card, __u8 *mac)
{
	int rc;

	QETH_CARD_TEXT(card, 2, "L2Delmac");
	if (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))
		return 0;
	rc = qeth_setdel_makerc(card, qeth_l2_send_setdelmac(card, mac,
					IPA_CMD_DELVMAC));
	if (rc == 0)
		card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
	return rc;
}

static int qeth_l2_request_initial_mac(struct qeth_card *card)
{
	int rc = 0;
@@ -794,14 +785,7 @@ static void qeth_l2_set_rx_mode(struct net_device *dev)

	hash_for_each_safe(card->mac_htable, i, tmp, mac, hnode) {
		if (mac->disp_flag == QETH_DISP_ADDR_DELETE) {
			if (!mac->is_uc)
				rc = qeth_l2_send_delgroupmac(card,
						mac->mac_addr);
			else {
				rc = qeth_l2_send_setdelmac(card, mac->mac_addr,
						IPA_CMD_DELVMAC);
			}

			qeth_l2_remove_mac(card, mac);
			hash_del(&mac->hnode);
			kfree(mac);

@@ -1193,21 +1177,6 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
	/* softsetup */
	QETH_DBF_TEXT(SETUP, 2, "softsetp");

	rc = qeth_send_startlan(card);
	if (rc) {
		QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
		if (rc == 0xe080) {
			dev_warn(&card->gdev->dev,
				"The LAN is offline\n");
			card->lan_online = 0;
			goto contin;
		}
		rc = -ENODEV;
		goto out_remove;
	} else
		card->lan_online = 1;

contin:
	if ((card->info.type == QETH_CARD_TYPE_OSD) ||
	    (card->info.type == QETH_CARD_TYPE_OSX)) {
		rc = qeth_l2_start_ipassists(card);
+0 −15
Original line number Diff line number Diff line
@@ -3227,21 +3227,6 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
	/* softsetup */
	QETH_DBF_TEXT(SETUP, 2, "softsetp");

	rc = qeth_send_startlan(card);
	if (rc) {
		QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc);
		if (rc == 0xe080) {
			dev_warn(&card->gdev->dev,
				"The LAN is offline\n");
			card->lan_online = 0;
			goto contin;
		}
		rc = -ENODEV;
		goto out_remove;
	} else
		card->lan_online = 1;

contin:
	rc = qeth_l3_setadapter_parms(card);
	if (rc)
		QETH_DBF_TEXT_(SETUP, 2, "2err%04x", rc);
Loading