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

Commit 6b1f8eda authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 's390-next'



Julian Wiedmann says:

====================
s390/net: updates 2017-10-18

please apply some additional robustness fixes and cleanups for 4.15.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 0843c092 52c44d29
Loading
Loading
Loading
Loading
+2 −6
Original line number Diff line number Diff line
@@ -170,9 +170,7 @@ fsm_addtimer(fsm_timer *this, int millisec, int event, void *arg)
	       this->fi->name, this, millisec);
#endif

	init_timer(&this->tl);
	this->tl.function = (void *)fsm_expire_timer;
	this->tl.data = (long)this;
	setup_timer(&this->tl, (void *)fsm_expire_timer, (long)this);
	this->expire_event = event;
	this->event_arg = arg;
	this->tl.expires = jiffies + (millisec * HZ) / 1000;
@@ -191,9 +189,7 @@ fsm_modtimer(fsm_timer *this, int millisec, int event, void *arg)
#endif

	del_timer(&this->tl);
	init_timer(&this->tl);
	this->tl.function = (void *)fsm_expire_timer;
	this->tl.data = (long)this;
	setup_timer(&this->tl, (void *)fsm_expire_timer, (long)this);
	this->expire_event = event;
	this->event_arg = arg;
	this->tl.expires = jiffies + (millisec * HZ) / 1000;
+1 −15
Original line number Diff line number Diff line
@@ -231,20 +231,6 @@ static inline int qeth_is_ipa_enabled(struct qeth_ipa_info *ipa,
#define QETH_IDX_FUNC_LEVEL_OSD		 0x0101
#define QETH_IDX_FUNC_LEVEL_IQD		 0x4108

#define QETH_MODELLIST_ARRAY \
	{{0x1731, 0x01, 0x1732, QETH_CARD_TYPE_OSD, QETH_MAX_QUEUES, 0}, \
	 {0x1731, 0x05, 0x1732, QETH_CARD_TYPE_IQD, QETH_MAX_QUEUES, 0x103}, \
	 {0x1731, 0x06, 0x1732, QETH_CARD_TYPE_OSN, QETH_MAX_QUEUES, 0}, \
	 {0x1731, 0x02, 0x1732, QETH_CARD_TYPE_OSM, QETH_MAX_QUEUES, 0}, \
	 {0x1731, 0x02, 0x1732, QETH_CARD_TYPE_OSX, QETH_MAX_QUEUES, 0}, \
	 {0, 0, 0, 0, 0, 0} }
#define QETH_CU_TYPE_IND	0
#define QETH_CU_MODEL_IND	1
#define QETH_DEV_TYPE_IND	2
#define QETH_DEV_MODEL_IND	3
#define QETH_QUEUE_NO_IND	4
#define QETH_MULTICAST_IND	5

#define QETH_REAL_CARD		1
#define QETH_VLAN_CARD		2
#define QETH_BUFSIZE		4096
@@ -998,7 +984,7 @@ struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *,
						 __u16, __u16,
						 enum qeth_prot_versions);
int qeth_set_features(struct net_device *, netdev_features_t);
int qeth_recover_features(struct net_device *);
void qeth_recover_features(struct net_device *dev);
netdev_features_t qeth_fix_features(struct net_device *, netdev_features_t);
int qeth_vm_request_mac(struct qeth_card *card);
int qeth_push_hdr(struct sk_buff *skb, struct qeth_hdr **hdr, unsigned int len);
+66 −121
Original line number Diff line number Diff line
@@ -52,7 +52,6 @@ EXPORT_SYMBOL_GPL(qeth_core_header_cache);
static struct kmem_cache *qeth_qdio_outbuf_cache;

static struct device *qeth_core_root_dev;
static unsigned int known_devices[][6] = QETH_MODELLIST_ARRAY;
static struct lock_class_key qdio_out_skb_queue_key;
static struct mutex qeth_mod_mutex;

@@ -1386,6 +1385,7 @@ static void qeth_init_qdio_info(struct qeth_card *card)
	QETH_DBF_TEXT(SETUP, 4, "intqdinf");
	atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED);
	/* inbound */
	card->qdio.no_in_queues = 1;
	card->qdio.in_buf_size = QETH_IN_BUF_SIZE_DEFAULT;
	if (card->info.type == QETH_CARD_TYPE_IQD)
		card->qdio.init_pool.buf_count = QETH_IN_BUF_COUNT_HSDEFAULT;
@@ -1519,34 +1519,17 @@ static struct qeth_card *qeth_alloc_card(void)
	return NULL;
}

static int qeth_determine_card_type(struct qeth_card *card)
static void qeth_determine_card_type(struct qeth_card *card)
{
	int i = 0;

	QETH_DBF_TEXT(SETUP, 2, "detcdtyp");

	card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT;
	card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
	while (known_devices[i][QETH_DEV_MODEL_IND]) {
		if ((CARD_RDEV(card)->id.dev_type ==
				known_devices[i][QETH_DEV_TYPE_IND]) &&
		    (CARD_RDEV(card)->id.dev_model ==
				known_devices[i][QETH_DEV_MODEL_IND])) {
			card->info.type = known_devices[i][QETH_DEV_MODEL_IND];
			card->qdio.no_out_queues =
				known_devices[i][QETH_QUEUE_NO_IND];
			card->qdio.no_in_queues = 1;
			card->info.is_multicast_different =
				known_devices[i][QETH_MULTICAST_IND];
	card->info.type = CARD_RDEV(card)->id.driver_info;
	card->qdio.no_out_queues = QETH_MAX_QUEUES;
	if (card->info.type == QETH_CARD_TYPE_IQD)
		card->info.is_multicast_different = 0x0103;
	qeth_update_from_chp_desc(card);
			return 0;
		}
		i++;
	}
	card->info.type = QETH_CARD_TYPE_UNKNOWN;
	dev_err(&card->gdev->dev, "The adapter hardware is of an "
		"unknown type\n");
	return -ENOENT;
}

static int qeth_clear_channel(struct qeth_channel *channel)
@@ -2090,7 +2073,6 @@ int qeth_send_control_data(struct qeth_card *card, int len,
	spin_lock_irqsave(&card->lock, flags);
	list_add_tail(&reply->list, &card->cmd_waiter_list);
	spin_unlock_irqrestore(&card->lock, flags);
	QETH_DBF_HEX(CTRL, 2, iob->data, QETH_DBF_CTRL_LEN);

	while (atomic_cmpxchg(&card->write.irq_pending, 0, 1)) ;
	qeth_prepare_control_data(card, len, iob);
@@ -2233,23 +2215,15 @@ static int qeth_cm_setup(struct qeth_card *card)
static int qeth_get_initial_mtu_for_card(struct qeth_card *card)
{
	switch (card->info.type) {
	case QETH_CARD_TYPE_UNKNOWN:
		return 1500;
	case QETH_CARD_TYPE_IQD:
		return card->info.max_mtu;
	case QETH_CARD_TYPE_OSD:
		switch (card->info.link_type) {
		case QETH_LINK_TYPE_HSTR:
		case QETH_LINK_TYPE_LANE_TR:
			return 2000;
		default:
			return card->options.layer2 ? 1500 : 1492;
		}
	case QETH_CARD_TYPE_OSM:
	case QETH_CARD_TYPE_OSX:
		return card->options.layer2 ? 1500 : 1492;
		if (!card->options.layer2)
			return ETH_DATA_LEN - 8; /* L3: allow for LLC + SNAP */
		/* fall through */
	default:
		return 1500;
		return ETH_DATA_LEN;
	}
}

@@ -2279,7 +2253,6 @@ static int qeth_mtu_is_valid(struct qeth_card *card, int mtu)
		return ((mtu >= 576) &&
			(mtu <= card->info.max_mtu));
	case QETH_CARD_TYPE_OSN:
	case QETH_CARD_TYPE_UNKNOWN:
	default:
		return 1;
	}
@@ -5196,49 +5169,27 @@ int qeth_core_hardsetup_card(struct qeth_card *card)
}
EXPORT_SYMBOL_GPL(qeth_core_hardsetup_card);

static int qeth_create_skb_frag(struct qeth_qdio_buffer *qethbuffer,
				struct qdio_buffer_element *element,
				struct sk_buff **pskb, int offset, int *pfrag,
				int data_len)
static void qeth_create_skb_frag(struct qdio_buffer_element *element,
				 struct sk_buff *skb, int offset, int data_len)
{
	struct page *page = virt_to_page(element->addr);
	if (*pskb == NULL) {
		if (qethbuffer->rx_skb) {
			/* only if qeth_card.options.cq == QETH_CQ_ENABLED */
			*pskb = qethbuffer->rx_skb;
			qethbuffer->rx_skb = NULL;
		} else {
			*pskb = dev_alloc_skb(QETH_RX_PULL_LEN + ETH_HLEN);
			if (!(*pskb))
				return -ENOMEM;
		}
	unsigned int next_frag;

		skb_reserve(*pskb, ETH_HLEN);
		if (data_len <= QETH_RX_PULL_LEN) {
			skb_put_data(*pskb, element->addr + offset, data_len);
		} else {
			get_page(page);
			skb_put_data(*pskb, element->addr + offset,
				     QETH_RX_PULL_LEN);
			skb_fill_page_desc(*pskb, *pfrag, page,
				offset + QETH_RX_PULL_LEN,
				data_len - QETH_RX_PULL_LEN);
			(*pskb)->data_len += data_len - QETH_RX_PULL_LEN;
			(*pskb)->len      += data_len - QETH_RX_PULL_LEN;
			(*pskb)->truesize += data_len - QETH_RX_PULL_LEN;
			(*pfrag)++;
		}
	} else {
		get_page(page);
		skb_fill_page_desc(*pskb, *pfrag, page, offset, data_len);
		(*pskb)->data_len += data_len;
		(*pskb)->len      += data_len;
		(*pskb)->truesize += data_len;
		(*pfrag)++;
	}
	/* first fill the linear space */
	if (!skb->len) {
		unsigned int linear = min(data_len, skb_tailroom(skb));

		skb_put_data(skb, element->addr + offset, linear);
		data_len -= linear;
		if (!data_len)
			return;
		offset += linear;
		/* fall through to add page frag for remaining data */
	}

	return 0;
	next_frag = skb_shinfo(skb)->nr_frags;
	get_page(page);
	skb_add_rx_frag(skb, next_frag, page, offset, data_len, data_len);
}

static inline int qeth_is_last_sbale(struct qdio_buffer_element *sbale)
@@ -5254,22 +5205,19 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
	struct qdio_buffer_element *element = *__element;
	struct qdio_buffer *buffer = qethbuffer->buffer;
	int offset = *__offset;
	struct sk_buff *skb = NULL;
	struct sk_buff *skb;
	int skb_len = 0;
	void *data_ptr;
	int data_len;
	int headroom = 0;
	int use_rx_sg = 0;
	int frag = 0;

	/* qeth_hdr must not cross element boundaries */
	if (element->length < offset + sizeof(struct qeth_hdr)) {
	while (element->length < offset + sizeof(struct qeth_hdr)) {
		if (qeth_is_last_sbale(element))
			return NULL;
		element++;
		offset = 0;
		if (element->length < sizeof(struct qeth_hdr))
			return NULL;
	}
	*hdr = element->addr + offset;

@@ -5296,28 +5244,33 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
	if (((skb_len >= card->options.rx_sg_cb) &&
	     (!(card->info.type == QETH_CARD_TYPE_OSN)) &&
	     (!atomic_read(&card->force_alloc_skb))) ||
	    (card->options.cq == QETH_CQ_ENABLED)) {
	    (card->options.cq == QETH_CQ_ENABLED))
		use_rx_sg = 1;

	if (use_rx_sg && qethbuffer->rx_skb) {
		/* QETH_CQ_ENABLED only: */
		skb = qethbuffer->rx_skb;
		qethbuffer->rx_skb = NULL;
	} else {
		skb = dev_alloc_skb(skb_len + headroom);
		unsigned int linear = (use_rx_sg) ? QETH_RX_PULL_LEN : skb_len;

		skb = dev_alloc_skb(linear + headroom);
	}
	if (!skb)
		goto no_mem;
	if (headroom)
		skb_reserve(skb, headroom);
	}

	data_ptr = element->addr + offset;
	while (skb_len) {
		data_len = min(skb_len, (int)(element->length - offset));
		if (data_len) {
			if (use_rx_sg) {
				if (qeth_create_skb_frag(qethbuffer, element,
				    &skb, offset, &frag, data_len))
					goto no_mem;
			} else {
			if (use_rx_sg)
				qeth_create_skb_frag(element, skb, offset,
						     data_len);
			else
				skb_put_data(skb, data_ptr, data_len);
		}
		}
		skb_len -= data_len;
		if (skb_len) {
			if (qeth_is_last_sbale(element)) {
@@ -5416,7 +5369,7 @@ int qeth_poll(struct napi_struct *napi, int budget)
		}
	}

	napi_complete(napi);
	napi_complete_done(napi, work_done);
	if (qdio_start_irq(card->data.ccwdev, 0))
		napi_schedule(&card->napi);
out:
@@ -5724,11 +5677,7 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
	gdev->cdev[1]->handler = qeth_irq;
	gdev->cdev[2]->handler = qeth_irq;

	rc = qeth_determine_card_type(card);
	if (rc) {
		QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc);
		goto err_card;
	}
	qeth_determine_card_type(card);
	rc = qeth_setup_card(card);
	if (rc) {
		QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc);
@@ -6403,32 +6352,29 @@ static int qeth_set_ipa_tso(struct qeth_card *card, int on)
	return rc;
}

/* try to restore device features on a device after recovery */
int qeth_recover_features(struct net_device *dev)
#define QETH_HW_FEATURES (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_TSO)

/**
 * qeth_recover_features() - Restore device features after recovery
 * @dev:	the recovering net_device
 *
 * Caller must hold rtnl lock.
 */
void qeth_recover_features(struct net_device *dev)
{
	netdev_features_t features = dev->features;
	struct qeth_card *card = dev->ml_priv;
	netdev_features_t recover = dev->features;

	if (recover & NETIF_F_IP_CSUM) {
		if (qeth_set_ipa_csum(card, 1, IPA_OUTBOUND_CHECKSUM))
			recover ^= NETIF_F_IP_CSUM;
	}
	if (recover & NETIF_F_RXCSUM) {
		if (qeth_set_ipa_csum(card, 1, IPA_INBOUND_CHECKSUM))
			recover ^= NETIF_F_RXCSUM;
	}
	if (recover & NETIF_F_TSO) {
		if (qeth_set_ipa_tso(card, 1))
			recover ^= NETIF_F_TSO;
	}

	if (recover == dev->features)
		return 0;
	/* force-off any feature that needs an IPA sequence.
	 * netdev_update_features() will restart them.
	 */
	dev->features &= ~QETH_HW_FEATURES;
	netdev_update_features(dev);

	if (features == dev->features)
		return;
	dev_warn(&card->gdev->dev,
		 "Device recovery failed to restore all offload features\n");
	dev->features = recover;
	return -EIO;
}
EXPORT_SYMBOL_GPL(qeth_recover_features);

@@ -6485,8 +6431,7 @@ netdev_features_t qeth_fix_features(struct net_device *dev,
	/* if the card isn't up, remove features that require hw changes */
	if (card->state == CARD_STATE_DOWN ||
	    card->state == CARD_STATE_RECOVER)
		features = features & ~(NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
					NETIF_F_TSO);
		features &= ~QETH_HW_FEATURES;
	QETH_DBF_HEX(SETUP, 2, &features, sizeof(features));
	return features;
}
+0 −1
Original line number Diff line number Diff line
@@ -44,7 +44,6 @@ extern unsigned char IPA_PDU_HEADER[];
#define IPA_CMD_PRIM_VERSION_NO 0x01

enum qeth_card_types {
	QETH_CARD_TYPE_UNKNOWN = 0,
	QETH_CARD_TYPE_OSD     = 1,
	QETH_CARD_TYPE_IQD     = 5,
	QETH_CARD_TYPE_OSN     = 6,
+1 −3
Original line number Diff line number Diff line
@@ -475,10 +475,8 @@ static ssize_t qeth_dev_isolation_store(struct device *dev,
		return -EINVAL;

	mutex_lock(&card->conf_mutex);
	/* check for unknown, too, in case we do not yet know who we are */
	if (card->info.type != QETH_CARD_TYPE_OSD &&
	    card->info.type != QETH_CARD_TYPE_OSX &&
	    card->info.type != QETH_CARD_TYPE_UNKNOWN) {
	    card->info.type != QETH_CARD_TYPE_OSX) {
		rc = -EOPNOTSUPP;
		dev_err(&card->gdev->dev, "Adapter does not "
			"support QDIO data connection isolation\n");
Loading