Commit 8f36e000 authored by David S. Miller's avatar David S. Miller

Merge branch 's390-net-next'

Julian Wiedmann says:

====================
s390/net: updates 2017-12-20

Please apply the following patch series for 4.16.
Nothing too exciting, mostly just beating the qeth L3 code into shape.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a943e8bc 556fd271
...@@ -91,9 +91,6 @@ config QETH_L3 ...@@ -91,9 +91,6 @@ config QETH_L3
To compile as a module choose M. The module name is qeth_l3. To compile as a module choose M. The module name is qeth_l3.
If unsure, choose Y. If unsure, choose Y.
config QETH_IPV6
def_bool y if (QETH_L3 = IPV6) || (QETH_L3 && IPV6 = 'y')
config CCWGROUP config CCWGROUP
tristate tristate
default (LCS || CTCM || QETH) default (LCS || CTCM || QETH)
......
...@@ -756,18 +756,14 @@ lcs_get_lancmd(struct lcs_card *card, int count) ...@@ -756,18 +756,14 @@ lcs_get_lancmd(struct lcs_card *card, int count)
static void static void
lcs_get_reply(struct lcs_reply *reply) lcs_get_reply(struct lcs_reply *reply)
{ {
WARN_ON(atomic_read(&reply->refcnt) <= 0); refcount_inc(&reply->refcnt);
atomic_inc(&reply->refcnt);
} }
static void static void
lcs_put_reply(struct lcs_reply *reply) lcs_put_reply(struct lcs_reply *reply)
{ {
WARN_ON(atomic_read(&reply->refcnt) <= 0); if (refcount_dec_and_test(&reply->refcnt))
if (atomic_dec_and_test(&reply->refcnt)) {
kfree(reply); kfree(reply);
}
} }
static struct lcs_reply * static struct lcs_reply *
...@@ -780,7 +776,7 @@ lcs_alloc_reply(struct lcs_cmd *cmd) ...@@ -780,7 +776,7 @@ lcs_alloc_reply(struct lcs_cmd *cmd)
reply = kzalloc(sizeof(struct lcs_reply), GFP_ATOMIC); reply = kzalloc(sizeof(struct lcs_reply), GFP_ATOMIC);
if (!reply) if (!reply)
return NULL; return NULL;
atomic_set(&reply->refcnt,1); refcount_set(&reply->refcnt, 1);
reply->sequence_no = cmd->sequence_no; reply->sequence_no = cmd->sequence_no;
reply->received = 0; reply->received = 0;
reply->rc = 0; reply->rc = 0;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/refcount.h>
#include <asm/ccwdev.h> #include <asm/ccwdev.h>
#define LCS_DBF_TEXT(level, name, text) \ #define LCS_DBF_TEXT(level, name, text) \
...@@ -271,7 +272,7 @@ struct lcs_buffer { ...@@ -271,7 +272,7 @@ struct lcs_buffer {
struct lcs_reply { struct lcs_reply {
struct list_head list; struct list_head list;
__u16 sequence_no; __u16 sequence_no;
atomic_t refcnt; refcount_t refcnt;
/* Callback for completion notification. */ /* Callback for completion notification. */
void (*callback)(struct lcs_card *, struct lcs_cmd *); void (*callback)(struct lcs_card *, struct lcs_cmd *);
wait_queue_head_t wait_q; wait_queue_head_t wait_q;
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <linux/hashtable.h> #include <linux/hashtable.h>
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/refcount.h>
#include <net/ipv6.h> #include <net/ipv6.h>
#include <net/if_inet6.h> #include <net/if_inet6.h>
...@@ -296,8 +297,23 @@ struct qeth_hdr_layer3 { ...@@ -296,8 +297,23 @@ struct qeth_hdr_layer3 {
__u8 ext_flags; __u8 ext_flags;
__u16 vlan_id; __u16 vlan_id;
__u16 frame_offset; __u16 frame_offset;
__u8 dest_addr[16]; union {
} __attribute__ ((packed)); /* TX: */
u8 ipv6_addr[16];
struct ipv4 {
u8 res[12];
u32 addr;
} ipv4;
/* RX: */
struct rx {
u8 res1[2];
u8 src_mac[6];
u8 res2[4];
u16 vlan_id;
u8 res3[2];
} rx;
} next_hop;
};
struct qeth_hdr_layer2 { struct qeth_hdr_layer2 {
__u8 id; __u8 id;
...@@ -504,12 +520,6 @@ struct qeth_qdio_info { ...@@ -504,12 +520,6 @@ struct qeth_qdio_info {
int default_out_queue; int default_out_queue;
}; };
#define QETH_ETH_MAC_V4 0x0100 /* like v4 */
#define QETH_ETH_MAC_V6 0x3333 /* like v6 */
/* tr mc mac is longer, but that will be enough to detect mc frames */
#define QETH_TR_MAC_NC 0xc000 /* non-canonical */
#define QETH_TR_MAC_C 0x0300 /* canonical */
/** /**
* buffer stuff for read channel * buffer stuff for read channel
*/ */
...@@ -632,7 +642,7 @@ struct qeth_reply { ...@@ -632,7 +642,7 @@ struct qeth_reply {
int rc; int rc;
void *param; void *param;
struct qeth_card *card; struct qeth_card *card;
atomic_t refcnt; refcount_t refcnt;
}; };
struct qeth_card_blkt { struct qeth_card_blkt {
...@@ -846,14 +856,16 @@ static inline int qeth_get_micros(void) ...@@ -846,14 +856,16 @@ static inline int qeth_get_micros(void)
static inline int qeth_get_ip_version(struct sk_buff *skb) static inline int qeth_get_ip_version(struct sk_buff *skb)
{ {
__be16 *p = &((struct ethhdr *)skb->data)->h_proto; struct vlan_ethhdr *veth = vlan_eth_hdr(skb);
__be16 prot = veth->h_vlan_proto;
if (prot == htons(ETH_P_8021Q))
prot = veth->h_vlan_encapsulated_proto;
if (be16_to_cpu(*p) == ETH_P_8021Q) switch (prot) {
p += 2; case htons(ETH_P_IPV6):
switch (be16_to_cpu(*p)) {
case ETH_P_IPV6:
return 6; return 6;
case ETH_P_IP: case htons(ETH_P_IP):
return 4; return 4;
default: default:
return 0; return 0;
......
...@@ -564,7 +564,7 @@ static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card) ...@@ -564,7 +564,7 @@ static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card)
reply = kzalloc(sizeof(struct qeth_reply), GFP_ATOMIC); reply = kzalloc(sizeof(struct qeth_reply), GFP_ATOMIC);
if (reply) { if (reply) {
atomic_set(&reply->refcnt, 1); refcount_set(&reply->refcnt, 1);
atomic_set(&reply->received, 0); atomic_set(&reply->received, 0);
reply->card = card; reply->card = card;
} }
...@@ -573,14 +573,12 @@ static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card) ...@@ -573,14 +573,12 @@ static struct qeth_reply *qeth_alloc_reply(struct qeth_card *card)
static void qeth_get_reply(struct qeth_reply *reply) static void qeth_get_reply(struct qeth_reply *reply)
{ {
WARN_ON(atomic_read(&reply->refcnt) <= 0); refcount_inc(&reply->refcnt);
atomic_inc(&reply->refcnt);
} }
static void qeth_put_reply(struct qeth_reply *reply) static void qeth_put_reply(struct qeth_reply *reply)
{ {
WARN_ON(atomic_read(&reply->refcnt) <= 0); if (refcount_dec_and_test(&reply->refcnt))
if (atomic_dec_and_test(&reply->refcnt))
kfree(reply); kfree(reply);
} }
...@@ -4218,9 +4216,8 @@ static int qeth_setadpparms_change_macaddr_cb(struct qeth_card *card, ...@@ -4218,9 +4216,8 @@ static int qeth_setadpparms_change_macaddr_cb(struct qeth_card *card,
cmd = (struct qeth_ipa_cmd *) data; cmd = (struct qeth_ipa_cmd *) data;
if (!card->options.layer2 || if (!card->options.layer2 ||
!(card->info.mac_bits & QETH_LAYER2_MAC_READ)) { !(card->info.mac_bits & QETH_LAYER2_MAC_READ)) {
memcpy(card->dev->dev_addr, ether_addr_copy(card->dev->dev_addr,
&cmd->data.setadapterparms.data.change_addr.addr, cmd->data.setadapterparms.data.change_addr.addr);
OSA_ADDR_LEN);
card->info.mac_bits |= QETH_LAYER2_MAC_READ; card->info.mac_bits |= QETH_LAYER2_MAC_READ;
} }
qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd); qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd);
...@@ -4242,9 +4239,9 @@ int qeth_setadpparms_change_macaddr(struct qeth_card *card) ...@@ -4242,9 +4239,9 @@ int qeth_setadpparms_change_macaddr(struct qeth_card *card)
return -ENOMEM; return -ENOMEM;
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
cmd->data.setadapterparms.data.change_addr.cmd = CHANGE_ADDR_READ_MAC; cmd->data.setadapterparms.data.change_addr.cmd = CHANGE_ADDR_READ_MAC;
cmd->data.setadapterparms.data.change_addr.addr_size = OSA_ADDR_LEN; cmd->data.setadapterparms.data.change_addr.addr_size = ETH_ALEN;
memcpy(&cmd->data.setadapterparms.data.change_addr.addr, ether_addr_copy(cmd->data.setadapterparms.data.change_addr.addr,
card->dev->dev_addr, OSA_ADDR_LEN); card->dev->dev_addr);
rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_change_macaddr_cb, rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_change_macaddr_cb,
NULL); NULL);
return rc; return rc;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#define __QETH_CORE_MPC_H__ #define __QETH_CORE_MPC_H__
#include <asm/qeth.h> #include <asm/qeth.h>
#include <uapi/linux/if_ether.h>
#define IPA_PDU_HEADER_SIZE 0x40 #define IPA_PDU_HEADER_SIZE 0x40
#define QETH_IPA_PDU_LEN_TOTAL(buffer) (buffer + 0x0e) #define QETH_IPA_PDU_LEN_TOTAL(buffer) (buffer + 0x0e)
...@@ -25,7 +26,6 @@ extern unsigned char IPA_PDU_HEADER[]; ...@@ -25,7 +26,6 @@ extern unsigned char IPA_PDU_HEADER[];
#define QETH_SEQ_NO_LENGTH 4 #define QETH_SEQ_NO_LENGTH 4
#define QETH_MPC_TOKEN_LENGTH 4 #define QETH_MPC_TOKEN_LENGTH 4
#define QETH_MCL_LENGTH 4 #define QETH_MCL_LENGTH 4
#define OSA_ADDR_LEN 6
#define QETH_TIMEOUT (10 * HZ) #define QETH_TIMEOUT (10 * HZ)
#define QETH_IPA_TIMEOUT (45 * HZ) #define QETH_IPA_TIMEOUT (45 * HZ)
...@@ -416,12 +416,11 @@ struct qeth_query_cmds_supp { ...@@ -416,12 +416,11 @@ struct qeth_query_cmds_supp {
} __attribute__ ((packed)); } __attribute__ ((packed));
struct qeth_change_addr { struct qeth_change_addr {
__u32 cmd; u32 cmd;
__u32 addr_size; u32 addr_size;
__u32 no_macs; u32 no_macs;
__u8 addr[OSA_ADDR_LEN]; u8 addr[ETH_ALEN];
} __attribute__ ((packed)); };
struct qeth_snmp_cmd { struct qeth_snmp_cmd {
__u8 token[16]; __u8 token[16];
......
...@@ -22,8 +22,7 @@ int qeth_l2_vnicc_get_timeout(struct qeth_card *card, u32 *timeout); ...@@ -22,8 +22,7 @@ int qeth_l2_vnicc_get_timeout(struct qeth_card *card, u32 *timeout);
bool qeth_l2_vnicc_is_in_use(struct qeth_card *card); bool qeth_l2_vnicc_is_in_use(struct qeth_card *card);
struct qeth_mac { struct qeth_mac {
u8 mac_addr[OSA_ADDR_LEN]; u8 mac_addr[ETH_ALEN];
u8 is_uc:1;
u8 disp_flag:2; u8 disp_flag:2;
struct hlist_node hnode; struct hlist_node hnode;
}; };
......
...@@ -109,8 +109,8 @@ static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac, ...@@ -109,8 +109,8 @@ static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac,
if (!iob) if (!iob)
return -ENOMEM; return -ENOMEM;
cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
cmd->data.setdelmac.mac_length = OSA_ADDR_LEN; cmd->data.setdelmac.mac_length = ETH_ALEN;
memcpy(&cmd->data.setdelmac.mac, mac, OSA_ADDR_LEN); ether_addr_copy(cmd->data.setdelmac.mac, mac);
return qeth_setdelmac_makerc(card, qeth_send_ipa_cmd(card, iob, return qeth_setdelmac_makerc(card, qeth_send_ipa_cmd(card, iob,
NULL, NULL)); NULL, NULL));
} }
...@@ -123,7 +123,7 @@ static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac) ...@@ -123,7 +123,7 @@ static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac)
rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC); rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC);
if (rc == 0) { if (rc == 0) {
card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED; card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;
memcpy(card->dev->dev_addr, mac, OSA_ADDR_LEN); ether_addr_copy(card->dev->dev_addr, mac);
dev_info(&card->gdev->dev, dev_info(&card->gdev->dev,
"MAC address %pM successfully registered on device %s\n", "MAC address %pM successfully registered on device %s\n",
card->dev->dev_addr, card->dev->name); card->dev->dev_addr, card->dev->name);
...@@ -156,54 +156,37 @@ static int qeth_l2_send_delmac(struct qeth_card *card, __u8 *mac) ...@@ -156,54 +156,37 @@ static int qeth_l2_send_delmac(struct qeth_card *card, __u8 *mac)
return rc; return rc;
} }
static int qeth_l2_send_setgroupmac(struct qeth_card *card, __u8 *mac) static int qeth_l2_write_mac(struct qeth_card *card, u8 *mac)
{ {
enum qeth_ipa_cmds cmd = is_multicast_ether_addr_64bits(mac) ?
IPA_CMD_SETGMAC : IPA_CMD_SETVMAC;
int rc; int rc;
QETH_CARD_TEXT(card, 2, "L2Sgmac"); QETH_CARD_TEXT(card, 2, "L2Wmac");
rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETGMAC); rc = qeth_l2_send_setdelmac(card, mac, cmd);
if (rc == -EEXIST) if (rc == -EEXIST)
QETH_DBF_MESSAGE(2, "Group MAC %pM already existing on %s\n", QETH_DBF_MESSAGE(2, "MAC %pM already registered on %s\n",
mac, QETH_CARD_IFNAME(card)); mac, QETH_CARD_IFNAME(card));
else if (rc) else if (rc)
QETH_DBF_MESSAGE(2, "Could not set group MAC %pM on %s: %d\n", QETH_DBF_MESSAGE(2, "Failed to register MAC %pM on %s: %d\n",
mac, QETH_CARD_IFNAME(card), rc); mac, QETH_CARD_IFNAME(card), rc);
return rc; return rc;
} }
static int qeth_l2_send_delgroupmac(struct qeth_card *card, __u8 *mac) static int qeth_l2_remove_mac(struct qeth_card *card, u8 *mac)
{ {
enum qeth_ipa_cmds cmd = is_multicast_ether_addr_64bits(mac) ?
IPA_CMD_DELGMAC : IPA_CMD_DELVMAC;
int rc; int rc;
QETH_CARD_TEXT(card, 2, "L2Dgmac"); QETH_CARD_TEXT(card, 2, "L2Rmac");
rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_DELGMAC); rc = qeth_l2_send_setdelmac(card, mac, cmd);
if (rc) if (rc)
QETH_DBF_MESSAGE(2, QETH_DBF_MESSAGE(2, "Failed to delete MAC %pM on %s: %d\n",
"Could not delete group MAC %pM on %s: %d\n",
mac, QETH_CARD_IFNAME(card), rc); mac, QETH_CARD_IFNAME(card), rc);
return rc; return rc;
} }
static int qeth_l2_write_mac(struct qeth_card *card, struct qeth_mac *mac)
{
if (mac->is_uc) {
return qeth_l2_send_setdelmac(card, mac->mac_addr,
IPA_CMD_SETVMAC);
} else {
return qeth_l2_send_setgroupmac(card, mac->mac_addr);
}
}
static int qeth_l2_remove_mac(struct qeth_card *card, struct qeth_mac *mac)
{
if (mac->is_uc) {
return qeth_l2_send_setdelmac(card, mac->mac_addr,
IPA_CMD_DELVMAC);
} else {
return qeth_l2_send_delgroupmac(card, mac->mac_addr);
}
}
static void qeth_l2_del_all_macs(struct qeth_card *card) static void qeth_l2_del_all_macs(struct qeth_card *card)
{ {
struct qeth_mac *mac; struct qeth_mac *mac;
...@@ -549,7 +532,7 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p) ...@@ -549,7 +532,7 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p)
QETH_CARD_TEXT(card, 3, "setmcTYP"); QETH_CARD_TEXT(card, 3, "setmcTYP");
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
QETH_CARD_HEX(card, 3, addr->sa_data, OSA_ADDR_LEN); QETH_CARD_HEX(card, 3, addr->sa_data, ETH_ALEN);
if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) { if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) {
QETH_CARD_TEXT(card, 3, "setmcREC"); QETH_CARD_TEXT(card, 3, "setmcREC");
return -ERESTARTSYS; return -ERESTARTSYS;
...@@ -597,27 +580,23 @@ static void qeth_promisc_to_bridge(struct qeth_card *card) ...@@ -597,27 +580,23 @@ static void qeth_promisc_to_bridge(struct qeth_card *card)
* only if there is not in the hash table storage already * only if there is not in the hash table storage already
* *
*/ */
static void qeth_l2_add_mac(struct qeth_card *card, struct netdev_hw_addr *ha, static void qeth_l2_add_mac(struct qeth_card *card, struct netdev_hw_addr *ha)
u8 is_uc)
{ {
u32 mac_hash = get_unaligned((u32 *)(&ha->addr[2])); u32 mac_hash = get_unaligned((u32 *)(&ha->addr[2]));
struct qeth_mac *mac; struct qeth_mac *mac;
hash_for_each_possible(card->mac_htable, mac, hnode, mac_hash) { hash_for_each_possible(card->mac_htable, mac, hnode, mac_hash) {
if (is_uc == mac->is_uc && if (ether_addr_equal_64bits(ha->addr, mac->mac_addr)) {
!memcmp(ha->addr, mac->mac_addr, OSA_ADDR_LEN)) {
mac->disp_flag = QETH_DISP_ADDR_DO_NOTHING; mac->disp_flag = QETH_DISP_ADDR_DO_NOTHING;
return; return;
} }
} }
mac = kzalloc(sizeof(struct qeth_mac), GFP_ATOMIC); mac = kzalloc(sizeof(struct qeth_mac), GFP_ATOMIC);
if (!mac) if (!mac)
return; return;
memcpy(mac->mac_addr, ha->addr, OSA_ADDR_LEN); ether_addr_copy(mac->mac_addr, ha->addr);
mac->is_uc = is_uc;
mac->disp_flag = QETH_DISP_ADDR_ADD; mac->disp_flag = QETH_DISP_ADDR_ADD;
hash_add(card->mac_htable, &mac->hnode, mac_hash); hash_add(card->mac_htable, &mac->hnode, mac_hash);
...@@ -643,27 +622,30 @@ static void qeth_l2_set_rx_mode(struct net_device *dev) ...@@ -643,27 +622,30 @@ static void qeth_l2_set_rx_mode(struct net_device *dev)
spin_lock_bh(&card->mclock); spin_lock_bh(&card->mclock);
netdev_for_each_mc_addr(ha, dev) netdev_for_each_mc_addr(ha, dev)
qeth_l2_add_mac(card, ha, 0); qeth_l2_add_mac(card, ha);
netdev_for_each_uc_addr(ha, dev) netdev_for_each_uc_addr(ha, dev)
qeth_l2_add_mac(card, ha, 1); qeth_l2_add_mac(card, ha);
hash_for_each_safe(card->mac_htable, i, tmp, mac, hnode) { hash_for_each_safe(card->mac_htable, i, tmp, mac, hnode) {
if (mac->disp_flag == QETH_DISP_ADDR_DELETE) { switch (mac->disp_flag) {
qeth_l2_remove_mac(card, mac); case QETH_DISP_ADDR_DELETE:
qeth_l2_remove_mac(card, mac->mac_addr);
hash_del(&mac->hnode); hash_del(&mac->hnode);
kfree(mac); kfree(mac);
break;
} else if (mac->disp_flag == QETH_DISP_ADDR_ADD) { case QETH_DISP_ADDR_ADD:
rc = qeth_l2_write_mac(card, mac); rc = qeth_l2_write_mac(card, mac->mac_addr);
if (rc) { if (rc) {
hash_del(&mac->hnode); hash_del(&mac->hnode);
kfree(mac); kfree(mac);
} else break;
mac->disp_flag = QETH_DISP_ADDR_DELETE; }
} else /* fall through */
default:
/* for next call to set_rx_mode(): */
mac->disp_flag = QETH_DISP_ADDR_DELETE; mac->disp_flag = QETH_DISP_ADDR_DELETE;
} }
}
spin_unlock_bh(&card->mclock); spin_unlock_bh(&card->mclock);
......
...@@ -29,7 +29,7 @@ struct qeth_ipaddr { ...@@ -29,7 +29,7 @@ struct qeth_ipaddr {
*/ */
int ref_counter; int ref_counter;
enum qeth_prot_versions proto; enum qeth_prot_versions proto;
unsigned char mac[OSA_ADDR_LEN]; unsigned char mac[ETH_ALEN];
union { union {
struct { struct {
unsigned int addr; unsigned int addr;
...@@ -69,7 +69,6 @@ struct qeth_ipato_entry { ...@@ -69,7 +69,6 @@ struct qeth_ipato_entry {
extern const struct attribute_group *qeth_l3_attr_groups[]; extern const struct attribute_group *qeth_l3_attr_groups[];
void qeth_l3_ipaddr_to_string(enum qeth_prot_versions, const __u8 *, char *); void qeth_l3_ipaddr_to_string(enum qeth_prot_versions, const __u8 *, char *);
int qeth_l3_string_to_ipaddr(const char *, enum qeth_prot_versions, __u8 *);
int qeth_l3_create_device_attributes(struct device *); int qeth_l3_create_device_attributes(struct device *);
void qeth_l3_remove_device_attributes(struct device *); void qeth_l3_remove_device_attributes(struct device *);
int qeth_l3_setrouting_v4(struct qeth_card *); int qeth_l3_setrouting_v4(struct qeth_card *);
......
This diff is collapsed.
...@@ -10,11 +10,23 @@ ...@@ -10,11 +10,23 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/ebcdic.h> #include <asm/ebcdic.h>
#include <linux/hashtable.h> #include <linux/hashtable.h>
#include <linux/inet.h>
#include "qeth_l3.h" #include "qeth_l3.h"
#define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \ #define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \
struct device_attribute dev_attr_##_id = __ATTR(_name, _mode, _show, _store) struct device_attribute dev_attr_##_id = __ATTR(_name, _mode, _show, _store)
static int qeth_l3_string_to_ipaddr(const char *buf,
enum qeth_prot_versions proto, u8 *addr)
{
const char *end;
if ((proto == QETH_PROT_IPV4 && !in4_pton(buf, -1, addr, -1, &end)) ||
(proto == QETH_PROT_IPV6 && !in6_pton(buf, -1, addr, -1, &end)))
return -EINVAL;
return 0;
}
static ssize_t qeth_l3_dev_route_show(struct qeth_card *card, static ssize_t qeth_l3_dev_route_show(struct qeth_card *card,
struct qeth_routing_info *route, char *buf) struct qeth_routing_info *route, char *buf)
{ {
......
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