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

Commit 729ecbc7 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 's390-net'



Ursula Braun says:

====================
s390: qeth patches for net-next

here are some s390 related patches for net-next. The qeth patches
are performance optimizations in the driver. The qdio patch corrects
a warning condition.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 68e4bd27 ec6674c6
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -319,6 +319,8 @@ static int qdio_siga_output(struct qdio_q *q, unsigned int *busy_bit,
	int retries = 0, cc;
	unsigned long laob = 0;

	WARN_ON_ONCE(aob && ((queue_type(q) != QDIO_IQDIO_QFMT) ||
			     !q->u.out.use_cq));
	if (q->u.out.use_cq && aob != 0) {
		fc = QDIO_SIGA_WRITEQ;
		laob = aob;
@@ -329,8 +331,6 @@ static int qdio_siga_output(struct qdio_q *q, unsigned int *busy_bit,
		fc |= QDIO_SIGA_QEBSM_FLAG;
	}
again:
	WARN_ON_ONCE((aob && queue_type(q) != QDIO_IQDIO_QFMT) ||
		(aob && fc != QDIO_SIGA_WRITEQ));
	cc = do_siga_output(schid, q->mask, busy_bit, fc, laob);

	/* hipersocket busy condition */
+13 −6
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <linux/bitops.h>
#include <linux/seq_file.h>
#include <linux/ethtool.h>
#include <linux/hashtable.h>

#include <net/ipv6.h>
#include <net/if_inet6.h>
@@ -739,11 +740,17 @@ struct qeth_vlan_vid {
	unsigned short vid;
};

struct qeth_mc_mac {
	struct list_head list;
	__u8 mc_addr[MAX_ADDR_LEN];
	unsigned char mc_addrlen;
	int is_vmac;
enum qeth_mac_disposition {
	QETH_DISP_MAC_DELETE = 0,
	QETH_DISP_MAC_DO_NOTHING = 1,
	QETH_DISP_MAC_ADD = 2,
};

struct qeth_mac {
	u8 mac_addr[OSA_ADDR_LEN];
	u8 is_uc:1;
	u8 disp_flag:2;
	struct hlist_node hnode;
};

struct qeth_rx {
@@ -790,7 +797,7 @@ struct qeth_card {
	spinlock_t mclock;
	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
	struct list_head vid_list;
	struct list_head mc_list;
	DECLARE_HASHTABLE(mac_htable, 4);
	struct work_struct kernel_thread_starter;
	spinlock_t thread_mask_lock;
	unsigned long thread_start_mask;
+99 −40
Original line number Diff line number Diff line
@@ -19,7 +19,9 @@
#include <linux/mii.h>
#include <linux/ip.h>
#include <linux/list.h>

#include <linux/hash.h>
#include <linux/hashtable.h>
#include <linux/string.h>
#include "qeth_core.h"
#include "qeth_l2.h"

@@ -28,7 +30,7 @@ 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_multicast_list(struct net_device *);
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);
static void qeth_bridge_state_change(struct qeth_card *card,
@@ -193,49 +195,44 @@ static int qeth_l2_send_delgroupmac(struct qeth_card *card, __u8 *mac)
	return rc;
}

static void qeth_l2_add_mc(struct qeth_card *card, __u8 *mac, int vmac)
static inline u32 qeth_l2_mac_hash(const u8 *addr)
{
	struct qeth_mc_mac *mc;
	int rc;

	mc = kmalloc(sizeof(struct qeth_mc_mac), GFP_ATOMIC);
	return get_unaligned((u32 *)(&addr[2]));
}

	if (!mc)
		return;
static int qeth_l2_write_mac(struct qeth_card *card, struct qeth_mac *mac)
{

	memcpy(mc->mc_addr, mac, OSA_ADDR_LEN);
	mc->mc_addrlen = OSA_ADDR_LEN;
	mc->is_vmac = vmac;
	int rc;

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

	if (!rc)
		list_add_tail(&mc->list, &card->mc_list);
	else
		kfree(mc);
	return rc;
}

static void qeth_l2_del_all_mc(struct qeth_card *card, int del)
static void qeth_l2_del_all_macs(struct qeth_card *card, int del)
{
	struct qeth_mc_mac *mc, *tmp;
	struct qeth_mac *mac;
	struct hlist_node *tmp;
	int i;

	spin_lock_bh(&card->mclock);
	list_for_each_entry_safe(mc, tmp, &card->mc_list, list) {
	hash_for_each_safe(card->mac_htable, i, tmp, mac, hnode) {
		if (del) {
			if (mc->is_vmac)
				qeth_l2_send_setdelmac(card, mc->mc_addr,
			if (mac->is_uc)
				qeth_l2_send_setdelmac(card, mac->mac_addr,
						IPA_CMD_DELVMAC);
			else
				qeth_l2_send_delgroupmac(card, mc->mc_addr);
				qeth_l2_send_delgroupmac(card, mac->mac_addr);
		}
		list_del(&mc->list);
		kfree(mc);
		hash_del(&mac->hnode);
		kfree(mac);
	}
	spin_unlock_bh(&card->mclock);
}
@@ -403,7 +400,7 @@ static int qeth_l2_vlan_rx_kill_vid(struct net_device *dev,
		rc = qeth_l2_send_setdelvlan(card, vid, IPA_CMD_DELVLAN);
		kfree(tmpid);
	}
	qeth_l2_set_multicast_list(card->dev);
	qeth_l2_set_rx_mode(card->dev);
	return rc;
}

@@ -460,7 +457,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_mc(card, 0);
		qeth_l2_del_all_macs(card, 0);
		qeth_clear_ipacmd_list(card);
		card->state = CARD_STATE_HARDSETUP;
	}
@@ -511,7 +508,7 @@ static int qeth_l2_process_inbound_buffer(struct qeth_card *card,
			if (skb->protocol == htons(ETH_P_802_2))
				*((__u32 *)skb->cb) = ++card->seqno.pkt_seqno;
			len = skb->len;
			netif_receive_skb(skb);
			napi_gro_receive(&card->napi, skb);
			break;
		case QETH_HEADER_TYPE_OSN:
			if (card->info.type == QETH_CARD_TYPE_OSN) {
@@ -768,12 +765,48 @@ static void qeth_promisc_to_bridge(struct qeth_card *card)
		card->options.sbp.role = role;
		card->info.promisc_mode = promisc_mode;
	}

}
/* New MAC address is added to the hash table and marked to be written on card
 * only if there is not in the hash table storage already
 *
*/
static	void
qeth_l2_add_mac(struct qeth_card *card, struct netdev_hw_addr *ha, u8 is_uc)
{
	struct qeth_mac *mac;

	hash_for_each_possible(card->mac_htable, mac, hnode,
			qeth_l2_mac_hash(ha->addr)) {
		if (is_uc == mac->is_uc &&
		    !memcmp(ha->addr, mac->mac_addr, OSA_ADDR_LEN)) {
			mac->disp_flag = QETH_DISP_MAC_DO_NOTHING;
			return;
		}
	}

static void qeth_l2_set_multicast_list(struct net_device *dev)
	mac = kzalloc(sizeof(struct qeth_mac), GFP_ATOMIC);

	if (!mac)
		return;

	memcpy(mac->mac_addr, ha->addr, OSA_ADDR_LEN);
	mac->is_uc = is_uc;
	mac->disp_flag = QETH_DISP_MAC_ADD;

	hash_add(card->mac_htable, &mac->hnode,
			qeth_l2_mac_hash(mac->mac_addr));

}

static void qeth_l2_set_rx_mode(struct net_device *dev)
{
	struct qeth_card *card = dev->ml_priv;
	struct netdev_hw_addr *ha;
	struct qeth_mac *mac;
	struct hlist_node *tmp;
	int i;
	int rc;

	if (card->info.type == QETH_CARD_TYPE_OSN)
		return;
@@ -782,15 +815,41 @@ static void qeth_l2_set_multicast_list(struct net_device *dev)
	if (qeth_threads_running(card, QETH_RECOVER_THREAD) &&
	    (card->state != CARD_STATE_UP))
		return;
	qeth_l2_del_all_mc(card, 1);

	spin_lock_bh(&card->mclock);

	netdev_for_each_mc_addr(ha, dev)
		qeth_l2_add_mc(card, ha->addr, 0);
		qeth_l2_add_mac(card, ha, 0);

	netdev_for_each_uc_addr(ha, dev)
		qeth_l2_add_mc(card, ha->addr, 1);
		qeth_l2_add_mac(card, ha, 1);

	hash_for_each_safe(card->mac_htable, i, tmp, mac, hnode) {
		if (mac->disp_flag == QETH_DISP_MAC_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);
			}

			hash_del(&mac->hnode);
			kfree(mac);

		} else if (mac->disp_flag == QETH_DISP_MAC_ADD) {
			rc = qeth_l2_write_mac(card, mac);
			if (rc) {
				hash_del(&mac->hnode);
				kfree(mac);
			} else
				mac->disp_flag = QETH_DISP_MAC_DELETE;
		} else
			mac->disp_flag = QETH_DISP_MAC_DELETE;
	}

	spin_unlock_bh(&card->mclock);

	if (qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
		qeth_setadp_promisc_mode(card);
	else
@@ -974,7 +1033,7 @@ static int qeth_l2_probe_device(struct ccwgroup_device *gdev)

	qeth_l2_create_device_attributes(&gdev->dev);
	INIT_LIST_HEAD(&card->vid_list);
	INIT_LIST_HEAD(&card->mc_list);
	hash_init(card->mac_htable);
	card->options.layer2 = 1;
	card->info.hwtrap = 0;
	return 0;
@@ -1020,7 +1079,7 @@ static const struct net_device_ops qeth_l2_netdev_ops = {
	.ndo_get_stats		= qeth_get_stats,
	.ndo_start_xmit		= qeth_l2_hard_start_xmit,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_rx_mode	= qeth_l2_set_multicast_list,
	.ndo_set_rx_mode	= qeth_l2_set_rx_mode,
	.ndo_do_ioctl	   	= qeth_l2_do_ioctl,
	.ndo_set_mac_address    = qeth_l2_set_mac_address,
	.ndo_change_mtu	   	= qeth_change_mtu,
@@ -1179,7 +1238,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
			rtnl_unlock();
		}
		/* this also sets saved unicast addresses */
		qeth_l2_set_multicast_list(card->dev);
		qeth_l2_set_rx_mode(card->dev);
	}
	/* let user_space know that device is online */
	kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);