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

Merge branch 's390-next'

Julian Wiedmann says:

====================
s390/qeth: updates 2019-03-28

please apply the following patchset to net-next. This reworks the control
IO code in qeth so that we no longer need to poll for cmd completion,
and refactors the IDX setup code to also use this improved IO path.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 1571e2fd 2e873d10
......@@ -10,6 +10,7 @@
#ifndef __QETH_CORE_H__
#define __QETH_CORE_H__
#include <linux/completion.h>
#include <linux/if.h>
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
......@@ -21,6 +22,7 @@
#include <linux/hashtable.h>
#include <linux/ip.h>
#include <linux/refcount.h>
#include <linux/wait.h>
#include <linux/workqueue.h>
#include <net/ipv6.h>
......@@ -538,7 +540,6 @@ struct qeth_qdio_info {
enum qeth_channel_states {
CH_STATE_UP,
CH_STATE_DOWN,
CH_STATE_ACTIVATING,
CH_STATE_HALTED,
CH_STATE_STOPPED,
CH_STATE_RCD,
......@@ -585,7 +586,10 @@ struct qeth_cmd_buffer {
enum qeth_cmd_buffer_state state;
struct qeth_channel *channel;
struct qeth_reply *reply;
long timeout;
unsigned char *data;
void (*finalize)(struct qeth_card *card, struct qeth_cmd_buffer *iob,
unsigned int length);
void (*callback)(struct qeth_card *card, struct qeth_channel *channel,
struct qeth_cmd_buffer *iob);
};
......@@ -610,6 +614,11 @@ struct qeth_channel {
int io_buf_no;
};
static inline bool qeth_trylock_channel(struct qeth_channel *channel)
{
return atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0;
}
/**
* OSA card related definitions
*/
......@@ -636,12 +645,11 @@ struct qeth_seqno {
struct qeth_reply {
struct list_head list;
wait_queue_head_t wait_q;
struct completion received;
int (*callback)(struct qeth_card *, struct qeth_reply *,
unsigned long);
u32 seqno;
unsigned long offset;
atomic_t received;
int rc;
void *param;
refcount_t refcnt;
......@@ -774,18 +782,19 @@ struct qeth_card {
struct qeth_card_options options;
struct workqueue_struct *event_wq;
struct workqueue_struct *cmd_wq;
wait_queue_head_t wait_q;
spinlock_t mclock;
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
DECLARE_HASHTABLE(mac_htable, 4);
DECLARE_HASHTABLE(ip_htable, 4);
struct mutex ip_lock;
DECLARE_HASHTABLE(ip_mc_htable, 4);
struct work_struct rx_mode_work;
struct work_struct kernel_thread_starter;
spinlock_t thread_mask_lock;
unsigned long thread_start_mask;
unsigned long thread_allowed_mask;
unsigned long thread_running_mask;
spinlock_t ip_lock;
struct qeth_ipato ipato;
struct list_head cmd_waiter_list;
/* QDIO buffer handling */
......@@ -983,8 +992,6 @@ void qeth_clear_qdio_buffers(struct qeth_card *);
void qeth_setadp_promisc_mode(struct qeth_card *);
int qeth_setadpparms_change_macaddr(struct qeth_card *);
void qeth_tx_timeout(struct net_device *);
void qeth_prepare_control_data(struct qeth_card *, int,
struct qeth_cmd_buffer *);
void qeth_release_buffer(struct qeth_channel *, struct qeth_cmd_buffer *);
void qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
u16 cmd_length);
......
This diff is collapsed.
......@@ -149,18 +149,16 @@ static int qeth_l2_remove_mac(struct qeth_card *card, u8 *mac)
return rc;
}
static void qeth_l2_del_all_macs(struct qeth_card *card)
static void qeth_l2_drain_rx_mode_cache(struct qeth_card *card)
{
struct qeth_mac *mac;
struct hlist_node *tmp;
int i;
spin_lock_bh(&card->mclock);
hash_for_each_safe(card->mac_htable, i, tmp, mac, hnode) {
hash_del(&mac->hnode);
kfree(mac);
}
spin_unlock_bh(&card->mclock);
}
static int qeth_l2_get_cast_type(struct qeth_card *card, struct sk_buff *skb)
......@@ -292,8 +290,10 @@ static void qeth_l2_stop_card(struct qeth_card *card)
qeth_set_allowed_threads(card, 0, 1);
cancel_work_sync(&card->rx_mode_work);
qeth_l2_drain_rx_mode_cache(card);
if (card->state == CARD_STATE_SOFTSETUP) {
qeth_l2_del_all_macs(card);
qeth_clear_ipacmd_list(card);
card->state = CARD_STATE_HARDSETUP;
}
......@@ -515,9 +515,11 @@ static void qeth_l2_add_mac(struct qeth_card *card, struct netdev_hw_addr *ha)
hash_add(card->mac_htable, &mac->hnode, mac_hash);
}
static void qeth_l2_set_rx_mode(struct net_device *dev)
static void qeth_l2_rx_mode_work(struct work_struct *work)
{
struct qeth_card *card = dev->ml_priv;
struct qeth_card *card = container_of(work, struct qeth_card,
rx_mode_work);
struct net_device *dev = card->dev;
struct netdev_hw_addr *ha;
struct qeth_mac *mac;
struct hlist_node *tmp;
......@@ -526,12 +528,12 @@ static void qeth_l2_set_rx_mode(struct net_device *dev)
QETH_CARD_TEXT(card, 3, "setmulti");
spin_lock_bh(&card->mclock);
netif_addr_lock_bh(dev);
netdev_for_each_mc_addr(ha, dev)
qeth_l2_add_mac(card, ha);
netdev_for_each_uc_addr(ha, dev)
qeth_l2_add_mac(card, ha);
netif_addr_unlock_bh(dev);
hash_for_each_safe(card->mac_htable, i, tmp, mac, hnode) {
switch (mac->disp_flag) {
......@@ -554,8 +556,6 @@ static void qeth_l2_set_rx_mode(struct net_device *dev)
}
}
spin_unlock_bh(&card->mclock);
if (qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
qeth_setadp_promisc_mode(card);
else
......@@ -653,6 +653,7 @@ static int qeth_l2_probe_device(struct ccwgroup_device *gdev)
}
hash_init(card->mac_htable);
INIT_WORK(&card->rx_mode_work, qeth_l2_rx_mode_work);
return 0;
}
......@@ -673,6 +674,13 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev)
unregister_netdev(card->dev);
}
static void qeth_l2_set_rx_mode(struct net_device *dev)
{
struct qeth_card *card = dev->ml_priv;
schedule_work(&card->rx_mode_work);
}
static const struct net_device_ops qeth_l2_netdev_ops = {
.ndo_open = qeth_open,
.ndo_stop = qeth_stop,
......@@ -1042,13 +1050,13 @@ static int qeth_osn_send_control_data(struct qeth_card *card, int len,
QETH_CARD_TEXT(card, 5, "osndctrd");
wait_event(card->wait_q,
atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0);
qeth_prepare_control_data(card, len, iob);
wait_event(card->wait_q, qeth_trylock_channel(channel));
iob->finalize(card, iob, len);
QETH_DBF_HEX(CTRL, 2, iob->data, min(len, QETH_DBF_CTRL_LEN));
QETH_CARD_TEXT(card, 6, "osnoirqp");
spin_lock_irq(get_ccwdev_lock(channel->ccwdev));
rc = ccw_device_start_timeout(channel->ccwdev, channel->ccw,
(addr_t) iob, 0, 0, QETH_IPA_TIMEOUT);
(addr_t) iob, 0, 0, iob->timeout);
spin_unlock_irq(get_ccwdev_lock(channel->ccwdev));
if (rc) {
QETH_DBF_MESSAGE(2, "qeth_osn_send_control_data: "
......
This diff is collapsed.
......@@ -367,9 +367,9 @@ static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev,
if (card->ipato.enabled != enable) {
card->ipato.enabled = enable;
spin_lock_bh(&card->ip_lock);
mutex_lock(&card->ip_lock);
qeth_l3_update_ipato(card);
spin_unlock_bh(&card->ip_lock);
mutex_unlock(&card->ip_lock);
}
out:
mutex_unlock(&card->conf_mutex);
......@@ -412,9 +412,9 @@ static ssize_t qeth_l3_dev_ipato_invert4_store(struct device *dev,
if (card->ipato.invert4 != invert) {
card->ipato.invert4 = invert;
spin_lock_bh(&card->ip_lock);
mutex_lock(&card->ip_lock);
qeth_l3_update_ipato(card);
spin_unlock_bh(&card->ip_lock);
mutex_unlock(&card->ip_lock);
}
out:
mutex_unlock(&card->conf_mutex);
......@@ -436,7 +436,7 @@ static ssize_t qeth_l3_dev_ipato_add_show(char *buf, struct qeth_card *card,
entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
/* add strlen for "/<mask>\n" */
entry_len += (proto == QETH_PROT_IPV4)? 5 : 6;
spin_lock_bh(&card->ip_lock);
mutex_lock(&card->ip_lock);
list_for_each_entry(ipatoe, &card->ipato.entries, entry) {
if (ipatoe->proto != proto)
continue;
......@@ -449,7 +449,7 @@ static ssize_t qeth_l3_dev_ipato_add_show(char *buf, struct qeth_card *card,
i += snprintf(buf + i, PAGE_SIZE - i,
"%s/%i\n", addr_str, ipatoe->mask_bits);
}
spin_unlock_bh(&card->ip_lock);
mutex_unlock(&card->ip_lock);
i += snprintf(buf + i, PAGE_SIZE - i, "\n");
return i;
......@@ -598,9 +598,9 @@ static ssize_t qeth_l3_dev_ipato_invert6_store(struct device *dev,
if (card->ipato.invert6 != invert) {
card->ipato.invert6 = invert;
spin_lock_bh(&card->ip_lock);
mutex_lock(&card->ip_lock);
qeth_l3_update_ipato(card);
spin_unlock_bh(&card->ip_lock);
mutex_unlock(&card->ip_lock);
}
out:
mutex_unlock(&card->conf_mutex);
......@@ -684,7 +684,7 @@ static ssize_t qeth_l3_dev_ip_add_show(struct device *dev, char *buf,
entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
entry_len += 2; /* \n + terminator */
spin_lock_bh(&card->ip_lock);
mutex_lock(&card->ip_lock);
hash_for_each(card->ip_htable, i, ipaddr, hnode) {
if (ipaddr->proto != proto || ipaddr->type != type)
continue;
......@@ -698,7 +698,7 @@ static ssize_t qeth_l3_dev_ip_add_show(struct device *dev, char *buf,
str_len += snprintf(buf + str_len, PAGE_SIZE - str_len, "%s\n",
addr_str);
}
spin_unlock_bh(&card->ip_lock);
mutex_unlock(&card->ip_lock);
str_len += snprintf(buf + str_len, PAGE_SIZE - str_len, "\n");
return str_len;
......
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