Merge branch 's390-qeth-next'
Julian Wiedmann says: ==================== s390/qeth: updates 2018-11-08 please apply the following qeth patches to net-next. The first patch allows one more device type to query the FW for a MAC address, the others are all basically just removal of duplicated or unused code. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
52358cb5a3
|
@ -314,7 +314,7 @@ struct qeth_hdr_layer3 {
|
|||
__u16 frame_offset;
|
||||
union {
|
||||
/* TX: */
|
||||
u8 ipv6_addr[16];
|
||||
struct in6_addr ipv6_addr;
|
||||
struct ipv4 {
|
||||
u8 res[12];
|
||||
u32 addr;
|
||||
|
@ -665,7 +665,6 @@ struct qeth_card_blkt {
|
|||
|
||||
#define QETH_BROADCAST_WITH_ECHO 0x01
|
||||
#define QETH_BROADCAST_WITHOUT_ECHO 0x02
|
||||
#define QETH_LAYER2_MAC_READ 0x01
|
||||
#define QETH_LAYER2_MAC_REGISTERED 0x02
|
||||
struct qeth_card_info {
|
||||
unsigned short unit_addr2;
|
||||
|
@ -775,7 +774,6 @@ struct qeth_switch_info {
|
|||
#define QETH_NAPI_WEIGHT NAPI_POLL_WEIGHT
|
||||
|
||||
struct qeth_card {
|
||||
struct list_head list;
|
||||
enum qeth_card_states state;
|
||||
spinlock_t lock;
|
||||
struct ccwgroup_device *gdev;
|
||||
|
@ -827,11 +825,6 @@ struct qeth_card {
|
|||
struct work_struct close_dev_work;
|
||||
};
|
||||
|
||||
struct qeth_card_list_struct {
|
||||
struct list_head list;
|
||||
rwlock_t rwlock;
|
||||
};
|
||||
|
||||
struct qeth_trap_id {
|
||||
__u16 lparnr;
|
||||
char vmname[8];
|
||||
|
@ -978,11 +971,11 @@ int qeth_core_load_discipline(struct qeth_card *, enum qeth_discipline_id);
|
|||
void qeth_core_free_discipline(struct qeth_card *);
|
||||
|
||||
/* exports for qeth discipline device drivers */
|
||||
extern struct qeth_card_list_struct qeth_core_card_list;
|
||||
extern struct kmem_cache *qeth_core_header_cache;
|
||||
extern struct qeth_dbf_info qeth_dbf[QETH_DBF_INFOS];
|
||||
|
||||
struct net_device *qeth_clone_netdev(struct net_device *orig);
|
||||
struct qeth_card *qeth_get_card_by_busid(char *bus_id);
|
||||
void qeth_set_recovery_task(struct qeth_card *);
|
||||
void qeth_clear_recovery_task(struct qeth_card *);
|
||||
void qeth_set_allowed_threads(struct qeth_card *, unsigned long , int);
|
||||
|
@ -1025,9 +1018,6 @@ int qeth_send_control_data(struct qeth_card *, int, struct qeth_cmd_buffer *,
|
|||
int (*reply_cb)(struct qeth_card *, struct qeth_reply*, unsigned long),
|
||||
void *reply_param);
|
||||
unsigned int qeth_count_elements(struct sk_buff *skb, unsigned int data_offset);
|
||||
int qeth_do_send_packet_fast(struct qeth_qdio_out_q *queue, struct sk_buff *skb,
|
||||
struct qeth_hdr *hdr, unsigned int offset,
|
||||
unsigned int hd_len);
|
||||
int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
|
||||
struct sk_buff *skb, struct qeth_hdr *hdr,
|
||||
unsigned int offset, unsigned int hd_len,
|
||||
|
@ -1058,11 +1048,6 @@ netdev_features_t qeth_features_check(struct sk_buff *skb,
|
|||
struct net_device *dev,
|
||||
netdev_features_t features);
|
||||
int qeth_vm_request_mac(struct qeth_card *card);
|
||||
int qeth_add_hw_header(struct qeth_card *card, struct sk_buff *skb,
|
||||
struct qeth_hdr **hdr, unsigned int hdr_len,
|
||||
unsigned int proto_len, unsigned int *elements);
|
||||
void qeth_fill_tso_ext(struct qeth_hdr_tso *hdr, unsigned int payload_len,
|
||||
struct sk_buff *skb, unsigned int proto_len);
|
||||
int qeth_xmit(struct qeth_card *card, struct sk_buff *skb,
|
||||
struct qeth_qdio_out_q *queue, int ipv, int cast_type,
|
||||
void (*fill_header)(struct qeth_card *card, struct qeth_hdr *hdr,
|
||||
|
|
|
@ -54,8 +54,6 @@ struct qeth_dbf_info qeth_dbf[QETH_DBF_INFOS] = {
|
|||
};
|
||||
EXPORT_SYMBOL_GPL(qeth_dbf);
|
||||
|
||||
struct qeth_card_list_struct qeth_core_card_list;
|
||||
EXPORT_SYMBOL_GPL(qeth_core_card_list);
|
||||
struct kmem_cache *qeth_core_header_cache;
|
||||
EXPORT_SYMBOL_GPL(qeth_core_header_cache);
|
||||
static struct kmem_cache *qeth_qdio_outbuf_cache;
|
||||
|
@ -2837,6 +2835,17 @@ static void qeth_fill_ipacmd_header(struct qeth_card *card,
|
|||
cmd->hdr.prot_version = prot;
|
||||
}
|
||||
|
||||
void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob)
|
||||
{
|
||||
u8 prot_type = qeth_mpc_select_prot_type(card);
|
||||
|
||||
memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
|
||||
memcpy(QETH_IPA_CMD_PROT_TYPE(iob->data), &prot_type, 1);
|
||||
memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
|
||||
&card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_prepare_ipa_cmd);
|
||||
|
||||
struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *card,
|
||||
enum qeth_ipa_cmds ipacmd, enum qeth_prot_versions prot)
|
||||
{
|
||||
|
@ -2844,6 +2853,7 @@ struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *card,
|
|||
|
||||
iob = qeth_get_buffer(&card->write);
|
||||
if (iob) {
|
||||
qeth_prepare_ipa_cmd(card, iob);
|
||||
qeth_fill_ipacmd_header(card, __ipa_cmd(iob), ipacmd, prot);
|
||||
} else {
|
||||
dev_warn(&card->gdev->dev,
|
||||
|
@ -2856,17 +2866,6 @@ struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *card,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_get_ipacmd_buffer);
|
||||
|
||||
void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob)
|
||||
{
|
||||
u8 prot_type = qeth_mpc_select_prot_type(card);
|
||||
|
||||
memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
|
||||
memcpy(QETH_IPA_CMD_PROT_TYPE(iob->data), &prot_type, 1);
|
||||
memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
|
||||
&card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_prepare_ipa_cmd);
|
||||
|
||||
/**
|
||||
* qeth_send_ipa_cmd() - send an IPA command
|
||||
*
|
||||
|
@ -2881,7 +2880,6 @@ int qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
|
|||
int rc;
|
||||
|
||||
QETH_CARD_TEXT(card, 4, "sendipa");
|
||||
qeth_prepare_ipa_cmd(card, iob);
|
||||
rc = qeth_send_control_data(card, IPA_CMD_LENGTH,
|
||||
iob, reply_cb, reply_param);
|
||||
if (rc == -ETIME) {
|
||||
|
@ -3777,9 +3775,9 @@ EXPORT_SYMBOL_GPL(qeth_count_elements);
|
|||
* The number of needed buffer elements is returned in @elements.
|
||||
* Error to create the hdr is indicated by returning with < 0.
|
||||
*/
|
||||
int qeth_add_hw_header(struct qeth_card *card, struct sk_buff *skb,
|
||||
struct qeth_hdr **hdr, unsigned int hdr_len,
|
||||
unsigned int proto_len, unsigned int *elements)
|
||||
static int qeth_add_hw_header(struct qeth_card *card, struct sk_buff *skb,
|
||||
struct qeth_hdr **hdr, unsigned int hdr_len,
|
||||
unsigned int proto_len, unsigned int *elements)
|
||||
{
|
||||
const unsigned int max_elements = QETH_MAX_BUFFER_ELEMENTS(card);
|
||||
const unsigned int contiguous = proto_len ? proto_len : 1;
|
||||
|
@ -3849,7 +3847,6 @@ check_layout:
|
|||
skb_copy_from_linear_data(skb, ((char *)*hdr) + hdr_len, proto_len);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_add_hw_header);
|
||||
|
||||
static void __qeth_fill_buffer(struct sk_buff *skb,
|
||||
struct qeth_qdio_out_buffer *buf,
|
||||
|
@ -3972,9 +3969,9 @@ static int qeth_fill_buffer(struct qeth_qdio_out_q *queue,
|
|||
return flush_cnt;
|
||||
}
|
||||
|
||||
int qeth_do_send_packet_fast(struct qeth_qdio_out_q *queue, struct sk_buff *skb,
|
||||
struct qeth_hdr *hdr, unsigned int offset,
|
||||
unsigned int hd_len)
|
||||
static int qeth_do_send_packet_fast(struct qeth_qdio_out_q *queue,
|
||||
struct sk_buff *skb, struct qeth_hdr *hdr,
|
||||
unsigned int offset, unsigned int hd_len)
|
||||
{
|
||||
int index = queue->next_buf_to_fill;
|
||||
struct qeth_qdio_out_buffer *buffer = queue->bufs[index];
|
||||
|
@ -3990,7 +3987,6 @@ int qeth_do_send_packet_fast(struct qeth_qdio_out_q *queue, struct sk_buff *skb,
|
|||
qeth_flush_buffers(queue, index, 1);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_do_send_packet_fast);
|
||||
|
||||
int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
|
||||
struct sk_buff *skb, struct qeth_hdr *hdr,
|
||||
|
@ -4082,8 +4078,9 @@ out:
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_do_send_packet);
|
||||
|
||||
void qeth_fill_tso_ext(struct qeth_hdr_tso *hdr, unsigned int payload_len,
|
||||
struct sk_buff *skb, unsigned int proto_len)
|
||||
static void qeth_fill_tso_ext(struct qeth_hdr_tso *hdr,
|
||||
unsigned int payload_len, struct sk_buff *skb,
|
||||
unsigned int proto_len)
|
||||
{
|
||||
struct qeth_hdr_ext_tso *ext = &hdr->ext;
|
||||
|
||||
|
@ -4096,7 +4093,6 @@ void qeth_fill_tso_ext(struct qeth_hdr_tso *hdr, unsigned int payload_len,
|
|||
ext->mss = skb_shinfo(skb)->gso_size;
|
||||
ext->dg_hdr_len = proto_len;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_fill_tso_ext);
|
||||
|
||||
int qeth_xmit(struct qeth_card *card, struct sk_buff *skb,
|
||||
struct qeth_qdio_out_q *queue, int ipv, int cast_type,
|
||||
|
@ -4119,7 +4115,7 @@ int qeth_xmit(struct qeth_card *card, struct sk_buff *skb,
|
|||
proto_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
|
||||
} else {
|
||||
hw_hdr_len = sizeof(struct qeth_hdr);
|
||||
proto_len = IS_IQD(card) ? ETH_HLEN : 0;
|
||||
proto_len = (IS_IQD(card) && IS_LAYER2(card)) ? ETH_HLEN : 0;
|
||||
}
|
||||
|
||||
rc = skb_cow_head(skb, hw_hdr_len);
|
||||
|
@ -4235,16 +4231,18 @@ static int qeth_setadpparms_change_macaddr_cb(struct qeth_card *card,
|
|||
struct qeth_reply *reply, unsigned long data)
|
||||
{
|
||||
struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
|
||||
struct qeth_ipacmd_setadpparms *adp_cmd;
|
||||
|
||||
QETH_CARD_TEXT(card, 4, "chgmaccb");
|
||||
if (qeth_setadpparms_inspect_rc(cmd))
|
||||
return 0;
|
||||
|
||||
if (IS_LAYER3(card) || !(card->info.mac_bits & QETH_LAYER2_MAC_READ)) {
|
||||
ether_addr_copy(card->dev->dev_addr,
|
||||
cmd->data.setadapterparms.data.change_addr.addr);
|
||||
card->info.mac_bits |= QETH_LAYER2_MAC_READ;
|
||||
}
|
||||
adp_cmd = &cmd->data.setadapterparms;
|
||||
if (IS_LAYER2(card) && IS_OSD(card) && !IS_VM_NIC(card) &&
|
||||
!(adp_cmd->hdr.flags & QETH_SETADP_FLAGS_VIRTUAL_MAC))
|
||||
return 0;
|
||||
|
||||
ether_addr_copy(card->dev->dev_addr, adp_cmd->data.change_addr.addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -4499,9 +4497,6 @@ static int qeth_send_ipa_snmp_cmd(struct qeth_card *card,
|
|||
|
||||
QETH_CARD_TEXT(card, 4, "sendsnmp");
|
||||
|
||||
memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
|
||||
memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
|
||||
&card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
|
||||
/* adjust PDU length fields in IPA_PDU_HEADER */
|
||||
s1 = (u32) IPA_PDU_HEADER_SIZE + len;
|
||||
s2 = (u32) len;
|
||||
|
@ -5480,34 +5475,11 @@ struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *card,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_get_setassparms_cmd);
|
||||
|
||||
static 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 = __ipa_cmd(iob);
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int rc;
|
||||
int length = 0;
|
||||
struct qeth_cmd_buffer *iob;
|
||||
|
||||
|
@ -5517,9 +5489,9 @@ int qeth_send_simple_setassparms_prot(struct qeth_card *card,
|
|||
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;
|
||||
|
||||
__ipa_cmd(iob)->data.setassparms.data.flags_32bit = (__u32) data;
|
||||
return qeth_send_ipa_cmd(card, iob, qeth_setassparms_cb, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_send_simple_setassparms_prot);
|
||||
|
||||
|
@ -5806,9 +5778,6 @@ static int qeth_core_probe_device(struct ccwgroup_device *gdev)
|
|||
break;
|
||||
}
|
||||
|
||||
write_lock_irq(&qeth_core_card_list.rwlock);
|
||||
list_add_tail(&card->list, &qeth_core_card_list.list);
|
||||
write_unlock_irq(&qeth_core_card_list.rwlock);
|
||||
return 0;
|
||||
|
||||
err_disc:
|
||||
|
@ -5833,9 +5802,6 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev)
|
|||
qeth_core_free_discipline(card);
|
||||
}
|
||||
|
||||
write_lock_irq(&qeth_core_card_list.rwlock);
|
||||
list_del(&card->list);
|
||||
write_unlock_irq(&qeth_core_card_list.rwlock);
|
||||
free_netdev(card->dev);
|
||||
qeth_core_free_card(card);
|
||||
put_device(&gdev->dev);
|
||||
|
@ -5950,6 +5916,21 @@ static struct ccwgroup_driver qeth_core_ccwgroup_driver = {
|
|||
.restore = qeth_core_restore,
|
||||
};
|
||||
|
||||
struct qeth_card *qeth_get_card_by_busid(char *bus_id)
|
||||
{
|
||||
struct ccwgroup_device *gdev;
|
||||
struct qeth_card *card;
|
||||
|
||||
gdev = get_ccwgroupdev_by_busid(&qeth_core_ccwgroup_driver, bus_id);
|
||||
if (!gdev)
|
||||
return NULL;
|
||||
|
||||
card = dev_get_drvdata(&gdev->dev);
|
||||
put_device(&gdev->dev);
|
||||
return card;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_get_card_by_busid);
|
||||
|
||||
int qeth_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
||||
{
|
||||
struct qeth_card *card = dev->ml_priv;
|
||||
|
@ -6381,16 +6362,16 @@ static int qeth_ipa_checksum_run_cmd(struct qeth_card *card,
|
|||
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), prot);
|
||||
if (iob)
|
||||
rc = qeth_send_setassparms(card, iob, sizeof(__u32), data,
|
||||
qeth_ipa_checksum_run_cmd_cb,
|
||||
chksum_cb);
|
||||
return rc;
|
||||
if (!iob)
|
||||
return -ENOMEM;
|
||||
|
||||
__ipa_cmd(iob)->data.setassparms.data.flags_32bit = (__u32) data;
|
||||
return qeth_send_ipa_cmd(card, iob, qeth_ipa_checksum_run_cmd_cb,
|
||||
chksum_cb);
|
||||
}
|
||||
|
||||
static int qeth_send_checksum_on(struct qeth_card *card, int cstype,
|
||||
|
@ -6488,8 +6469,7 @@ static int qeth_set_tso_on(struct qeth_card *card,
|
|||
if (!iob)
|
||||
return -ENOMEM;
|
||||
|
||||
rc = qeth_send_setassparms(card, iob, 0, 0 /* unused */,
|
||||
qeth_start_tso_cb, &tso_data);
|
||||
rc = qeth_send_ipa_cmd(card, iob, qeth_start_tso_cb, &tso_data);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
|
@ -6506,10 +6486,9 @@ static int qeth_set_tso_on(struct qeth_card *card,
|
|||
}
|
||||
|
||||
/* enable TSO capability */
|
||||
caps.supported = 0;
|
||||
caps.enabled = QETH_IPA_LARGE_SEND_TCP;
|
||||
rc = qeth_send_setassparms(card, iob, sizeof(caps), (long) &caps,
|
||||
qeth_setassparms_get_caps_cb, &caps);
|
||||
__ipa_cmd(iob)->data.setassparms.data.caps.enabled =
|
||||
QETH_IPA_LARGE_SEND_TCP;
|
||||
rc = qeth_send_ipa_cmd(card, iob, qeth_setassparms_get_caps_cb, &caps);
|
||||
if (rc) {
|
||||
qeth_set_tso_off(card, prot);
|
||||
return rc;
|
||||
|
@ -6688,8 +6667,6 @@ static int __init qeth_core_init(void)
|
|||
int rc;
|
||||
|
||||
pr_info("loading core functions\n");
|
||||
INIT_LIST_HEAD(&qeth_core_card_list.list);
|
||||
rwlock_init(&qeth_core_card_list.rwlock);
|
||||
|
||||
qeth_wq = create_singlethread_workqueue("qeth_wq");
|
||||
if (!qeth_wq) {
|
||||
|
|
|
@ -144,7 +144,6 @@ unsigned char IPA_PDU_HEADER[] = {
|
|||
sizeof(struct qeth_ipa_cmd) % 256,
|
||||
0x00, 0x00, 0x00, 0x40,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(IPA_PDU_HEADER);
|
||||
|
||||
struct ipa_rc_msg {
|
||||
enum qeth_ipa_return_codes rc;
|
||||
|
|
|
@ -80,7 +80,9 @@ enum qeth_card_types {
|
|||
};
|
||||
|
||||
#define IS_IQD(card) ((card)->info.type == QETH_CARD_TYPE_IQD)
|
||||
#define IS_OSD(card) ((card)->info.type == QETH_CARD_TYPE_OSD)
|
||||
#define IS_OSN(card) ((card)->info.type == QETH_CARD_TYPE_OSN)
|
||||
#define IS_VM_NIC(card) ((card)->info.guestlan)
|
||||
|
||||
#define QETH_MPC_DIFINFO_LEN_INDICATES_LINK_TYPE 0x18
|
||||
/* only the first two bytes are looked at in qeth_get_cardname_short */
|
||||
|
@ -529,17 +531,20 @@ struct qeth_query_switch_attributes {
|
|||
__u8 reserved3[8];
|
||||
};
|
||||
|
||||
#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;
|
||||
__u16 return_code;
|
||||
__u8 used_total;
|
||||
__u8 seq_no;
|
||||
__u32 reserved3;
|
||||
} __attribute__ ((packed));
|
||||
u32 supp_hw_cmds;
|
||||
u32 reserved1;
|
||||
u16 cmdlength;
|
||||
u16 reserved2;
|
||||
u32 command_code;
|
||||
u16 return_code;
|
||||
u8 used_total;
|
||||
u8 seq_no;
|
||||
u8 flags;
|
||||
u8 reserved3[3];
|
||||
};
|
||||
|
||||
struct qeth_ipacmd_setadpparms {
|
||||
struct qeth_ipacmd_setadpparms_hdr hdr;
|
||||
|
@ -828,10 +833,9 @@ 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_SETASS_BASE_LEN (sizeof(struct qeth_ipacmd_hdr) + \
|
||||
sizeof(struct qeth_ipacmd_setassparms_hdr))
|
||||
#define QETH_IPA_ARP_DATA_POS(buffer) (buffer + IPA_PDU_HEADER_SIZE + \
|
||||
QETH_SETASS_BASE_LEN)
|
||||
#define QETH_SETASS_BASE_LEN (IPA_PDU_HEADER_SIZE + \
|
||||
sizeof(struct qeth_ipacmd_hdr) + \
|
||||
sizeof(struct qeth_ipacmd_setassparms_hdr))
|
||||
#define QETH_SETADP_BASE_LEN (sizeof(struct qeth_ipacmd_hdr) + \
|
||||
sizeof(struct qeth_ipacmd_setadpparms_hdr))
|
||||
#define QETH_SNMP_SETADP_CMDLENGTH 16
|
||||
|
|
|
@ -36,28 +36,6 @@ static void qeth_l2_vnicc_init(struct qeth_card *card);
|
|||
static bool qeth_l2_vnicc_recover_timeout(struct qeth_card *card, u32 vnicc,
|
||||
u32 *timeout);
|
||||
|
||||
static struct net_device *qeth_l2_netdev_by_devno(unsigned char *read_dev_no)
|
||||
{
|
||||
struct qeth_card *card;
|
||||
struct net_device *ndev;
|
||||
__u16 temp_dev_no;
|
||||
unsigned long flags;
|
||||
struct ccw_dev_id read_devid;
|
||||
|
||||
ndev = NULL;
|
||||
memcpy(&temp_dev_no, read_dev_no, 2);
|
||||
read_lock_irqsave(&qeth_core_card_list.rwlock, flags);
|
||||
list_for_each_entry(card, &qeth_core_card_list.list, list) {
|
||||
ccw_device_get_id(CARD_RDEV(card), &read_devid);
|
||||
if (read_devid.devno == temp_dev_no) {
|
||||
ndev = card->dev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
read_unlock_irqrestore(&qeth_core_card_list.rwlock, flags);
|
||||
return ndev;
|
||||
}
|
||||
|
||||
static int qeth_setdelmac_makerc(struct qeth_card *card, int retcode)
|
||||
{
|
||||
int rc;
|
||||
|
@ -461,12 +439,9 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card)
|
|||
/* fall back to alternative mechanism: */
|
||||
}
|
||||
|
||||
if (card->info.type == QETH_CARD_TYPE_IQD ||
|
||||
card->info.type == QETH_CARD_TYPE_OSM ||
|
||||
card->info.type == QETH_CARD_TYPE_OSX ||
|
||||
card->info.guestlan) {
|
||||
if (!IS_OSN(card)) {
|
||||
rc = qeth_setadpparms_change_macaddr(card);
|
||||
if (!rc)
|
||||
if (!rc && is_valid_ether_addr(card->dev->dev_addr))
|
||||
goto out;
|
||||
QETH_DBF_MESSAGE(2, "READ_MAC Assist failed on device %x: %#x\n",
|
||||
CARD_DEVID(card), rc);
|
||||
|
@ -917,7 +892,8 @@ static int qeth_l2_setup_netdev(struct qeth_card *card, bool carrier_ok)
|
|||
PAGE_SIZE * (QDIO_MAX_ELEMENTS_PER_BUFFER - 1));
|
||||
}
|
||||
|
||||
qeth_l2_request_initial_mac(card);
|
||||
if (!is_valid_ether_addr(card->dev->dev_addr))
|
||||
qeth_l2_request_initial_mac(card);
|
||||
netif_napi_add(card->dev, &card->napi, qeth_poll, QETH_NAPI_WEIGHT);
|
||||
rc = register_netdev(card->dev);
|
||||
if (!rc && carrier_ok)
|
||||
|
@ -1288,13 +1264,16 @@ int qeth_osn_register(unsigned char *read_dev_no, struct net_device **dev,
|
|||
int (*data_cb)(struct sk_buff *))
|
||||
{
|
||||
struct qeth_card *card;
|
||||
char bus_id[16];
|
||||
u16 devno;
|
||||
|
||||
*dev = qeth_l2_netdev_by_devno(read_dev_no);
|
||||
if (*dev == NULL)
|
||||
return -ENODEV;
|
||||
card = (*dev)->ml_priv;
|
||||
if (!card)
|
||||
memcpy(&devno, read_dev_no, 2);
|
||||
sprintf(bus_id, "0.0.%04x", devno);
|
||||
card = qeth_get_card_by_busid(bus_id);
|
||||
if (!card || !IS_OSN(card))
|
||||
return -ENODEV;
|
||||
*dev = card->dev;
|
||||
|
||||
QETH_CARD_TEXT(card, 2, "osnreg");
|
||||
if ((assist_cb == NULL) || (data_cb == NULL))
|
||||
return -EINVAL;
|
||||
|
|
|
@ -949,9 +949,6 @@ static int qeth_l3_iqd_read_initial_mac_cb(struct qeth_card *card,
|
|||
if (cmd->hdr.return_code == 0)
|
||||
ether_addr_copy(card->dev->dev_addr,
|
||||
cmd->data.create_destroy_addr.unique_id);
|
||||
else
|
||||
eth_random_addr(card->dev->dev_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1685,21 +1682,6 @@ out_error:
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int qeth_l3_send_ipa_arp_cmd(struct qeth_card *card,
|
||||
struct qeth_cmd_buffer *iob, int len,
|
||||
int (*reply_cb)(struct qeth_card *, struct qeth_reply *,
|
||||
unsigned long),
|
||||
void *reply_param)
|
||||
{
|
||||
QETH_CARD_TEXT(card, 4, "sendarp");
|
||||
|
||||
memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
|
||||
memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
|
||||
&card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
|
||||
return qeth_send_control_data(card, IPA_PDU_HEADER_SIZE + len, iob,
|
||||
reply_cb, reply_param);
|
||||
}
|
||||
|
||||
static int qeth_l3_query_arp_cache_info(struct qeth_card *card,
|
||||
enum qeth_prot_versions prot,
|
||||
struct qeth_arp_query_info *qinfo)
|
||||
|
@ -1719,11 +1701,9 @@ static int qeth_l3_query_arp_cache_info(struct qeth_card *card,
|
|||
return -ENOMEM;
|
||||
cmd = __ipa_cmd(iob);
|
||||
cmd->data.setassparms.data.query_arp.request_bits = 0x000F;
|
||||
cmd->data.setassparms.data.query_arp.reply_bits = 0;
|
||||
cmd->data.setassparms.data.query_arp.no_entries = 0;
|
||||
rc = qeth_l3_send_ipa_arp_cmd(card, iob,
|
||||
QETH_SETASS_BASE_LEN+QETH_ARP_CMD_LEN,
|
||||
qeth_l3_arp_query_cb, (void *)qinfo);
|
||||
rc = qeth_send_control_data(card,
|
||||
QETH_SETASS_BASE_LEN + QETH_ARP_CMD_LEN,
|
||||
iob, qeth_l3_arp_query_cb, qinfo);
|
||||
if (rc)
|
||||
QETH_DBF_MESSAGE(2, "Error while querying ARP cache on device %x: %#x\n",
|
||||
CARD_DEVID(card), rc);
|
||||
|
@ -1929,22 +1909,6 @@ static int qeth_l3_get_cast_type(struct sk_buff *skb)
|
|||
}
|
||||
}
|
||||
|
||||
static void qeth_l3_fill_af_iucv_hdr(struct qeth_hdr *hdr, struct sk_buff *skb,
|
||||
unsigned int data_len)
|
||||
{
|
||||
char daddr[16];
|
||||
|
||||
hdr->hdr.l3.id = QETH_HEADER_TYPE_LAYER3;
|
||||
hdr->hdr.l3.length = data_len;
|
||||
hdr->hdr.l3.flags = QETH_HDR_IPV6 | QETH_CAST_UNICAST;
|
||||
|
||||
memset(daddr, 0, sizeof(daddr));
|
||||
daddr[0] = 0xfe;
|
||||
daddr[1] = 0x80;
|
||||
memcpy(&daddr[8], iucv_trans_hdr(skb)->destUserID, 8);
|
||||
memcpy(hdr->hdr.l3.next_hop.ipv6_addr, daddr, 16);
|
||||
}
|
||||
|
||||
static u8 qeth_l3_cast_type_to_flag(int cast_type)
|
||||
{
|
||||
if (cast_type == RTN_MULTICAST)
|
||||
|
@ -1960,6 +1924,7 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
|
|||
struct sk_buff *skb, int ipv, int cast_type,
|
||||
unsigned int data_len)
|
||||
{
|
||||
struct qeth_hdr_layer3 *l3_hdr = &hdr->hdr.l3;
|
||||
struct vlan_ethhdr *veth = vlan_eth_hdr(skb);
|
||||
|
||||
hdr->hdr.l3.length = data_len;
|
||||
|
@ -1968,6 +1933,15 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
|
|||
hdr->hdr.l3.id = QETH_HEADER_TYPE_L3_TSO;
|
||||
} else {
|
||||
hdr->hdr.l3.id = QETH_HEADER_TYPE_LAYER3;
|
||||
|
||||
if (skb->protocol == htons(ETH_P_AF_IUCV)) {
|
||||
l3_hdr->flags = QETH_HDR_IPV6 | QETH_CAST_UNICAST;
|
||||
l3_hdr->next_hop.ipv6_addr.s6_addr16[0] = htons(0xfe80);
|
||||
memcpy(&l3_hdr->next_hop.ipv6_addr.s6_addr32[2],
|
||||
iucv_trans_hdr(skb)->destUserID, 8);
|
||||
return;
|
||||
}
|
||||
|
||||
if (skb->ip_summed == CHECKSUM_PARTIAL) {
|
||||
qeth_tx_csum(skb, &hdr->hdr.l3.ext_flags, ipv);
|
||||
/* some HW requires combined L3+L4 csum offload: */
|
||||
|
@ -2012,13 +1986,11 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
|
|||
} else {
|
||||
/* IPv6 */
|
||||
const struct rt6_info *rt = skb_rt6_info(skb);
|
||||
const struct in6_addr *next_hop;
|
||||
|
||||
if (rt && !ipv6_addr_any(&rt->rt6i_gateway))
|
||||
next_hop = &rt->rt6i_gateway;
|
||||
l3_hdr->next_hop.ipv6_addr = rt->rt6i_gateway;
|
||||
else
|
||||
next_hop = &ipv6_hdr(skb)->daddr;
|
||||
memcpy(hdr->hdr.l3.next_hop.ipv6_addr, next_hop, 16);
|
||||
l3_hdr->next_hop.ipv6_addr = ipv6_hdr(skb)->daddr;
|
||||
|
||||
hdr->hdr.l3.flags |= QETH_HDR_IPV6;
|
||||
if (card->info.type != QETH_CARD_TYPE_IQD)
|
||||
|
@ -2044,84 +2016,25 @@ static void qeth_l3_fixup_headers(struct sk_buff *skb)
|
|||
static int qeth_l3_xmit(struct qeth_card *card, struct sk_buff *skb,
|
||||
struct qeth_qdio_out_q *queue, int ipv, int cast_type)
|
||||
{
|
||||
unsigned int hw_hdr_len, proto_len, frame_len, elements;
|
||||
unsigned char eth_hdr[ETH_HLEN];
|
||||
bool is_tso = skb_is_gso(skb);
|
||||
unsigned int data_offset = 0;
|
||||
struct qeth_hdr *hdr = NULL;
|
||||
unsigned int hd_len = 0;
|
||||
int push_len, rc;
|
||||
bool is_sg;
|
||||
|
||||
if (is_tso) {
|
||||
hw_hdr_len = sizeof(struct qeth_hdr_tso);
|
||||
proto_len = skb_transport_offset(skb) + tcp_hdrlen(skb) -
|
||||
ETH_HLEN;
|
||||
} else {
|
||||
hw_hdr_len = sizeof(struct qeth_hdr);
|
||||
proto_len = 0;
|
||||
}
|
||||
unsigned int hw_hdr_len;
|
||||
int rc;
|
||||
|
||||
/* re-use the L2 header area for the HW header: */
|
||||
hw_hdr_len = skb_is_gso(skb) ? sizeof(struct qeth_hdr_tso) :
|
||||
sizeof(struct qeth_hdr);
|
||||
rc = skb_cow_head(skb, hw_hdr_len - ETH_HLEN);
|
||||
if (rc)
|
||||
return rc;
|
||||
skb_copy_from_linear_data(skb, eth_hdr, ETH_HLEN);
|
||||
skb_pull(skb, ETH_HLEN);
|
||||
frame_len = skb->len;
|
||||
|
||||
qeth_l3_fixup_headers(skb);
|
||||
push_len = qeth_add_hw_header(card, skb, &hdr, hw_hdr_len, proto_len,
|
||||
&elements);
|
||||
if (push_len < 0)
|
||||
return push_len;
|
||||
if (is_tso || !push_len) {
|
||||
/* HW header needs its own buffer element. */
|
||||
hd_len = hw_hdr_len + proto_len;
|
||||
data_offset = push_len + proto_len;
|
||||
}
|
||||
memset(hdr, 0, hw_hdr_len);
|
||||
|
||||
if (skb->protocol == htons(ETH_P_AF_IUCV)) {
|
||||
qeth_l3_fill_af_iucv_hdr(hdr, skb, frame_len);
|
||||
} else {
|
||||
qeth_l3_fill_header(card, hdr, skb, ipv, cast_type, frame_len);
|
||||
if (is_tso)
|
||||
qeth_fill_tso_ext((struct qeth_hdr_tso *) hdr,
|
||||
frame_len - proto_len, skb,
|
||||
proto_len);
|
||||
}
|
||||
|
||||
is_sg = skb_is_nonlinear(skb);
|
||||
if (IS_IQD(card)) {
|
||||
rc = qeth_do_send_packet_fast(queue, skb, hdr, data_offset,
|
||||
hd_len);
|
||||
} else {
|
||||
/* TODO: drop skb_orphan() once TX completion is fast enough */
|
||||
skb_orphan(skb);
|
||||
rc = qeth_do_send_packet(card, queue, skb, hdr, data_offset,
|
||||
hd_len, elements);
|
||||
}
|
||||
|
||||
if (!rc) {
|
||||
if (card->options.performance_stats) {
|
||||
card->perf_stats.buf_elements_sent += elements;
|
||||
if (is_sg)
|
||||
card->perf_stats.sg_skbs_sent++;
|
||||
if (is_tso) {
|
||||
card->perf_stats.large_send_bytes += frame_len;
|
||||
card->perf_stats.large_send_cnt++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!push_len)
|
||||
kmem_cache_free(qeth_core_header_cache, hdr);
|
||||
if (rc == -EBUSY) {
|
||||
/* roll back to ETH header */
|
||||
skb_pull(skb, push_len);
|
||||
skb_push(skb, ETH_HLEN);
|
||||
skb_copy_to_linear_data(skb, eth_hdr, ETH_HLEN);
|
||||
}
|
||||
rc = qeth_xmit(card, skb, queue, ipv, cast_type, qeth_l3_fill_header);
|
||||
if (rc == -EBUSY) {
|
||||
/* roll back to ETH header */
|
||||
skb_push(skb, ETH_HLEN);
|
||||
skb_copy_to_linear_data(skb, eth_hdr, ETH_HLEN);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
@ -2366,9 +2279,6 @@ static int qeth_l3_setup_netdev(struct qeth_card *card, bool carrier_ok)
|
|||
rc = qeth_l3_iqd_read_initial_mac(card);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
if (card->options.hsuid[0])
|
||||
memcpy(card->dev->perm_addr, card->options.hsuid, 9);
|
||||
} else
|
||||
return -ENODEV;
|
||||
|
||||
|
|
Loading…
Reference in New Issue