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

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

Merge branch 's390-qeth-next'



Julian Wiedmann says:

====================
s390/qeth: updates 2019-06-27

please apply another round of qeth updates for net-next.
This completes the conversion of the control path to use dynamically
allocated cmd buffers, along with some fine-tuning for the route
validation fix that recently went into -net.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 39f41f36 eca1d5c2
Loading
Loading
Loading
Loading
+43 −51
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@
#include <linux/wait.h>
#include <linux/workqueue.h>

#include <net/dst.h>
#include <net/ip6_fib.h>
#include <net/ipv6.h>
#include <net/if_inet6.h>
#include <net/addrconf.h>
@@ -60,7 +62,7 @@ struct qeth_dbf_info {
	debug_info_t *id;
};

#define QETH_DBF_CTRL_LEN 256
#define QETH_DBF_CTRL_LEN 256U

#define QETH_DBF_TEXT(name, level, text) \
	debug_text_event(qeth_dbf[QETH_DBF_##name].id, level, text)
@@ -524,11 +526,6 @@ struct qeth_qdio_info {
	int default_out_queue;
};

/**
 * buffer stuff for read channel
 */
#define QETH_CMD_BUFFER_NO	8

/**
 *  channel state machine
 */
@@ -551,16 +548,11 @@ enum qeth_card_states {
 * Protocol versions
 */
enum qeth_prot_versions {
	QETH_PROT_NONE = 0x0000,
	QETH_PROT_IPV4 = 0x0004,
	QETH_PROT_IPV6 = 0x0006,
};

enum qeth_cmd_buffer_state {
	BUF_STATE_FREE,
	BUF_STATE_LOCKED,
	BUF_STATE_MALLOC,
};

enum qeth_cq {
	QETH_CQ_DISABLED = 0,
	QETH_CQ_ENABLED = 1,
@@ -574,18 +566,20 @@ struct qeth_ipato {
	struct list_head entries;
};

struct qeth_channel;
struct qeth_channel {
	struct ccw_device *ccwdev;
	enum qeth_channel_states state;
	atomic_t irq_pending;
};

struct qeth_cmd_buffer {
	enum qeth_cmd_buffer_state state;
	unsigned int length;
	refcount_t ref_count;
	struct qeth_channel *channel;
	struct qeth_reply *reply;
	long timeout;
	unsigned char *data;
	void (*finalize)(struct qeth_card *card, struct qeth_cmd_buffer *iob,
			 unsigned int length);
	void (*finalize)(struct qeth_card *card, struct qeth_cmd_buffer *iob);
	void (*callback)(struct qeth_card *card, struct qeth_cmd_buffer *iob);
};

@@ -599,25 +593,8 @@ static inline struct qeth_ipa_cmd *__ipa_cmd(struct qeth_cmd_buffer *iob)
	return (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE);
}

/**
 * definition of a qeth channel, used for read and write
 */
struct qeth_channel {
	enum qeth_channel_states state;
	struct ccw1 *ccw;
	spinlock_t iob_lock;
	wait_queue_head_t wait_q;
	struct ccw_device *ccwdev;
/*command buffer for control data*/
	struct qeth_cmd_buffer iob[QETH_CMD_BUFFER_NO];
	atomic_t irq_pending;
	int io_buf_no;
};

static inline struct ccw1 *__ccw_from_cmd(struct qeth_cmd_buffer *iob)
{
	if (iob->state != BUF_STATE_MALLOC)
		return iob->channel->ccw;
	return (struct ccw1 *)(iob->data + ALIGN(iob->length, 8));
}

@@ -738,9 +715,6 @@ struct qeth_discipline {
	void (*remove) (struct ccwgroup_device *);
	int (*set_online) (struct ccwgroup_device *);
	int (*set_offline) (struct ccwgroup_device *);
	int (*freeze)(struct ccwgroup_device *);
	int (*thaw) (struct ccwgroup_device *);
	int (*restore)(struct ccwgroup_device *);
	int (*do_ioctl)(struct net_device *dev, struct ifreq *rq, int cmd);
	int (*control_event_handler)(struct qeth_card *card,
					struct qeth_ipa_cmd *cmd);
@@ -905,6 +879,17 @@ static inline int qeth_get_ether_cast_type(struct sk_buff *skb)
	return RTN_UNICAST;
}

static inline struct dst_entry *qeth_dst_check_rcu(struct sk_buff *skb, int ipv)
{
	struct dst_entry *dst = skb_dst(skb);
	struct rt6_info *rt;

	rt = (struct rt6_info *) dst;
	if (dst)
		dst = dst_check(dst, (ipv == 6) ? rt6_get_cookie(rt) : 0);
	return dst;
}

static inline void qeth_rx_csum(struct qeth_card *card, struct sk_buff *skb,
				u8 flags)
{
@@ -939,12 +924,12 @@ static inline int qeth_is_diagass_supported(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, u32 *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)
					       u16 cmd_code, u32 *data)
{
	return qeth_send_simple_setassparms_prot(card, ipa_func, cmd_code,
						 data, QETH_PROT_IPV4);
@@ -952,7 +937,7 @@ static inline int qeth_send_simple_setassparms(struct qeth_card *card,

static inline int qeth_send_simple_setassparms_v6(struct qeth_card *card,
						  enum qeth_ipa_funcs ipa_func,
						  u16 cmd_code, long data)
						  u16 cmd_code, u32 *data)
{
	return qeth_send_simple_setassparms_prot(card, ipa_func, cmd_code,
						 data, QETH_PROT_IPV6);
@@ -993,8 +978,23 @@ int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *,
		  int (*reply_cb)
		  (struct qeth_card *, struct qeth_reply *, unsigned long),
		  void *);
struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *,
			enum qeth_ipa_cmds, enum qeth_prot_versions);
struct qeth_cmd_buffer *qeth_ipa_alloc_cmd(struct qeth_card *card,
					   enum qeth_ipa_cmds cmd_code,
					   enum qeth_prot_versions prot,
					   unsigned int data_length);
struct qeth_cmd_buffer *qeth_alloc_cmd(struct qeth_channel *channel,
				       unsigned int length, unsigned int ccws,
				       long timeout);
struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *card,
						 enum qeth_ipa_funcs ipa_func,
						 u16 cmd_code,
						 unsigned int data_length,
						 enum qeth_prot_versions prot);
struct qeth_cmd_buffer *qeth_get_diag_cmd(struct qeth_card *card,
					  enum qeth_diags_cmds sub_cmd,
					  unsigned int data_length);
void qeth_put_cmd(struct qeth_cmd_buffer *iob);

struct sk_buff *qeth_core_get_next_skb(struct qeth_card *,
		struct qeth_qdio_buffer *, struct qdio_buffer_element **, int *,
		struct qeth_hdr **);
@@ -1003,16 +1003,13 @@ int qeth_poll(struct napi_struct *napi, int budget);
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 *);
void qeth_clear_cmd_buffers(struct qeth_channel *);
void qeth_drain_output_queues(struct qeth_card *card);
void qeth_setadp_promisc_mode(struct qeth_card *);
int qeth_setadpparms_change_macaddr(struct qeth_card *);
void qeth_tx_timeout(struct net_device *);
void qeth_release_buffer(struct qeth_cmd_buffer *iob);
void qeth_notify_reply(struct qeth_reply *reply, int reason);
void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
			  u16 cmd_length);
struct qeth_cmd_buffer *qeth_get_buffer(struct qeth_channel *channel);
int qeth_query_switch_attributes(struct qeth_card *card,
				  struct qeth_switch_info *sw_info);
int qeth_query_card_info(struct qeth_card *card,
@@ -1029,10 +1026,6 @@ int qeth_configure_cq(struct qeth_card *, enum qeth_cq);
int qeth_hw_trap(struct qeth_card *, enum qeth_diags_trap_action);
void qeth_trace_features(struct qeth_card *);
int qeth_setassparms_cb(struct qeth_card *, struct qeth_reply *, unsigned long);
struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *,
						 enum qeth_ipa_funcs,
						 __u16, __u16,
						 enum qeth_prot_versions);
int qeth_set_features(struct net_device *, netdev_features_t);
void qeth_enable_hw_features(struct net_device *dev);
netdev_features_t qeth_fix_features(struct net_device *, netdev_features_t);
@@ -1047,11 +1040,10 @@ int qeth_stop(struct net_device *dev);

int qeth_vm_request_mac(struct qeth_card *card);
int qeth_xmit(struct qeth_card *card, struct sk_buff *skb,
	      struct qeth_qdio_out_q *queue, int ipv, int cast_type,
	      struct qeth_qdio_out_q *queue, int ipv,
	      void (*fill_header)(struct qeth_qdio_out_q *queue,
				  struct qeth_hdr *hdr, struct sk_buff *skb,
				  int ipv, int cast_type,
				  unsigned int data_len));
				  int ipv, unsigned int data_len));

/* exports for OSN */
int qeth_osn_assist(struct net_device *, void *, int);
+193 −324

File changed.

Preview size limit exceeded, changes collapsed.

+23 −26
Original line number Diff line number Diff line
@@ -379,9 +379,7 @@ struct qeth_ipacmd_layer2setdelvlan {
	__u16 vlan_id;
} __attribute__ ((packed));


struct qeth_ipacmd_setassparms_hdr {
	__u32 assist_no;
	__u16 length;
	__u16 command_code;
	__u16 return_code;
@@ -426,6 +424,7 @@ struct qeth_tso_start_data {

/* SETASSPARMS IPA Command: */
struct qeth_ipacmd_setassparms {
	u32 assist_no;
	struct qeth_ipacmd_setassparms_hdr hdr;
	union {
		__u32 flags_32bit;
@@ -437,6 +436,8 @@ struct qeth_ipacmd_setassparms {
	} data;
} __attribute__ ((packed));

#define SETASS_DATA_SIZEOF(field) FIELD_SIZEOF(struct qeth_ipacmd_setassparms,\
					       data.field)

/* SETRTG IPA Command:    ****************************************************/
struct qeth_set_routing {
@@ -524,8 +525,6 @@ struct qeth_query_switch_attributes {
#define QETH_SETADP_FLAGS_VIRTUAL_MAC	0x80	/* for CHANGE_ADDR_READ_MAC */

struct qeth_ipacmd_setadpparms_hdr {
	u32 supp_hw_cmds;
	u32 reserved1;
	u16 cmdlength;
	u16 reserved2;
	u32 command_code;
@@ -537,6 +536,7 @@ struct qeth_ipacmd_setadpparms_hdr {
};

struct qeth_ipacmd_setadpparms {
	struct qeth_ipa_caps hw_cmds;
	struct qeth_ipacmd_setadpparms_hdr hdr;
	union {
		struct qeth_query_cmds_supp query_cmds_supp;
@@ -550,6 +550,9 @@ struct qeth_ipacmd_setadpparms {
	} data;
} __attribute__ ((packed));

#define SETADP_DATA_SIZEOF(field) FIELD_SIZEOF(struct qeth_ipacmd_setadpparms,\
					       data.field)

/* CREATE_ADDR IPA Command:    ***********************************************/
struct qeth_create_destroy_address {
	__u8 unique_id[8];
@@ -596,6 +599,11 @@ struct qeth_ipacmd_diagass {
	__u8   cdata[64];
} __attribute__ ((packed));

#define DIAG_HDR_LEN		offsetofend(struct qeth_ipacmd_diagass, ext)
#define DIAG_SUB_HDR_LEN	(offsetofend(struct qeth_ipacmd_diagass, ext) -\
				 offsetof(struct qeth_ipacmd_diagass, \
					  subcmd_len))

/* VNIC Characteristics IPA Command: *****************************************/
/* IPA commands/sub commands for VNICC */
#define IPA_VNICC_QUERY_CHARS		0x00000000L
@@ -622,12 +630,6 @@ struct qeth_ipacmd_diagass {

/* VNICC header */
struct qeth_ipacmd_vnicc_hdr {
	u32 sup;
	u32 cur;
};

/* VNICC sub command header */
struct qeth_vnicc_sub_hdr {
	u16 data_length;
	u16 reserved;
	u32 sub_command;
@@ -652,14 +654,17 @@ struct qeth_vnicc_getset_timeout {

/* complete VNICC IPA command message */
struct qeth_ipacmd_vnicc {
	struct qeth_ipa_caps vnicc_cmds;
	struct qeth_ipacmd_vnicc_hdr hdr;
	struct qeth_vnicc_sub_hdr sub_hdr;
	union {
		struct qeth_vnicc_query_cmds query_cmds;
		struct qeth_vnicc_set_char set_char;
		struct qeth_vnicc_getset_timeout getset_timeout;
	} data;
};
};

#define VNICC_DATA_SIZEOF(field)	FIELD_SIZEOF(struct qeth_ipacmd_vnicc,\
						     data.field)

/* SETBRIDGEPORT IPA Command:	 *********************************************/
enum qeth_ipa_sbp_cmd {
@@ -686,8 +691,6 @@ struct mac_addr_lnid {
} __packed;

struct qeth_ipacmd_sbp_hdr {
	__u32 supported_sbp_cmds;
	__u32 enabled_sbp_cmds;
	__u16 cmdlength;
	__u16 reserved1;
	__u32 command_code;
@@ -702,16 +705,10 @@ struct qeth_sbp_query_cmds_supp {
	__u32 reserved;
} __packed;

struct qeth_sbp_reset_role {
} __packed;

struct qeth_sbp_set_primary {
	struct net_if_token token;
} __packed;

struct qeth_sbp_set_secondary {
} __packed;

struct qeth_sbp_port_entry {
		__u8 role;
		__u8 state;
@@ -737,17 +734,19 @@ struct qeth_sbp_state_change {
} __packed;

struct qeth_ipacmd_setbridgeport {
	struct qeth_ipa_caps sbp_cmds;
	struct qeth_ipacmd_sbp_hdr hdr;
	union {
		struct qeth_sbp_query_cmds_supp query_cmds_supp;
		struct qeth_sbp_reset_role reset_role;
		struct qeth_sbp_set_primary set_primary;
		struct qeth_sbp_set_secondary set_secondary;
		struct qeth_sbp_query_ports query_ports;
		struct qeth_sbp_state_change state_change;
	} data;
} __packed;

#define SBP_DATA_SIZEOF(field)	FIELD_SIZEOF(struct qeth_ipacmd_setbridgeport,\
					     data.field)

/* ADDRESS_CHANGE_NOTIFICATION adapter-initiated "command" *******************/
/* Bitmask for entry->change_code. Both bits may be raised.		     */
enum qeth_ipa_addr_change_code {
@@ -806,6 +805,8 @@ struct qeth_ipa_cmd {
	} data;
} __attribute__ ((packed));

#define IPA_DATA_SIZEOF(field)	FIELD_SIZEOF(struct qeth_ipa_cmd, data.field)

/*
 * special command for ARP processing.
 * this is not included in setassparms command before, because we get
@@ -823,10 +824,6 @@ enum qeth_ipa_arp_return_codes {
extern const char *qeth_get_ipa_msg(enum qeth_ipa_return_codes rc);
extern const char *qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd);

#define QETH_SETADP_BASE_LEN (sizeof(struct qeth_ipacmd_hdr) + \
			      sizeof(struct qeth_ipacmd_setadpparms_hdr))
#define QETH_SNMP_SETADP_CMDLENGTH 16

/* Helper functions */
#define IS_IPA_REPLY(cmd) ((cmd->hdr.initiator == IPA_CMD_INITIATOR_HOST) || \
			   (cmd->hdr.initiator == IPA_CMD_INITIATOR_OSA_REPLY))
+84 −117
Original line number Diff line number Diff line
@@ -85,7 +85,8 @@ static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac,
	struct qeth_cmd_buffer *iob;

	QETH_CARD_TEXT(card, 2, "L2sdmac");
	iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
	iob = qeth_ipa_alloc_cmd(card, ipacmd, QETH_PROT_IPV4,
				 IPA_DATA_SIZEOF(setdelmac));
	if (!iob)
		return -ENOMEM;
	cmd = __ipa_cmd(iob);
@@ -163,8 +164,9 @@ static void qeth_l2_drain_rx_mode_cache(struct qeth_card *card)

static void qeth_l2_fill_header(struct qeth_qdio_out_q *queue,
				struct qeth_hdr *hdr, struct sk_buff *skb,
				int ipv, int cast_type, unsigned int data_len)
				int ipv, unsigned int data_len)
{
	int cast_type = qeth_get_ether_cast_type(skb);
	struct vlan_ethhdr *veth = vlan_eth_hdr(skb);

	hdr->hdr.l2.pkt_length = data_len;
@@ -240,7 +242,8 @@ static int qeth_l2_send_setdelvlan(struct qeth_card *card, __u16 i,
	struct qeth_cmd_buffer *iob;

	QETH_CARD_TEXT_(card, 4, "L2sdv%x", ipacmd);
	iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
	iob = qeth_ipa_alloc_cmd(card, ipacmd, QETH_PROT_IPV4,
				 IPA_DATA_SIZEOF(setdelvlan));
	if (!iob)
		return -ENOMEM;
	cmd = __ipa_cmd(iob);
@@ -292,7 +295,6 @@ static void qeth_l2_stop_card(struct qeth_card *card)
		card->state = CARD_STATE_DOWN;
	}

	qeth_clear_cmd_buffers(&card->write);
	flush_workqueue(card->event_wq);
	card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
}
@@ -597,7 +599,6 @@ static netdev_tx_t qeth_l2_hard_start_xmit(struct sk_buff *skb,
		rc = qeth_l2_xmit_osn(card, skb, queue);
	else
		rc = qeth_xmit(card, skb, queue, qeth_get_ip_version(skb),
			       qeth_get_ether_cast_type(skb),
			       qeth_l2_fill_header);

	if (!rc) {
@@ -964,33 +965,6 @@ static void __exit qeth_l2_exit(void)
	pr_info("unregister layer 2 discipline\n");
}

static int qeth_l2_pm_suspend(struct ccwgroup_device *gdev)
{
	struct qeth_card *card = dev_get_drvdata(&gdev->dev);

	qeth_set_allowed_threads(card, 0, 1);
	wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
	if (gdev->state == CCWGROUP_OFFLINE)
		return 0;

	qeth_l2_set_offline(gdev);
	return 0;
}

static int qeth_l2_pm_resume(struct ccwgroup_device *gdev)
{
	struct qeth_card *card = dev_get_drvdata(&gdev->dev);
	int rc;

	rc = qeth_l2_set_online(gdev);

	qeth_set_allowed_threads(card, 0xffffffff, 0);
	if (rc)
		dev_warn(&card->gdev->dev, "The qeth device driver "
			"failed to recover an error on the device\n");
	return rc;
}

/* Returns zero if the command is successfully "consumed" */
static int qeth_l2_control_event(struct qeth_card *card,
					struct qeth_ipa_cmd *cmd)
@@ -1020,9 +994,6 @@ struct qeth_discipline qeth_l2_discipline = {
	.remove = qeth_l2_remove_device,
	.set_online = qeth_l2_set_online,
	.set_offline = qeth_l2_set_offline,
	.freeze = qeth_l2_pm_suspend,
	.thaw = qeth_l2_pm_resume,
	.restore = qeth_l2_pm_resume,
	.do_ioctl = NULL,
	.control_event_handler = qeth_l2_control_event,
};
@@ -1032,7 +1003,7 @@ static void qeth_osn_assist_cb(struct qeth_card *card,
			       struct qeth_cmd_buffer *iob)
{
	qeth_notify_reply(iob->reply, 0);
	qeth_release_buffer(iob);
	qeth_put_cmd(iob);
}

int qeth_osn_assist(struct net_device *dev, void *data, int data_len)
@@ -1040,6 +1011,8 @@ int qeth_osn_assist(struct net_device *dev, void *data, int data_len)
	struct qeth_cmd_buffer *iob;
	struct qeth_card *card;

	if (data_len < 0)
		return -EINVAL;
	if (!dev)
		return -ENODEV;
	card = dev->ml_priv;
@@ -1048,7 +1021,9 @@ int qeth_osn_assist(struct net_device *dev, void *data, int data_len)
	QETH_CARD_TEXT(card, 2, "osnsdmc");
	if (!qeth_card_hw_is_reachable(card))
		return -ENODEV;
	iob = qeth_get_buffer(&card->write);

	iob = qeth_alloc_cmd(&card->write, IPA_PDU_HEADER_SIZE + data_len, 1,
			     QETH_IPA_TIMEOUT);
	if (!iob)
		return -ENOMEM;

@@ -1421,22 +1396,25 @@ static int qeth_bridgeport_makerc(struct qeth_card *card,

static struct qeth_cmd_buffer *qeth_sbp_build_cmd(struct qeth_card *card,
						  enum qeth_ipa_sbp_cmd sbp_cmd,
						  unsigned int cmd_length)
						  unsigned int data_length)
{
	enum qeth_ipa_cmds ipa_cmd = IS_IQD(card) ? IPA_CMD_SETBRIDGEPORT_IQD :
						    IPA_CMD_SETBRIDGEPORT_OSA;
	struct qeth_ipacmd_sbp_hdr *hdr;
	struct qeth_cmd_buffer *iob;
	struct qeth_ipa_cmd *cmd;

	iob = qeth_get_ipacmd_buffer(card, ipa_cmd, 0);
	iob = qeth_ipa_alloc_cmd(card, ipa_cmd, QETH_PROT_NONE,
				 data_length +
				 offsetof(struct qeth_ipacmd_setbridgeport,
					  data));
	if (!iob)
		return iob;
	cmd = __ipa_cmd(iob);
	cmd->data.sbp.hdr.cmdlength = sizeof(struct qeth_ipacmd_sbp_hdr) +
				      cmd_length;
	cmd->data.sbp.hdr.command_code = sbp_cmd;
	cmd->data.sbp.hdr.used_total = 1;
	cmd->data.sbp.hdr.seq_no = 1;

	hdr = &__ipa_cmd(iob)->data.sbp.hdr;
	hdr->cmdlength = sizeof(*hdr) + data_length;
	hdr->command_code = sbp_cmd;
	hdr->used_total = 1;
	hdr->seq_no = 1;
	return iob;
}

@@ -1471,7 +1449,7 @@ static void qeth_bridgeport_query_support(struct qeth_card *card)

	QETH_CARD_TEXT(card, 2, "brqsuppo");
	iob = qeth_sbp_build_cmd(card, IPA_SBP_QUERY_COMMANDS_SUPPORTED,
				 sizeof(struct qeth_sbp_query_cmds_supp));
				 SBP_DATA_SIZEOF(query_cmds_supp));
	if (!iob)
		return;

@@ -1563,23 +1541,21 @@ static int qeth_bridgeport_set_cb(struct qeth_card *card,
 */
int qeth_bridgeport_setrole(struct qeth_card *card, enum qeth_sbp_roles role)
{
	int cmdlength;
	struct qeth_cmd_buffer *iob;
	enum qeth_ipa_sbp_cmd setcmd;
	unsigned int cmdlength = 0;

	QETH_CARD_TEXT(card, 2, "brsetrol");
	switch (role) {
	case QETH_SBP_ROLE_NONE:
		setcmd = IPA_SBP_RESET_BRIDGE_PORT_ROLE;
		cmdlength = sizeof(struct qeth_sbp_reset_role);
		break;
	case QETH_SBP_ROLE_PRIMARY:
		setcmd = IPA_SBP_SET_PRIMARY_BRIDGE_PORT;
		cmdlength = sizeof(struct qeth_sbp_set_primary);
		cmdlength = SBP_DATA_SIZEOF(set_primary);
		break;
	case QETH_SBP_ROLE_SECONDARY:
		setcmd = IPA_SBP_SET_SECONDARY_BRIDGE_PORT;
		cmdlength = sizeof(struct qeth_sbp_set_secondary);
		break;
	default:
		return -EINVAL;
@@ -1728,10 +1704,6 @@ static int qeth_l2_vnicc_makerc(struct qeth_card *card, u16 ipa_rc)
/* generic VNICC request call back control */
struct _qeth_l2_vnicc_request_cbctl {
	u32 sub_cmd;
	struct {
		u32 vnic_char;
		u32 timeout;
	} param;
	struct {
		union{
			u32 *sup_cmds;
@@ -1754,80 +1726,52 @@ static int qeth_l2_vnicc_request_cb(struct qeth_card *card,
	if (cmd->hdr.return_code)
		return qeth_l2_vnicc_makerc(card, cmd->hdr.return_code);
	/* return results to caller */
	card->options.vnicc.sup_chars = rep->hdr.sup;
	card->options.vnicc.cur_chars = rep->hdr.cur;
	card->options.vnicc.sup_chars = rep->vnicc_cmds.supported;
	card->options.vnicc.cur_chars = rep->vnicc_cmds.enabled;

	if (cbctl->sub_cmd == IPA_VNICC_QUERY_CMDS)
		*cbctl->result.sup_cmds = rep->query_cmds.sup_cmds;
		*cbctl->result.sup_cmds = rep->data.query_cmds.sup_cmds;

	if (cbctl->sub_cmd == IPA_VNICC_GET_TIMEOUT)
		*cbctl->result.timeout = rep->getset_timeout.timeout;
		*cbctl->result.timeout = rep->data.getset_timeout.timeout;

	return 0;
}

/* generic VNICC request */
static int qeth_l2_vnicc_request(struct qeth_card *card,
				 struct _qeth_l2_vnicc_request_cbctl *cbctl)
static struct qeth_cmd_buffer *qeth_l2_vnicc_build_cmd(struct qeth_card *card,
						       u32 vnicc_cmd,
						       unsigned int data_length)
{
	struct qeth_ipacmd_vnicc *req;
	struct qeth_ipacmd_vnicc_hdr *hdr;
	struct qeth_cmd_buffer *iob;
	struct qeth_ipa_cmd *cmd;

	QETH_CARD_TEXT(card, 2, "vniccreq");

	/* get new buffer for request */
	iob = qeth_get_ipacmd_buffer(card, IPA_CMD_VNICC, 0);
	iob = qeth_ipa_alloc_cmd(card, IPA_CMD_VNICC, QETH_PROT_NONE,
				 data_length +
				 offsetof(struct qeth_ipacmd_vnicc, data));
	if (!iob)
		return -ENOMEM;

	/* create header for request */
	cmd = __ipa_cmd(iob);
	req = &cmd->data.vnicc;
		return NULL;

	/* create sub command header for request */
	req->sub_hdr.data_length = sizeof(req->sub_hdr);
	req->sub_hdr.sub_command = cbctl->sub_cmd;

	/* create sub command specific request fields */
	switch (cbctl->sub_cmd) {
	case IPA_VNICC_QUERY_CHARS:
		break;
	case IPA_VNICC_QUERY_CMDS:
		req->sub_hdr.data_length += sizeof(req->query_cmds);
		req->query_cmds.vnic_char = cbctl->param.vnic_char;
		break;
	case IPA_VNICC_ENABLE:
	case IPA_VNICC_DISABLE:
		req->sub_hdr.data_length += sizeof(req->set_char);
		req->set_char.vnic_char = cbctl->param.vnic_char;
		break;
	case IPA_VNICC_SET_TIMEOUT:
		req->getset_timeout.timeout = cbctl->param.timeout;
		/* fallthrough */
	case IPA_VNICC_GET_TIMEOUT:
		req->sub_hdr.data_length += sizeof(req->getset_timeout);
		req->getset_timeout.vnic_char = cbctl->param.vnic_char;
		break;
	default:
		qeth_release_buffer(iob);
		return -EOPNOTSUPP;
	}

	/* send request */
	return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, cbctl);
	hdr = &__ipa_cmd(iob)->data.vnicc.hdr;
	hdr->data_length = sizeof(*hdr) + data_length;
	hdr->sub_command = vnicc_cmd;
	return iob;
}

/* VNICC query VNIC characteristics request */
static int qeth_l2_vnicc_query_chars(struct qeth_card *card)
{
	struct _qeth_l2_vnicc_request_cbctl cbctl;
	struct qeth_cmd_buffer *iob;

	QETH_CARD_TEXT(card, 2, "vniccqch");
	iob = qeth_l2_vnicc_build_cmd(card, IPA_VNICC_QUERY_CHARS, 0);
	if (!iob)
		return -ENOMEM;

	/* prepare callback control */
	cbctl.sub_cmd = IPA_VNICC_QUERY_CHARS;

	QETH_CARD_TEXT(card, 2, "vniccqch");
	return qeth_l2_vnicc_request(card, &cbctl);
	return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, &cbctl);
}

/* VNICC query sub commands request */
@@ -1835,14 +1779,21 @@ static int qeth_l2_vnicc_query_cmds(struct qeth_card *card, u32 vnic_char,
				    u32 *sup_cmds)
{
	struct _qeth_l2_vnicc_request_cbctl cbctl;
	struct qeth_cmd_buffer *iob;

	QETH_CARD_TEXT(card, 2, "vniccqcm");
	iob = qeth_l2_vnicc_build_cmd(card, IPA_VNICC_QUERY_CMDS,
				      VNICC_DATA_SIZEOF(query_cmds));
	if (!iob)
		return -ENOMEM;

	__ipa_cmd(iob)->data.vnicc.data.query_cmds.vnic_char = vnic_char;

	/* prepare callback control */
	cbctl.sub_cmd = IPA_VNICC_QUERY_CMDS;
	cbctl.param.vnic_char = vnic_char;
	cbctl.result.sup_cmds = sup_cmds;

	QETH_CARD_TEXT(card, 2, "vniccqcm");
	return qeth_l2_vnicc_request(card, &cbctl);
	return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, &cbctl);
}

/* VNICC enable/disable characteristic request */
@@ -1850,31 +1801,47 @@ static int qeth_l2_vnicc_set_char(struct qeth_card *card, u32 vnic_char,
				      u32 cmd)
{
	struct _qeth_l2_vnicc_request_cbctl cbctl;
	struct qeth_cmd_buffer *iob;

	QETH_CARD_TEXT(card, 2, "vniccedc");
	iob = qeth_l2_vnicc_build_cmd(card, cmd, VNICC_DATA_SIZEOF(set_char));
	if (!iob)
		return -ENOMEM;

	__ipa_cmd(iob)->data.vnicc.data.set_char.vnic_char = vnic_char;

	/* prepare callback control */
	cbctl.sub_cmd = cmd;
	cbctl.param.vnic_char = vnic_char;

	QETH_CARD_TEXT(card, 2, "vniccedc");
	return qeth_l2_vnicc_request(card, &cbctl);
	return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, &cbctl);
}

/* VNICC get/set timeout for characteristic request */
static int qeth_l2_vnicc_getset_timeout(struct qeth_card *card, u32 vnicc,
					u32 cmd, u32 *timeout)
{
	struct qeth_vnicc_getset_timeout *getset_timeout;
	struct _qeth_l2_vnicc_request_cbctl cbctl;
	struct qeth_cmd_buffer *iob;

	QETH_CARD_TEXT(card, 2, "vniccgst");
	iob = qeth_l2_vnicc_build_cmd(card, cmd,
				      VNICC_DATA_SIZEOF(getset_timeout));
	if (!iob)
		return -ENOMEM;

	getset_timeout = &__ipa_cmd(iob)->data.vnicc.data.getset_timeout;
	getset_timeout->vnic_char = vnicc;

	if (cmd == IPA_VNICC_SET_TIMEOUT)
		getset_timeout->timeout = *timeout;

	/* prepare callback control */
	cbctl.sub_cmd = cmd;
	cbctl.param.vnic_char = vnicc;
	if (cmd == IPA_VNICC_SET_TIMEOUT)
		cbctl.param.timeout = *timeout;
	if (cmd == IPA_VNICC_GET_TIMEOUT)
		cbctl.result.timeout = timeout;

	QETH_CARD_TEXT(card, 2, "vniccgst");
	return qeth_l2_vnicc_request(card, &cbctl);
	return qeth_send_ipa_cmd(card, iob, qeth_l2_vnicc_request_cb, &cbctl);
}

/* set current VNICC flag state; called from sysfs store function */
+82 −128

File changed.

Preview size limit exceeded, changes collapsed.