diff options
author | Lakhvich Dmitriy | 2016-06-16 16:18:58 +0200 |
---|---|---|
committer | David S. Miller | 2016-06-16 22:16:12 -0700 |
commit | 5f78e29ceebf03a80a5141515bd5b48ca83f0495 (patch) | |
tree | e4a10605c77cb9217d9cea58e9fdaeeea3d87f09 /drivers/s390/net/qeth_l3.h | |
parent | 6059c90537868bfd365163ba3dff95cf775939ff (diff) |
qeth: optimize IP handling in rx_mode callback
In layer3 mode of the qeth driver, multicast IP addresses
from struct net_device and other type of IP addresses
from other sources require mapping to the OSA-card.
This patch simplifies the IP address mapping logic, and changes imple-
mentation of ndo_set_rx_mode callback and ip notifier events.
Addresses are stored in private hashtables instead of lists now.
It allows hardware registration/removal for new/deleted multicast
addresses only.
Signed-off-by: Lakhvich Dmitriy <ldmitriy@ru.ibm.com>
Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com>
Reviewed-by: Evgeny Cherkashin <Eugene.Crosser@ru.ibm.com>
Reviewed-by: Thomas Richter <tmricht@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/s390/net/qeth_l3.h')
-rw-r--r-- | drivers/s390/net/qeth_l3.h | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/drivers/s390/net/qeth_l3.h b/drivers/s390/net/qeth_l3.h index 551a4b4c03fd..26f79533e62e 100644 --- a/drivers/s390/net/qeth_l3.h +++ b/drivers/s390/net/qeth_l3.h @@ -10,16 +10,23 @@ #define __QETH_L3_H__ #include "qeth_core.h" +#include <linux/hashtable.h> #define QETH_SNIFF_AVAIL 0x0008 struct qeth_ipaddr { - struct list_head entry; + struct hlist_node hnode; enum qeth_ip_types type; enum qeth_ipa_setdelip_flags set_flags; enum qeth_ipa_setdelip_flags del_flags; - int is_multicast; - int users; + u8 is_multicast:1; + u8 in_progress:1; + u8 disp_flag:2; + + /* 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[OSA_ADDR_LEN]; union { @@ -32,7 +39,24 @@ struct qeth_ipaddr { unsigned int pfxlen; } a6; } u; + }; +static inline u64 qeth_l3_ipaddr_hash(struct qeth_ipaddr *addr) +{ + u64 ret = 0; + u8 *point; + + if (addr->proto == QETH_PROT_IPV6) { + point = (u8 *) &addr->u.a6.addr; + ret = get_unaligned((u64 *)point) ^ + get_unaligned((u64 *) (point + 8)); + } + if (addr->proto == QETH_PROT_IPV4) { + point = (u8 *) &addr->u.a4.addr; + ret = get_unaligned((u32 *) point); + } + return ret; +} struct qeth_ipato_entry { struct list_head entry; @@ -60,6 +84,5 @@ int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *, struct qeth_ipaddr *); 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 *); -void qeth_l3_set_ip_addr_list(struct qeth_card *); #endif /* __QETH_L3_H__ */ |