Commit 37ac5db6 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 's390-net-next'



Julian Wiedmann says:

====================
s390/net: updates 2018-09-26

please apply one more series of cleanups and small improvements for qeth
to net-next. Note that one patch needs to touch both af_iucv and qeth, in
order to untangle their receive paths.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 4b1bd697 91cc98f5
Loading
Loading
Loading
Loading
+12 −9
Original line number Diff line number Diff line
@@ -582,7 +582,8 @@ struct qeth_cmd_buffer {
	struct qeth_channel *channel;
	unsigned char *data;
	int rc;
	void (*callback) (struct qeth_channel *, struct qeth_cmd_buffer *);
	void (*callback)(struct qeth_card *card, struct qeth_channel *channel,
			 struct qeth_cmd_buffer *iob);
};

static inline struct qeth_ipa_cmd *__ipa_cmd(struct qeth_cmd_buffer *iob)
@@ -671,6 +672,12 @@ struct qeth_card_info {
	__u32 hwtrap;
};

enum qeth_discipline_id {
	QETH_DISCIPLINE_UNDETERMINED = -1,
	QETH_DISCIPLINE_LAYER3 = 0,
	QETH_DISCIPLINE_LAYER2 = 1,
};

struct qeth_card_options {
	struct qeth_routing_info route4;
	struct qeth_ipa_info ipa4;
@@ -680,7 +687,7 @@ struct qeth_card_options {
	struct qeth_sbp_info sbp; /* SETBRIDGEPORT options */
	struct qeth_vnicc_info vnicc; /* VNICC options */
	int fake_broadcast;
	int layer2;
	enum qeth_discipline_id layer;
	int performance_stats;
	int rx_sg_cb;
	enum qeth_ipa_isolation_modes isolation;
@@ -690,6 +697,9 @@ struct qeth_card_options {
	char hsuid[9];
};

#define	IS_LAYER2(card)	((card)->options.layer == QETH_DISCIPLINE_LAYER2)
#define	IS_LAYER3(card)	((card)->options.layer == QETH_DISCIPLINE_LAYER3)

/*
 * thread bits for qeth_card thread masks
 */
@@ -702,12 +712,6 @@ struct qeth_osn_info {
	int (*data_cb)(struct sk_buff *skb);
};

enum qeth_discipline_id {
	QETH_DISCIPLINE_UNDETERMINED = -1,
	QETH_DISCIPLINE_LAYER3 = 0,
	QETH_DISCIPLINE_LAYER2 = 1,
};

struct qeth_discipline {
	const struct device_type *devtype;
	int (*process_rx_buffer)(struct qeth_card *card, int budget, int *done);
@@ -759,7 +763,6 @@ struct qeth_switch_info {
struct qeth_card {
	struct list_head list;
	enum qeth_card_states state;
	int lan_online;
	spinlock_t lock;
	struct ccwgroup_device *gdev;
	struct qeth_channel read;
+155 −218
Original line number Diff line number Diff line
@@ -62,10 +62,10 @@ static struct kmem_cache *qeth_qdio_outbuf_cache;

static struct device *qeth_core_root_dev;
static struct lock_class_key qdio_out_skb_queue_key;
static struct mutex qeth_mod_mutex;

static void qeth_send_control_data_cb(struct qeth_channel *,
			struct qeth_cmd_buffer *);
static void qeth_send_control_data_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 *);
@@ -626,52 +626,39 @@ static void qeth_issue_ipa_msg(struct qeth_ipa_cmd *cmd, int rc,
}

static struct qeth_ipa_cmd *qeth_check_ipa_data(struct qeth_card *card,
		struct qeth_cmd_buffer *iob)
						struct qeth_ipa_cmd *cmd)
{
	struct qeth_ipa_cmd *cmd = NULL;

	QETH_CARD_TEXT(card, 5, "chkipad");
	if (IS_IPA(iob->data)) {
		cmd = (struct qeth_ipa_cmd *) PDU_ENCAPSULATION(iob->data);

	if (IS_IPA_REPLY(cmd)) {
		if (cmd->hdr.command != IPA_CMD_SETCCID &&
		    cmd->hdr.command != IPA_CMD_DELCCID &&
		    cmd->hdr.command != IPA_CMD_MODCCID &&
		    cmd->hdr.command != IPA_CMD_SET_DIAG_ASS)
				qeth_issue_ipa_msg(cmd,
						cmd->hdr.return_code, card);
			qeth_issue_ipa_msg(cmd, cmd->hdr.return_code, card);
		return cmd;
		} else {
	}

	/* handle unsolicited event: */
	switch (cmd->hdr.command) {
	case IPA_CMD_STOPLAN:
				if (cmd->hdr.return_code ==
						IPA_RC_VEPA_TO_VEB_TRANSITION) {
		if (cmd->hdr.return_code == IPA_RC_VEPA_TO_VEB_TRANSITION) {
			dev_err(&card->gdev->dev,
					   "Interface %s is down because the "
					   "adjacent port is no longer in "
					   "reflective relay mode\n",
				"Interface %s is down because the adjacent port is no longer in reflective relay mode\n",
				QETH_CARD_IFNAME(card));
			qeth_close_dev(card);
		} else {
			dev_warn(&card->gdev->dev,
					   "The link for interface %s on CHPID"
					   " 0x%X failed\n",
					   QETH_CARD_IFNAME(card),
					   card->info.chpid);
					qeth_issue_ipa_msg(cmd,
						cmd->hdr.return_code, card);
				}
				card->lan_online = 0;
				 "The link for interface %s on CHPID 0x%X failed\n",
				 QETH_CARD_IFNAME(card), card->info.chpid);
			qeth_issue_ipa_msg(cmd, cmd->hdr.return_code, card);
			netif_carrier_off(card->dev);
		}
		return NULL;
	case IPA_CMD_STARTLAN:
		dev_info(&card->gdev->dev,
					   "The link for %s on CHPID 0x%X has"
					   " been restored\n",
					   QETH_CARD_IFNAME(card),
					   card->info.chpid);
				netif_carrier_on(card->dev);
				card->lan_online = 1;
			 "The link for %s on CHPID 0x%X has been restored\n",
			 QETH_CARD_IFNAME(card), card->info.chpid);
		if (card->info.hwtrap)
			card->info.hwtrap = 2;
		qeth_schedule_recovery(card);
@@ -679,28 +666,22 @@ static struct qeth_ipa_cmd *qeth_check_ipa_data(struct qeth_card *card,
	case IPA_CMD_SETBRIDGEPORT_IQD:
	case IPA_CMD_SETBRIDGEPORT_OSA:
	case IPA_CMD_ADDRESS_CHANGE_NOTIF:
				if (card->discipline->control_event_handler
								(card, cmd))
		if (card->discipline->control_event_handler(card, cmd))
			return cmd;
				else
		return NULL;
	case IPA_CMD_MODCCID:
		return cmd;
	case IPA_CMD_REGISTER_LOCAL_ADDR:
		QETH_CARD_TEXT(card, 3, "irla");
				break;
		return NULL;
	case IPA_CMD_UNREGISTER_LOCAL_ADDR:
		QETH_CARD_TEXT(card, 3, "urla");
				break;
		return NULL;
	default:
				QETH_DBF_MESSAGE(2, "Received data is IPA "
					   "but not a reply!\n");
				break;
			}
		}
	}
		QETH_DBF_MESSAGE(2, "Received data is IPA but not a reply!\n");
		return cmd;
	}
}

void qeth_clear_ipacmd_list(struct qeth_card *card)
{
@@ -746,18 +727,10 @@ static int qeth_check_idx_response(struct qeth_card *card,
	return 0;
}

static struct qeth_card *CARD_FROM_CDEV(struct ccw_device *cdev)
{
	struct qeth_card *card = dev_get_drvdata(&((struct ccwgroup_device *)
		dev_get_drvdata(&cdev->dev))->dev);
	return card;
}

static struct qeth_cmd_buffer *__qeth_get_buffer(struct qeth_channel *channel)
{
	__u8 index;

	QETH_CARD_TEXT(CARD_FROM_CDEV(channel->ccwdev), 6, "getbuff");
	index = channel->io_buf_no;
	do {
		if (channel->iob[index].state == BUF_STATE_FREE) {
@@ -778,7 +751,6 @@ void qeth_release_buffer(struct qeth_channel *channel,
{
	unsigned long flags;

	QETH_CARD_TEXT(CARD_FROM_CDEV(channel->ccwdev), 6, "relbuff");
	spin_lock_irqsave(&channel->iob_lock, flags);
	iob->state = BUF_STATE_FREE;
	iob->callback = qeth_send_control_data_cb;
@@ -788,6 +760,13 @@ 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);
}

static struct qeth_cmd_buffer *qeth_get_buffer(struct qeth_channel *channel)
{
	struct qeth_cmd_buffer *buffer = NULL;
@@ -818,17 +797,16 @@ void qeth_clear_cmd_buffers(struct qeth_channel *channel)
}
EXPORT_SYMBOL_GPL(qeth_clear_cmd_buffers);

static void qeth_send_control_data_cb(struct qeth_channel *channel,
static void qeth_send_control_data_cb(struct qeth_card *card,
				      struct qeth_channel *channel,
				      struct qeth_cmd_buffer *iob)
{
	struct qeth_card *card;
	struct qeth_ipa_cmd *cmd = NULL;
	struct qeth_reply *reply, *r;
	struct qeth_ipa_cmd *cmd;
	unsigned long flags;
	int keep_reply;
	int rc = 0;

	card = CARD_FROM_CDEV(channel->ccwdev);
	QETH_CARD_TEXT(card, 4, "sndctlcb");
	rc = qeth_check_idx_response(card, iob->data);
	switch (rc) {
@@ -842,17 +820,21 @@ static void qeth_send_control_data_cb(struct qeth_channel *channel,
		goto out;
	}

	cmd = qeth_check_ipa_data(card, iob);
	if ((cmd == NULL) && (card->state != CARD_STATE_DOWN))
	if (IS_IPA(iob->data)) {
		cmd = (struct qeth_ipa_cmd *) PDU_ENCAPSULATION(iob->data);
		cmd = qeth_check_ipa_data(card, cmd);
		if (!cmd)
			goto out;
	/*in case of OSN : check if cmd is set */
	if (card->info.type == QETH_CARD_TYPE_OSN &&
	    cmd &&
	    cmd->hdr.command != IPA_CMD_STARTLAN &&
	    card->osn_info.assist_cb != NULL) {
		if (IS_OSN(card) && card->osn_info.assist_cb &&
		    cmd->hdr.command != IPA_CMD_STARTLAN) {
			card->osn_info.assist_cb(card->dev, cmd);
			goto out;
		}
	} else {
		/* non-IPA commands should only flow during initialization */
		if (card->state != CARD_STATE_DOWN)
			goto out;
	}

	spin_lock_irqsave(&card->lock, flags);
	list_for_each_entry_safe(reply, r, &card->cmd_waiter_list, list) {
@@ -974,16 +956,15 @@ void qeth_schedule_recovery(struct qeth_card *card)
}
EXPORT_SYMBOL_GPL(qeth_schedule_recovery);

static int qeth_get_problem(struct ccw_device *cdev, struct irb *irb)
static int qeth_get_problem(struct qeth_card *card, struct ccw_device *cdev,
			    struct irb *irb)
{
	int dstat, cstat;
	char *sense;
	struct qeth_card *card;

	sense = (char *) irb->ecw;
	cstat = irb->scsw.cmd.cstat;
	dstat = irb->scsw.cmd.dstat;
	card = CARD_FROM_CDEV(cdev);

	if (cstat & (SCHN_STAT_CHN_CTRL_CHK | SCHN_STAT_INTF_CTRL_CHK |
		     SCHN_STAT_CHN_DATA_CHK | SCHN_STAT_CHAIN_CHECK |
@@ -1023,14 +1004,11 @@ static int qeth_get_problem(struct ccw_device *cdev, struct irb *irb)
	return 0;
}

static long __qeth_check_irb_error(struct ccw_device *cdev,
		unsigned long intparm, struct irb *irb)
static long qeth_check_irb_error(struct qeth_card *card,
				 struct ccw_device *cdev, unsigned long intparm,
				 struct irb *irb)
{
	struct qeth_card *card;

	card = CARD_FROM_CDEV(cdev);

	if (!card || !IS_ERR(irb))
	if (!IS_ERR(irb))
		return 0;

	switch (PTR_ERR(irb)) {
@@ -1067,10 +1045,13 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm,
	int rc;
	int cstat, dstat;
	struct qeth_cmd_buffer *iob = NULL;
	struct ccwgroup_device *gdev;
	struct qeth_channel *channel;
	struct qeth_card *card;

	card = CARD_FROM_CDEV(cdev);
	/* while we hold the ccwdev lock, this stays valid: */
	gdev = dev_get_drvdata(&cdev->dev);
	card = dev_get_drvdata(&gdev->dev);
	if (!card)
		return;

@@ -1090,7 +1071,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);

	if (__qeth_check_irb_error(cdev, intparm, irb)) {
	if (qeth_check_irb_error(card, cdev, intparm, irb)) {
		/* IO was terminated, free its resources. */
		if (iob)
			qeth_release_buffer(iob->channel, iob);
@@ -1145,7 +1126,7 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm,
			channel->state = CH_STATE_DOWN;
			goto out;
		}
		rc = qeth_get_problem(cdev, irb);
		rc = qeth_get_problem(card, cdev, irb);
		if (rc) {
			card->read_or_write_problem = 1;
			qeth_clear_ipacmd_list(card);
@@ -1165,7 +1146,7 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm,
		__qeth_issue_next_read(card);

	if (iob && iob->callback)
		iob->callback(iob->channel, iob);
		iob->callback(card, iob->channel, iob);

out:
	wake_up(&card->wait_q);
@@ -1178,54 +1159,23 @@ static void qeth_notify_skbs(struct qeth_qdio_out_q *q,
{
	struct sk_buff *skb;

	if (skb_queue_empty(&buf->skb_list))
		goto out;
	skb = skb_peek(&buf->skb_list);
	while (skb) {
	skb_queue_walk(&buf->skb_list, skb) {
		QETH_CARD_TEXT_(q->card, 5, "skbn%d", notification);
		QETH_CARD_TEXT_(q->card, 5, "%lx", (long) skb);
		if (be16_to_cpu(skb->protocol) == ETH_P_AF_IUCV) {
			if (skb->sk) {
				struct iucv_sock *iucv = iucv_sk(skb->sk);
				iucv->sk_txnotify(skb, notification);
		if (skb->protocol == htons(ETH_P_AF_IUCV) && skb->sk)
			iucv_sk(skb->sk)->sk_txnotify(skb, notification);
	}
}
		if (skb_queue_is_last(&buf->skb_list, skb))
			skb = NULL;
		else
			skb = skb_queue_next(&buf->skb_list, skb);
	}
out:
	return;
}

static void qeth_release_skbs(struct qeth_qdio_out_buffer *buf)
{
	struct sk_buff *skb;
	struct iucv_sock *iucv;
	int notify_general_error = 0;

	if (atomic_read(&buf->state) == QETH_QDIO_BUF_PENDING)
		notify_general_error = 1;

	/* release may never happen from within CQ tasklet scope */
	WARN_ON_ONCE(atomic_read(&buf->state) == QETH_QDIO_BUF_IN_CQ);

	skb = skb_dequeue(&buf->skb_list);
	while (skb) {
		QETH_CARD_TEXT(buf->q->card, 5, "skbr");
		QETH_CARD_TEXT_(buf->q->card, 5, "%lx", (long) skb);
		if (notify_general_error &&
		    be16_to_cpu(skb->protocol) == ETH_P_AF_IUCV) {
			if (skb->sk) {
				iucv = iucv_sk(skb->sk);
				iucv->sk_txnotify(skb, TX_NOTIFY_GENERALERROR);
			}
		}
		refcount_dec(&skb->users);
		dev_kfree_skb_any(skb);
		skb = skb_dequeue(&buf->skb_list);
	}
	if (atomic_read(&buf->state) == QETH_QDIO_BUF_PENDING)
		qeth_notify_skbs(buf->q, buf, TX_NOTIFY_GENERALERROR);

	__skb_queue_purge(&buf->skb_list);
}

static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
@@ -1429,6 +1379,7 @@ static void qeth_set_initial_options(struct qeth_card *card)
	card->options.rx_sg_cb = QETH_RX_SG_CB;
	card->options.isolation = ISOLATION_MODE_NONE;
	card->options.cq = QETH_CQ_DISABLED;
	card->options.layer = QETH_DISCIPLINE_UNDETERMINED;
}

static int qeth_do_start_thread(struct qeth_card *card, unsigned long thread)
@@ -1513,6 +1464,7 @@ static struct qeth_card *qeth_alloc_card(struct ccwgroup_device *gdev)
	QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));

	card->gdev = gdev;
	dev_set_drvdata(&gdev->dev, card);
	CARD_RDEV(card) = gdev->cdev[0];
	CARD_WDEV(card) = gdev->cdev[1];
	CARD_DDEV(card) = gdev->cdev[2];
@@ -1522,7 +1474,6 @@ static struct qeth_card *qeth_alloc_card(struct ccwgroup_device *gdev)
		goto out_channel;
	if (qeth_setup_channel(&card->data, false))
		goto out_data;
	card->options.layer2 = -1;
	card->qeth_service_level.seq_print = qeth_core_sl_print;
	register_service_level(&card->qeth_service_level);
	return card;
@@ -1532,17 +1483,17 @@ out_data:
out_channel:
	qeth_clean_channel(&card->read);
out_ip:
	dev_set_drvdata(&gdev->dev, NULL);
	kfree(card);
out:
	return NULL;
}

static int qeth_clear_channel(struct qeth_channel *channel)
static int qeth_clear_channel(struct qeth_card *card,
			      struct qeth_channel *channel)
{
	struct qeth_card *card;
	int rc;

	card = CARD_FROM_CDEV(channel->ccwdev);
	QETH_CARD_TEXT(card, 3, "clearch");
	spin_lock_irq(get_ccwdev_lock(channel->ccwdev));
	rc = ccw_device_clear(channel->ccwdev, QETH_CLEAR_CHANNEL_PARM);
@@ -1560,12 +1511,11 @@ static int qeth_clear_channel(struct qeth_channel *channel)
	return 0;
}

static int qeth_halt_channel(struct qeth_channel *channel)
static int qeth_halt_channel(struct qeth_card *card,
			     struct qeth_channel *channel)
{
	struct qeth_card *card;
	int rc;

	card = CARD_FROM_CDEV(channel->ccwdev);
	QETH_CARD_TEXT(card, 3, "haltch");
	spin_lock_irq(get_ccwdev_lock(channel->ccwdev));
	rc = ccw_device_halt(channel->ccwdev, QETH_HALT_CHANNEL_PARM);
@@ -1587,9 +1537,9 @@ static int qeth_halt_channels(struct qeth_card *card)
	int rc1 = 0, rc2 = 0, rc3 = 0;

	QETH_CARD_TEXT(card, 3, "haltchs");
	rc1 = qeth_halt_channel(&card->read);
	rc2 = qeth_halt_channel(&card->write);
	rc3 = qeth_halt_channel(&card->data);
	rc1 = qeth_halt_channel(card, &card->read);
	rc2 = qeth_halt_channel(card, &card->write);
	rc3 = qeth_halt_channel(card, &card->data);
	if (rc1)
		return rc1;
	if (rc2)
@@ -1602,9 +1552,9 @@ static int qeth_clear_channels(struct qeth_card *card)
	int rc1 = 0, rc2 = 0, rc3 = 0;

	QETH_CARD_TEXT(card, 3, "clearchs");
	rc1 = qeth_clear_channel(&card->read);
	rc2 = qeth_clear_channel(&card->write);
	rc3 = qeth_clear_channel(&card->data);
	rc1 = qeth_clear_channel(card, &card->read);
	rc2 = qeth_clear_channel(card, &card->write);
	rc3 = qeth_clear_channel(card, &card->data);
	if (rc1)
		return rc1;
	if (rc2)
@@ -1833,20 +1783,20 @@ static void qeth_init_func_level(struct qeth_card *card)
	}
}

static int qeth_idx_activate_get_answer(struct qeth_channel *channel,
		void (*idx_reply_cb)(struct qeth_channel *,
static int qeth_idx_activate_get_answer(struct qeth_card *card,
					struct qeth_channel *channel,
					void (*reply_cb)(struct qeth_card *,
							 struct qeth_channel *,
							 struct qeth_cmd_buffer *))
{
	struct qeth_cmd_buffer *iob;
	int rc;
	struct qeth_card *card;

	QETH_DBF_TEXT(SETUP, 2, "idxanswr");
	card = CARD_FROM_CDEV(channel->ccwdev);
	iob = qeth_get_buffer(channel);
	if (!iob)
		return -ENOMEM;
	iob->callback = idx_reply_cb;
	iob->callback = reply_cb;
	qeth_setup_ccw(channel->ccw, CCW_CMD_READ, QETH_BUFSIZE, iob->data);

	wait_event(card->wait_q,
@@ -1876,25 +1826,24 @@ static int qeth_idx_activate_get_answer(struct qeth_channel *channel,
	return rc;
}

static int qeth_idx_activate_channel(struct qeth_channel *channel,
		void (*idx_reply_cb)(struct qeth_channel *,
static int qeth_idx_activate_channel(struct qeth_card *card,
				     struct qeth_channel *channel,
				     void (*reply_cb)(struct qeth_card *,
						      struct qeth_channel *,
						      struct qeth_cmd_buffer *))
{
	struct qeth_card *card;
	struct qeth_cmd_buffer *iob;
	__u16 temp;
	__u8 tmp;
	int rc;
	struct ccw_dev_id temp_devid;

	card = CARD_FROM_CDEV(channel->ccwdev);

	QETH_DBF_TEXT(SETUP, 2, "idxactch");

	iob = qeth_get_buffer(channel);
	if (!iob)
		return -ENOMEM;
	iob->callback = idx_reply_cb;
	iob->callback = reply_cb;
	qeth_setup_ccw(channel->ccw, CCW_CMD_WRITE, IDX_ACTIVATE_SIZE,
		       iob->data);
	if (channel == &card->write) {
@@ -1946,7 +1895,7 @@ static int qeth_idx_activate_channel(struct qeth_channel *channel,
		QETH_DBF_TEXT_(SETUP, 2, "2err%d", -ETIME);
		return -ETIME;
	}
	return qeth_idx_activate_get_answer(channel, idx_reply_cb);
	return qeth_idx_activate_get_answer(card, channel, reply_cb);
}

static int qeth_peer_func_level(int level)
@@ -1958,10 +1907,10 @@ static int qeth_peer_func_level(int level)
	return level;
}

static void qeth_idx_write_cb(struct qeth_channel *channel,
static void qeth_idx_write_cb(struct qeth_card *card,
			      struct qeth_channel *channel,
			      struct qeth_cmd_buffer *iob)
{
	struct qeth_card *card;
	__u16 temp;

	QETH_DBF_TEXT(SETUP , 2, "idxwrcb");
@@ -1970,7 +1919,6 @@ static void qeth_idx_write_cb(struct qeth_channel *channel,
		channel->state = CH_STATE_ACTIVATING;
		goto out;
	}
	card = CARD_FROM_CDEV(channel->ccwdev);

	if (!(QETH_IS_IDX_ACT_POS_REPLY(iob->data))) {
		if (QETH_IDX_ACT_CAUSE_CODE(iob->data) == QETH_IDX_ACT_ERR_EXCL)
@@ -1996,10 +1944,10 @@ out:
	qeth_release_buffer(channel, iob);
}

static void qeth_idx_read_cb(struct qeth_channel *channel,
static void qeth_idx_read_cb(struct qeth_card *card,
			     struct qeth_channel *channel,
			     struct qeth_cmd_buffer *iob)
{
	struct qeth_card *card;
	__u16 temp;

	QETH_DBF_TEXT(SETUP , 2, "idxrdcb");
@@ -2008,7 +1956,6 @@ static void qeth_idx_read_cb(struct qeth_channel *channel,
		goto out;
	}

	card = CARD_FROM_CDEV(channel->ccwdev);
	if (qeth_check_idx_response(card, iob->data))
			goto out;

@@ -2057,7 +2004,7 @@ void qeth_prepare_control_data(struct qeth_card *card, int len,
		struct qeth_cmd_buffer *iob)
{
	qeth_setup_ccw(iob->channel->ccw, CCW_CMD_WRITE, len, iob->data);
	iob->callback = qeth_release_buffer;
	iob->callback = qeth_release_buffer_cb;

	memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data),
	       &card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH);
@@ -2205,7 +2152,6 @@ static int qeth_cm_enable_cb(struct qeth_card *card, struct qeth_reply *reply,
	memcpy(&card->token.cm_filter_r,
	       QETH_CM_ENABLE_RESP_FILTER_TOKEN(iob->data),
	       QETH_MPC_TOKEN_LENGTH);
	QETH_DBF_TEXT_(SETUP, 2, "  rc%d", iob->rc);
	return 0;
}

@@ -2231,7 +2177,6 @@ static int qeth_cm_enable(struct qeth_card *card)
static int qeth_cm_setup_cb(struct qeth_card *card, struct qeth_reply *reply,
		unsigned long data)
{

	struct qeth_cmd_buffer *iob;

	QETH_DBF_TEXT(SETUP, 2, "cmsetpcb");
@@ -2240,7 +2185,6 @@ static int qeth_cm_setup_cb(struct qeth_card *card, struct qeth_reply *reply,
	memcpy(&card->token.cm_connection_r,
	       QETH_CM_SETUP_RESP_DEST_ADDR(iob->data),
	       QETH_MPC_TOKEN_LENGTH);
	QETH_DBF_TEXT_(SETUP, 2, "  rc%d", iob->rc);
	return 0;
}

@@ -2262,7 +2206,6 @@ static int qeth_cm_setup(struct qeth_card *card)
	rc = qeth_send_control_data(card, CM_SETUP_SIZE, iob,
				    qeth_cm_setup_cb, NULL);
	return rc;

}

static int qeth_update_max_mtu(struct qeth_card *card, unsigned int max_mtu)
@@ -2291,7 +2234,7 @@ static int qeth_update_max_mtu(struct qeth_card *card, unsigned int max_mtu)
		if (dev->mtu)
			new_mtu = dev->mtu;
		/* default MTUs for first setup: */
		else if (card->options.layer2)
		else if (IS_LAYER2(card))
			new_mtu = ETH_DATA_LEN;
		else
			new_mtu = ETH_DATA_LEN - 8; /* allow for LLC + SNAP */
@@ -2322,7 +2265,6 @@ static int qeth_get_mtu_outof_framesize(int framesize)
static int qeth_ulp_enable_cb(struct qeth_card *card, struct qeth_reply *reply,
		unsigned long data)
{

	__u16 mtu, framesize;
	__u16 len;
	__u8 link_type;
@@ -2350,7 +2292,6 @@ static int qeth_ulp_enable_cb(struct qeth_card *card, struct qeth_reply *reply,
	} else
		card->info.link_type = 0;
	QETH_DBF_TEXT_(SETUP, 2, "link%d", card->info.link_type);
	QETH_DBF_TEXT_(SETUP, 2, "  rc%d", iob->rc);
	return 0;
}

@@ -2358,7 +2299,7 @@ static u8 qeth_mpc_select_prot_type(struct qeth_card *card)
{
	if (IS_OSN(card))
		return QETH_PROT_OSN2;
	return (card->options.layer2 == 1) ? QETH_PROT_LAYER2 : QETH_PROT_TCPIP;
	return IS_LAYER2(card) ? QETH_PROT_LAYER2 : QETH_PROT_TCPIP;
}

static int qeth_ulp_enable(struct qeth_card *card)
@@ -2896,10 +2837,7 @@ static void qeth_fill_ipacmd_header(struct qeth_card *card,
	/* 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;
	if (card->options.layer2)
		cmd->hdr.prim_version_no = 2;
	else
		cmd->hdr.prim_version_no = 1;
	cmd->hdr.prim_version_no = IS_LAYER2(card) ? 2 : 1;
	cmd->hdr.param_count = 1;
	cmd->hdr.prot_version = prot;
}
@@ -4001,8 +3939,7 @@ static int qeth_fill_buffer(struct qeth_qdio_out_q *queue,
	bool is_first_elem = true;
	int flush_cnt = 0;

	refcount_inc(&skb->users);
	skb_queue_tail(&buf->skb_list, skb);
	__skb_queue_tail(&buf->skb_list, skb);

	/* build dedicated header element */
	if (hd_len) {
@@ -4278,8 +4215,7 @@ static int qeth_setadpparms_change_macaddr_cb(struct qeth_card *card,
	if (qeth_setadpparms_inspect_rc(cmd))
		return 0;

	if (!card->options.layer2 ||
	    !(card->info.mac_bits & QETH_LAYER2_MAC_READ)) {
	if (IS_LAYER3(card) || !(card->info.mac_bits & QETH_LAYER2_MAC_READ)) {
		ether_addr_copy(card->dev->dev_addr,
				cmd->data.setadapterparms.data.change_addr.addr);
		card->info.mac_bits |= QETH_LAYER2_MAC_READ;
@@ -4633,9 +4569,9 @@ static int qeth_snmp_command(struct qeth_card *card, char __user *udata)
		return -EOPNOTSUPP;

	if ((!qeth_adp_supported(card, IPA_SETADP_SET_SNMP_CONTROL)) &&
	    (!card->options.layer2)) {
	    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)))
		return -EFAULT;
@@ -5079,6 +5015,7 @@ static void qeth_core_free_card(struct qeth_card *card)
	qeth_clean_channel(&card->data);
	qeth_free_qdio_buffers(card);
	unregister_service_level(&card->qeth_service_level);
	dev_set_drvdata(&card->gdev->dev, NULL);
	kfree(card);
}

@@ -5158,7 +5095,7 @@ retriable:
	qeth_determine_capabilities(card);
	qeth_init_tokens(card);
	qeth_init_func_level(card);
	rc = qeth_idx_activate_channel(&card->read, qeth_idx_read_cb);
	rc = qeth_idx_activate_channel(card, &card->read, qeth_idx_read_cb);
	if (rc == -ERESTARTSYS) {
		QETH_DBF_TEXT(SETUP, 2, "break2");
		return rc;
@@ -5169,7 +5106,7 @@ retriable:
		else
			goto retry;
	}
	rc = qeth_idx_activate_channel(&card->write, qeth_idx_write_cb);
	rc = qeth_idx_activate_channel(card, &card->write, qeth_idx_write_cb);
	if (rc == -ERESTARTSYS) {
		QETH_DBF_TEXT(SETUP, 2, "break3");
		return rc;
@@ -5193,13 +5130,14 @@ retriable:
		if (rc == IPA_RC_LAN_OFFLINE) {
			dev_warn(&card->gdev->dev,
				"The LAN is offline\n");
			card->lan_online = 0;
			netif_carrier_off(card->dev);
		} else {
			rc = -ENODEV;
			goto out;
		}
	} else
		card->lan_online = 1;
	} else {
		netif_carrier_on(card->dev);
	}

	card->options.ipa4.supported_funcs = 0;
	card->options.ipa6.supported_funcs = 0;
@@ -5593,11 +5531,11 @@ static int qeth_register_dbf_views(void)
	return 0;
}

static DEFINE_MUTEX(qeth_mod_mutex);	/* for synchronized module loading */

int qeth_core_load_discipline(struct qeth_card *card,
		enum qeth_discipline_id discipline)
{
	int rc = 0;

	mutex_lock(&qeth_mod_mutex);
	switch (discipline) {
	case QETH_DISCIPLINE_LAYER3:
@@ -5611,22 +5549,25 @@ int qeth_core_load_discipline(struct qeth_card *card,
	default:
		break;
	}
	mutex_unlock(&qeth_mod_mutex);

	if (!card->discipline) {
		dev_err(&card->gdev->dev, "There is no kernel module to "
			"support discipline %d\n", discipline);
		rc = -EINVAL;
		return -EINVAL;
	}
	mutex_unlock(&qeth_mod_mutex);
	return rc;

	card->options.layer = discipline;
	return 0;
}

void qeth_core_free_discipline(struct qeth_card *card)
{
	if (card->options.layer2)
	if (IS_LAYER2(card))
		symbol_put(qeth_l2_discipline);
	else
		symbol_put(qeth_l3_discipline);
	card->options.layer = QETH_DISCIPLINE_UNDETERMINED;
	card->discipline = NULL;
}

@@ -5790,7 +5731,6 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
			goto err_card;
	}

	dev_set_drvdata(&gdev->dev, card);
	qeth_setup_card(card);
	qeth_update_from_chp_desc(card);

@@ -5853,7 +5793,6 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev)
	write_unlock_irq(&qeth_core_card_list.rwlock);
	free_netdev(card->dev);
	qeth_core_free_card(card);
	dev_set_drvdata(&gdev->dev, NULL);
	put_device(&gdev->dev);
}

@@ -6146,7 +6085,7 @@ void qeth_core_get_drvinfo(struct net_device *dev,
{
	struct qeth_card *card = dev->ml_priv;

	strlcpy(info->driver, card->options.layer2 ? "qeth_l2" : "qeth_l3",
	strlcpy(info->driver, IS_LAYER2(card) ? "qeth_l2" : "qeth_l3",
		sizeof(info->driver));
	strlcpy(info->version, "1.0", sizeof(info->version));
	strlcpy(info->fw_version, card->info.mcl_level,
@@ -6625,9 +6564,7 @@ static int __init qeth_core_init(void)

	pr_info("loading core functions\n");
	INIT_LIST_HEAD(&qeth_core_card_list.list);
	INIT_LIST_HEAD(&qeth_dbf_list);
	rwlock_init(&qeth_core_card_list.rwlock);
	mutex_init(&qeth_mod_mutex);

	qeth_wq = create_singlethread_workqueue("qeth_wq");
	if (!qeth_wq) {
+6 −9
Original line number Diff line number Diff line
@@ -31,10 +31,9 @@ static ssize_t qeth_dev_state_show(struct device *dev,
	case CARD_STATE_SOFTSETUP:
		return sprintf(buf, "SOFTSETUP\n");
	case CARD_STATE_UP:
		if (card->lan_online)
		return sprintf(buf, "UP (LAN ONLINE)\n");
		else
			return sprintf(buf, "UP (LAN OFFLINE)\n");
		return sprintf(buf, "UP (LAN %s)\n",
			       netif_carrier_ok(card->dev) ? "ONLINE" :
							     "OFFLINE");
	case CARD_STATE_RECOVER:
		return sprintf(buf, "RECOVER\n");
	default:
@@ -228,7 +227,7 @@ static ssize_t qeth_dev_prioqing_store(struct device *dev,
		card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_TOS;
		card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
	} else if (sysfs_streq(buf, "prio_queueing_vlan")) {
		if (!card->options.layer2) {
		if (IS_LAYER3(card)) {
			rc = -ENOTSUPP;
			goto out;
		}
@@ -379,7 +378,7 @@ static ssize_t qeth_dev_layer2_show(struct device *dev,
	if (!card)
		return -EINVAL;

	return sprintf(buf, "%i\n", card->options.layer2);
	return sprintf(buf, "%i\n", card->options.layer);
}

static ssize_t qeth_dev_layer2_store(struct device *dev,
@@ -413,7 +412,7 @@ static ssize_t qeth_dev_layer2_store(struct device *dev,
		goto out;
	}

	if (card->options.layer2 == newdis)
	if (card->options.layer == newdis)
		goto out;
	if (card->info.layer_enforced) {
		/* fixed layer, can't switch */
@@ -432,8 +431,6 @@ static ssize_t qeth_dev_layer2_store(struct device *dev,

		card->discipline->remove(card->gdev);
		qeth_core_free_discipline(card);
		card->options.layer2 = -1;

		free_netdev(card->dev);
		card->dev = ndev;
	}
+2 −10
Original line number Diff line number Diff line
@@ -694,7 +694,7 @@ static netdev_tx_t qeth_l2_hard_start_xmit(struct sk_buff *skb,
	int tx_bytes = skb->len;
	int rc;

	if ((card->state != CARD_STATE_UP) || !card->lan_online) {
	if (card->state != CARD_STATE_UP) {
		card->stats.tx_carrier_errors++;
		goto tx_drop;
	}
@@ -806,7 +806,6 @@ static int qeth_l2_probe_device(struct ccwgroup_device *gdev)
	}
	INIT_LIST_HEAD(&card->vid_list);
	hash_init(card->mac_htable);
	card->options.layer2 = 1;
	card->info.hwtrap = 0;
	qeth_l2_vnicc_set_defaults(card);
	return 0;
@@ -998,10 +997,6 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
		goto out_remove;
	}
	card->state = CARD_STATE_SOFTSETUP;
	if (card->lan_online)
		netif_carrier_on(card->dev);
	else
		netif_carrier_off(card->dev);

	qeth_set_allowed_threads(card, 0xffffffff, 0);

@@ -1147,9 +1142,6 @@ static int qeth_l2_pm_resume(struct ccwgroup_device *gdev)
	struct qeth_card *card = dev_get_drvdata(&gdev->dev);
	int rc = 0;

	if (gdev->state == CCWGROUP_OFFLINE)
		goto out;

	if (card->state == CARD_STATE_RECOVER) {
		rc = __qeth_l2_set_online(card->gdev, 1);
		if (rc) {
@@ -1159,7 +1151,7 @@ static int qeth_l2_pm_resume(struct ccwgroup_device *gdev)
		}
	} else
		rc = __qeth_l2_set_online(card->gdev, 0);
out:

	qeth_set_allowed_threads(card, 0xffffffff, 0);
	netif_device_attach(card->dev);
	if (rc)
Loading