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

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

Merge branch 's390-next'



Julian Wiedmann says:

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

please apply the following patches to net-next. There's the usual
cleanups & small improvements, and Kittipon adds HW offload support
for IPv6 checksumming.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d8fb1648 21b1702a
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -1928,6 +1928,8 @@ lcs_portno_store (struct device *dev, struct device_attribute *attr, const char
		return -EINVAL;
        /* TODO: sanity checks */
        card->portno = value;
	if (card->dev)
		card->dev->dev_port = card->portno;

        return count;

@@ -2158,6 +2160,7 @@ lcs_new_device(struct ccwgroup_device *ccwgdev)
	card->dev = dev;
	card->dev->ml_priv = card;
	card->dev->netdev_ops = &lcs_netdev_ops;
	card->dev->dev_port = card->portno;
	memcpy(card->dev->dev_addr, card->mac, LCS_MAC_LENGTH);
#ifdef CONFIG_IP_MULTICAST
	if (!lcs_check_multicast_support(card))
+49 −12
Original line number Diff line number Diff line
@@ -148,6 +148,7 @@ struct qeth_perf_stats {
	unsigned int tx_csum;
	unsigned int tx_lin;
	unsigned int tx_linfail;
	unsigned int rx_csum;
};

/* Routing stuff */
@@ -712,9 +713,6 @@ enum qeth_discipline_id {

struct qeth_discipline {
	const struct device_type *devtype;
	void (*start_poll)(struct ccw_device *, int, unsigned long);
	qdio_handler_t *input_handler;
	qdio_handler_t *output_handler;
	int (*process_rx_buffer)(struct qeth_card *card, int budget, int *done);
	int (*recover)(void *ptr);
	int (*setup) (struct ccwgroup_device *);
@@ -780,9 +778,9 @@ struct qeth_card {
	struct qeth_card_options options;

	wait_queue_head_t wait_q;
	spinlock_t vlanlock;
	spinlock_t mclock;
	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
	struct mutex vid_list_mutex;		/* vid_list */
	struct list_head vid_list;
	DECLARE_HASHTABLE(mac_htable, 4);
	DECLARE_HASHTABLE(ip_htable, 4);
@@ -867,6 +865,32 @@ static inline int qeth_get_ip_version(struct sk_buff *skb)
	}
}

static inline void qeth_rx_csum(struct qeth_card *card, struct sk_buff *skb,
				u8 flags)
{
	if ((card->dev->features & NETIF_F_RXCSUM) &&
	    (flags & QETH_HDR_EXT_CSUM_TRANSP_REQ)) {
		skb->ip_summed = CHECKSUM_UNNECESSARY;
		if (card->options.performance_stats)
			card->perf_stats.rx_csum++;
	} else {
		skb->ip_summed = CHECKSUM_NONE;
	}
}

static inline void qeth_tx_csum(struct sk_buff *skb, u8 *flags, int ipv)
{
	*flags |= QETH_HDR_EXT_CSUM_TRANSP_REQ;
	if ((ipv == 4 && ip_hdr(skb)->protocol == IPPROTO_UDP) ||
	    (ipv == 6 && ipv6_hdr(skb)->nexthdr == IPPROTO_UDP))
		*flags |= QETH_HDR_EXT_UDP;
	if (ipv == 4) {
		/* some HW requires combined L3+L4 csum offload: */
		*flags |= QETH_HDR_EXT_CSUM_HDR_REQ;
		ip_hdr(skb)->check = 0;
	}
}

static inline void qeth_put_buffer_pool_entry(struct qeth_card *card,
		struct qeth_buffer_pool_entry *entry)
{
@@ -879,6 +903,27 @@ static inline int qeth_is_diagass_supported(struct qeth_card *card,
	return card->info.diagass_support & (__u32)cmd;
}

int qeth_send_simple_setassparms_prot(struct qeth_card *card,
				      enum qeth_ipa_funcs ipa_func,
				      u16 cmd_code, long data,
				      enum qeth_prot_versions prot);
/* IPv4 variant */
static inline int qeth_send_simple_setassparms(struct qeth_card *card,
					       enum qeth_ipa_funcs ipa_func,
					       u16 cmd_code, long data)
{
	return qeth_send_simple_setassparms_prot(card, ipa_func, cmd_code,
						 data, QETH_PROT_IPV4);
}

static inline int qeth_send_simple_setassparms_v6(struct qeth_card *card,
						  enum qeth_ipa_funcs ipa_func,
						  u16 cmd_code, long data)
{
	return qeth_send_simple_setassparms_prot(card, ipa_func, cmd_code,
						 data, QETH_PROT_IPV6);
}

extern struct qeth_discipline qeth_l2_discipline;
extern struct qeth_discipline qeth_l3_discipline;
extern const struct attribute_group *qeth_generic_attr_groups[];
@@ -921,13 +966,7 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *,
		struct qeth_qdio_buffer *, struct qdio_buffer_element **, int *,
		struct qeth_hdr **);
void qeth_schedule_recovery(struct qeth_card *);
void qeth_qdio_start_poll(struct ccw_device *, int, unsigned long);
int qeth_poll(struct napi_struct *napi, int budget);
void qeth_qdio_input_handler(struct ccw_device *,
		unsigned int, unsigned int, int,
		int, unsigned long);
void qeth_qdio_output_handler(struct ccw_device *, unsigned int,
			int, int, int, unsigned long);
void qeth_clear_ipacmd_list(struct qeth_card *);
int qeth_qdio_clear_card(struct qeth_card *, int);
void qeth_clear_working_pool_list(struct qeth_card *);
@@ -979,8 +1018,6 @@ int qeth_hw_trap(struct qeth_card *, enum qeth_diags_trap_action);
int qeth_query_ipassists(struct qeth_card *, enum qeth_prot_versions prot);
void qeth_trace_features(struct qeth_card *);
void qeth_close_dev(struct qeth_card *);
int qeth_send_simple_setassparms(struct qeth_card *, enum qeth_ipa_funcs,
				 __u16, long);
int qeth_send_setassparms(struct qeth_card *, struct qeth_cmd_buffer *, __u16,
			  long,
			  int (*reply_cb)(struct qeth_card *,
+94 −54
Original line number Diff line number Diff line
@@ -1467,13 +1467,13 @@ static int qeth_setup_card(struct qeth_card *card)
	card->lan_online = 0;
	card->read_or_write_problem = 0;
	card->dev = NULL;
	spin_lock_init(&card->vlanlock);
	spin_lock_init(&card->mclock);
	spin_lock_init(&card->lock);
	spin_lock_init(&card->ip_lock);
	spin_lock_init(&card->thread_mask_lock);
	mutex_init(&card->conf_mutex);
	mutex_init(&card->discipline_mutex);
	mutex_init(&card->vid_list_mutex);
	card->thread_start_mask = 0;
	card->thread_allowed_mask = 0;
	card->thread_running_mask = 0;
@@ -3588,7 +3588,7 @@ static void qeth_check_outbound_queue(struct qeth_qdio_out_q *queue)
	}
}

void qeth_qdio_start_poll(struct ccw_device *ccwdev, int queue,
static void qeth_qdio_start_poll(struct ccw_device *ccwdev, int queue,
				 unsigned long card_ptr)
{
	struct qeth_card *card = (struct qeth_card *)card_ptr;
@@ -3596,7 +3596,6 @@ void qeth_qdio_start_poll(struct ccw_device *ccwdev, int queue,
	if (card->dev && (card->dev->flags & IFF_UP))
		napi_schedule(&card->napi);
}
EXPORT_SYMBOL_GPL(qeth_qdio_start_poll);

int qeth_configure_cq(struct qeth_card *card, enum qeth_cq cq)
{
@@ -3698,8 +3697,9 @@ static void qeth_qdio_cq_handler(struct qeth_card *card,
	return;
}

void qeth_qdio_input_handler(struct ccw_device *ccwdev, unsigned int qdio_err,
		unsigned int queue, int first_elem, int count,
static void qeth_qdio_input_handler(struct ccw_device *ccwdev,
				    unsigned int qdio_err, int queue,
				    int first_elem, int count,
				    unsigned long card_ptr)
{
	struct qeth_card *card = (struct qeth_card *)card_ptr;
@@ -3711,14 +3711,12 @@ void qeth_qdio_input_handler(struct ccw_device *ccwdev, unsigned int qdio_err,
		qeth_qdio_cq_handler(card, qdio_err, queue, first_elem, count);
	else if (qdio_err)
		qeth_schedule_recovery(card);


}
EXPORT_SYMBOL_GPL(qeth_qdio_input_handler);

void qeth_qdio_output_handler(struct ccw_device *ccwdev,
		unsigned int qdio_error, int __queue, int first_element,
		int count, unsigned long card_ptr)
static void qeth_qdio_output_handler(struct ccw_device *ccwdev,
				     unsigned int qdio_error, int __queue,
				     int first_element, int count,
				     unsigned long card_ptr)
{
	struct qeth_card *card        = (struct qeth_card *) card_ptr;
	struct qeth_qdio_out_q *queue = card->qdio.out_qs[__queue];
@@ -3787,7 +3785,6 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev,
		card->perf_stats.outbound_handler_time += qeth_get_micros() -
			card->perf_stats.outbound_handler_start_time;
}
EXPORT_SYMBOL_GPL(qeth_qdio_output_handler);

/* We cannot use outbound queue 3 for unicast packets on HiperSockets */
static inline int qeth_cut_iqd_prio(struct qeth_card *card, int queue_num)
@@ -4995,7 +4992,7 @@ static int qeth_qdio_establish(struct qeth_card *card)
		goto out_free_in_sbals;
	}
	for (i = 0; i < card->qdio.no_in_queues; ++i)
		queue_start_poll[i] = card->discipline->start_poll;
		queue_start_poll[i] = qeth_qdio_start_poll;

	qeth_qdio_establish_cq(card, in_sbal_ptrs, queue_start_poll);

@@ -5019,8 +5016,8 @@ static int qeth_qdio_establish(struct qeth_card *card)
	init_data.qib_param_field        = qib_param_field;
	init_data.no_input_qs            = card->qdio.no_in_queues;
	init_data.no_output_qs           = card->qdio.no_out_queues;
	init_data.input_handler 	 = card->discipline->input_handler;
	init_data.output_handler	 = card->discipline->output_handler;
	init_data.input_handler		 = qeth_qdio_input_handler;
	init_data.output_handler	 = qeth_qdio_output_handler;
	init_data.queue_start_poll_array = queue_start_poll;
	init_data.int_parm               = (unsigned long) card;
	init_data.input_sbal_addr_array  = (void **) in_sbal_ptrs;
@@ -5204,6 +5201,11 @@ int qeth_core_hardsetup_card(struct qeth_card *card)
	rc = qeth_query_ipassists(card, QETH_PROT_IPV4);
	if (rc == -ENOMEM)
		goto out;
	if (qeth_is_supported(card, IPA_IPV6)) {
		rc = qeth_query_ipassists(card, QETH_PROT_IPV6);
		if (rc == -ENOMEM)
			goto out;
	}
	if (qeth_is_supported(card, IPA_SETADAPTERPARMS)) {
		rc = qeth_query_setadapterparms(card);
		if (rc < 0) {
@@ -5511,26 +5513,26 @@ int qeth_send_setassparms(struct qeth_card *card,
}
EXPORT_SYMBOL_GPL(qeth_send_setassparms);

int qeth_send_simple_setassparms(struct qeth_card *card,
int qeth_send_simple_setassparms_prot(struct qeth_card *card,
				      enum qeth_ipa_funcs ipa_func,
				 __u16 cmd_code, long data)
				      u16 cmd_code, long data,
				      enum qeth_prot_versions prot)
{
	int rc;
	int length = 0;
	struct qeth_cmd_buffer *iob;

	QETH_CARD_TEXT(card, 4, "simassp4");
	QETH_CARD_TEXT_(card, 4, "simassp%i", prot);
	if (data)
		length = sizeof(__u32);
	iob = qeth_get_setassparms_cmd(card, ipa_func, cmd_code,
				       length, QETH_PROT_IPV4);
	iob = qeth_get_setassparms_cmd(card, ipa_func, cmd_code, length, prot);
	if (!iob)
		return -ENOMEM;
	rc = qeth_send_setassparms(card, iob, length, data,
				   qeth_setassparms_cb, NULL);
	return rc;
}
EXPORT_SYMBOL_GPL(qeth_send_simple_setassparms);
EXPORT_SYMBOL_GPL(qeth_send_simple_setassparms_prot);

static void qeth_unregister_dbf_views(void)
{
@@ -6008,7 +6010,8 @@ static struct {
	{"tx lin"},
	{"tx linfail"},
	{"cq handler count"},
	{"cq handler time"}
	{"cq handler time"},
	{"rx csum"}
};

int qeth_core_get_sset_count(struct net_device *dev, int stringset)
@@ -6070,6 +6073,7 @@ void qeth_core_get_ethtool_stats(struct net_device *dev,
	data[35] = card->perf_stats.tx_linfail;
	data[36] = card->perf_stats.cq_cnt;
	data[37] = card->perf_stats.cq_time;
	data[38] = card->perf_stats.rx_csum;
}
EXPORT_SYMBOL_GPL(qeth_core_get_ethtool_stats);

@@ -6326,14 +6330,15 @@ static int qeth_ipa_checksum_run_cmd_cb(struct qeth_card *card,
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_checksum_cmd *chksum_cb,
				     enum qeth_prot_versions prot)
{
	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);
				       sizeof(__u32), prot);
	if (iob)
		rc = qeth_send_setassparms(card, iob, sizeof(__u32), data,
					   qeth_ipa_checksum_run_cmd_cb,
@@ -6341,16 +6346,17 @@ static int qeth_ipa_checksum_run_cmd(struct qeth_card *card,
	return rc;
}

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

	if (prot == QETH_PROT_IPV4)
		required_features |= QETH_IPA_CHECKSUM_IP_HDR;
	rc = qeth_ipa_checksum_run_cmd(card, cstype, IPA_CMD_ASS_START, 0,
				       &chksum_cb);
				       &chksum_cb, prot);
	if (!rc) {
		if ((required_features & chksum_cb.supported) !=
		    required_features)
@@ -6362,37 +6368,42 @@ static int qeth_send_checksum_on(struct qeth_card *card, int cstype)
				 QETH_CARD_IFNAME(card));
	}
	if (rc) {
		qeth_send_simple_setassparms(card, cstype, IPA_CMD_ASS_STOP, 0);
		qeth_send_simple_setassparms_prot(card, cstype,
						  IPA_CMD_ASS_STOP, 0, prot);
		dev_warn(&card->gdev->dev,
			 "Starting HW checksumming for %s failed, using SW checksumming\n",
			 QETH_CARD_IFNAME(card));
			 "Starting HW IPv%d checksumming for %s failed, using SW checksumming\n",
			 prot, QETH_CARD_IFNAME(card));
		return rc;
	}
	rc = qeth_ipa_checksum_run_cmd(card, cstype, IPA_CMD_ASS_ENABLE,
				       chksum_cb.supported, &chksum_cb);
				       chksum_cb.supported, &chksum_cb,
				       prot);
	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);
		qeth_send_simple_setassparms_prot(card, cstype,
						  IPA_CMD_ASS_STOP, 0, prot);
		dev_warn(&card->gdev->dev,
			 "Enabling HW checksumming for %s failed, using SW checksumming\n",
			 QETH_CARD_IFNAME(card));
			 "Enabling HW IPv%d checksumming for %s failed, using SW checksumming\n",
			 prot, QETH_CARD_IFNAME(card));
		return rc;
	}

	dev_info(&card->gdev->dev, "HW Checksumming (%sbound) enabled\n",
		 cstype == IPA_INBOUND_CHECKSUM ? "in" : "out");
	dev_info(&card->gdev->dev, "HW Checksumming (%sbound IPv%d) enabled\n",
		 cstype == IPA_INBOUND_CHECKSUM ? "in" : "out", prot);
	return 0;
}

static int qeth_set_ipa_csum(struct qeth_card *card, int on, int cstype)
static int qeth_set_ipa_csum(struct qeth_card *card, bool on, int cstype,
			     enum qeth_prot_versions prot)
{
	int rc = (on) ? qeth_send_checksum_on(card, cstype)
		      : qeth_send_simple_setassparms(card, cstype,
						     IPA_CMD_ASS_STOP, 0);
	int rc = (on) ? qeth_send_checksum_on(card, cstype, prot)
		      : qeth_send_simple_setassparms_prot(card, cstype,
							  IPA_CMD_ASS_STOP, 0,
							  prot);
	return rc ? -EIO : 0;
}

@@ -6419,8 +6430,31 @@ static int qeth_set_ipa_tso(struct qeth_card *card, int on)
	return rc;
}

#define QETH_HW_FEATURES (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_TSO)
static int qeth_set_ipa_rx_csum(struct qeth_card *card, bool on)
{
	int rc_ipv4 = (on) ? -EOPNOTSUPP : 0;
	int rc_ipv6;

	if (qeth_is_supported(card, IPA_INBOUND_CHECKSUM))
		rc_ipv4 = qeth_set_ipa_csum(card, on, IPA_INBOUND_CHECKSUM,
					    QETH_PROT_IPV4);
	if (!qeth_is_supported6(card, IPA_INBOUND_CHECKSUM_V6))
		/* no/one Offload Assist available, so the rc is trivial */
		return rc_ipv4;

	rc_ipv6 = qeth_set_ipa_csum(card, on, IPA_INBOUND_CHECKSUM,
				    QETH_PROT_IPV6);

	if (on)
		/* enable: success if any Assist is active */
		return (rc_ipv6) ? rc_ipv4 : 0;

	/* disable: failure if any Assist is still active */
	return (rc_ipv6) ? rc_ipv6 : rc_ipv4;
}

#define QETH_HW_FEATURES (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_TSO | \
			  NETIF_F_IPV6_CSUM)
/**
 * qeth_recover_features() - Restore device features after recovery
 * @dev:	the recovering net_device
@@ -6455,16 +6489,19 @@ int qeth_set_features(struct net_device *dev, netdev_features_t features)
	QETH_DBF_HEX(SETUP, 2, &features, sizeof(features));

	if ((changed & NETIF_F_IP_CSUM)) {
		rc = qeth_set_ipa_csum(card,
				       features & NETIF_F_IP_CSUM ? 1 : 0,
				       IPA_OUTBOUND_CHECKSUM);
		rc = qeth_set_ipa_csum(card, features & NETIF_F_IP_CSUM,
				       IPA_OUTBOUND_CHECKSUM, QETH_PROT_IPV4);
		if (rc)
			changed ^= NETIF_F_IP_CSUM;
	}
	if ((changed & NETIF_F_RXCSUM)) {
		rc = qeth_set_ipa_csum(card,
					features & NETIF_F_RXCSUM ? 1 : 0,
					IPA_INBOUND_CHECKSUM);
	if (changed & NETIF_F_IPV6_CSUM) {
		rc = qeth_set_ipa_csum(card, features & NETIF_F_IPV6_CSUM,
				       IPA_OUTBOUND_CHECKSUM, QETH_PROT_IPV6);
		if (rc)
			changed ^= NETIF_F_IPV6_CSUM;
	}
	if (changed & NETIF_F_RXCSUM) {
		rc = qeth_set_ipa_rx_csum(card, features & NETIF_F_RXCSUM);
		if (rc)
			changed ^= NETIF_F_RXCSUM;
	}
@@ -6491,7 +6528,10 @@ netdev_features_t qeth_fix_features(struct net_device *dev,
	QETH_DBF_TEXT(SETUP, 2, "fixfeat");
	if (!qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM))
		features &= ~NETIF_F_IP_CSUM;
	if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM))
	if (!qeth_is_supported6(card, IPA_OUTBOUND_CHECKSUM_V6))
		features &= ~NETIF_F_IPV6_CSUM;
	if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM) &&
	    !qeth_is_supported6(card, IPA_INBOUND_CHECKSUM_V6))
		features &= ~NETIF_F_RXCSUM;
	if (!qeth_is_supported(card, IPA_OUTBOUND_TSO))
		features &= ~NETIF_F_TSO;
+2 −0
Original line number Diff line number Diff line
@@ -246,6 +246,8 @@ enum qeth_ipa_funcs {
	IPA_QUERY_ARP_ASSIST	= 0x00040000L,
	IPA_INBOUND_TSO         = 0x00080000L,
	IPA_OUTBOUND_TSO        = 0x00100000L,
	IPA_INBOUND_CHECKSUM_V6 = 0x00400000L,
	IPA_OUTBOUND_CHECKSUM_V6 = 0x00800000L,
};

/* SETIP/DELIP IPA Command: ***************************************************/
+2 −0
Original line number Diff line number Diff line
@@ -144,6 +144,8 @@ static ssize_t qeth_dev_portno_store(struct device *dev,
		goto out;
	}
	card->info.portno = portno;
	if (card->dev)
		card->dev->dev_port = portno;
out:
	mutex_unlock(&card->conf_mutex);
	return rc ? rc : count;
Loading