summaryrefslogtreecommitdiff
path: root/drivers/s390
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-11-04 09:41:05 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-04 09:41:05 -0800
commitb0f85fa11aefc4f3e03306b4cd47f113bd57dcba (patch)
tree1333d36d99fde3f97210795941fc246f0ad08a75 /drivers/s390
parentccc9d4a6d640cbde05d519edeb727881646cf71b (diff)
parentf32bfb9a8ca083f8d148ea90ae5ba66f4831836e (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: Changes of note: 1) Allow to schedule ICMP packets in IPVS, from Alex Gartrell. 2) Provide FIB table ID in ipv4 route dumps just as ipv6 does, from David Ahern. 3) Allow the user to ask for the statistics to be filtered out of ipv4/ipv6 address netlink dumps. From Sowmini Varadhan. 4) More work to pass the network namespace context around deep into various packet path APIs, starting with the netfilter hooks. From Eric W Biederman. 5) Add layer 2 TX/RX checksum offloading to qeth driver, from Thomas Richter. 6) Use usec resolution for SYN/ACK RTTs in TCP, from Yuchung Cheng. 7) Support Very High Throughput in wireless MESH code, from Bob Copeland. 8) Allow setting the ageing_time in switchdev/rocker. From Scott Feldman. 9) Properly autoload L2TP type modules, from Stephen Hemminger. 10) Fix and enable offload features by default in 8139cp driver, from David Woodhouse. 11) Support both ipv4 and ipv6 sockets in a single vxlan device, from Jiri Benc. 12) Fix CWND limiting of thin streams in TCP, from Bendik Rønning Opstad. 13) Fix IPSEC flowcache overflows on large systems, from Steffen Klassert. 14) Convert bridging to track VLANs using rhashtable entries rather than a bitmap. From Nikolay Aleksandrov. 15) Make TCP listener handling completely lockless, this is a major accomplishment. Incoming request sockets now live in the established hash table just like any other socket too. From Eric Dumazet. 15) Provide more bridging attributes to netlink, from Nikolay Aleksandrov. 16) Use hash based algorithm for ipv4 multipath routing, this was very long overdue. From Peter Nørlund. 17) Several y2038 cures, mostly avoiding timespec. From Arnd Bergmann. 18) Allow non-root execution of EBPF programs, from Alexei Starovoitov. 19) Support SO_INCOMING_CPU as setsockopt, from Eric Dumazet. This influences the port binding selection logic used by SO_REUSEPORT. 20) Add ipv6 support to VRF, from David Ahern. 21) Add support for Mellanox Spectrum switch ASIC, from Jiri Pirko. 22) Add rtl8xxxu Realtek wireless driver, from Jes Sorensen. 23) Implement RACK loss recovery in TCP, from Yuchung Cheng. 24) Support multipath routes in MPLS, from Roopa Prabhu. 25) Fix POLLOUT notification for listening sockets in AF_UNIX, from Eric Dumazet. 26) Add new QED Qlogic river, from Yuval Mintz, Manish Chopra, and Sudarsana Kalluru. 27) Don't fetch timestamps on AF_UNIX sockets, from Hannes Frederic Sowa. 28) Support ipv6 geneve tunnels, from John W Linville. 29) Add flood control support to switchdev layer, from Ido Schimmel. 30) Fix CHECKSUM_PARTIAL handling of potentially fragmented frames, from Hannes Frederic Sowa. 31) Support persistent maps and progs in bpf, from Daniel Borkmann. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1790 commits) sh_eth: use DMA barriers switchdev: respect SKIP_EOPNOTSUPP flag in case there is no recursion net: sched: kill dead code in sch_choke.c irda: Delete an unnecessary check before the function call "irlmp_unregister_service" net: dsa: mv88e6xxx: include DSA ports in VLANs net: dsa: mv88e6xxx: disable SA learning for DSA and CPU ports net/core: fix for_each_netdev_feature vlan: Invoke driver vlan hooks only if device is present arcnet/com20020: add LEDS_CLASS dependency bpf, verifier: annotate verbose printer with __printf dp83640: Only wait for timestamps for packets with timestamping enabled. ptp: Change ptp_class to a proper bitmask dp83640: Prune rx timestamp list before reading from it dp83640: Delay scheduled work. dp83640: Include hash in timestamp/packet matching ipv6: fix tunnel error handling net/mlx5e: Fix LSO vlan insertion net/mlx5e: Re-eanble client vlan TX acceleration net/mlx5e: Return error in case mlx5e_set_features() fails net/mlx5e: Don't allow more than max supported channels ...
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/char/monreader.c4
-rw-r--r--drivers/s390/char/vmlogrdr.c8
-rw-r--r--drivers/s390/cio/qdio_main.c4
-rw-r--r--drivers/s390/net/netiucv.c21
-rw-r--r--drivers/s390/net/qeth_core.h30
-rw-r--r--drivers/s390/net/qeth_core_main.c241
-rw-r--r--drivers/s390/net/qeth_core_sys.c43
-rw-r--r--drivers/s390/net/qeth_l2_main.c228
-rw-r--r--drivers/s390/net/qeth_l2_sys.c2
-rw-r--r--drivers/s390/net/qeth_l3_main.c158
-rw-r--r--drivers/s390/net/smsgiucv.c5
11 files changed, 430 insertions, 314 deletions
diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c
index b7d60306b0bc..fc94bfdceb95 100644
--- a/drivers/s390/char/monreader.c
+++ b/drivers/s390/char/monreader.c
@@ -229,7 +229,7 @@ static struct mon_msg *mon_next_message(struct mon_private *monpriv)
/******************************************************************************
* IUCV handler *
*****************************************************************************/
-static void mon_iucv_path_complete(struct iucv_path *path, u8 ipuser[16])
+static void mon_iucv_path_complete(struct iucv_path *path, u8 *ipuser)
{
struct mon_private *monpriv = path->private;
@@ -237,7 +237,7 @@ static void mon_iucv_path_complete(struct iucv_path *path, u8 ipuser[16])
wake_up(&mon_conn_wait_queue);
}
-static void mon_iucv_path_severed(struct iucv_path *path, u8 ipuser[16])
+static void mon_iucv_path_severed(struct iucv_path *path, u8 *ipuser)
{
struct mon_private *monpriv = path->private;
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index 9bb48d70957c..799c1524c779 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -99,8 +99,8 @@ static const struct file_operations vmlogrdr_fops = {
};
-static void vmlogrdr_iucv_path_complete(struct iucv_path *, u8 ipuser[16]);
-static void vmlogrdr_iucv_path_severed(struct iucv_path *, u8 ipuser[16]);
+static void vmlogrdr_iucv_path_complete(struct iucv_path *, u8 *ipuser);
+static void vmlogrdr_iucv_path_severed(struct iucv_path *, u8 *ipuser);
static void vmlogrdr_iucv_message_pending(struct iucv_path *,
struct iucv_message *);
@@ -160,7 +160,7 @@ static struct cdev *vmlogrdr_cdev = NULL;
static int recording_class_AB;
-static void vmlogrdr_iucv_path_complete(struct iucv_path *path, u8 ipuser[16])
+static void vmlogrdr_iucv_path_complete(struct iucv_path *path, u8 *ipuser)
{
struct vmlogrdr_priv_t * logptr = path->private;
@@ -171,7 +171,7 @@ static void vmlogrdr_iucv_path_complete(struct iucv_path *path, u8 ipuser[16])
}
-static void vmlogrdr_iucv_path_severed(struct iucv_path *path, u8 ipuser[16])
+static void vmlogrdr_iucv_path_severed(struct iucv_path *path, u8 *ipuser)
{
struct vmlogrdr_priv_t * logptr = path->private;
u8 reason = (u8) ipuser[8];
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 848e3b64ea6e..4bb5262f7aee 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -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 */
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index 33f7040d711d..0ba3a2f81750 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -149,12 +149,11 @@ static struct device_driver netiucv_driver = {
.pm = &netiucv_pm_ops,
};
-static int netiucv_callback_connreq(struct iucv_path *,
- u8 ipvmid[8], u8 ipuser[16]);
-static void netiucv_callback_connack(struct iucv_path *, u8 ipuser[16]);
-static void netiucv_callback_connrej(struct iucv_path *, u8 ipuser[16]);
-static void netiucv_callback_connsusp(struct iucv_path *, u8 ipuser[16]);
-static void netiucv_callback_connres(struct iucv_path *, u8 ipuser[16]);
+static int netiucv_callback_connreq(struct iucv_path *, u8 *, u8 *);
+static void netiucv_callback_connack(struct iucv_path *, u8 *);
+static void netiucv_callback_connrej(struct iucv_path *, u8 *);
+static void netiucv_callback_connsusp(struct iucv_path *, u8 *);
+static void netiucv_callback_connres(struct iucv_path *, u8 *);
static void netiucv_callback_rx(struct iucv_path *, struct iucv_message *);
static void netiucv_callback_txdone(struct iucv_path *, struct iucv_message *);
@@ -556,8 +555,8 @@ static void netiucv_callback_connack(struct iucv_path *path, u8 ipuser[16])
fsm_event(conn->fsm, CONN_EVENT_CONN_ACK, conn);
}
-static int netiucv_callback_connreq(struct iucv_path *path,
- u8 ipvmid[8], u8 ipuser[16])
+static int netiucv_callback_connreq(struct iucv_path *path, u8 *ipvmid,
+ u8 *ipuser)
{
struct iucv_connection *conn = path->private;
struct iucv_event ev;
@@ -587,21 +586,21 @@ static int netiucv_callback_connreq(struct iucv_path *path,
return rc;
}
-static void netiucv_callback_connrej(struct iucv_path *path, u8 ipuser[16])
+static void netiucv_callback_connrej(struct iucv_path *path, u8 *ipuser)
{
struct iucv_connection *conn = path->private;
fsm_event(conn->fsm, CONN_EVENT_CONN_REJ, conn);
}
-static void netiucv_callback_connsusp(struct iucv_path *path, u8 ipuser[16])
+static void netiucv_callback_connsusp(struct iucv_path *path, u8 *ipuser)
{
struct iucv_connection *conn = path->private;
fsm_event(conn->fsm, CONN_EVENT_CONN_SUS, conn);
}
-static void netiucv_callback_connres(struct iucv_path *path, u8 ipuser[16])
+static void netiucv_callback_connres(struct iucv_path *path, u8 *ipuser)
{
struct iucv_connection *conn = path->private;
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index ba974a2e409f..1766a20ebcb1 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -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>
@@ -663,9 +664,7 @@ struct qeth_card_info {
char mcl_level[QETH_MCL_LENGTH + 1];
int guestlan;
int mac_bits;
- int portname_required;
int portno;
- char portname[9];
enum qeth_card_types type;
enum qeth_link_types link_type;
int is_multicast_different;
@@ -741,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 {
@@ -792,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;
@@ -969,6 +974,15 @@ 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 *,
+ struct qeth_reply *, unsigned long),
+ void *);
+int qeth_start_ipa_tx_checksum(struct qeth_card *);
+int qeth_set_rx_csum(struct qeth_card *, int);
/* exports for OSN */
int qeth_osn_assist(struct net_device *, void *, int);
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 5e20fba37bff..31ac53fa5cee 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -1982,14 +1982,6 @@ static void qeth_idx_read_cb(struct qeth_channel *channel,
goto out;
}
-/**
- * * temporary fix for microcode bug
- * * to revert it,replace OR by AND
- * */
- if ((!QETH_IDX_NO_PORTNAME_REQUIRED(iob->data)) ||
- (card->info.type == QETH_CARD_TYPE_OSD))
- card->info.portname_required = 1;
-
memcpy(&temp, QETH_IDX_ACT_FUNC_LEVEL(iob->data), 2);
if (temp != qeth_peer_func_level(card->info.func_level)) {
QETH_DBF_MESSAGE(2, "%s IDX_ACTIVATE on read channel: function "
@@ -2360,8 +2352,6 @@ static int qeth_ulp_enable(struct qeth_card *card)
&card->token.cm_connection_r, QETH_MPC_TOKEN_LENGTH);
memcpy(QETH_ULP_ENABLE_FILTER_TOKEN(iob->data),
&card->token.ulp_filter_w, QETH_MPC_TOKEN_LENGTH);
- memcpy(QETH_ULP_ENABLE_PORTNAME_AND_LL(iob->data),
- card->info.portname, 9);
rc = qeth_send_control_data(card, ULP_ENABLE_SIZE, iob,
qeth_ulp_enable_cb, NULL);
return rc;
@@ -2680,48 +2670,6 @@ out_qdio:
return rc;
}
-static void qeth_print_status_with_portname(struct qeth_card *card)
-{
- char dbf_text[15];
- int i;
-
- sprintf(dbf_text, "%s", card->info.portname + 1);
- for (i = 0; i < 8; i++)
- dbf_text[i] =
- (char) _ebcasc[(__u8) dbf_text[i]];
- dbf_text[8] = 0;
- dev_info(&card->gdev->dev, "Device is a%s card%s%s%s\n"
- "with link type %s (portname: %s)\n",
- qeth_get_cardname(card),
- (card->info.mcl_level[0]) ? " (level: " : "",
- (card->info.mcl_level[0]) ? card->info.mcl_level : "",
- (card->info.mcl_level[0]) ? ")" : "",
- qeth_get_cardname_short(card),
- dbf_text);
-
-}
-
-static void qeth_print_status_no_portname(struct qeth_card *card)
-{
- if (card->info.portname[0])
- dev_info(&card->gdev->dev, "Device is a%s "
- "card%s%s%s\nwith link type %s "
- "(no portname needed by interface).\n",
- qeth_get_cardname(card),
- (card->info.mcl_level[0]) ? " (level: " : "",
- (card->info.mcl_level[0]) ? card->info.mcl_level : "",
- (card->info.mcl_level[0]) ? ")" : "",
- qeth_get_cardname_short(card));
- else
- dev_info(&card->gdev->dev, "Device is a%s "
- "card%s%s%s\nwith link type %s.\n",
- qeth_get_cardname(card),
- (card->info.mcl_level[0]) ? " (level: " : "",
- (card->info.mcl_level[0]) ? card->info.mcl_level : "",
- (card->info.mcl_level[0]) ? ")" : "",
- qeth_get_cardname_short(card));
-}
-
void qeth_print_status_message(struct qeth_card *card)
{
switch (card->info.type) {
@@ -2758,10 +2706,13 @@ void qeth_print_status_message(struct qeth_card *card)
default:
memset(&card->info.mcl_level[0], 0, QETH_MCL_LENGTH + 1);
}
- if (card->info.portname_required)
- qeth_print_status_with_portname(card);
- else
- qeth_print_status_no_portname(card);
+ dev_info(&card->gdev->dev,
+ "Device is a%s card%s%s%s\nwith link type %s.\n",
+ qeth_get_cardname(card),
+ (card->info.mcl_level[0]) ? " (level: " : "",
+ (card->info.mcl_level[0]) ? card->info.mcl_level : "",
+ (card->info.mcl_level[0]) ? ")" : "",
+ qeth_get_cardname_short(card));
}
EXPORT_SYMBOL_GPL(qeth_print_status_message);
@@ -5027,13 +4978,11 @@ static void qeth_core_free_card(struct qeth_card *card)
void qeth_trace_features(struct qeth_card *card)
{
QETH_CARD_TEXT(card, 2, "features");
- QETH_CARD_TEXT_(card, 2, "%x", card->options.ipa4.supported_funcs);
- QETH_CARD_TEXT_(card, 2, "%x", card->options.ipa4.enabled_funcs);
- QETH_CARD_TEXT_(card, 2, "%x", card->options.ipa6.supported_funcs);
- QETH_CARD_TEXT_(card, 2, "%x", card->options.ipa6.enabled_funcs);
- QETH_CARD_TEXT_(card, 2, "%x", card->options.adp.supported_funcs);
- QETH_CARD_TEXT_(card, 2, "%x", card->options.adp.enabled_funcs);
- QETH_CARD_TEXT_(card, 2, "%x", card->info.diagass_support);
+ QETH_CARD_HEX(card, 2, &card->options.ipa4, sizeof(card->options.ipa4));
+ QETH_CARD_HEX(card, 2, &card->options.ipa6, sizeof(card->options.ipa6));
+ QETH_CARD_HEX(card, 2, &card->options.adp, sizeof(card->options.adp));
+ QETH_CARD_HEX(card, 2, &card->info.diagass_support,
+ sizeof(card->info.diagass_support));
}
EXPORT_SYMBOL_GPL(qeth_trace_features);
@@ -5132,6 +5081,7 @@ retriable:
}
card->options.ipa4.supported_funcs = 0;
+ card->options.ipa6.supported_funcs = 0;
card->options.adp.supported_funcs = 0;
card->options.sbp.supported_funcs = 0;
card->info.diagass_support = 0;
@@ -5317,6 +5267,102 @@ no_mem:
}
EXPORT_SYMBOL_GPL(qeth_core_get_next_skb);
+static int qeth_setassparms_cb(struct qeth_card *card,
+ struct qeth_reply *reply, unsigned long data)
+{
+ struct qeth_ipa_cmd *cmd;
+
+ QETH_CARD_TEXT(card, 4, "defadpcb");
+
+ cmd = (struct qeth_ipa_cmd *) data;
+ if (cmd->hdr.return_code == 0) {
+ cmd->hdr.return_code = cmd->data.setassparms.hdr.return_code;
+ if (cmd->hdr.prot_version == QETH_PROT_IPV4)
+ card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
+ if (cmd->hdr.prot_version == QETH_PROT_IPV6)
+ card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
+ }
+ if (cmd->data.setassparms.hdr.assist_no == IPA_INBOUND_CHECKSUM &&
+ cmd->data.setassparms.hdr.command_code == IPA_CMD_ASS_START) {
+ card->info.csum_mask = cmd->data.setassparms.data.flags_32bit;
+ QETH_CARD_TEXT_(card, 3, "csum:%d", card->info.csum_mask);
+ }
+ if (cmd->data.setassparms.hdr.assist_no == IPA_OUTBOUND_CHECKSUM &&
+ cmd->data.setassparms.hdr.command_code == IPA_CMD_ASS_START) {
+ card->info.tx_csum_mask =
+ cmd->data.setassparms.data.flags_32bit;
+ QETH_CARD_TEXT_(card, 3, "tcsu:%d", card->info.tx_csum_mask);
+ }
+
+ return 0;
+}
+
+static struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *card,
+ enum qeth_ipa_funcs ipa_func,
+ __u16 cmd_code, __u16 len,
+ enum qeth_prot_versions prot)
+{
+ struct qeth_cmd_buffer *iob;
+ struct qeth_ipa_cmd *cmd;
+
+ QETH_CARD_TEXT(card, 4, "getasscm");
+ iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETASSPARMS, prot);
+
+ if (iob) {
+ cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
+ cmd->data.setassparms.hdr.assist_no = ipa_func;
+ cmd->data.setassparms.hdr.length = 8 + len;
+ cmd->data.setassparms.hdr.command_code = cmd_code;
+ cmd->data.setassparms.hdr.return_code = 0;
+ cmd->data.setassparms.hdr.seq_no = 0;
+ }
+
+ return iob;
+}
+
+int qeth_send_setassparms(struct qeth_card *card,
+ struct qeth_cmd_buffer *iob, __u16 len, long data,
+ int (*reply_cb)(struct qeth_card *,
+ struct qeth_reply *, unsigned long),
+ void *reply_param)
+{
+ int rc;
+ struct qeth_ipa_cmd *cmd;
+
+ QETH_CARD_TEXT(card, 4, "sendassp");
+
+ cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
+ if (len <= sizeof(__u32))
+ cmd->data.setassparms.data.flags_32bit = (__u32) data;
+ else /* (len > sizeof(__u32)) */
+ memcpy(&cmd->data.setassparms.data, (void *) data, len);
+
+ rc = qeth_send_ipa_cmd(card, iob, reply_cb, reply_param);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(qeth_send_setassparms);
+
+int qeth_send_simple_setassparms(struct qeth_card *card,
+ enum qeth_ipa_funcs ipa_func,
+ __u16 cmd_code, long data)
+{
+ int rc;
+ int length = 0;
+ struct qeth_cmd_buffer *iob;
+
+ QETH_CARD_TEXT(card, 4, "simassp4");
+ if (data)
+ length = sizeof(__u32);
+ iob = qeth_get_setassparms_cmd(card, ipa_func, cmd_code,
+ length, QETH_PROT_IPV4);
+ 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);
+
static void qeth_unregister_dbf_views(void)
{
int x;
@@ -6003,6 +6049,75 @@ int qeth_core_ethtool_get_settings(struct net_device *netdev,
}
EXPORT_SYMBOL_GPL(qeth_core_ethtool_get_settings);
+static int qeth_send_checksum_command(struct qeth_card *card)
+{
+ int rc;
+
+ rc = qeth_send_simple_setassparms(card, IPA_INBOUND_CHECKSUM,
+ IPA_CMD_ASS_START, 0);
+ if (rc) {
+ dev_warn(&card->gdev->dev, "Starting HW checksumming for %s "
+ "failed, using SW checksumming\n",
+ QETH_CARD_IFNAME(card));
+ return rc;
+ }
+ rc = qeth_send_simple_setassparms(card, IPA_INBOUND_CHECKSUM,
+ IPA_CMD_ASS_ENABLE,
+ card->info.csum_mask);
+ if (rc) {
+ dev_warn(&card->gdev->dev, "Enabling HW checksumming for %s "
+ "failed, using SW checksumming\n",
+ QETH_CARD_IFNAME(card));
+ return rc;
+ }
+ return 0;
+}
+
+int qeth_set_rx_csum(struct qeth_card *card, int on)
+{
+ int rc;
+
+ if (on) {
+ rc = qeth_send_checksum_command(card);
+ if (rc)
+ return -EIO;
+ dev_info(&card->gdev->dev,
+ "HW Checksumming (inbound) enabled\n");
+ } else {
+ rc = qeth_send_simple_setassparms(card,
+ IPA_INBOUND_CHECKSUM, IPA_CMD_ASS_STOP, 0);
+ if (rc)
+ return -EIO;
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(qeth_set_rx_csum);
+
+int qeth_start_ipa_tx_checksum(struct qeth_card *card)
+{
+ int rc = 0;
+
+ if (!qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM))
+ return rc;
+ rc = qeth_send_simple_setassparms(card, IPA_OUTBOUND_CHECKSUM,
+ IPA_CMD_ASS_START, 0);
+ if (rc)
+ goto err_out;
+ rc = qeth_send_simple_setassparms(card, IPA_OUTBOUND_CHECKSUM,
+ IPA_CMD_ASS_ENABLE,
+ card->info.tx_csum_mask);
+ if (rc)
+ goto err_out;
+
+ dev_info(&card->gdev->dev, "HW TX Checksumming enabled\n");
+ return rc;
+err_out:
+ dev_warn(&card->gdev->dev, "Enabling HW TX checksumming for %s "
+ "failed, using SW TX checksumming\n", QETH_CARD_IFNAME(card));
+ return rc;
+}
+EXPORT_SYMBOL_GPL(qeth_start_ipa_tx_checksum);
+
static int __init qeth_core_init(void)
{
int rc;
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c
index 423bec56cffa..e6e5b9671bf2 100644
--- a/drivers/s390/net/qeth_core_sys.c
+++ b/drivers/s390/net/qeth_core_sys.c
@@ -153,52 +153,17 @@ static DEVICE_ATTR(portno, 0644, qeth_dev_portno_show, qeth_dev_portno_store);
static ssize_t qeth_dev_portname_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct qeth_card *card = dev_get_drvdata(dev);
- char portname[9] = {0, };
-
- if (!card)
- return -EINVAL;
-
- if (card->info.portname_required) {
- memcpy(portname, card->info.portname + 1, 8);
- EBCASC(portname, 8);
- return sprintf(buf, "%s\n", portname);
- } else
- return sprintf(buf, "no portname required\n");
+ return sprintf(buf, "no portname required\n");
}
static ssize_t qeth_dev_portname_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct qeth_card *card = dev_get_drvdata(dev);
- char *tmp;
- int i, rc = 0;
-
- if (!card)
- return -EINVAL;
-
- mutex_lock(&card->conf_mutex);
- if ((card->state != CARD_STATE_DOWN) &&
- (card->state != CARD_STATE_RECOVER)) {
- rc = -EPERM;
- goto out;
- }
- tmp = strsep((char **) &buf, "\n");
- if ((strlen(tmp) > 8) || (strlen(tmp) == 0)) {
- rc = -EINVAL;
- goto out;
- }
-
- card->info.portname[0] = strlen(tmp);
- /* for beauty reasons */
- for (i = 1; i < 9; i++)
- card->info.portname[i] = ' ';
- strcpy(card->info.portname + 1, tmp);
- ASCEBC(card->info.portname + 1, 8);
-out:
- mutex_unlock(&card->conf_mutex);
- return rc ? rc : count;
+ dev_warn_once(&card->gdev->dev,
+ "portname is deprecated and is ignored\n");
+ return count;
}
static DEVICE_ATTR(portname, 0644, qeth_dev_portname_show,
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index a8556692f632..8f1b091e1732 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -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,
- IPA_CMD_DELVMAC);
+ 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);
}
@@ -252,6 +249,23 @@ static inline int qeth_l2_get_cast_type(struct qeth_card *card,
return RTN_UNSPEC;
}
+static inline void qeth_l2_hdr_csum(struct qeth_card *card,
+ struct qeth_hdr *hdr, struct sk_buff *skb)
+{
+ struct iphdr *iph = ip_hdr(skb);
+
+ /* tcph->check contains already the pseudo hdr checksum
+ * so just set the header flags
+ */
+ if (iph->protocol == IPPROTO_UDP)
+ hdr->hdr.l2.flags[1] |= QETH_HDR_EXT_UDP;
+ hdr->hdr.l2.flags[1] |= QETH_HDR_EXT_CSUM_TRANSP_REQ |
+ QETH_HDR_EXT_CSUM_HDR_REQ;
+ iph->check = 0;
+ if (card->options.performance_stats)
+ card->perf_stats.tx_csum++;
+}
+
static void qeth_l2_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
struct sk_buff *skb, int cast_type)
{
@@ -386,10 +400,42 @@ 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;
}
+static netdev_features_t qeth_l2_fix_features(struct net_device *dev,
+ netdev_features_t features)
+{
+ struct qeth_card *card = dev->ml_priv;
+
+ 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))
+ features &= ~NETIF_F_RXCSUM;
+ QETH_DBF_HEX(SETUP, 2, &features, sizeof(features));
+ return features;
+}
+
+static int qeth_l2_set_features(struct net_device *dev,
+ netdev_features_t features)
+{
+ struct qeth_card *card = dev->ml_priv;
+ netdev_features_t changed = dev->features ^ features;
+
+ QETH_DBF_TEXT(SETUP, 2, "setfeat");
+ QETH_DBF_HEX(SETUP, 2, &features, sizeof(features));
+
+ if (card->state == CARD_STATE_DOWN ||
+ card->state == CARD_STATE_RECOVER)
+ return 0;
+
+ if (!(changed & NETIF_F_RXCSUM))
+ return 0;
+ return qeth_set_rx_csum(card, features & NETIF_F_RXCSUM ? 1 : 0);
+}
+
static void qeth_l2_stop_card(struct qeth_card *card, int recovery_mode)
{
QETH_DBF_TEXT(SETUP , 2, "stopcard");
@@ -411,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;
}
@@ -450,11 +496,19 @@ static int qeth_l2_process_inbound_buffer(struct qeth_card *card,
case QETH_HEADER_TYPE_LAYER2:
skb->pkt_type = PACKET_HOST;
skb->protocol = eth_type_trans(skb, skb->dev);
- skb->ip_summed = CHECKSUM_NONE;
+ if ((card->dev->features & NETIF_F_RXCSUM)
+ && ((hdr->hdr.l2.flags[1] &
+ (QETH_HDR_EXT_CSUM_HDR_REQ |
+ QETH_HDR_EXT_CSUM_TRANSP_REQ)) ==
+ (QETH_HDR_EXT_CSUM_HDR_REQ |
+ QETH_HDR_EXT_CSUM_TRANSP_REQ)))
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ else
+ skb->ip_summed = CHECKSUM_NONE;
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) {
@@ -711,29 +765,91 @@ 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;
-static void qeth_l2_set_multicast_list(struct net_device *dev)
+ 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;
+ }
+ }
+
+ 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 ;
+ return;
QETH_CARD_TEXT(card, 3, "setmulti");
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
@@ -803,6 +919,8 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
sizeof(struct qeth_hdr));
skb_set_mac_header(new_skb, sizeof(struct qeth_hdr));
qeth_l2_fill_header(card, hdr, new_skb, cast_type);
+ if (new_skb->ip_summed == CHECKSUM_PARTIAL)
+ qeth_l2_hdr_csum(card, hdr, new_skb);
}
}
@@ -915,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;
@@ -961,13 +1079,15 @@ 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,
.ndo_vlan_rx_add_vid = qeth_l2_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = qeth_l2_vlan_rx_kill_vid,
.ndo_tx_timeout = qeth_tx_timeout,
+ .ndo_fix_features = qeth_l2_fix_features,
+ .ndo_set_features = qeth_l2_set_features
};
static int qeth_l2_setup_netdev(struct qeth_card *card)
@@ -997,6 +1117,11 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
(card->info.type != QETH_CARD_TYPE_OSN) ?
&qeth_l2_ethtool_ops : &qeth_l2_osn_ops;
card->dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
+ if (card->info.type == QETH_CARD_TYPE_OSD && !card->info.guestlan) {
+ card->dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
+ /* Turn on RX offloading per default */
+ card->dev->features |= NETIF_F_RXCSUM;
+ }
card->info.broadcast_capable = 1;
qeth_l2_request_initial_mac(card);
SET_NETDEV_DEV(card->dev, &card->gdev->dev);
@@ -1004,6 +1129,17 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
return register_netdev(card->dev);
}
+static int qeth_l2_start_ipassists(struct qeth_card *card)
+{
+ /* configure isolation level */
+ if (qeth_set_access_ctrl_online(card, 0))
+ return -ENODEV;
+ if (qeth_is_supported(card, IPA_INBOUND_CHECKSUM))
+ qeth_set_rx_csum(card, 1);
+ qeth_start_ipa_tx_checksum(card);
+ return 0;
+}
+
static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
{
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
@@ -1069,12 +1205,8 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
contin:
if ((card->info.type == QETH_CARD_TYPE_OSD) ||
(card->info.type == QETH_CARD_TYPE_OSX)) {
- /* configure isolation level */
- rc = qeth_set_access_ctrl_online(card, 0);
- if (rc) {
- rc = -ENODEV;
+ if (qeth_l2_start_ipassists(card))
goto out_remove;
- }
}
if (card->info.type != QETH_CARD_TYPE_OSN &&
@@ -1106,7 +1238,7 @@ contin:
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);
@@ -1452,8 +1584,8 @@ static void qeth_bridge_emit_host_event(struct qeth_card *card,
env[i] = str[i]; i++;
}
if (code & IPA_ADDR_CHANGE_CODE_MACADDR) {
- snprintf(str[i], sizeof(str[i]), "MAC=%pM6",
- &addr_lnid->mac);
+ snprintf(str[i], sizeof(str[i]), "MAC=%pM",
+ addr_lnid->mac);
env[i] = str[i]; i++;
}
snprintf(str[i], sizeof(str[i]), "NTOK_BUSID=%x.%x.%04x",
diff --git a/drivers/s390/net/qeth_l2_sys.c b/drivers/s390/net/qeth_l2_sys.c
index 52673cd1db99..692db49e3d2a 100644
--- a/drivers/s390/net/qeth_l2_sys.c
+++ b/drivers/s390/net/qeth_l2_sys.c
@@ -109,7 +109,7 @@ static ssize_t qeth_bridge_port_state_show(struct device *dev,
return qeth_bridge_port_role_state_show(dev, attr, buf, 1);
}
-static DEVICE_ATTR(bridge_state, 0644, qeth_bridge_port_state_show,
+static DEVICE_ATTR(bridge_state, 0444, qeth_bridge_port_state_show,
NULL);
static ssize_t qeth_bridgeport_hostnotification_show(struct device *dev,
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index a1aaa36e9ebb..543960e96b42 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -1065,27 +1065,6 @@ static struct qeth_cmd_buffer *qeth_l3_get_setassparms_cmd(
return iob;
}
-static int qeth_l3_send_setassparms(struct qeth_card *card,
- struct qeth_cmd_buffer *iob, __u16 len, long data,
- int (*reply_cb)(struct qeth_card *, struct qeth_reply *,
- unsigned long),
- void *reply_param)
-{
- int rc;
- struct qeth_ipa_cmd *cmd;
-
- QETH_CARD_TEXT(card, 4, "sendassp");
-
- cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
- if (len <= sizeof(__u32))
- cmd->data.setassparms.data.flags_32bit = (__u32) data;
- else /* (len > sizeof(__u32)) */
- memcpy(&cmd->data.setassparms.data, (void *) data, len);
-
- rc = qeth_send_ipa_cmd(card, iob, reply_cb, reply_param);
- return rc;
-}
-
#ifdef CONFIG_QETH_IPV6
static int qeth_l3_send_simple_setassparms_ipv6(struct qeth_card *card,
enum qeth_ipa_funcs ipa_func, __u16 cmd_code)
@@ -1098,31 +1077,12 @@ static int qeth_l3_send_simple_setassparms_ipv6(struct qeth_card *card,
0, QETH_PROT_IPV6);
if (!iob)
return -ENOMEM;
- rc = qeth_l3_send_setassparms(card, iob, 0, 0,
+ rc = qeth_send_setassparms(card, iob, 0, 0,
qeth_l3_default_setassparms_cb, NULL);
return rc;
}
#endif
-static int qeth_l3_send_simple_setassparms(struct qeth_card *card,
- enum qeth_ipa_funcs ipa_func, __u16 cmd_code, long data)
-{
- int rc;
- int length = 0;
- struct qeth_cmd_buffer *iob;
-
- QETH_CARD_TEXT(card, 4, "simassp4");
- if (data)
- length = sizeof(__u32);
- iob = qeth_l3_get_setassparms_cmd(card, ipa_func, cmd_code,
- length, QETH_PROT_IPV4);
- if (!iob)
- return -ENOMEM;
- rc = qeth_l3_send_setassparms(card, iob, length, data,
- qeth_l3_default_setassparms_cb, NULL);
- return rc;
-}
-
static int qeth_l3_start_ipa_arp_processing(struct qeth_card *card)
{
int rc;
@@ -1135,8 +1095,8 @@ static int qeth_l3_start_ipa_arp_processing(struct qeth_card *card)
QETH_CARD_IFNAME(card));
return 0;
}
- rc = qeth_l3_send_simple_setassparms(card, IPA_ARP_PROCESSING,
- IPA_CMD_ASS_START, 0);
+ rc = qeth_send_simple_setassparms(card, IPA_ARP_PROCESSING,
+ IPA_CMD_ASS_START, 0);
if (rc) {
dev_warn(&card->gdev->dev,
"Starting ARP processing support for %s failed\n",
@@ -1158,7 +1118,7 @@ static int qeth_l3_start_ipa_ip_fragmentation(struct qeth_card *card)
return -EOPNOTSUPP;
}
- rc = qeth_l3_send_simple_setassparms(card, IPA_IP_FRAGMENTATION,
+ rc = qeth_send_simple_setassparms(card, IPA_IP_FRAGMENTATION,
IPA_CMD_ASS_START, 0);
if (rc) {
dev_warn(&card->gdev->dev,
@@ -1183,7 +1143,7 @@ static int qeth_l3_start_ipa_source_mac(struct qeth_card *card)
return -EOPNOTSUPP;
}
- rc = qeth_l3_send_simple_setassparms(card, IPA_SOURCE_MAC,
+ rc = qeth_send_simple_setassparms(card, IPA_SOURCE_MAC,
IPA_CMD_ASS_START, 0);
if (rc)
dev_warn(&card->gdev->dev,
@@ -1204,7 +1164,7 @@ static int qeth_l3_start_ipa_vlan(struct qeth_card *card)
return -EOPNOTSUPP;
}
- rc = qeth_l3_send_simple_setassparms(card, IPA_VLAN_PRIO,
+ rc = qeth_send_simple_setassparms(card, IPA_VLAN_PRIO,
IPA_CMD_ASS_START, 0);
if (rc) {
dev_warn(&card->gdev->dev,
@@ -1229,7 +1189,7 @@ static int qeth_l3_start_ipa_multicast(struct qeth_card *card)
return -EOPNOTSUPP;
}
- rc = qeth_l3_send_simple_setassparms(card, IPA_MULTICASTING,
+ rc = qeth_send_simple_setassparms(card, IPA_MULTICASTING,
IPA_CMD_ASS_START, 0);
if (rc) {
dev_warn(&card->gdev->dev,
@@ -1259,7 +1219,7 @@ static int qeth_l3_softsetup_ipv6(struct qeth_card *card)
QETH_CARD_IFNAME(card));
return rc;
}
- rc = qeth_l3_send_simple_setassparms(card, IPA_IPV6,
+ rc = qeth_send_simple_setassparms(card, IPA_IPV6,
IPA_CMD_ASS_START, 3);
if (rc) {
dev_err(&card->gdev->dev,
@@ -1319,7 +1279,7 @@ static int qeth_l3_start_ipa_broadcast(struct qeth_card *card)
rc = -EOPNOTSUPP;
goto out;
}
- rc = qeth_l3_send_simple_setassparms(card, IPA_FILTERING,
+ rc = qeth_send_simple_setassparms(card, IPA_FILTERING,
IPA_CMD_ASS_START, 0);
if (rc) {
dev_warn(&card->gdev->dev, "Enabling broadcast filtering for "
@@ -1327,7 +1287,7 @@ static int qeth_l3_start_ipa_broadcast(struct qeth_card *card)
goto out;
}
- rc = qeth_l3_send_simple_setassparms(card, IPA_FILTERING,
+ rc = qeth_send_simple_setassparms(card, IPA_FILTERING,
IPA_CMD_ASS_CONFIGURE, 1);
if (rc) {
dev_warn(&card->gdev->dev,
@@ -1337,7 +1297,7 @@ static int qeth_l3_start_ipa_broadcast(struct qeth_card *card)
}
card->info.broadcast_capable = QETH_BROADCAST_WITH_ECHO;
dev_info(&card->gdev->dev, "Broadcast enabled\n");
- rc = qeth_l3_send_simple_setassparms(card, IPA_FILTERING,
+ rc = qeth_send_simple_setassparms(card, IPA_FILTERING,
IPA_CMD_ASS_ENABLE, 1);
if (rc) {
dev_warn(&card->gdev->dev, "Setting up broadcast echo "
@@ -1353,84 +1313,18 @@ out:
return rc;
}
-static int qeth_l3_send_checksum_command(struct qeth_card *card)
-{
- int rc;
-
- rc = qeth_l3_send_simple_setassparms(card, IPA_INBOUND_CHECKSUM,
- IPA_CMD_ASS_START, 0);
- if (rc) {
- dev_warn(&card->gdev->dev, "Starting HW checksumming for %s "
- "failed, using SW checksumming\n",
- QETH_CARD_IFNAME(card));
- return rc;
- }
- rc = qeth_l3_send_simple_setassparms(card, IPA_INBOUND_CHECKSUM,
- IPA_CMD_ASS_ENABLE,
- card->info.csum_mask);
- if (rc) {
- dev_warn(&card->gdev->dev, "Enabling HW checksumming for %s "
- "failed, using SW checksumming\n",
- QETH_CARD_IFNAME(card));
- return rc;
- }
- return 0;
-}
-
-static int qeth_l3_set_rx_csum(struct qeth_card *card, int on)
-{
- int rc = 0;
-
- if (on) {
- rc = qeth_l3_send_checksum_command(card);
- if (rc)
- return -EIO;
- dev_info(&card->gdev->dev,
- "HW Checksumming (inbound) enabled\n");
- } else {
- rc = qeth_l3_send_simple_setassparms(card,
- IPA_INBOUND_CHECKSUM, IPA_CMD_ASS_STOP, 0);
- if (rc)
- return -EIO;
- }
-
- return 0;
-}
-
-static int qeth_l3_start_ipa_checksum(struct qeth_card *card)
+static void qeth_l3_start_ipa_checksum(struct qeth_card *card)
{
QETH_CARD_TEXT(card, 3, "strtcsum");
-
- if (card->dev->features & NETIF_F_RXCSUM) {
- rtnl_lock();
- /* force set_features call */
- card->dev->features &= ~NETIF_F_RXCSUM;
- netdev_update_features(card->dev);
- rtnl_unlock();
- }
- return 0;
+ if (qeth_is_supported(card, IPA_INBOUND_CHECKSUM)
+ && (card->dev->features & NETIF_F_RXCSUM))
+ qeth_set_rx_csum(card, 1);
}
-static int qeth_l3_start_ipa_tx_checksum(struct qeth_card *card)
+static void qeth_l3_start_ipa_tx_checksum(struct qeth_card *card)
{
- int rc = 0;
-
- if (!qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM))
- return rc;
- rc = qeth_l3_send_simple_setassparms(card, IPA_OUTBOUND_CHECKSUM,
- IPA_CMD_ASS_START, 0);
- if (rc)
- goto err_out;
- rc = qeth_l3_send_simple_setassparms(card, IPA_OUTBOUND_CHECKSUM,
- IPA_CMD_ASS_ENABLE, card->info.tx_csum_mask);
- if (rc)
- goto err_out;
- dev_info(&card->gdev->dev, "HW TX Checksumming enabled\n");
- return rc;
-err_out:
- dev_warn(&card->gdev->dev, "Enabling HW TX checksumming for %s "
- "failed, using SW TX checksumming\n", QETH_CARD_IFNAME(card));
- return rc;
+ QETH_CARD_TEXT(card, 3, "strttxcs");
+ qeth_start_ipa_tx_checksum(card);
}
static int qeth_l3_start_ipa_tso(struct qeth_card *card)
@@ -1445,8 +1339,8 @@ static int qeth_l3_start_ipa_tso(struct qeth_card *card)
QETH_CARD_IFNAME(card));
rc = -EOPNOTSUPP;
} else {
- rc = qeth_l3_send_simple_setassparms(card, IPA_OUTBOUND_TSO,
- IPA_CMD_ASS_START, 0);
+ rc = qeth_send_simple_setassparms(card, IPA_OUTBOUND_TSO,
+ IPA_CMD_ASS_START, 0);
if (rc)
dev_warn(&card->gdev->dev, "Starting outbound TCP "
"segmentation offload for %s failed\n",
@@ -1950,7 +1844,6 @@ static inline int qeth_l3_rebuild_skb(struct qeth_card *card,
skb->ip_summed = CHECKSUM_NONE;
} else
skb->ip_summed = CHECKSUM_NONE;
-
return is_vlan;
}
@@ -2287,7 +2180,7 @@ static int qeth_l3_arp_set_no_entries(struct qeth_card *card, int no_entries)
if (!qeth_is_supported(card, IPA_ARP_PROCESSING)) {
return -EOPNOTSUPP;
}
- rc = qeth_l3_send_simple_setassparms(card, IPA_ARP_PROCESSING,
+ rc = qeth_send_simple_setassparms(card, IPA_ARP_PROCESSING,
IPA_CMD_ASS_ARP_SET_NO_ENTRIES,
no_entries);
if (rc) {
@@ -2552,7 +2445,7 @@ static int qeth_l3_arp_add_entry(struct qeth_card *card,
QETH_PROT_IPV4);
if (!iob)
return -ENOMEM;
- rc = qeth_l3_send_setassparms(card, iob,
+ rc = qeth_send_setassparms(card, iob,
sizeof(struct qeth_arp_cache_entry),
(unsigned long) entry,
qeth_l3_default_setassparms_cb, NULL);
@@ -2593,7 +2486,7 @@ static int qeth_l3_arp_remove_entry(struct qeth_card *card,
QETH_PROT_IPV4);
if (!iob)
return -ENOMEM;
- rc = qeth_l3_send_setassparms(card, iob,
+ rc = qeth_send_setassparms(card, iob,
12, (unsigned long)buf,
qeth_l3_default_setassparms_cb, NULL);
if (rc) {
@@ -2624,7 +2517,7 @@ static int qeth_l3_arp_flush_cache(struct qeth_card *card)
if (!qeth_is_supported(card, IPA_ARP_PROCESSING)) {
return -EOPNOTSUPP;
}
- rc = qeth_l3_send_simple_setassparms(card, IPA_ARP_PROCESSING,
+ rc = qeth_send_simple_setassparms(card, IPA_ARP_PROCESSING,
IPA_CMD_ASS_ARP_FLUSH_CACHE, 0);
if (rc) {
tmp = rc;
@@ -3187,7 +3080,6 @@ static netdev_features_t qeth_l3_fix_features(struct net_device *dev,
features &= ~NETIF_F_TSO;
if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM))
features &= ~NETIF_F_RXCSUM;
-
return features;
}
@@ -3204,7 +3096,7 @@ static int qeth_l3_set_features(struct net_device *dev,
card->state == CARD_STATE_RECOVER)
return 0;
- return qeth_l3_set_rx_csum(card, features & NETIF_F_RXCSUM ? 1 : 0);
+ return qeth_set_rx_csum(card, features & NETIF_F_RXCSUM ? 1 : 0);
}
static const struct ethtool_ops qeth_l3_ethtool_ops = {
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c
index d8f990b6b332..a851d34c642b 100644
--- a/drivers/s390/net/smsgiucv.c
+++ b/drivers/s390/net/smsgiucv.c
@@ -49,7 +49,7 @@ static DEFINE_SPINLOCK(smsg_list_lock);
static LIST_HEAD(smsg_list);
static int iucv_path_connected;
-static int smsg_path_pending(struct iucv_path *, u8 ipvmid[8], u8 ipuser[16]);
+static int smsg_path_pending(struct iucv_path *, u8 *, u8 *);
static void smsg_message_pending(struct iucv_path *, struct iucv_message *);
static struct iucv_handler smsg_handler = {
@@ -57,8 +57,7 @@ static struct iucv_handler smsg_handler = {
.message_pending = smsg_message_pending,
};
-static int smsg_path_pending(struct iucv_path *path, u8 ipvmid[8],
- u8 ipuser[16])
+static int smsg_path_pending(struct iucv_path *path, u8 *ipvmid, u8 *ipuser)
{
if (strncmp(ipvmid, "*MSG ", 8) != 0)
return -EINVAL;