Merge branch 's390-net'
Ursula Braun says: ==================== s390: qeth patches for net-next here are some s390 related patches for net-next. The qeth patches are performance optimizations in the driver. The qdio patch corrects a warning condition. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
729ecbc77a
|
@ -319,6 +319,8 @@ static int qdio_siga_output(struct qdio_q *q, unsigned int *busy_bit,
|
|||
int retries = 0, cc;
|
||||
unsigned long laob = 0;
|
||||
|
||||
WARN_ON_ONCE(aob && ((queue_type(q) != QDIO_IQDIO_QFMT) ||
|
||||
!q->u.out.use_cq));
|
||||
if (q->u.out.use_cq && aob != 0) {
|
||||
fc = QDIO_SIGA_WRITEQ;
|
||||
laob = aob;
|
||||
|
@ -329,8 +331,6 @@ static int qdio_siga_output(struct qdio_q *q, unsigned int *busy_bit,
|
|||
fc |= QDIO_SIGA_QEBSM_FLAG;
|
||||
}
|
||||
again:
|
||||
WARN_ON_ONCE((aob && queue_type(q) != QDIO_IQDIO_QFMT) ||
|
||||
(aob && fc != QDIO_SIGA_WRITEQ));
|
||||
cc = do_siga_output(schid, q->mask, busy_bit, fc, laob);
|
||||
|
||||
/* hipersocket busy condition */
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <linux/bitops.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/hashtable.h>
|
||||
|
||||
#include <net/ipv6.h>
|
||||
#include <net/if_inet6.h>
|
||||
|
@ -739,11 +740,17 @@ struct qeth_vlan_vid {
|
|||
unsigned short vid;
|
||||
};
|
||||
|
||||
struct qeth_mc_mac {
|
||||
struct list_head list;
|
||||
__u8 mc_addr[MAX_ADDR_LEN];
|
||||
unsigned char mc_addrlen;
|
||||
int is_vmac;
|
||||
enum qeth_mac_disposition {
|
||||
QETH_DISP_MAC_DELETE = 0,
|
||||
QETH_DISP_MAC_DO_NOTHING = 1,
|
||||
QETH_DISP_MAC_ADD = 2,
|
||||
};
|
||||
|
||||
struct qeth_mac {
|
||||
u8 mac_addr[OSA_ADDR_LEN];
|
||||
u8 is_uc:1;
|
||||
u8 disp_flag:2;
|
||||
struct hlist_node hnode;
|
||||
};
|
||||
|
||||
struct qeth_rx {
|
||||
|
@ -790,7 +797,7 @@ struct qeth_card {
|
|||
spinlock_t mclock;
|
||||
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
|
||||
struct list_head vid_list;
|
||||
struct list_head mc_list;
|
||||
DECLARE_HASHTABLE(mac_htable, 4);
|
||||
struct work_struct kernel_thread_starter;
|
||||
spinlock_t thread_mask_lock;
|
||||
unsigned long thread_start_mask;
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
#include <linux/mii.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
#include <linux/hash.h>
|
||||
#include <linux/hashtable.h>
|
||||
#include <linux/string.h>
|
||||
#include "qeth_core.h"
|
||||
#include "qeth_l2.h"
|
||||
|
||||
|
@ -28,7 +30,7 @@ static int qeth_l2_stop(struct net_device *);
|
|||
static int qeth_l2_send_delmac(struct qeth_card *, __u8 *);
|
||||
static int qeth_l2_send_setdelmac(struct qeth_card *, __u8 *,
|
||||
enum qeth_ipa_cmds);
|
||||
static void qeth_l2_set_multicast_list(struct net_device *);
|
||||
static void qeth_l2_set_rx_mode(struct net_device *);
|
||||
static int qeth_l2_recover(void *);
|
||||
static void qeth_bridgeport_query_support(struct qeth_card *card);
|
||||
static void qeth_bridge_state_change(struct qeth_card *card,
|
||||
|
@ -193,49 +195,44 @@ static int qeth_l2_send_delgroupmac(struct qeth_card *card, __u8 *mac)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static void qeth_l2_add_mc(struct qeth_card *card, __u8 *mac, int vmac)
|
||||
static inline u32 qeth_l2_mac_hash(const u8 *addr)
|
||||
{
|
||||
struct qeth_mc_mac *mc;
|
||||
int rc;
|
||||
|
||||
mc = kmalloc(sizeof(struct qeth_mc_mac), GFP_ATOMIC);
|
||||
|
||||
if (!mc)
|
||||
return;
|
||||
|
||||
memcpy(mc->mc_addr, mac, OSA_ADDR_LEN);
|
||||
mc->mc_addrlen = OSA_ADDR_LEN;
|
||||
mc->is_vmac = vmac;
|
||||
|
||||
if (vmac) {
|
||||
rc = qeth_setdel_makerc(card,
|
||||
qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC));
|
||||
} else {
|
||||
rc = qeth_setdel_makerc(card,
|
||||
qeth_l2_send_setgroupmac(card, mac));
|
||||
}
|
||||
|
||||
if (!rc)
|
||||
list_add_tail(&mc->list, &card->mc_list);
|
||||
else
|
||||
kfree(mc);
|
||||
return get_unaligned((u32 *)(&addr[2]));
|
||||
}
|
||||
|
||||
static void qeth_l2_del_all_mc(struct qeth_card *card, int del)
|
||||
static int qeth_l2_write_mac(struct qeth_card *card, struct qeth_mac *mac)
|
||||
{
|
||||
struct qeth_mc_mac *mc, *tmp;
|
||||
|
||||
int rc;
|
||||
|
||||
if (mac->is_uc) {
|
||||
rc = qeth_setdel_makerc(card,
|
||||
qeth_l2_send_setdelmac(card, mac->mac_addr,
|
||||
IPA_CMD_SETVMAC));
|
||||
} else {
|
||||
rc = qeth_setdel_makerc(card,
|
||||
qeth_l2_send_setgroupmac(card, mac->mac_addr));
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void qeth_l2_del_all_macs(struct qeth_card *card, int del)
|
||||
{
|
||||
struct qeth_mac *mac;
|
||||
struct hlist_node *tmp;
|
||||
int i;
|
||||
|
||||
spin_lock_bh(&card->mclock);
|
||||
list_for_each_entry_safe(mc, tmp, &card->mc_list, list) {
|
||||
hash_for_each_safe(card->mac_htable, i, tmp, mac, hnode) {
|
||||
if (del) {
|
||||
if (mc->is_vmac)
|
||||
qeth_l2_send_setdelmac(card, mc->mc_addr,
|
||||
IPA_CMD_DELVMAC);
|
||||
if (mac->is_uc)
|
||||
qeth_l2_send_setdelmac(card, mac->mac_addr,
|
||||
IPA_CMD_DELVMAC);
|
||||
else
|
||||
qeth_l2_send_delgroupmac(card, mc->mc_addr);
|
||||
qeth_l2_send_delgroupmac(card, mac->mac_addr);
|
||||
}
|
||||
list_del(&mc->list);
|
||||
kfree(mc);
|
||||
hash_del(&mac->hnode);
|
||||
kfree(mac);
|
||||
}
|
||||
spin_unlock_bh(&card->mclock);
|
||||
}
|
||||
|
@ -403,7 +400,7 @@ static int qeth_l2_vlan_rx_kill_vid(struct net_device *dev,
|
|||
rc = qeth_l2_send_setdelvlan(card, vid, IPA_CMD_DELVLAN);
|
||||
kfree(tmpid);
|
||||
}
|
||||
qeth_l2_set_multicast_list(card->dev);
|
||||
qeth_l2_set_rx_mode(card->dev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -460,7 +457,7 @@ static void qeth_l2_stop_card(struct qeth_card *card, int recovery_mode)
|
|||
card->state = CARD_STATE_SOFTSETUP;
|
||||
}
|
||||
if (card->state == CARD_STATE_SOFTSETUP) {
|
||||
qeth_l2_del_all_mc(card, 0);
|
||||
qeth_l2_del_all_macs(card, 0);
|
||||
qeth_clear_ipacmd_list(card);
|
||||
card->state = CARD_STATE_HARDSETUP;
|
||||
}
|
||||
|
@ -511,7 +508,7 @@ static int qeth_l2_process_inbound_buffer(struct qeth_card *card,
|
|||
if (skb->protocol == htons(ETH_P_802_2))
|
||||
*((__u32 *)skb->cb) = ++card->seqno.pkt_seqno;
|
||||
len = skb->len;
|
||||
netif_receive_skb(skb);
|
||||
napi_gro_receive(&card->napi, skb);
|
||||
break;
|
||||
case QETH_HEADER_TYPE_OSN:
|
||||
if (card->info.type == QETH_CARD_TYPE_OSN) {
|
||||
|
@ -768,29 +765,91 @@ static void qeth_promisc_to_bridge(struct qeth_card *card)
|
|||
card->options.sbp.role = role;
|
||||
card->info.promisc_mode = promisc_mode;
|
||||
}
|
||||
|
||||
}
|
||||
/* New MAC address is added to the hash table and marked to be written on card
|
||||
* 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, u8 is_uc)
|
||||
{
|
||||
struct qeth_mac *mac;
|
||||
|
||||
hash_for_each_possible(card->mac_htable, mac, hnode,
|
||||
qeth_l2_mac_hash(ha->addr)) {
|
||||
if (is_uc == mac->is_uc &&
|
||||
!memcmp(ha->addr, mac->mac_addr, OSA_ADDR_LEN)) {
|
||||
mac->disp_flag = QETH_DISP_MAC_DO_NOTHING;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mac = kzalloc(sizeof(struct qeth_mac), GFP_ATOMIC);
|
||||
|
||||
if (!mac)
|
||||
return;
|
||||
|
||||
memcpy(mac->mac_addr, ha->addr, OSA_ADDR_LEN);
|
||||
mac->is_uc = is_uc;
|
||||
mac->disp_flag = QETH_DISP_MAC_ADD;
|
||||
|
||||
hash_add(card->mac_htable, &mac->hnode,
|
||||
qeth_l2_mac_hash(mac->mac_addr));
|
||||
|
||||
}
|
||||
|
||||
static void qeth_l2_set_multicast_list(struct net_device *dev)
|
||||
static void qeth_l2_set_rx_mode(struct net_device *dev)
|
||||
{
|
||||
struct qeth_card *card = dev->ml_priv;
|
||||
struct netdev_hw_addr *ha;
|
||||
struct qeth_mac *mac;
|
||||
struct hlist_node *tmp;
|
||||
int i;
|
||||
int rc;
|
||||
|
||||
if (card->info.type == QETH_CARD_TYPE_OSN)
|
||||
return ;
|
||||
return;
|
||||
|
||||
QETH_CARD_TEXT(card, 3, "setmulti");
|
||||
if (qeth_threads_running(card, QETH_RECOVER_THREAD) &&
|
||||
(card->state != CARD_STATE_UP))
|
||||
return;
|
||||
qeth_l2_del_all_mc(card, 1);
|
||||
|
||||
spin_lock_bh(&card->mclock);
|
||||
|
||||
netdev_for_each_mc_addr(ha, dev)
|
||||
qeth_l2_add_mc(card, ha->addr, 0);
|
||||
qeth_l2_add_mac(card, ha, 0);
|
||||
|
||||
netdev_for_each_uc_addr(ha, dev)
|
||||
qeth_l2_add_mc(card, ha->addr, 1);
|
||||
qeth_l2_add_mac(card, ha, 1);
|
||||
|
||||
hash_for_each_safe(card->mac_htable, i, tmp, mac, hnode) {
|
||||
if (mac->disp_flag == QETH_DISP_MAC_DELETE) {
|
||||
if (!mac->is_uc)
|
||||
rc = qeth_l2_send_delgroupmac(card,
|
||||
mac->mac_addr);
|
||||
else {
|
||||
rc = qeth_l2_send_setdelmac(card, mac->mac_addr,
|
||||
IPA_CMD_DELVMAC);
|
||||
}
|
||||
|
||||
hash_del(&mac->hnode);
|
||||
kfree(mac);
|
||||
|
||||
} else if (mac->disp_flag == QETH_DISP_MAC_ADD) {
|
||||
rc = qeth_l2_write_mac(card, mac);
|
||||
if (rc) {
|
||||
hash_del(&mac->hnode);
|
||||
kfree(mac);
|
||||
} else
|
||||
mac->disp_flag = QETH_DISP_MAC_DELETE;
|
||||
} else
|
||||
mac->disp_flag = QETH_DISP_MAC_DELETE;
|
||||
}
|
||||
|
||||
spin_unlock_bh(&card->mclock);
|
||||
|
||||
if (qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
|
||||
qeth_setadp_promisc_mode(card);
|
||||
else
|
||||
|
@ -974,7 +1033,7 @@ static int qeth_l2_probe_device(struct ccwgroup_device *gdev)
|
|||
|
||||
qeth_l2_create_device_attributes(&gdev->dev);
|
||||
INIT_LIST_HEAD(&card->vid_list);
|
||||
INIT_LIST_HEAD(&card->mc_list);
|
||||
hash_init(card->mac_htable);
|
||||
card->options.layer2 = 1;
|
||||
card->info.hwtrap = 0;
|
||||
return 0;
|
||||
|
@ -1020,7 +1079,7 @@ static const struct net_device_ops qeth_l2_netdev_ops = {
|
|||
.ndo_get_stats = qeth_get_stats,
|
||||
.ndo_start_xmit = qeth_l2_hard_start_xmit,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
.ndo_set_rx_mode = qeth_l2_set_multicast_list,
|
||||
.ndo_set_rx_mode = qeth_l2_set_rx_mode,
|
||||
.ndo_do_ioctl = qeth_l2_do_ioctl,
|
||||
.ndo_set_mac_address = qeth_l2_set_mac_address,
|
||||
.ndo_change_mtu = qeth_change_mtu,
|
||||
|
@ -1179,7 +1238,7 @@ contin:
|
|||
rtnl_unlock();
|
||||
}
|
||||
/* this also sets saved unicast addresses */
|
||||
qeth_l2_set_multicast_list(card->dev);
|
||||
qeth_l2_set_rx_mode(card->dev);
|
||||
}
|
||||
/* let user_space know that device is online */
|
||||
kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);
|
||||
|
|
Загрузка…
Ссылка в новой задаче