Merge branch 's390-qeth-next'
Julian Wiedmann says: ==================== s390/qeth: updates 2018-03-09 here is the current pile of qeth patches for net-next. Just the usual small updates and clean ups. Please apply. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
f44b1886a5
|
@ -233,8 +233,6 @@ static inline int qeth_is_ipa_enabled(struct qeth_ipa_info *ipa,
|
|||
#define QETH_IDX_FUNC_LEVEL_OSD 0x0101
|
||||
#define QETH_IDX_FUNC_LEVEL_IQD 0x4108
|
||||
|
||||
#define QETH_REAL_CARD 1
|
||||
#define QETH_VLAN_CARD 2
|
||||
#define QETH_BUFSIZE 4096
|
||||
|
||||
/**
|
||||
|
@ -556,12 +554,6 @@ enum qeth_prot_versions {
|
|||
QETH_PROT_IPV6 = 0x0006,
|
||||
};
|
||||
|
||||
enum qeth_ip_types {
|
||||
QETH_IP_TYPE_NORMAL,
|
||||
QETH_IP_TYPE_VIPA,
|
||||
QETH_IP_TYPE_RXIP,
|
||||
};
|
||||
|
||||
enum qeth_cmd_buffer_state {
|
||||
BUF_STATE_FREE,
|
||||
BUF_STATE_LOCKED,
|
||||
|
|
|
@ -708,11 +708,8 @@ static int qeth_check_idx_response(struct qeth_card *card,
|
|||
|
||||
QETH_DBF_HEX(CTRL, 2, buffer, QETH_DBF_CTRL_LEN);
|
||||
if ((buffer[2] & 0xc0) == 0xc0) {
|
||||
QETH_DBF_MESSAGE(2, "received an IDX TERMINATE "
|
||||
"with cause code 0x%02x%s\n",
|
||||
buffer[4],
|
||||
((buffer[4] == 0x22) ?
|
||||
" -- try another portname" : ""));
|
||||
QETH_DBF_MESSAGE(2, "received an IDX TERMINATE with cause code %#02x\n",
|
||||
buffer[4]);
|
||||
QETH_CARD_TEXT(card, 2, "ckidxres");
|
||||
QETH_CARD_TEXT(card, 2, " idxterm");
|
||||
QETH_CARD_TEXT_(card, 2, " rc%d", -EIO);
|
||||
|
@ -2838,7 +2835,8 @@ static int qeth_init_input_buffer(struct qeth_card *card,
|
|||
int i;
|
||||
|
||||
if ((card->options.cq == QETH_CQ_ENABLED) && (!buf->rx_skb)) {
|
||||
buf->rx_skb = dev_alloc_skb(QETH_RX_PULL_LEN + ETH_HLEN);
|
||||
buf->rx_skb = netdev_alloc_skb(card->dev,
|
||||
QETH_RX_PULL_LEN + ETH_HLEN);
|
||||
if (!buf->rx_skb)
|
||||
return 1;
|
||||
}
|
||||
|
@ -2875,8 +2873,8 @@ int qeth_init_qdio_queues(struct qeth_card *card)
|
|||
QETH_DBF_TEXT(SETUP, 2, "initqdqs");
|
||||
|
||||
/* inbound queue */
|
||||
qdio_reset_buffers(card->qdio.in_q->qdio_bufs,
|
||||
QDIO_MAX_BUFFERS_PER_Q);
|
||||
qdio_reset_buffers(card->qdio.in_q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q);
|
||||
memset(&card->rx, 0, sizeof(struct qeth_rx));
|
||||
qeth_initialize_working_pool_list(card);
|
||||
/*give only as many buffers to hardware as we have buffer pool entries*/
|
||||
for (i = 0; i < card->qdio.in_buf_pool.buf_count - 1; ++i)
|
||||
|
@ -2951,12 +2949,10 @@ struct qeth_cmd_buffer *qeth_get_ipacmd_buffer(struct qeth_card *card,
|
|||
enum qeth_ipa_cmds ipacmd, enum qeth_prot_versions prot)
|
||||
{
|
||||
struct qeth_cmd_buffer *iob;
|
||||
struct qeth_ipa_cmd *cmd;
|
||||
|
||||
iob = qeth_get_buffer(&card->write);
|
||||
if (iob) {
|
||||
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
|
||||
qeth_fill_ipacmd_header(card, cmd, ipacmd, prot);
|
||||
qeth_fill_ipacmd_header(card, __ipa_cmd(iob), ipacmd, prot);
|
||||
} else {
|
||||
dev_warn(&card->gdev->dev,
|
||||
"The qeth driver ran out of channel command buffers\n");
|
||||
|
@ -3067,7 +3063,7 @@ static struct qeth_cmd_buffer *qeth_get_adapter_cmd(struct qeth_card *card,
|
|||
iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETADAPTERPARMS,
|
||||
QETH_PROT_IPV4);
|
||||
if (iob) {
|
||||
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
|
||||
cmd = __ipa_cmd(iob);
|
||||
cmd->data.setadapterparms.hdr.cmdlength = cmdlen;
|
||||
cmd->data.setadapterparms.hdr.command_code = command;
|
||||
cmd->data.setadapterparms.hdr.used_total = 1;
|
||||
|
@ -3209,7 +3205,7 @@ static int qeth_query_setdiagass(struct qeth_card *card)
|
|||
iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0);
|
||||
if (!iob)
|
||||
return -ENOMEM;
|
||||
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
|
||||
cmd = __ipa_cmd(iob);
|
||||
cmd->data.diagass.subcmd_len = 16;
|
||||
cmd->data.diagass.subcmd = QETH_DIAGS_CMD_QUERY;
|
||||
return qeth_send_ipa_cmd(card, iob, qeth_query_setdiagass_cb, NULL);
|
||||
|
@ -3262,7 +3258,7 @@ int qeth_hw_trap(struct qeth_card *card, enum qeth_diags_trap_action action)
|
|||
iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0);
|
||||
if (!iob)
|
||||
return -ENOMEM;
|
||||
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
|
||||
cmd = __ipa_cmd(iob);
|
||||
cmd->data.diagass.subcmd_len = 80;
|
||||
cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRAP;
|
||||
cmd->data.diagass.type = 1;
|
||||
|
@ -4240,7 +4236,7 @@ void qeth_setadp_promisc_mode(struct qeth_card *card)
|
|||
sizeof(struct qeth_ipacmd_setadpparms_hdr) + 8);
|
||||
if (!iob)
|
||||
return;
|
||||
cmd = (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE);
|
||||
cmd = __ipa_cmd(iob);
|
||||
cmd->data.setadapterparms.data.mode = mode;
|
||||
qeth_send_ipa_cmd(card, iob, qeth_setadp_promisc_mode_cb, NULL);
|
||||
}
|
||||
|
@ -4307,7 +4303,7 @@ int qeth_setadpparms_change_macaddr(struct qeth_card *card)
|
|||
sizeof(struct qeth_change_addr));
|
||||
if (!iob)
|
||||
return -ENOMEM;
|
||||
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
|
||||
cmd = __ipa_cmd(iob);
|
||||
cmd->data.setadapterparms.data.change_addr.cmd = CHANGE_ADDR_READ_MAC;
|
||||
cmd->data.setadapterparms.data.change_addr.addr_size = ETH_ALEN;
|
||||
ether_addr_copy(cmd->data.setadapterparms.data.change_addr.addr,
|
||||
|
@ -4422,7 +4418,7 @@ static int qeth_setadpparms_set_access_ctrl(struct qeth_card *card,
|
|||
sizeof(struct qeth_set_access_ctrl));
|
||||
if (!iob)
|
||||
return -ENOMEM;
|
||||
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
|
||||
cmd = __ipa_cmd(iob);
|
||||
access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl;
|
||||
access_ctrl_req->subcmd_code = isolation;
|
||||
|
||||
|
@ -4668,7 +4664,7 @@ static int qeth_snmp_command(struct qeth_card *card, char __user *udata)
|
|||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
|
||||
cmd = __ipa_cmd(iob);
|
||||
memcpy(&cmd->data.setadapterparms.data.snmp, &ureq->cmd, req_len);
|
||||
rc = qeth_send_ipa_snmp_cmd(card, iob, QETH_SETADP_BASE_LEN + req_len,
|
||||
qeth_snmp_command_cb, (void *)&qinfo);
|
||||
|
@ -4753,7 +4749,7 @@ static int qeth_query_oat_command(struct qeth_card *card, char __user *udata)
|
|||
rc = -ENOMEM;
|
||||
goto out_free;
|
||||
}
|
||||
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
|
||||
cmd = __ipa_cmd(iob);
|
||||
oat_req = &cmd->data.setadapterparms.data.query_oat;
|
||||
oat_req->subcmd_code = oat_data.command;
|
||||
|
||||
|
@ -5330,7 +5326,7 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
|
|||
} else {
|
||||
unsigned int linear = (use_rx_sg) ? QETH_RX_PULL_LEN : skb_len;
|
||||
|
||||
skb = dev_alloc_skb(linear + headroom);
|
||||
skb = napi_alloc_skb(&card->napi, linear + headroom);
|
||||
}
|
||||
if (!skb)
|
||||
goto no_mem;
|
||||
|
@ -5494,7 +5490,7 @@ struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *card,
|
|||
iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETASSPARMS, prot);
|
||||
|
||||
if (iob) {
|
||||
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
|
||||
cmd = __ipa_cmd(iob);
|
||||
cmd->data.setassparms.hdr.assist_no = ipa_func;
|
||||
cmd->data.setassparms.hdr.length = 8 + len;
|
||||
cmd->data.setassparms.hdr.command_code = cmd_code;
|
||||
|
@ -5517,7 +5513,7 @@ int qeth_send_setassparms(struct qeth_card *card,
|
|||
|
||||
QETH_CARD_TEXT(card, 4, "sendassp");
|
||||
|
||||
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
|
||||
cmd = __ipa_cmd(iob);
|
||||
if (len <= sizeof(__u32))
|
||||
cmd->data.setassparms.data.flags_32bit = (__u32) data;
|
||||
else /* (len > sizeof(__u32)) */
|
||||
|
|
|
@ -108,7 +108,7 @@ static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac,
|
|||
iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
|
||||
if (!iob)
|
||||
return -ENOMEM;
|
||||
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
|
||||
cmd = __ipa_cmd(iob);
|
||||
cmd->data.setdelmac.mac_length = ETH_ALEN;
|
||||
ether_addr_copy(cmd->data.setdelmac.mac, mac);
|
||||
return qeth_setdelmac_makerc(card, qeth_send_ipa_cmd(card, iob,
|
||||
|
@ -305,7 +305,7 @@ static int qeth_l2_send_setdelvlan(struct qeth_card *card, __u16 i,
|
|||
iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
|
||||
if (!iob)
|
||||
return -ENOMEM;
|
||||
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
|
||||
cmd = __ipa_cmd(iob);
|
||||
cmd->data.setdelvlan.vlan_id = i;
|
||||
return qeth_setdelvlan_makerc(card, qeth_send_ipa_cmd(card, iob,
|
||||
qeth_l2_send_setdelvlan_cb, NULL));
|
||||
|
@ -437,10 +437,8 @@ static int qeth_l2_process_inbound_buffer(struct qeth_card *card,
|
|||
*done = 1;
|
||||
break;
|
||||
}
|
||||
skb->dev = card->dev;
|
||||
switch (hdr->hdr.l2.id) {
|
||||
case QETH_HEADER_TYPE_LAYER2:
|
||||
skb->pkt_type = PACKET_HOST;
|
||||
skb->protocol = eth_type_trans(skb, skb->dev);
|
||||
if ((card->dev->features & NETIF_F_RXCSUM)
|
||||
&& ((hdr->hdr.l2.flags[1] &
|
||||
|
@ -975,6 +973,7 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
|
|||
return -ENODEV;
|
||||
|
||||
card->dev->ml_priv = card;
|
||||
card->dev->priv_flags |= IFF_UNICAST_FLT;
|
||||
card->dev->watchdog_timeo = QETH_TX_TIMEOUT;
|
||||
card->dev->mtu = card->info.initial_mtu;
|
||||
card->dev->min_mtu = 64;
|
||||
|
@ -991,9 +990,16 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
|
|||
card->dev->features |= NETIF_F_VLAN_CHALLENGED;
|
||||
else
|
||||
card->dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
|
||||
|
||||
if (card->info.type != QETH_CARD_TYPE_OSN &&
|
||||
card->info.type != QETH_CARD_TYPE_IQD) {
|
||||
card->dev->priv_flags &= ~IFF_TX_SKB_SHARING;
|
||||
card->dev->needed_headroom = sizeof(struct qeth_hdr);
|
||||
card->dev->hw_features |= NETIF_F_SG;
|
||||
card->dev->vlan_features |= NETIF_F_SG;
|
||||
}
|
||||
|
||||
if (card->info.type == QETH_CARD_TYPE_OSD && !card->info.guestlan) {
|
||||
card->dev->hw_features = NETIF_F_SG;
|
||||
card->dev->vlan_features = NETIF_F_SG;
|
||||
card->dev->features |= NETIF_F_SG;
|
||||
/* OSA 3S and earlier has no RX/TX support */
|
||||
if (qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM)) {
|
||||
|
@ -1005,11 +1011,6 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
|
|||
card->dev->vlan_features |= NETIF_F_RXCSUM;
|
||||
}
|
||||
}
|
||||
if (card->info.type != QETH_CARD_TYPE_OSN &&
|
||||
card->info.type != QETH_CARD_TYPE_IQD) {
|
||||
card->dev->priv_flags &= ~IFF_TX_SKB_SHARING;
|
||||
card->dev->needed_headroom = sizeof(struct qeth_hdr);
|
||||
}
|
||||
|
||||
card->info.broadcast_capable = 1;
|
||||
qeth_l2_request_initial_mac(card);
|
||||
|
@ -1086,7 +1087,6 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
|
|||
qeth_l2_setup_bridgeport_attrs(card);
|
||||
|
||||
card->state = CARD_STATE_HARDSETUP;
|
||||
memset(&card->rx, 0, sizeof(struct qeth_rx));
|
||||
qeth_print_status_message(card);
|
||||
|
||||
/* softsetup */
|
||||
|
@ -1374,7 +1374,6 @@ int qeth_osn_assist(struct net_device *dev, void *data, int data_len)
|
|||
{
|
||||
struct qeth_cmd_buffer *iob;
|
||||
struct qeth_card *card;
|
||||
int rc;
|
||||
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
|
@ -1385,9 +1384,8 @@ int qeth_osn_assist(struct net_device *dev, void *data, int data_len)
|
|||
if (!qeth_card_hw_is_reachable(card))
|
||||
return -ENODEV;
|
||||
iob = qeth_wait_for_buffer(&card->write);
|
||||
memcpy(iob->data+IPA_PDU_HEADER_SIZE, data, data_len);
|
||||
rc = qeth_osn_send_ipa_cmd(card, iob, data_len);
|
||||
return rc;
|
||||
memcpy(__ipa_cmd(iob), data, data_len);
|
||||
return qeth_osn_send_ipa_cmd(card, iob, data_len);
|
||||
}
|
||||
EXPORT_SYMBOL(qeth_osn_assist);
|
||||
|
||||
|
@ -1764,7 +1762,7 @@ static struct qeth_cmd_buffer *qeth_sbp_build_cmd(struct qeth_card *card,
|
|||
iob = qeth_get_ipacmd_buffer(card, ipa_cmd, 0);
|
||||
if (!iob)
|
||||
return iob;
|
||||
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
|
||||
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;
|
||||
|
@ -2129,7 +2127,7 @@ static int qeth_l2_vnicc_request(struct qeth_card *card,
|
|||
return -ENOMEM;
|
||||
|
||||
/* create header for request */
|
||||
cmd = (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE);
|
||||
cmd = __ipa_cmd(iob);
|
||||
req = &cmd->data.vnicc;
|
||||
|
||||
/* create sub command header for request */
|
||||
|
|
|
@ -15,21 +15,26 @@
|
|||
|
||||
#define QETH_SNIFF_AVAIL 0x0008
|
||||
|
||||
enum qeth_ip_types {
|
||||
QETH_IP_TYPE_NORMAL,
|
||||
QETH_IP_TYPE_VIPA,
|
||||
QETH_IP_TYPE_RXIP,
|
||||
};
|
||||
|
||||
struct qeth_ipaddr {
|
||||
struct hlist_node hnode;
|
||||
enum qeth_ip_types type;
|
||||
enum qeth_ipa_setdelip_flags set_flags;
|
||||
enum qeth_ipa_setdelip_flags del_flags;
|
||||
unsigned char mac[ETH_ALEN];
|
||||
u8 is_multicast:1;
|
||||
u8 in_progress:1;
|
||||
u8 disp_flag:2;
|
||||
u8 ipato:1; /* ucast only */
|
||||
|
||||
/* is changed only for normal ip addresses
|
||||
* for non-normal addresses it always is 1
|
||||
*/
|
||||
int ref_counter;
|
||||
enum qeth_prot_versions proto;
|
||||
unsigned char mac[ETH_ALEN];
|
||||
union {
|
||||
struct {
|
||||
unsigned int addr;
|
||||
|
@ -42,6 +47,16 @@ struct qeth_ipaddr {
|
|||
} u;
|
||||
};
|
||||
|
||||
static inline void qeth_l3_init_ipaddr(struct qeth_ipaddr *addr,
|
||||
enum qeth_ip_types type,
|
||||
enum qeth_prot_versions proto)
|
||||
{
|
||||
memset(addr, 0, sizeof(*addr));
|
||||
addr->type = type;
|
||||
addr->proto = proto;
|
||||
addr->disp_flag = QETH_DISP_ADDR_DO_NOTHING;
|
||||
}
|
||||
|
||||
static inline bool qeth_l3_addr_match_ip(struct qeth_ipaddr *a1,
|
||||
struct qeth_ipaddr *a2)
|
||||
{
|
||||
|
@ -109,15 +124,10 @@ int qeth_l3_add_ipato_entry(struct qeth_card *, struct qeth_ipato_entry *);
|
|||
int qeth_l3_del_ipato_entry(struct qeth_card *card,
|
||||
enum qeth_prot_versions proto, u8 *addr,
|
||||
int mask_bits);
|
||||
int qeth_l3_add_vipa(struct qeth_card *, enum qeth_prot_versions, const u8 *);
|
||||
int qeth_l3_del_vipa(struct qeth_card *card, enum qeth_prot_versions proto,
|
||||
const u8 *addr);
|
||||
int qeth_l3_add_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *);
|
||||
int qeth_l3_del_rxip(struct qeth_card *card, enum qeth_prot_versions proto,
|
||||
const u8 *addr);
|
||||
void qeth_l3_update_ipato(struct qeth_card *card);
|
||||
struct qeth_ipaddr *qeth_l3_get_addr_buffer(enum qeth_prot_versions);
|
||||
int qeth_l3_add_ip(struct qeth_card *, struct qeth_ipaddr *);
|
||||
int qeth_l3_delete_ip(struct qeth_card *, struct qeth_ipaddr *);
|
||||
int qeth_l3_modify_hsuid(struct qeth_card *card, bool add);
|
||||
int qeth_l3_modify_rxip_vipa(struct qeth_card *card, bool add, const u8 *ip,
|
||||
enum qeth_ip_types type,
|
||||
enum qeth_prot_versions proto);
|
||||
|
||||
#endif /* __QETH_L3_H__ */
|
||||
|
|
|
@ -67,6 +67,15 @@ void qeth_l3_ipaddr_to_string(enum qeth_prot_versions proto, const __u8 *addr,
|
|||
qeth_l3_ipaddr6_to_string(addr, buf);
|
||||
}
|
||||
|
||||
static struct qeth_ipaddr *qeth_l3_get_addr_buffer(enum qeth_prot_versions prot)
|
||||
{
|
||||
struct qeth_ipaddr *addr = kmalloc(sizeof(*addr), GFP_ATOMIC);
|
||||
|
||||
if (addr)
|
||||
qeth_l3_init_ipaddr(addr, QETH_IP_TYPE_NORMAL, prot);
|
||||
return addr;
|
||||
}
|
||||
|
||||
static struct qeth_ipaddr *qeth_l3_find_addr_by_ip(struct qeth_card *card,
|
||||
struct qeth_ipaddr *query)
|
||||
{
|
||||
|
@ -138,12 +147,18 @@ static bool qeth_l3_is_addr_covered_by_ipato(struct qeth_card *card,
|
|||
return rc;
|
||||
}
|
||||
|
||||
int qeth_l3_delete_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr)
|
||||
static int qeth_l3_delete_ip(struct qeth_card *card,
|
||||
struct qeth_ipaddr *tmp_addr)
|
||||
{
|
||||
int rc = 0;
|
||||
struct qeth_ipaddr *addr;
|
||||
|
||||
QETH_CARD_TEXT(card, 4, "delip");
|
||||
if (tmp_addr->type == QETH_IP_TYPE_RXIP)
|
||||
QETH_CARD_TEXT(card, 2, "delrxip");
|
||||
else if (tmp_addr->type == QETH_IP_TYPE_VIPA)
|
||||
QETH_CARD_TEXT(card, 2, "delvipa");
|
||||
else
|
||||
QETH_CARD_TEXT(card, 2, "delip");
|
||||
|
||||
if (tmp_addr->proto == QETH_PROT_IPV4)
|
||||
QETH_CARD_HEX(card, 4, &tmp_addr->u.a4.addr, 4);
|
||||
|
@ -171,13 +186,18 @@ int qeth_l3_delete_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr)
|
|||
return rc;
|
||||
}
|
||||
|
||||
int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr)
|
||||
static int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr)
|
||||
{
|
||||
int rc = 0;
|
||||
struct qeth_ipaddr *addr;
|
||||
char buf[40];
|
||||
|
||||
QETH_CARD_TEXT(card, 4, "addip");
|
||||
if (tmp_addr->type == QETH_IP_TYPE_RXIP)
|
||||
QETH_CARD_TEXT(card, 2, "addrxip");
|
||||
else if (tmp_addr->type == QETH_IP_TYPE_VIPA)
|
||||
QETH_CARD_TEXT(card, 2, "addvipa");
|
||||
else
|
||||
QETH_CARD_TEXT(card, 2, "addip");
|
||||
|
||||
if (tmp_addr->proto == QETH_PROT_IPV4)
|
||||
QETH_CARD_HEX(card, 4, &tmp_addr->u.a4.addr, 4);
|
||||
|
@ -209,7 +229,7 @@ int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr)
|
|||
|
||||
if (qeth_l3_is_addr_covered_by_ipato(card, addr)) {
|
||||
QETH_CARD_TEXT(card, 2, "tkovaddr");
|
||||
addr->set_flags |= QETH_IPA_SETIP_TAKEOVER_FLAG;
|
||||
addr->ipato = 1;
|
||||
}
|
||||
hash_add(card->ip_htable, &addr->hnode,
|
||||
qeth_l3_ipaddr_hash(addr));
|
||||
|
@ -251,23 +271,6 @@ int qeth_l3_add_ip(struct qeth_card *card, struct qeth_ipaddr *tmp_addr)
|
|||
return rc;
|
||||
}
|
||||
|
||||
|
||||
struct qeth_ipaddr *qeth_l3_get_addr_buffer(
|
||||
enum qeth_prot_versions prot)
|
||||
{
|
||||
struct qeth_ipaddr *addr;
|
||||
|
||||
addr = kzalloc(sizeof(struct qeth_ipaddr), GFP_ATOMIC);
|
||||
if (!addr)
|
||||
return NULL;
|
||||
|
||||
addr->type = QETH_IP_TYPE_NORMAL;
|
||||
addr->disp_flag = QETH_DISP_ADDR_DO_NOTHING;
|
||||
addr->proto = prot;
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
static void qeth_l3_clear_ip_htable(struct qeth_card *card, int recover)
|
||||
{
|
||||
struct qeth_ipaddr *addr;
|
||||
|
@ -352,7 +355,7 @@ static int qeth_l3_send_setdelmc(struct qeth_card *card,
|
|||
iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto);
|
||||
if (!iob)
|
||||
return -ENOMEM;
|
||||
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
|
||||
cmd = __ipa_cmd(iob);
|
||||
ether_addr_copy(cmd->data.setdelipm.mac, addr->mac);
|
||||
if (addr->proto == QETH_PROT_IPV6)
|
||||
memcpy(cmd->data.setdelipm.ip6, &addr->u.a6.addr,
|
||||
|
@ -379,21 +382,38 @@ static void qeth_l3_fill_netmask(u8 *netmask, unsigned int len)
|
|||
}
|
||||
}
|
||||
|
||||
static int qeth_l3_send_setdelip(struct qeth_card *card,
|
||||
struct qeth_ipaddr *addr, int ipacmd, unsigned int flags)
|
||||
static u32 qeth_l3_get_setdelip_flags(struct qeth_ipaddr *addr, bool set)
|
||||
{
|
||||
switch (addr->type) {
|
||||
case QETH_IP_TYPE_RXIP:
|
||||
return (set) ? QETH_IPA_SETIP_TAKEOVER_FLAG : 0;
|
||||
case QETH_IP_TYPE_VIPA:
|
||||
return (set) ? QETH_IPA_SETIP_VIPA_FLAG :
|
||||
QETH_IPA_DELIP_VIPA_FLAG;
|
||||
default:
|
||||
return (set && addr->ipato) ? QETH_IPA_SETIP_TAKEOVER_FLAG : 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int qeth_l3_send_setdelip(struct qeth_card *card,
|
||||
struct qeth_ipaddr *addr,
|
||||
enum qeth_ipa_cmds ipacmd)
|
||||
{
|
||||
int rc;
|
||||
struct qeth_cmd_buffer *iob;
|
||||
struct qeth_ipa_cmd *cmd;
|
||||
__u8 netmask[16];
|
||||
u32 flags;
|
||||
|
||||
QETH_CARD_TEXT(card, 4, "setdelip");
|
||||
QETH_CARD_TEXT_(card, 4, "flags%02X", flags);
|
||||
|
||||
iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto);
|
||||
if (!iob)
|
||||
return -ENOMEM;
|
||||
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
|
||||
cmd = __ipa_cmd(iob);
|
||||
|
||||
flags = qeth_l3_get_setdelip_flags(addr, ipacmd == IPA_CMD_SETIP);
|
||||
QETH_CARD_TEXT_(card, 4, "flags%02X", flags);
|
||||
|
||||
if (addr->proto == QETH_PROT_IPV6) {
|
||||
memcpy(cmd->data.setdelip6.ip_addr, &addr->u.a6.addr,
|
||||
sizeof(struct in6_addr));
|
||||
|
@ -407,9 +427,7 @@ static int qeth_l3_send_setdelip(struct qeth_card *card,
|
|||
cmd->data.setdelip4.flags = flags;
|
||||
}
|
||||
|
||||
rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);
|
||||
|
||||
return rc;
|
||||
return qeth_send_ipa_cmd(card, iob, NULL, NULL);
|
||||
}
|
||||
|
||||
static int qeth_l3_send_setrouting(struct qeth_card *card,
|
||||
|
@ -423,7 +441,7 @@ static int qeth_l3_send_setrouting(struct qeth_card *card,
|
|||
iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETRTG, prot);
|
||||
if (!iob)
|
||||
return -ENOMEM;
|
||||
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
|
||||
cmd = __ipa_cmd(iob);
|
||||
cmd->data.setrtg.type = (type);
|
||||
rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);
|
||||
|
||||
|
@ -525,10 +543,7 @@ void qeth_l3_update_ipato(struct qeth_card *card)
|
|||
hash_for_each(card->ip_htable, i, addr, hnode) {
|
||||
if (addr->type != QETH_IP_TYPE_NORMAL)
|
||||
continue;
|
||||
if (qeth_l3_is_addr_covered_by_ipato(card, addr))
|
||||
addr->set_flags |= QETH_IPA_SETIP_TAKEOVER_FLAG;
|
||||
else
|
||||
addr->set_flags &= ~QETH_IPA_SETIP_TAKEOVER_FLAG;
|
||||
addr->ipato = qeth_l3_is_addr_covered_by_ipato(card, addr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -606,132 +621,39 @@ int qeth_l3_del_ipato_entry(struct qeth_card *card,
|
|||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* VIPA related functions
|
||||
*/
|
||||
int qeth_l3_add_vipa(struct qeth_card *card, enum qeth_prot_versions proto,
|
||||
const u8 *addr)
|
||||
int qeth_l3_modify_rxip_vipa(struct qeth_card *card, bool add, const u8 *ip,
|
||||
enum qeth_ip_types type,
|
||||
enum qeth_prot_versions proto)
|
||||
{
|
||||
struct qeth_ipaddr *ipaddr;
|
||||
struct qeth_ipaddr addr;
|
||||
int rc;
|
||||
|
||||
ipaddr = qeth_l3_get_addr_buffer(proto);
|
||||
if (ipaddr) {
|
||||
if (proto == QETH_PROT_IPV4) {
|
||||
QETH_CARD_TEXT(card, 2, "addvipa4");
|
||||
memcpy(&ipaddr->u.a4.addr, addr, 4);
|
||||
ipaddr->u.a4.mask = 0;
|
||||
} else if (proto == QETH_PROT_IPV6) {
|
||||
QETH_CARD_TEXT(card, 2, "addvipa6");
|
||||
memcpy(&ipaddr->u.a6.addr, addr, 16);
|
||||
ipaddr->u.a6.pfxlen = 0;
|
||||
}
|
||||
ipaddr->type = QETH_IP_TYPE_VIPA;
|
||||
ipaddr->set_flags = QETH_IPA_SETIP_VIPA_FLAG;
|
||||
ipaddr->del_flags = QETH_IPA_DELIP_VIPA_FLAG;
|
||||
} else
|
||||
return -ENOMEM;
|
||||
qeth_l3_init_ipaddr(&addr, type, proto);
|
||||
if (proto == QETH_PROT_IPV4)
|
||||
memcpy(&addr.u.a4.addr, ip, 4);
|
||||
else
|
||||
memcpy(&addr.u.a6.addr, ip, 16);
|
||||
|
||||
spin_lock_bh(&card->ip_lock);
|
||||
rc = qeth_l3_add_ip(card, ipaddr);
|
||||
rc = add ? qeth_l3_add_ip(card, &addr) : qeth_l3_delete_ip(card, &addr);
|
||||
spin_unlock_bh(&card->ip_lock);
|
||||
|
||||
kfree(ipaddr);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int qeth_l3_del_vipa(struct qeth_card *card, enum qeth_prot_versions proto,
|
||||
const u8 *addr)
|
||||
int qeth_l3_modify_hsuid(struct qeth_card *card, bool add)
|
||||
{
|
||||
struct qeth_ipaddr *ipaddr;
|
||||
int rc;
|
||||
struct qeth_ipaddr addr;
|
||||
int rc, i;
|
||||
|
||||
ipaddr = qeth_l3_get_addr_buffer(proto);
|
||||
if (ipaddr) {
|
||||
if (proto == QETH_PROT_IPV4) {
|
||||
QETH_CARD_TEXT(card, 2, "delvipa4");
|
||||
memcpy(&ipaddr->u.a4.addr, addr, 4);
|
||||
ipaddr->u.a4.mask = 0;
|
||||
} else if (proto == QETH_PROT_IPV6) {
|
||||
QETH_CARD_TEXT(card, 2, "delvipa6");
|
||||
memcpy(&ipaddr->u.a6.addr, addr, 16);
|
||||
ipaddr->u.a6.pfxlen = 0;
|
||||
}
|
||||
ipaddr->type = QETH_IP_TYPE_VIPA;
|
||||
} else
|
||||
return -ENOMEM;
|
||||
qeth_l3_init_ipaddr(&addr, QETH_IP_TYPE_NORMAL, QETH_PROT_IPV6);
|
||||
addr.u.a6.addr.s6_addr[0] = 0xfe;
|
||||
addr.u.a6.addr.s6_addr[1] = 0x80;
|
||||
for (i = 0; i < 8; i++)
|
||||
addr.u.a6.addr.s6_addr[8+i] = card->options.hsuid[i];
|
||||
|
||||
spin_lock_bh(&card->ip_lock);
|
||||
rc = qeth_l3_delete_ip(card, ipaddr);
|
||||
rc = add ? qeth_l3_add_ip(card, &addr) : qeth_l3_delete_ip(card, &addr);
|
||||
spin_unlock_bh(&card->ip_lock);
|
||||
|
||||
kfree(ipaddr);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* proxy ARP related functions
|
||||
*/
|
||||
int qeth_l3_add_rxip(struct qeth_card *card, enum qeth_prot_versions proto,
|
||||
const u8 *addr)
|
||||
{
|
||||
struct qeth_ipaddr *ipaddr;
|
||||
int rc;
|
||||
|
||||
ipaddr = qeth_l3_get_addr_buffer(proto);
|
||||
if (ipaddr) {
|
||||
if (proto == QETH_PROT_IPV4) {
|
||||
QETH_CARD_TEXT(card, 2, "addrxip4");
|
||||
memcpy(&ipaddr->u.a4.addr, addr, 4);
|
||||
ipaddr->u.a4.mask = 0;
|
||||
} else if (proto == QETH_PROT_IPV6) {
|
||||
QETH_CARD_TEXT(card, 2, "addrxip6");
|
||||
memcpy(&ipaddr->u.a6.addr, addr, 16);
|
||||
ipaddr->u.a6.pfxlen = 0;
|
||||
}
|
||||
|
||||
ipaddr->type = QETH_IP_TYPE_RXIP;
|
||||
ipaddr->set_flags = QETH_IPA_SETIP_TAKEOVER_FLAG;
|
||||
ipaddr->del_flags = 0;
|
||||
} else
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_bh(&card->ip_lock);
|
||||
rc = qeth_l3_add_ip(card, ipaddr);
|
||||
spin_unlock_bh(&card->ip_lock);
|
||||
|
||||
kfree(ipaddr);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int qeth_l3_del_rxip(struct qeth_card *card, enum qeth_prot_versions proto,
|
||||
const u8 *addr)
|
||||
{
|
||||
struct qeth_ipaddr *ipaddr;
|
||||
int rc;
|
||||
|
||||
ipaddr = qeth_l3_get_addr_buffer(proto);
|
||||
if (ipaddr) {
|
||||
if (proto == QETH_PROT_IPV4) {
|
||||
QETH_CARD_TEXT(card, 2, "delrxip4");
|
||||
memcpy(&ipaddr->u.a4.addr, addr, 4);
|
||||
ipaddr->u.a4.mask = 0;
|
||||
} else if (proto == QETH_PROT_IPV6) {
|
||||
QETH_CARD_TEXT(card, 2, "delrxip6");
|
||||
memcpy(&ipaddr->u.a6.addr, addr, 16);
|
||||
ipaddr->u.a6.pfxlen = 0;
|
||||
}
|
||||
ipaddr->type = QETH_IP_TYPE_RXIP;
|
||||
} else
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_bh(&card->ip_lock);
|
||||
rc = qeth_l3_delete_ip(card, ipaddr);
|
||||
spin_unlock_bh(&card->ip_lock);
|
||||
|
||||
kfree(ipaddr);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -758,8 +680,7 @@ static int qeth_l3_register_addr_entry(struct qeth_card *card,
|
|||
if (addr->is_multicast)
|
||||
rc = qeth_l3_send_setdelmc(card, addr, IPA_CMD_SETIPM);
|
||||
else
|
||||
rc = qeth_l3_send_setdelip(card, addr, IPA_CMD_SETIP,
|
||||
addr->set_flags);
|
||||
rc = qeth_l3_send_setdelip(card, addr, IPA_CMD_SETIP);
|
||||
if (rc)
|
||||
QETH_CARD_TEXT(card, 2, "failed");
|
||||
} while ((--cnt > 0) && rc);
|
||||
|
@ -791,8 +712,7 @@ static int qeth_l3_deregister_addr_entry(struct qeth_card *card,
|
|||
if (addr->is_multicast)
|
||||
rc = qeth_l3_send_setdelmc(card, addr, IPA_CMD_DELIPM);
|
||||
else
|
||||
rc = qeth_l3_send_setdelip(card, addr, IPA_CMD_DELIP,
|
||||
addr->del_flags);
|
||||
rc = qeth_l3_send_setdelip(card, addr, IPA_CMD_DELIP);
|
||||
if (rc)
|
||||
QETH_CARD_TEXT(card, 2, "failed");
|
||||
|
||||
|
@ -1072,7 +992,7 @@ static int qeth_l3_iqd_read_initial_mac(struct qeth_card *card)
|
|||
QETH_PROT_IPV6);
|
||||
if (!iob)
|
||||
return -ENOMEM;
|
||||
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
|
||||
cmd = __ipa_cmd(iob);
|
||||
*((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) =
|
||||
card->info.unique_id;
|
||||
|
||||
|
@ -1117,7 +1037,7 @@ static int qeth_l3_get_unique_id(struct qeth_card *card)
|
|||
QETH_PROT_IPV6);
|
||||
if (!iob)
|
||||
return -ENOMEM;
|
||||
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
|
||||
cmd = __ipa_cmd(iob);
|
||||
*((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) =
|
||||
card->info.unique_id;
|
||||
|
||||
|
@ -1193,7 +1113,7 @@ qeth_diags_trace(struct qeth_card *card, enum qeth_diags_trace_cmds diags_cmd)
|
|||
iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SET_DIAG_ASS, 0);
|
||||
if (!iob)
|
||||
return -ENOMEM;
|
||||
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
|
||||
cmd = __ipa_cmd(iob);
|
||||
cmd->data.diagass.subcmd_len = 16;
|
||||
cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRACE;
|
||||
cmd->data.diagass.type = QETH_DIAGS_TYPE_HIPERSOCKET;
|
||||
|
@ -1502,30 +1422,24 @@ static void qeth_l3_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
|
|||
ipv6_eth_mc_map(&ipv6_hdr(skb)->daddr, tg_addr);
|
||||
|
||||
card->stats.multicast++;
|
||||
skb->pkt_type = PACKET_MULTICAST;
|
||||
break;
|
||||
case QETH_CAST_BROADCAST:
|
||||
ether_addr_copy(tg_addr, card->dev->broadcast);
|
||||
card->stats.multicast++;
|
||||
skb->pkt_type = PACKET_BROADCAST;
|
||||
break;
|
||||
case QETH_CAST_UNICAST:
|
||||
case QETH_CAST_ANYCAST:
|
||||
case QETH_CAST_NOCAST:
|
||||
default:
|
||||
if (card->options.sniffer)
|
||||
skb->pkt_type = PACKET_OTHERHOST;
|
||||
else
|
||||
skb->pkt_type = PACKET_HOST;
|
||||
ether_addr_copy(tg_addr, card->dev->dev_addr);
|
||||
}
|
||||
|
||||
if (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_SRC_MAC_ADDR)
|
||||
card->dev->header_ops->create(skb, card->dev, prot,
|
||||
tg_addr, &hdr->hdr.l3.next_hop.rx.src_mac,
|
||||
card->dev->addr_len);
|
||||
skb->len);
|
||||
else
|
||||
card->dev->header_ops->create(skb, card->dev, prot,
|
||||
tg_addr, "FAKELL", card->dev->addr_len);
|
||||
tg_addr, "FAKELL", skb->len);
|
||||
}
|
||||
|
||||
skb->protocol = eth_type_trans(skb, card->dev);
|
||||
|
@ -1572,20 +1486,16 @@ static int qeth_l3_process_inbound_buffer(struct qeth_card *card,
|
|||
*done = 1;
|
||||
break;
|
||||
}
|
||||
skb->dev = card->dev;
|
||||
switch (hdr->hdr.l3.id) {
|
||||
case QETH_HEADER_TYPE_LAYER3:
|
||||
magic = *(__u16 *)skb->data;
|
||||
if ((card->info.type == QETH_CARD_TYPE_IQD) &&
|
||||
(magic == ETH_P_AF_IUCV)) {
|
||||
skb->protocol = cpu_to_be16(ETH_P_AF_IUCV);
|
||||
skb->pkt_type = PACKET_HOST;
|
||||
skb->mac_header = NET_SKB_PAD;
|
||||
skb->dev = card->dev;
|
||||
len = skb->len;
|
||||
card->dev->header_ops->create(skb, card->dev, 0,
|
||||
card->dev->dev_addr, "FAKELL",
|
||||
card->dev->addr_len);
|
||||
card->dev->dev_addr, "FAKELL", len);
|
||||
skb_reset_mac_header(skb);
|
||||
netif_receive_skb(skb);
|
||||
} else {
|
||||
qeth_l3_rebuild_skb(card, skb, hdr);
|
||||
|
@ -1594,7 +1504,6 @@ static int qeth_l3_process_inbound_buffer(struct qeth_card *card,
|
|||
}
|
||||
break;
|
||||
case QETH_HEADER_TYPE_LAYER2: /* for HiperSockets sniffer */
|
||||
skb->pkt_type = PACKET_HOST;
|
||||
skb->protocol = eth_type_trans(skb, skb->dev);
|
||||
len = skb->len;
|
||||
netif_receive_skb(skb);
|
||||
|
@ -1613,69 +1522,6 @@ static int qeth_l3_process_inbound_buffer(struct qeth_card *card,
|
|||
return work_done;
|
||||
}
|
||||
|
||||
static int qeth_l3_verify_vlan_dev(struct net_device *dev,
|
||||
struct qeth_card *card)
|
||||
{
|
||||
int rc = 0;
|
||||
u16 vid;
|
||||
|
||||
for_each_set_bit(vid, card->active_vlans, VLAN_N_VID) {
|
||||
struct net_device *netdev;
|
||||
|
||||
rcu_read_lock();
|
||||
netdev = __vlan_find_dev_deep_rcu(card->dev, htons(ETH_P_8021Q),
|
||||
vid);
|
||||
rcu_read_unlock();
|
||||
if (netdev == dev) {
|
||||
rc = QETH_VLAN_CARD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc && !(vlan_dev_real_dev(dev)->ml_priv == (void *)card))
|
||||
return 0;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int qeth_l3_verify_dev(struct net_device *dev)
|
||||
{
|
||||
struct qeth_card *card;
|
||||
int rc = 0;
|
||||
unsigned long flags;
|
||||
|
||||
read_lock_irqsave(&qeth_core_card_list.rwlock, flags);
|
||||
list_for_each_entry(card, &qeth_core_card_list.list, list) {
|
||||
if (card->dev == dev) {
|
||||
rc = QETH_REAL_CARD;
|
||||
break;
|
||||
}
|
||||
rc = qeth_l3_verify_vlan_dev(dev, card);
|
||||
if (rc)
|
||||
break;
|
||||
}
|
||||
read_unlock_irqrestore(&qeth_core_card_list.rwlock, flags);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct qeth_card *qeth_l3_get_card_from_dev(struct net_device *dev)
|
||||
{
|
||||
struct qeth_card *card = NULL;
|
||||
int rc;
|
||||
|
||||
rc = qeth_l3_verify_dev(dev);
|
||||
if (rc == QETH_REAL_CARD)
|
||||
card = dev->ml_priv;
|
||||
else if (rc == QETH_VLAN_CARD)
|
||||
card = vlan_dev_real_dev(dev)->ml_priv;
|
||||
if (card && card->options.layer2)
|
||||
card = NULL;
|
||||
if (card)
|
||||
QETH_CARD_TEXT_(card, 4, "%d", rc);
|
||||
return card ;
|
||||
}
|
||||
|
||||
static void qeth_l3_stop_card(struct qeth_card *card, int recovery_mode)
|
||||
{
|
||||
QETH_DBF_TEXT(SETUP, 2, "stopcard");
|
||||
|
@ -2004,7 +1850,7 @@ static int qeth_l3_query_arp_cache_info(struct qeth_card *card,
|
|||
prot);
|
||||
if (!iob)
|
||||
return -ENOMEM;
|
||||
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
|
||||
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;
|
||||
|
@ -2785,14 +2631,16 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
|
|||
if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD))
|
||||
card->dev->dev_id = card->info.unique_id &
|
||||
0xffff;
|
||||
|
||||
card->dev->hw_features |= NETIF_F_SG;
|
||||
card->dev->vlan_features |= NETIF_F_SG;
|
||||
|
||||
if (!card->info.guestlan) {
|
||||
card->dev->hw_features = NETIF_F_SG |
|
||||
NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
|
||||
NETIF_F_TSO;
|
||||
card->dev->vlan_features = NETIF_F_SG |
|
||||
NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
|
||||
NETIF_F_TSO;
|
||||
card->dev->features |= NETIF_F_SG;
|
||||
card->dev->hw_features |= NETIF_F_TSO |
|
||||
NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
|
||||
card->dev->vlan_features |= NETIF_F_TSO |
|
||||
NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
|
||||
}
|
||||
}
|
||||
} else if (card->info.type == QETH_CARD_TYPE_IQD) {
|
||||
|
@ -2907,7 +2755,6 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
|
|||
card->info.hwtrap = 0;
|
||||
|
||||
card->state = CARD_STATE_HARDSETUP;
|
||||
memset(&card->rx, 0, sizeof(struct qeth_rx));
|
||||
qeth_print_status_message(card);
|
||||
|
||||
/* softsetup */
|
||||
|
@ -3130,13 +2977,43 @@ struct qeth_discipline qeth_l3_discipline = {
|
|||
};
|
||||
EXPORT_SYMBOL_GPL(qeth_l3_discipline);
|
||||
|
||||
static int qeth_l3_handle_ip_event(struct qeth_card *card,
|
||||
struct qeth_ipaddr *addr,
|
||||
unsigned long event)
|
||||
{
|
||||
switch (event) {
|
||||
case NETDEV_UP:
|
||||
spin_lock_bh(&card->ip_lock);
|
||||
qeth_l3_add_ip(card, addr);
|
||||
spin_unlock_bh(&card->ip_lock);
|
||||
return NOTIFY_OK;
|
||||
case NETDEV_DOWN:
|
||||
spin_lock_bh(&card->ip_lock);
|
||||
qeth_l3_delete_ip(card, addr);
|
||||
spin_unlock_bh(&card->ip_lock);
|
||||
return NOTIFY_OK;
|
||||
default:
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
}
|
||||
|
||||
static struct qeth_card *qeth_l3_get_card_from_dev(struct net_device *dev)
|
||||
{
|
||||
if (is_vlan_dev(dev))
|
||||
dev = vlan_dev_real_dev(dev);
|
||||
if (dev->netdev_ops == &qeth_l3_osa_netdev_ops ||
|
||||
dev->netdev_ops == &qeth_l3_netdev_ops)
|
||||
return (struct qeth_card *) dev->ml_priv;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int qeth_l3_ip_event(struct notifier_block *this,
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
|
||||
struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
|
||||
struct net_device *dev = (struct net_device *)ifa->ifa_dev->dev;
|
||||
struct qeth_ipaddr *addr;
|
||||
struct net_device *dev = ifa->ifa_dev->dev;
|
||||
struct qeth_ipaddr addr;
|
||||
struct qeth_card *card;
|
||||
|
||||
if (dev_net(dev) != &init_net)
|
||||
|
@ -3147,29 +3024,11 @@ static int qeth_l3_ip_event(struct notifier_block *this,
|
|||
return NOTIFY_DONE;
|
||||
QETH_CARD_TEXT(card, 3, "ipevent");
|
||||
|
||||
addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV4);
|
||||
if (addr) {
|
||||
addr->u.a4.addr = be32_to_cpu(ifa->ifa_address);
|
||||
addr->u.a4.mask = be32_to_cpu(ifa->ifa_mask);
|
||||
addr->type = QETH_IP_TYPE_NORMAL;
|
||||
} else
|
||||
return NOTIFY_DONE;
|
||||
qeth_l3_init_ipaddr(&addr, QETH_IP_TYPE_NORMAL, QETH_PROT_IPV4);
|
||||
addr.u.a4.addr = be32_to_cpu(ifa->ifa_address);
|
||||
addr.u.a4.mask = be32_to_cpu(ifa->ifa_mask);
|
||||
|
||||
switch (event) {
|
||||
case NETDEV_UP:
|
||||
spin_lock_bh(&card->ip_lock);
|
||||
qeth_l3_add_ip(card, addr);
|
||||
spin_unlock_bh(&card->ip_lock);
|
||||
break;
|
||||
case NETDEV_DOWN:
|
||||
spin_lock_bh(&card->ip_lock);
|
||||
qeth_l3_delete_ip(card, addr);
|
||||
spin_unlock_bh(&card->ip_lock);
|
||||
break;
|
||||
}
|
||||
|
||||
kfree(addr);
|
||||
return NOTIFY_DONE;
|
||||
return qeth_l3_handle_ip_event(card, &addr, event);
|
||||
}
|
||||
|
||||
static struct notifier_block qeth_l3_ip_notifier = {
|
||||
|
@ -3181,8 +3040,8 @@ static int qeth_l3_ip6_event(struct notifier_block *this,
|
|||
unsigned long event, void *ptr)
|
||||
{
|
||||
struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
|
||||
struct net_device *dev = (struct net_device *)ifa->idev->dev;
|
||||
struct qeth_ipaddr *addr;
|
||||
struct net_device *dev = ifa->idev->dev;
|
||||
struct qeth_ipaddr addr;
|
||||
struct qeth_card *card;
|
||||
|
||||
card = qeth_l3_get_card_from_dev(dev);
|
||||
|
@ -3192,29 +3051,11 @@ static int qeth_l3_ip6_event(struct notifier_block *this,
|
|||
if (!qeth_is_supported(card, IPA_IPV6))
|
||||
return NOTIFY_DONE;
|
||||
|
||||
addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV6);
|
||||
if (addr) {
|
||||
memcpy(&addr->u.a6.addr, &ifa->addr, sizeof(struct in6_addr));
|
||||
addr->u.a6.pfxlen = ifa->prefix_len;
|
||||
addr->type = QETH_IP_TYPE_NORMAL;
|
||||
} else
|
||||
return NOTIFY_DONE;
|
||||
qeth_l3_init_ipaddr(&addr, QETH_IP_TYPE_NORMAL, QETH_PROT_IPV6);
|
||||
addr.u.a6.addr = ifa->addr;
|
||||
addr.u.a6.pfxlen = ifa->prefix_len;
|
||||
|
||||
switch (event) {
|
||||
case NETDEV_UP:
|
||||
spin_lock_bh(&card->ip_lock);
|
||||
qeth_l3_add_ip(card, addr);
|
||||
spin_unlock_bh(&card->ip_lock);
|
||||
break;
|
||||
case NETDEV_DOWN:
|
||||
spin_lock_bh(&card->ip_lock);
|
||||
qeth_l3_delete_ip(card, addr);
|
||||
spin_unlock_bh(&card->ip_lock);
|
||||
break;
|
||||
}
|
||||
|
||||
kfree(addr);
|
||||
return NOTIFY_DONE;
|
||||
return qeth_l3_handle_ip_event(card, &addr, event);
|
||||
}
|
||||
|
||||
static struct notifier_block qeth_l3_ip6_notifier = {
|
||||
|
|
|
@ -272,9 +272,8 @@ static ssize_t qeth_l3_dev_hsuid_store(struct device *dev,
|
|||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
struct qeth_card *card = dev_get_drvdata(dev);
|
||||
struct qeth_ipaddr *addr;
|
||||
char *tmp;
|
||||
int rc, i;
|
||||
int rc;
|
||||
|
||||
if (!card)
|
||||
return -EINVAL;
|
||||
|
@ -293,25 +292,9 @@ static ssize_t qeth_l3_dev_hsuid_store(struct device *dev,
|
|||
if (strlen(tmp) > 8)
|
||||
return -EINVAL;
|
||||
|
||||
if (card->options.hsuid[0]) {
|
||||
if (card->options.hsuid[0])
|
||||
/* delete old ip address */
|
||||
addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV6);
|
||||
if (!addr)
|
||||
return -ENOMEM;
|
||||
|
||||
addr->u.a6.addr.s6_addr32[0] = cpu_to_be32(0xfe800000);
|
||||
addr->u.a6.addr.s6_addr32[1] = 0x00000000;
|
||||
for (i = 8; i < 16; i++)
|
||||
addr->u.a6.addr.s6_addr[i] =
|
||||
card->options.hsuid[i - 8];
|
||||
addr->u.a6.pfxlen = 0;
|
||||
addr->type = QETH_IP_TYPE_NORMAL;
|
||||
|
||||
spin_lock_bh(&card->ip_lock);
|
||||
qeth_l3_delete_ip(card, addr);
|
||||
spin_unlock_bh(&card->ip_lock);
|
||||
kfree(addr);
|
||||
}
|
||||
qeth_l3_modify_hsuid(card, false);
|
||||
|
||||
if (strlen(tmp) == 0) {
|
||||
/* delete ip address only */
|
||||
|
@ -331,21 +314,7 @@ static ssize_t qeth_l3_dev_hsuid_store(struct device *dev,
|
|||
if (card->dev)
|
||||
memcpy(card->dev->perm_addr, card->options.hsuid, 9);
|
||||
|
||||
addr = qeth_l3_get_addr_buffer(QETH_PROT_IPV6);
|
||||
if (addr != NULL) {
|
||||
addr->u.a6.addr.s6_addr32[0] = cpu_to_be32(0xfe800000);
|
||||
addr->u.a6.addr.s6_addr32[1] = 0x00000000;
|
||||
for (i = 8; i < 16; i++)
|
||||
addr->u.a6.addr.s6_addr[i] = card->options.hsuid[i - 8];
|
||||
addr->u.a6.pfxlen = 0;
|
||||
addr->type = QETH_IP_TYPE_NORMAL;
|
||||
} else
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_bh(&card->ip_lock);
|
||||
rc = qeth_l3_add_ip(card, addr);
|
||||
spin_unlock_bh(&card->ip_lock);
|
||||
kfree(addr);
|
||||
rc = qeth_l3_modify_hsuid(card, true);
|
||||
|
||||
return rc ? rc : count;
|
||||
}
|
||||
|
@ -767,7 +736,8 @@ static ssize_t qeth_l3_dev_vipa_add_store(const char *buf, size_t count,
|
|||
mutex_lock(&card->conf_mutex);
|
||||
rc = qeth_l3_parse_vipae(buf, proto, addr);
|
||||
if (!rc)
|
||||
rc = qeth_l3_add_vipa(card, proto, addr);
|
||||
rc = qeth_l3_modify_rxip_vipa(card, true, addr,
|
||||
QETH_IP_TYPE_VIPA, proto);
|
||||
mutex_unlock(&card->conf_mutex);
|
||||
return rc ? rc : count;
|
||||
}
|
||||
|
@ -796,7 +766,8 @@ static ssize_t qeth_l3_dev_vipa_del_store(const char *buf, size_t count,
|
|||
mutex_lock(&card->conf_mutex);
|
||||
rc = qeth_l3_parse_vipae(buf, proto, addr);
|
||||
if (!rc)
|
||||
rc = qeth_l3_del_vipa(card, proto, addr);
|
||||
rc = qeth_l3_modify_rxip_vipa(card, false, addr,
|
||||
QETH_IP_TYPE_VIPA, proto);
|
||||
mutex_unlock(&card->conf_mutex);
|
||||
return rc ? rc : count;
|
||||
}
|
||||
|
@ -908,7 +879,8 @@ static ssize_t qeth_l3_dev_rxip_add_store(const char *buf, size_t count,
|
|||
mutex_lock(&card->conf_mutex);
|
||||
rc = qeth_l3_parse_rxipe(buf, proto, addr);
|
||||
if (!rc)
|
||||
rc = qeth_l3_add_rxip(card, proto, addr);
|
||||
rc = qeth_l3_modify_rxip_vipa(card, true, addr,
|
||||
QETH_IP_TYPE_RXIP, proto);
|
||||
mutex_unlock(&card->conf_mutex);
|
||||
return rc ? rc : count;
|
||||
}
|
||||
|
@ -937,7 +909,8 @@ static ssize_t qeth_l3_dev_rxip_del_store(const char *buf, size_t count,
|
|||
mutex_lock(&card->conf_mutex);
|
||||
rc = qeth_l3_parse_rxipe(buf, proto, addr);
|
||||
if (!rc)
|
||||
rc = qeth_l3_del_rxip(card, proto, addr);
|
||||
rc = qeth_l3_modify_rxip_vipa(card, false, addr,
|
||||
QETH_IP_TYPE_RXIP, proto);
|
||||
mutex_unlock(&card->conf_mutex);
|
||||
return rc ? rc : count;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче