Commit f44b1886 authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents f5426250 b1d5e36b
......@@ -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 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, int ipacmd, unsigned int flags)
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;
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_vipa(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, "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, 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_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)
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, "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;
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_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_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;
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;
}
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;
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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment