Commit 4253ef8f authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'qeth-fixes'



Ursula Braun says:

====================
390: qeth patches

here are several fixes for the s390 qeth driver, built for net.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents bc6c03fa 732a59cb
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -999,6 +999,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 *);
netdev_features_t qeth_fix_features(struct net_device *, netdev_features_t);

/* exports for OSN */
+31 −1
Original line number Diff line number Diff line
@@ -3619,7 +3619,8 @@ static void qeth_qdio_cq_handler(struct qeth_card *card,
		int e;

		e = 0;
		while (buffer->element[e].addr) {
		while ((e < QDIO_MAX_ELEMENTS_PER_BUFFER) &&
		       buffer->element[e].addr) {
			unsigned long phys_aob_addr;

			phys_aob_addr = (unsigned long) buffer->element[e].addr;
@@ -6131,6 +6132,35 @@ 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)
{
	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;

	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);

int qeth_set_features(struct net_device *dev, netdev_features_t features)
{
	struct qeth_card *card = dev->ml_priv;
+3 −3
Original line number Diff line number Diff line
@@ -1124,14 +1124,11 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
			card->dev->hw_features |= NETIF_F_RXCSUM;
			card->dev->vlan_features |= NETIF_F_RXCSUM;
		}
		/* Turn on SG per default */
		card->dev->features |= NETIF_F_SG;
	}
	card->info.broadcast_capable = 1;
	qeth_l2_request_initial_mac(card);
	card->dev->gso_max_size = (QETH_MAX_BUFFER_ELEMENTS(card) - 1) *
				  PAGE_SIZE;
	card->dev->gso_max_segs = (QETH_MAX_BUFFER_ELEMENTS(card) - 1);
	SET_NETDEV_DEV(card->dev, &card->gdev->dev);
	netif_napi_add(card->dev, &card->napi, qeth_l2_poll, QETH_NAPI_WEIGHT);
	netif_carrier_off(card->dev);
@@ -1246,6 +1243,9 @@ contin:
		}
		/* this also sets saved unicast addresses */
		qeth_l2_set_rx_mode(card->dev);
		rtnl_lock();
		qeth_recover_features(card->dev);
		rtnl_unlock();
	}
	/* let user_space know that device is online */
	kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);
+20 −9
Original line number Diff line number Diff line
@@ -257,6 +257,11 @@ int qeth_l3_delete_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr)
	if (addr->in_progress)
		return -EINPROGRESS;

	if (!qeth_card_hw_is_reachable(card)) {
		addr->disp_flag = QETH_DISP_ADDR_DELETE;
		return 0;
	}

	rc = qeth_l3_deregister_addr_entry(card, addr);

	hash_del(&addr->hnode);
@@ -296,6 +301,11 @@ int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr)
		hash_add(card->ip_htable, &addr->hnode,
				qeth_l3_ipaddr_hash(addr));

		if (!qeth_card_hw_is_reachable(card)) {
			addr->disp_flag = QETH_DISP_ADDR_ADD;
			return 0;
		}

		/* qeth_l3_register_addr_entry can go to sleep
		 * if we add a IPV4 addr. It is caused by the reason
		 * that SETIP ipa cmd starts ARP staff for IPV4 addr.
@@ -390,12 +400,16 @@ static void qeth_l3_recover_ip(struct qeth_card *card)
	int i;
	int rc;

	QETH_CARD_TEXT(card, 4, "recoverip");
	QETH_CARD_TEXT(card, 4, "recovrip");

	spin_lock_bh(&card->ip_lock);

	hash_for_each_safe(card->ip_htable, i, tmp, addr, hnode) {
		if (addr->disp_flag == QETH_DISP_ADDR_ADD) {
		if (addr->disp_flag == QETH_DISP_ADDR_DELETE) {
			qeth_l3_deregister_addr_entry(card, addr);
			hash_del(&addr->hnode);
			kfree(addr);
		} else if (addr->disp_flag == QETH_DISP_ADDR_ADD) {
			if (addr->proto == QETH_PROT_IPV4) {
				addr->in_progress = 1;
				spin_unlock_bh(&card->ip_lock);
@@ -407,10 +421,8 @@ static void qeth_l3_recover_ip(struct qeth_card *card)

			if (!rc) {
				addr->disp_flag = QETH_DISP_ADDR_DO_NOTHING;
				if (addr->ref_counter < 1) {
				if (addr->ref_counter < 1)
					qeth_l3_delete_ip(card, addr);
					kfree(addr);
				}
			} else {
				hash_del(&addr->hnode);
				kfree(addr);
@@ -689,7 +701,7 @@ int qeth_l3_add_vipa(struct qeth_card *card, enum qeth_prot_versions proto,

	spin_lock_bh(&card->ip_lock);

	if (!qeth_l3_ip_from_hash(card, ipaddr))
	if (qeth_l3_ip_from_hash(card, ipaddr))
		rc = -EEXIST;
	else
		qeth_l3_add_ip(card, ipaddr);
@@ -757,7 +769,7 @@ int qeth_l3_add_rxip(struct qeth_card *card, enum qeth_prot_versions proto,

	spin_lock_bh(&card->ip_lock);

	if (!qeth_l3_ip_from_hash(card, ipaddr))
	if (qeth_l3_ip_from_hash(card, ipaddr))
		rc = -EEXIST;
	else
		qeth_l3_add_ip(card, ipaddr);
@@ -3108,7 +3120,6 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
				card->dev->vlan_features = NETIF_F_SG |
					NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
					NETIF_F_TSO;
				card->dev->features = NETIF_F_SG;
			}
		}
	} else if (card->info.type == QETH_CARD_TYPE_IQD) {
@@ -3136,7 +3147,6 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
	netif_keep_dst(card->dev);
	card->dev->gso_max_size = (QETH_MAX_BUFFER_ELEMENTS(card) - 1) *
				  PAGE_SIZE;
	card->dev->gso_max_segs = (QETH_MAX_BUFFER_ELEMENTS(card) - 1);

	SET_NETDEV_DEV(card->dev, &card->gdev->dev);
	netif_napi_add(card->dev, &card->napi, qeth_l3_poll, QETH_NAPI_WEIGHT);
@@ -3269,6 +3279,7 @@ contin:
		else
			dev_open(card->dev);
		qeth_l3_set_multicast_list(card->dev);
		qeth_recover_features(card->dev);
		rtnl_unlock();
	}
	qeth_trace_features(card);
+5 −0
Original line number Diff line number Diff line
@@ -297,7 +297,9 @@ static ssize_t qeth_l3_dev_hsuid_store(struct device *dev,
		addr->u.a6.pfxlen = 0;
		addr->type = QETH_IP_TYPE_NORMAL;

		spin_lock_bh(&card->ip_lock);
		qeth_l3_delete_ip(card, addr);
		spin_unlock_bh(&card->ip_lock);
		kfree(addr);
	}

@@ -329,7 +331,10 @@ static ssize_t qeth_l3_dev_hsuid_store(struct device *dev,
		addr->type = QETH_IP_TYPE_NORMAL;
	} else
		return -ENOMEM;

	spin_lock_bh(&card->ip_lock);
	qeth_l3_add_ip(card, addr);
	spin_unlock_bh(&card->ip_lock);
	kfree(addr);

	return count;