Merge branch 's390-qeth-next'
Julian Wiedmann says: ==================== s390/qeth: updates 2019-01-25 please apply a first batch of qeth patches for net-next, primarily touching the net_device parts of the driver. In addition to the usual refactoring & code consolidation, patch 7 makes use of netif_device_detach() to let the stack know when our control plane is down. This helps quite a bit wrt to overall locking and proper init/shutdown sequencing. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
ccaceadc4e
|
@ -741,11 +741,6 @@ struct qeth_discipline {
|
|||
struct qeth_ipa_cmd *cmd);
|
||||
};
|
||||
|
||||
struct qeth_vlan_vid {
|
||||
struct list_head list;
|
||||
unsigned short vid;
|
||||
};
|
||||
|
||||
enum qeth_addr_disposition {
|
||||
QETH_DISP_ADDR_DELETE = 0,
|
||||
QETH_DISP_ADDR_DO_NOTHING = 1,
|
||||
|
@ -792,8 +787,6 @@ struct qeth_card {
|
|||
wait_queue_head_t wait_q;
|
||||
spinlock_t mclock;
|
||||
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
|
||||
struct mutex vid_list_mutex; /* vid_list */
|
||||
struct list_head vid_list;
|
||||
DECLARE_HASHTABLE(mac_htable, 4);
|
||||
DECLARE_HASHTABLE(ip_htable, 4);
|
||||
DECLARE_HASHTABLE(ip_mc_htable, 4);
|
||||
|
@ -802,7 +795,6 @@ struct qeth_card {
|
|||
unsigned long thread_start_mask;
|
||||
unsigned long thread_allowed_mask;
|
||||
unsigned long thread_running_mask;
|
||||
struct task_struct *recovery_task;
|
||||
spinlock_t ip_lock;
|
||||
struct qeth_ipato ipato;
|
||||
struct list_head cmd_waiter_list;
|
||||
|
@ -976,11 +968,8 @@ extern struct qeth_dbf_info qeth_dbf[QETH_DBF_INFOS];
|
|||
|
||||
struct net_device *qeth_clone_netdev(struct net_device *orig);
|
||||
struct qeth_card *qeth_get_card_by_busid(char *bus_id);
|
||||
void qeth_set_recovery_task(struct qeth_card *);
|
||||
void qeth_clear_recovery_task(struct qeth_card *);
|
||||
void qeth_set_allowed_threads(struct qeth_card *, unsigned long , int);
|
||||
int qeth_threads_running(struct qeth_card *, unsigned long);
|
||||
int qeth_wait_for_threads(struct qeth_card *, unsigned long);
|
||||
int qeth_do_run_thread(struct qeth_card *, unsigned long);
|
||||
void qeth_clear_thread_start_bit(struct qeth_card *, unsigned long);
|
||||
void qeth_clear_thread_running_bit(struct qeth_card *, unsigned long);
|
||||
|
@ -1047,6 +1036,9 @@ netdev_features_t qeth_fix_features(struct net_device *, netdev_features_t);
|
|||
netdev_features_t qeth_features_check(struct sk_buff *skb,
|
||||
struct net_device *dev,
|
||||
netdev_features_t features);
|
||||
int qeth_open(struct net_device *dev);
|
||||
int qeth_stop(struct net_device *dev);
|
||||
|
||||
int qeth_vm_request_mac(struct qeth_card *card);
|
||||
int qeth_xmit(struct qeth_card *card, struct sk_buff *skb,
|
||||
struct qeth_qdio_out_q *queue, int ipv, int cast_type,
|
||||
|
|
|
@ -193,23 +193,6 @@ const char *qeth_get_cardname_short(struct qeth_card *card)
|
|||
return "n/a";
|
||||
}
|
||||
|
||||
void qeth_set_recovery_task(struct qeth_card *card)
|
||||
{
|
||||
card->recovery_task = current;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_set_recovery_task);
|
||||
|
||||
void qeth_clear_recovery_task(struct qeth_card *card)
|
||||
{
|
||||
card->recovery_task = NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_clear_recovery_task);
|
||||
|
||||
static bool qeth_is_recovery_task(const struct qeth_card *card)
|
||||
{
|
||||
return card->recovery_task == current;
|
||||
}
|
||||
|
||||
void qeth_set_allowed_threads(struct qeth_card *card, unsigned long threads,
|
||||
int clear_start_mask)
|
||||
{
|
||||
|
@ -236,15 +219,6 @@ int qeth_threads_running(struct qeth_card *card, unsigned long threads)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_threads_running);
|
||||
|
||||
int qeth_wait_for_threads(struct qeth_card *card, unsigned long threads)
|
||||
{
|
||||
if (qeth_is_recovery_task(card))
|
||||
return 0;
|
||||
return wait_event_interruptible(card->wait_q,
|
||||
qeth_threads_running(card, threads) == 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_wait_for_threads);
|
||||
|
||||
void qeth_clear_working_pool_list(struct qeth_card *card)
|
||||
{
|
||||
struct qeth_buffer_pool_entry *pool_entry, *tmp;
|
||||
|
@ -1430,7 +1404,6 @@ static void qeth_setup_card(struct qeth_card *card)
|
|||
spin_lock_init(&card->thread_mask_lock);
|
||||
mutex_init(&card->conf_mutex);
|
||||
mutex_init(&card->discipline_mutex);
|
||||
mutex_init(&card->vid_list_mutex);
|
||||
INIT_WORK(&card->kernel_thread_starter, qeth_start_kernel_thread);
|
||||
INIT_LIST_HEAD(&card->cmd_waiter_list);
|
||||
init_waitqueue_head(&card->wait_q);
|
||||
|
@ -3558,8 +3531,6 @@ static void qeth_qdio_cq_handler(struct qeth_card *card, unsigned int qdio_err,
|
|||
card->qdio.c_q->next_buf_to_init = (card->qdio.c_q->next_buf_to_init
|
||||
+ count) % QDIO_MAX_BUFFERS_PER_Q;
|
||||
|
||||
netif_wake_queue(card->dev);
|
||||
|
||||
if (card->options.performance_stats) {
|
||||
int delta_t = qeth_get_micros();
|
||||
delta_t -= card->perf_stats.cq_start_time;
|
||||
|
@ -3928,7 +3899,6 @@ static int qeth_fill_buffer(struct qeth_qdio_out_q *queue,
|
|||
{
|
||||
struct qdio_buffer *buffer = buf->buffer;
|
||||
bool is_first_elem = true;
|
||||
int flush_cnt = 0;
|
||||
|
||||
__skb_queue_tail(&buf->skb_list, skb);
|
||||
|
||||
|
@ -3949,24 +3919,22 @@ static int qeth_fill_buffer(struct qeth_qdio_out_q *queue,
|
|||
|
||||
if (!queue->do_pack) {
|
||||
QETH_CARD_TEXT(queue->card, 6, "fillbfnp");
|
||||
/* set state to PRIMED -> will be flushed */
|
||||
atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
|
||||
flush_cnt = 1;
|
||||
} else {
|
||||
QETH_CARD_TEXT(queue->card, 6, "fillbfpa");
|
||||
if (queue->card->options.performance_stats)
|
||||
queue->card->perf_stats.skbs_sent_pack++;
|
||||
if (buf->next_element_to_fill >=
|
||||
QETH_MAX_BUFFER_ELEMENTS(queue->card)) {
|
||||
/*
|
||||
* packed buffer if full -> set state PRIMED
|
||||
* -> will be flushed
|
||||
*/
|
||||
atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
|
||||
flush_cnt = 1;
|
||||
}
|
||||
|
||||
/* If the buffer still has free elements, keep using it. */
|
||||
if (buf->next_element_to_fill <
|
||||
QETH_MAX_BUFFER_ELEMENTS(queue->card))
|
||||
return 0;
|
||||
}
|
||||
return flush_cnt;
|
||||
|
||||
/* flush out the buffer */
|
||||
atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
|
||||
queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
|
||||
QDIO_MAX_BUFFERS_PER_Q;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int qeth_do_send_packet_fast(struct qeth_qdio_out_q *queue,
|
||||
|
@ -3982,7 +3950,6 @@ static int qeth_do_send_packet_fast(struct qeth_qdio_out_q *queue,
|
|||
*/
|
||||
if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY)
|
||||
return -EBUSY;
|
||||
queue->next_buf_to_fill = (index + 1) % QDIO_MAX_BUFFERS_PER_Q;
|
||||
qeth_fill_buffer(queue, buffer, skb, hdr, offset, hd_len);
|
||||
qeth_flush_buffers(queue, index, 1);
|
||||
return 0;
|
||||
|
@ -4040,10 +4007,9 @@ int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
|
|||
}
|
||||
}
|
||||
}
|
||||
tmp = qeth_fill_buffer(queue, buffer, skb, hdr, offset, hd_len);
|
||||
queue->next_buf_to_fill = (queue->next_buf_to_fill + tmp) %
|
||||
QDIO_MAX_BUFFERS_PER_Q;
|
||||
flush_count += tmp;
|
||||
|
||||
flush_count += qeth_fill_buffer(queue, buffer, skb, hdr, offset,
|
||||
hd_len);
|
||||
if (flush_count)
|
||||
qeth_flush_buffers(queue, start_index, flush_count);
|
||||
else if (!atomic_read(&queue->set_pci_flags_count))
|
||||
|
@ -5154,13 +5120,6 @@ retriable:
|
|||
*carrier_ok = true;
|
||||
}
|
||||
|
||||
if (qeth_netdev_is_registered(card->dev)) {
|
||||
if (*carrier_ok)
|
||||
netif_carrier_on(card->dev);
|
||||
else
|
||||
netif_carrier_off(card->dev);
|
||||
}
|
||||
|
||||
card->options.ipa4.supported_funcs = 0;
|
||||
card->options.ipa6.supported_funcs = 0;
|
||||
card->options.adp.supported_funcs = 0;
|
||||
|
@ -5937,9 +5896,6 @@ int qeth_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
|||
if (!card)
|
||||
return -ENODEV;
|
||||
|
||||
if (!qeth_card_hw_is_reachable(card))
|
||||
return -ENODEV;
|
||||
|
||||
if (card->info.type == QETH_CARD_TYPE_OSN)
|
||||
return -EPERM;
|
||||
|
||||
|
@ -6250,8 +6206,6 @@ int qeth_core_ethtool_get_link_ksettings(struct net_device *netdev,
|
|||
/* Check if we can obtain more accurate information. */
|
||||
/* If QUERY_CARD_INFO command is not supported or fails, */
|
||||
/* just return the heuristics that was filled above. */
|
||||
if (!qeth_card_hw_is_reachable(card))
|
||||
return -ENODEV;
|
||||
rc = qeth_query_card_info(card, &carrier_info);
|
||||
if (rc == -EOPNOTSUPP) /* for old hardware, return heuristic */
|
||||
return 0;
|
||||
|
@ -6534,8 +6488,6 @@ static int qeth_set_ipa_rx_csum(struct qeth_card *card, bool on)
|
|||
return (rc_ipv6) ? rc_ipv6 : rc_ipv4;
|
||||
}
|
||||
|
||||
#define QETH_HW_FEATURES (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_TSO | \
|
||||
NETIF_F_IPV6_CSUM | NETIF_F_TSO6)
|
||||
/**
|
||||
* qeth_enable_hw_features() - (Re-)Enable HW functions for device features
|
||||
* @dev: a net_device
|
||||
|
@ -6545,17 +6497,20 @@ void qeth_enable_hw_features(struct net_device *dev)
|
|||
struct qeth_card *card = dev->ml_priv;
|
||||
netdev_features_t features;
|
||||
|
||||
rtnl_lock();
|
||||
features = dev->features;
|
||||
/* force-off any feature that needs an IPA sequence.
|
||||
/* force-off any feature that might need an IPA sequence.
|
||||
* netdev_update_features() will restart them.
|
||||
*/
|
||||
dev->features &= ~QETH_HW_FEATURES;
|
||||
dev->features &= ~dev->hw_features;
|
||||
/* toggle VLAN filter, so that VIDs are re-programmed: */
|
||||
if (IS_LAYER2(card) && IS_VM_NIC(card)) {
|
||||
dev->features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
|
||||
dev->wanted_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
|
||||
}
|
||||
netdev_update_features(dev);
|
||||
if (features != dev->features)
|
||||
dev_warn(&card->gdev->dev,
|
||||
"Device recovery failed to restore all offload features\n");
|
||||
rtnl_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_enable_hw_features);
|
||||
|
||||
|
@ -6624,10 +6579,7 @@ netdev_features_t qeth_fix_features(struct net_device *dev,
|
|||
features &= ~NETIF_F_TSO;
|
||||
if (!qeth_is_supported6(card, IPA_OUTBOUND_TSO))
|
||||
features &= ~NETIF_F_TSO6;
|
||||
/* if the card isn't up, remove features that require hw changes */
|
||||
if (card->state == CARD_STATE_DOWN ||
|
||||
card->state == CARD_STATE_RECOVER)
|
||||
features &= ~QETH_HW_FEATURES;
|
||||
|
||||
QETH_DBF_HEX(SETUP, 2, &features, sizeof(features));
|
||||
return features;
|
||||
}
|
||||
|
@ -6659,6 +6611,46 @@ netdev_features_t qeth_features_check(struct sk_buff *skb,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_features_check);
|
||||
|
||||
int qeth_open(struct net_device *dev)
|
||||
{
|
||||
struct qeth_card *card = dev->ml_priv;
|
||||
|
||||
QETH_CARD_TEXT(card, 4, "qethopen");
|
||||
if (card->state == CARD_STATE_UP)
|
||||
return 0;
|
||||
if (card->state != CARD_STATE_SOFTSETUP)
|
||||
return -ENODEV;
|
||||
|
||||
if (qdio_stop_irq(CARD_DDEV(card), 0) < 0)
|
||||
return -EIO;
|
||||
|
||||
card->data.state = CH_STATE_UP;
|
||||
card->state = CARD_STATE_UP;
|
||||
netif_start_queue(dev);
|
||||
|
||||
napi_enable(&card->napi);
|
||||
local_bh_disable();
|
||||
napi_schedule(&card->napi);
|
||||
/* kick-start the NAPI softirq: */
|
||||
local_bh_enable();
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_open);
|
||||
|
||||
int qeth_stop(struct net_device *dev)
|
||||
{
|
||||
struct qeth_card *card = dev->ml_priv;
|
||||
|
||||
QETH_CARD_TEXT(card, 4, "qethstop");
|
||||
netif_tx_disable(dev);
|
||||
if (card->state == CARD_STATE_UP) {
|
||||
card->state = CARD_STATE_SOFTSETUP;
|
||||
napi_disable(&card->napi);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qeth_stop);
|
||||
|
||||
static int __init qeth_core_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
|
|
@ -81,6 +81,7 @@ enum qeth_card_types {
|
|||
|
||||
#define IS_IQD(card) ((card)->info.type == QETH_CARD_TYPE_IQD)
|
||||
#define IS_OSD(card) ((card)->info.type == QETH_CARD_TYPE_OSD)
|
||||
#define IS_OSM(card) ((card)->info.type == QETH_CARD_TYPE_OSM)
|
||||
#define IS_OSN(card) ((card)->info.type == QETH_CARD_TYPE_OSN)
|
||||
#define IS_VM_NIC(card) ((card)->info.guestlan)
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "qeth_l2.h"
|
||||
|
||||
static int qeth_l2_set_offline(struct ccwgroup_device *);
|
||||
static int qeth_l2_stop(struct net_device *);
|
||||
static void qeth_bridgeport_query_support(struct qeth_card *card);
|
||||
static void qeth_bridge_state_change(struct qeth_card *card,
|
||||
struct qeth_ipa_cmd *cmd);
|
||||
|
@ -98,8 +97,7 @@ static int qeth_l2_send_setmac(struct qeth_card *card, __u8 *mac)
|
|||
rc = qeth_l2_send_setdelmac(card, mac, IPA_CMD_SETVMAC);
|
||||
if (rc == 0) {
|
||||
dev_info(&card->gdev->dev,
|
||||
"MAC address %pM successfully registered on device %s\n",
|
||||
mac, card->dev->name);
|
||||
"MAC address %pM successfully registered\n", mac);
|
||||
} else {
|
||||
switch (rc) {
|
||||
case -EEXIST:
|
||||
|
@ -263,75 +261,28 @@ static int qeth_l2_send_setdelvlan(struct qeth_card *card, __u16 i,
|
|||
qeth_l2_send_setdelvlan_cb, NULL));
|
||||
}
|
||||
|
||||
static void qeth_l2_process_vlans(struct qeth_card *card)
|
||||
{
|
||||
struct qeth_vlan_vid *id;
|
||||
|
||||
QETH_CARD_TEXT(card, 3, "L2prcvln");
|
||||
mutex_lock(&card->vid_list_mutex);
|
||||
list_for_each_entry(id, &card->vid_list, list) {
|
||||
qeth_l2_send_setdelvlan(card, id->vid, IPA_CMD_SETVLAN);
|
||||
}
|
||||
mutex_unlock(&card->vid_list_mutex);
|
||||
}
|
||||
|
||||
static int qeth_l2_vlan_rx_add_vid(struct net_device *dev,
|
||||
__be16 proto, u16 vid)
|
||||
{
|
||||
struct qeth_card *card = dev->ml_priv;
|
||||
struct qeth_vlan_vid *id;
|
||||
int rc;
|
||||
|
||||
QETH_CARD_TEXT_(card, 4, "aid:%d", vid);
|
||||
if (!vid)
|
||||
return 0;
|
||||
if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) {
|
||||
QETH_CARD_TEXT(card, 3, "aidREC");
|
||||
return 0;
|
||||
}
|
||||
id = kmalloc(sizeof(*id), GFP_KERNEL);
|
||||
if (id) {
|
||||
id->vid = vid;
|
||||
rc = qeth_l2_send_setdelvlan(card, vid, IPA_CMD_SETVLAN);
|
||||
if (rc) {
|
||||
kfree(id);
|
||||
return rc;
|
||||
}
|
||||
mutex_lock(&card->vid_list_mutex);
|
||||
list_add_tail(&id->list, &card->vid_list);
|
||||
mutex_unlock(&card->vid_list_mutex);
|
||||
} else {
|
||||
return -ENOMEM;
|
||||
}
|
||||
return 0;
|
||||
|
||||
return qeth_l2_send_setdelvlan(card, vid, IPA_CMD_SETVLAN);
|
||||
}
|
||||
|
||||
static int qeth_l2_vlan_rx_kill_vid(struct net_device *dev,
|
||||
__be16 proto, u16 vid)
|
||||
{
|
||||
struct qeth_vlan_vid *id, *tmpid = NULL;
|
||||
struct qeth_card *card = dev->ml_priv;
|
||||
int rc = 0;
|
||||
|
||||
QETH_CARD_TEXT_(card, 4, "kid:%d", vid);
|
||||
if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) {
|
||||
QETH_CARD_TEXT(card, 3, "kidREC");
|
||||
if (!vid)
|
||||
return 0;
|
||||
}
|
||||
mutex_lock(&card->vid_list_mutex);
|
||||
list_for_each_entry(id, &card->vid_list, list) {
|
||||
if (id->vid == vid) {
|
||||
list_del(&id->list);
|
||||
tmpid = id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&card->vid_list_mutex);
|
||||
if (tmpid) {
|
||||
rc = qeth_l2_send_setdelvlan(card, vid, IPA_CMD_DELVLAN);
|
||||
kfree(tmpid);
|
||||
}
|
||||
return rc;
|
||||
|
||||
return qeth_l2_send_setdelvlan(card, vid, IPA_CMD_DELVLAN);
|
||||
}
|
||||
|
||||
static void qeth_l2_stop_card(struct qeth_card *card, int recovery_mode)
|
||||
|
@ -343,9 +294,8 @@ static void qeth_l2_stop_card(struct qeth_card *card, int recovery_mode)
|
|||
if (card->read.state == CH_STATE_UP &&
|
||||
card->write.state == CH_STATE_UP &&
|
||||
(card->state == CARD_STATE_UP)) {
|
||||
if (recovery_mode &&
|
||||
card->info.type != QETH_CARD_TYPE_OSN) {
|
||||
qeth_l2_stop(card->dev);
|
||||
if (recovery_mode && !IS_OSN(card)) {
|
||||
qeth_stop(card->dev);
|
||||
} else {
|
||||
rtnl_lock();
|
||||
dev_close(card->dev);
|
||||
|
@ -460,6 +410,26 @@ out:
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void qeth_l2_register_dev_addr(struct qeth_card *card)
|
||||
{
|
||||
if (!is_valid_ether_addr(card->dev->dev_addr))
|
||||
qeth_l2_request_initial_mac(card);
|
||||
|
||||
if (!IS_OSN(card) && !qeth_l2_send_setmac(card, card->dev->dev_addr))
|
||||
card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;
|
||||
}
|
||||
|
||||
static int qeth_l2_validate_addr(struct net_device *dev)
|
||||
{
|
||||
struct qeth_card *card = dev->ml_priv;
|
||||
|
||||
if (IS_OSN(card) || (card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))
|
||||
return eth_validate_addr(dev);
|
||||
|
||||
QETH_CARD_TEXT(card, 4, "nomacadr");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
static int qeth_l2_set_mac_address(struct net_device *dev, void *p)
|
||||
{
|
||||
struct sockaddr *addr = p;
|
||||
|
@ -479,39 +449,22 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p)
|
|||
if (!is_valid_ether_addr(addr->sa_data))
|
||||
return -EADDRNOTAVAIL;
|
||||
|
||||
if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) {
|
||||
QETH_CARD_TEXT(card, 3, "setmcREC");
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
|
||||
/* avoid racing against concurrent state change: */
|
||||
if (!mutex_trylock(&card->conf_mutex))
|
||||
return -EAGAIN;
|
||||
|
||||
if (!qeth_card_hw_is_reachable(card)) {
|
||||
ether_addr_copy(dev->dev_addr, addr->sa_data);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
/* don't register the same address twice */
|
||||
if (ether_addr_equal_64bits(dev->dev_addr, addr->sa_data) &&
|
||||
(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))
|
||||
goto out_unlock;
|
||||
return 0;
|
||||
|
||||
/* add the new address, switch over, drop the old */
|
||||
rc = qeth_l2_send_setmac(card, addr->sa_data);
|
||||
if (rc)
|
||||
goto out_unlock;
|
||||
return rc;
|
||||
ether_addr_copy(old_addr, dev->dev_addr);
|
||||
ether_addr_copy(dev->dev_addr, addr->sa_data);
|
||||
|
||||
if (card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED)
|
||||
qeth_l2_remove_mac(card, old_addr);
|
||||
card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&card->conf_mutex);
|
||||
return rc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void qeth_promisc_to_bridge(struct qeth_card *card)
|
||||
|
@ -586,9 +539,6 @@ static void qeth_l2_set_rx_mode(struct net_device *dev)
|
|||
return;
|
||||
|
||||
QETH_CARD_TEXT(card, 3, "setmulti");
|
||||
if (qeth_threads_running(card, QETH_RECOVER_THREAD) &&
|
||||
(card->state != CARD_STATE_UP))
|
||||
return;
|
||||
|
||||
spin_lock_bh(&card->mclock);
|
||||
|
||||
|
@ -712,62 +662,6 @@ tx_drop:
|
|||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
static int __qeth_l2_open(struct net_device *dev)
|
||||
{
|
||||
struct qeth_card *card = dev->ml_priv;
|
||||
int rc = 0;
|
||||
|
||||
QETH_CARD_TEXT(card, 4, "qethopen");
|
||||
if (card->state == CARD_STATE_UP)
|
||||
return rc;
|
||||
if (card->state != CARD_STATE_SOFTSETUP)
|
||||
return -ENODEV;
|
||||
|
||||
if ((card->info.type != QETH_CARD_TYPE_OSN) &&
|
||||
(!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))) {
|
||||
QETH_CARD_TEXT(card, 4, "nomacadr");
|
||||
return -EPERM;
|
||||
}
|
||||
card->data.state = CH_STATE_UP;
|
||||
card->state = CARD_STATE_UP;
|
||||
netif_start_queue(dev);
|
||||
|
||||
if (qdio_stop_irq(card->data.ccwdev, 0) >= 0) {
|
||||
napi_enable(&card->napi);
|
||||
local_bh_disable();
|
||||
napi_schedule(&card->napi);
|
||||
/* kick-start the NAPI softirq: */
|
||||
local_bh_enable();
|
||||
} else
|
||||
rc = -EIO;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int qeth_l2_open(struct net_device *dev)
|
||||
{
|
||||
struct qeth_card *card = dev->ml_priv;
|
||||
|
||||
QETH_CARD_TEXT(card, 5, "qethope_");
|
||||
if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) {
|
||||
QETH_CARD_TEXT(card, 3, "openREC");
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
return __qeth_l2_open(dev);
|
||||
}
|
||||
|
||||
static int qeth_l2_stop(struct net_device *dev)
|
||||
{
|
||||
struct qeth_card *card = dev->ml_priv;
|
||||
|
||||
QETH_CARD_TEXT(card, 4, "qethstop");
|
||||
netif_tx_disable(dev);
|
||||
if (card->state == CARD_STATE_UP) {
|
||||
card->state = CARD_STATE_SOFTSETUP;
|
||||
napi_disable(&card->napi);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct device_type qeth_l2_devtype = {
|
||||
.name = "qeth_layer2",
|
||||
.groups = qeth_l2_attr_groups,
|
||||
|
@ -783,7 +677,7 @@ static int qeth_l2_probe_device(struct ccwgroup_device *gdev)
|
|||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
INIT_LIST_HEAD(&card->vid_list);
|
||||
|
||||
hash_init(card->mac_htable);
|
||||
card->info.hwtrap = 0;
|
||||
qeth_l2_vnicc_set_defaults(card);
|
||||
|
@ -822,12 +716,12 @@ static const struct ethtool_ops qeth_l2_osn_ops = {
|
|||
};
|
||||
|
||||
static const struct net_device_ops qeth_l2_netdev_ops = {
|
||||
.ndo_open = qeth_l2_open,
|
||||
.ndo_stop = qeth_l2_stop,
|
||||
.ndo_open = qeth_open,
|
||||
.ndo_stop = qeth_stop,
|
||||
.ndo_get_stats = qeth_get_stats,
|
||||
.ndo_start_xmit = qeth_l2_hard_start_xmit,
|
||||
.ndo_features_check = qeth_features_check,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
.ndo_validate_addr = qeth_l2_validate_addr,
|
||||
.ndo_set_rx_mode = qeth_l2_set_rx_mode,
|
||||
.ndo_do_ioctl = qeth_do_ioctl,
|
||||
.ndo_set_mac_address = qeth_l2_set_mac_address,
|
||||
|
@ -842,9 +736,6 @@ static int qeth_l2_setup_netdev(struct qeth_card *card, bool carrier_ok)
|
|||
{
|
||||
int rc;
|
||||
|
||||
if (qeth_netdev_is_registered(card->dev))
|
||||
return 0;
|
||||
|
||||
card->dev->priv_flags |= IFF_UNICAST_FLT;
|
||||
card->dev->netdev_ops = &qeth_l2_netdev_ops;
|
||||
if (card->info.type == QETH_CARD_TYPE_OSN) {
|
||||
|
@ -855,10 +746,13 @@ static int qeth_l2_setup_netdev(struct qeth_card *card, bool carrier_ok)
|
|||
card->dev->needed_headroom = sizeof(struct qeth_hdr);
|
||||
}
|
||||
|
||||
if (card->info.type == QETH_CARD_TYPE_OSM)
|
||||
if (IS_OSM(card)) {
|
||||
card->dev->features |= NETIF_F_VLAN_CHALLENGED;
|
||||
else
|
||||
} else {
|
||||
if (!IS_VM_NIC(card))
|
||||
card->dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
|
||||
card->dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
|
||||
}
|
||||
|
||||
if (card->info.type == QETH_CARD_TYPE_OSD && !card->info.guestlan) {
|
||||
card->dev->features |= NETIF_F_SG;
|
||||
|
@ -892,8 +786,6 @@ static int qeth_l2_setup_netdev(struct qeth_card *card, bool carrier_ok)
|
|||
PAGE_SIZE * (QDIO_MAX_ELEMENTS_PER_BUFFER - 1));
|
||||
}
|
||||
|
||||
if (!is_valid_ether_addr(card->dev->dev_addr))
|
||||
qeth_l2_request_initial_mac(card);
|
||||
netif_napi_add(card->dev, &card->napi, qeth_poll, QETH_NAPI_WEIGHT);
|
||||
rc = register_netdev(card->dev);
|
||||
if (!rc && carrier_ok)
|
||||
|
@ -927,6 +819,7 @@ static void qeth_l2_trace_features(struct qeth_card *card)
|
|||
static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
|
||||
{
|
||||
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
|
||||
struct net_device *dev = card->dev;
|
||||
int rc = 0;
|
||||
enum qeth_card_states recover_flag;
|
||||
bool carrier_ok;
|
||||
|
@ -948,13 +841,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
|
|||
dev_info(&card->gdev->dev,
|
||||
"The device represents a Bridge Capable Port\n");
|
||||
|
||||
rc = qeth_l2_setup_netdev(card, carrier_ok);
|
||||
if (rc)
|
||||
goto out_remove;
|
||||
|
||||
if (card->info.type != QETH_CARD_TYPE_OSN &&
|
||||
!qeth_l2_send_setmac(card, card->dev->dev_addr))
|
||||
card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;
|
||||
qeth_l2_register_dev_addr(card);
|
||||
|
||||
if (qeth_is_diagass_supported(card, QETH_DIAGS_CMD_TRAP)) {
|
||||
if (card->info.hwtrap &&
|
||||
|
@ -984,11 +871,6 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
|
|||
goto out_remove;
|
||||
}
|
||||
|
||||
if (card->info.type != QETH_CARD_TYPE_OSN)
|
||||
qeth_l2_process_vlans(card);
|
||||
|
||||
netif_tx_disable(card->dev);
|
||||
|
||||
rc = qeth_init_qdio_queues(card);
|
||||
if (rc) {
|
||||
QETH_DBF_TEXT_(SETUP, 2, "6err%d", rc);
|
||||
|
@ -999,17 +881,31 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
|
|||
|
||||
qeth_set_allowed_threads(card, 0xffffffff, 0);
|
||||
|
||||
qeth_enable_hw_features(card->dev);
|
||||
if (recover_flag == CARD_STATE_RECOVER) {
|
||||
if (recovery_mode &&
|
||||
card->info.type != QETH_CARD_TYPE_OSN) {
|
||||
__qeth_l2_open(card->dev);
|
||||
qeth_l2_set_rx_mode(card->dev);
|
||||
} else {
|
||||
rtnl_lock();
|
||||
dev_open(card->dev, NULL);
|
||||
rtnl_unlock();
|
||||
if (!qeth_netdev_is_registered(dev)) {
|
||||
rc = qeth_l2_setup_netdev(card, carrier_ok);
|
||||
if (rc)
|
||||
goto out_remove;
|
||||
} else {
|
||||
rtnl_lock();
|
||||
if (carrier_ok)
|
||||
netif_carrier_on(dev);
|
||||
else
|
||||
netif_carrier_off(dev);
|
||||
|
||||
netif_device_attach(dev);
|
||||
qeth_enable_hw_features(dev);
|
||||
|
||||
if (recover_flag == CARD_STATE_RECOVER) {
|
||||
if (recovery_mode && !IS_OSN(card)) {
|
||||
if (!qeth_l2_validate_addr(dev)) {
|
||||
qeth_open(dev);
|
||||
qeth_l2_set_rx_mode(dev);
|
||||
}
|
||||
} else {
|
||||
dev_open(dev, NULL);
|
||||
}
|
||||
}
|
||||
rtnl_unlock();
|
||||
}
|
||||
/* let user_space know that device is online */
|
||||
kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);
|
||||
|
@ -1049,7 +945,11 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev,
|
|||
QETH_DBF_TEXT(SETUP, 3, "setoffl");
|
||||
QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *));
|
||||
|
||||
rtnl_lock();
|
||||
netif_device_detach(card->dev);
|
||||
netif_carrier_off(card->dev);
|
||||
rtnl_unlock();
|
||||
|
||||
recover_flag = card->state;
|
||||
if ((!recovery_mode && card->info.hwtrap) || card->info.hwtrap == 2) {
|
||||
qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
|
||||
|
@ -1090,7 +990,6 @@ static int qeth_l2_recover(void *ptr)
|
|||
QETH_CARD_TEXT(card, 2, "recover2");
|
||||
dev_warn(&card->gdev->dev,
|
||||
"A recovery process has been started for the device\n");
|
||||
qeth_set_recovery_task(card);
|
||||
__qeth_l2_set_offline(card->gdev, 1);
|
||||
rc = __qeth_l2_set_online(card->gdev, 1);
|
||||
if (!rc)
|
||||
|
@ -1101,7 +1000,6 @@ static int qeth_l2_recover(void *ptr)
|
|||
dev_warn(&card->gdev->dev, "The qeth device driver "
|
||||
"failed to recover an error on the device\n");
|
||||
}
|
||||
qeth_clear_recovery_task(card);
|
||||
qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
|
||||
qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
|
||||
return 0;
|
||||
|
@ -1122,7 +1020,6 @@ static int qeth_l2_pm_suspend(struct ccwgroup_device *gdev)
|
|||
{
|
||||
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
|
||||
|
||||
netif_device_detach(card->dev);
|
||||
qeth_set_allowed_threads(card, 0, 1);
|
||||
wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
|
||||
if (gdev->state == CCWGROUP_OFFLINE)
|
||||
|
@ -1152,7 +1049,6 @@ static int qeth_l2_pm_resume(struct ccwgroup_device *gdev)
|
|||
rc = __qeth_l2_set_online(card->gdev, 0);
|
||||
|
||||
qeth_set_allowed_threads(card, 0xffffffff, 0);
|
||||
netif_device_attach(card->dev);
|
||||
if (rc)
|
||||
dev_warn(&card->gdev->dev, "The qeth device driver "
|
||||
"failed to recover an error on the device\n");
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
|
||||
|
||||
static int qeth_l3_set_offline(struct ccwgroup_device *);
|
||||
static int qeth_l3_stop(struct net_device *);
|
||||
static void qeth_l3_set_rx_mode(struct net_device *dev);
|
||||
static int qeth_l3_register_addr_entry(struct qeth_card *,
|
||||
struct qeth_ipaddr *);
|
||||
|
@ -1281,10 +1280,6 @@ static int qeth_l3_vlan_rx_kill_vid(struct net_device *dev,
|
|||
|
||||
QETH_CARD_TEXT_(card, 4, "kid:%d", vid);
|
||||
|
||||
if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) {
|
||||
QETH_CARD_TEXT(card, 3, "kidREC");
|
||||
return 0;
|
||||
}
|
||||
clear_bit(vid, card->active_vlans);
|
||||
qeth_l3_set_rx_mode(dev);
|
||||
return 0;
|
||||
|
@ -1410,7 +1405,7 @@ static void qeth_l3_stop_card(struct qeth_card *card, int recovery_mode)
|
|||
card->write.state == CH_STATE_UP &&
|
||||
(card->state == CARD_STATE_UP)) {
|
||||
if (recovery_mode)
|
||||
qeth_l3_stop(card->dev);
|
||||
qeth_stop(card->dev);
|
||||
else {
|
||||
rtnl_lock();
|
||||
dev_close(card->dev);
|
||||
|
@ -1473,9 +1468,7 @@ static void qeth_l3_set_rx_mode(struct net_device *dev)
|
|||
int i, rc;
|
||||
|
||||
QETH_CARD_TEXT(card, 3, "setmulti");
|
||||
if (qeth_threads_running(card, QETH_RECOVER_THREAD) &&
|
||||
(card->state != CARD_STATE_UP))
|
||||
return;
|
||||
|
||||
if (!card->options.sniffer) {
|
||||
spin_lock_bh(&card->mclock);
|
||||
|
||||
|
@ -2100,56 +2093,6 @@ tx_drop:
|
|||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
static int __qeth_l3_open(struct net_device *dev)
|
||||
{
|
||||
struct qeth_card *card = dev->ml_priv;
|
||||
int rc = 0;
|
||||
|
||||
QETH_CARD_TEXT(card, 4, "qethopen");
|
||||
if (card->state == CARD_STATE_UP)
|
||||
return rc;
|
||||
if (card->state != CARD_STATE_SOFTSETUP)
|
||||
return -ENODEV;
|
||||
card->data.state = CH_STATE_UP;
|
||||
card->state = CARD_STATE_UP;
|
||||
netif_start_queue(dev);
|
||||
|
||||
if (qdio_stop_irq(card->data.ccwdev, 0) >= 0) {
|
||||
napi_enable(&card->napi);
|
||||
local_bh_disable();
|
||||
napi_schedule(&card->napi);
|
||||
/* kick-start the NAPI softirq: */
|
||||
local_bh_enable();
|
||||
} else
|
||||
rc = -EIO;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int qeth_l3_open(struct net_device *dev)
|
||||
{
|
||||
struct qeth_card *card = dev->ml_priv;
|
||||
|
||||
QETH_CARD_TEXT(card, 5, "qethope_");
|
||||
if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) {
|
||||
QETH_CARD_TEXT(card, 3, "openREC");
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
return __qeth_l3_open(dev);
|
||||
}
|
||||
|
||||
static int qeth_l3_stop(struct net_device *dev)
|
||||
{
|
||||
struct qeth_card *card = dev->ml_priv;
|
||||
|
||||
QETH_CARD_TEXT(card, 4, "qethstop");
|
||||
netif_tx_disable(dev);
|
||||
if (card->state == CARD_STATE_UP) {
|
||||
card->state = CARD_STATE_SOFTSETUP;
|
||||
napi_disable(&card->napi);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ethtool_ops qeth_l3_ethtool_ops = {
|
||||
.get_link = ethtool_op_get_link,
|
||||
.get_strings = qeth_core_get_strings,
|
||||
|
@ -2193,8 +2136,8 @@ static netdev_features_t qeth_l3_osa_features_check(struct sk_buff *skb,
|
|||
}
|
||||
|
||||
static const struct net_device_ops qeth_l3_netdev_ops = {
|
||||
.ndo_open = qeth_l3_open,
|
||||
.ndo_stop = qeth_l3_stop,
|
||||
.ndo_open = qeth_open,
|
||||
.ndo_stop = qeth_stop,
|
||||
.ndo_get_stats = qeth_get_stats,
|
||||
.ndo_start_xmit = qeth_l3_hard_start_xmit,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
|
@ -2208,8 +2151,8 @@ static const struct net_device_ops qeth_l3_netdev_ops = {
|
|||
};
|
||||
|
||||
static const struct net_device_ops qeth_l3_osa_netdev_ops = {
|
||||
.ndo_open = qeth_l3_open,
|
||||
.ndo_stop = qeth_l3_stop,
|
||||
.ndo_open = qeth_open,
|
||||
.ndo_stop = qeth_stop,
|
||||
.ndo_get_stats = qeth_get_stats,
|
||||
.ndo_start_xmit = qeth_l3_hard_start_xmit,
|
||||
.ndo_features_check = qeth_l3_osa_features_check,
|
||||
|
@ -2229,9 +2172,6 @@ static int qeth_l3_setup_netdev(struct qeth_card *card, bool carrier_ok)
|
|||
unsigned int headroom;
|
||||
int rc;
|
||||
|
||||
if (qeth_netdev_is_registered(card->dev))
|
||||
return 0;
|
||||
|
||||
if (card->info.type == QETH_CARD_TYPE_OSD ||
|
||||
card->info.type == QETH_CARD_TYPE_OSX) {
|
||||
if ((card->info.link_type == QETH_LINK_TYPE_LANE_TR) ||
|
||||
|
@ -2347,6 +2287,7 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev)
|
|||
static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
|
||||
{
|
||||
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
|
||||
struct net_device *dev = card->dev;
|
||||
int rc = 0;
|
||||
enum qeth_card_states recover_flag;
|
||||
bool carrier_ok;
|
||||
|
@ -2364,10 +2305,6 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
|
|||
goto out_remove;
|
||||
}
|
||||
|
||||
rc = qeth_l3_setup_netdev(card, carrier_ok);
|
||||
if (rc)
|
||||
goto out_remove;
|
||||
|
||||
if (qeth_is_diagass_supported(card, QETH_DIAGS_CMD_TRAP)) {
|
||||
if (card->info.hwtrap &&
|
||||
qeth_hw_trap(card, QETH_DIAGS_TRAP_ARM))
|
||||
|
@ -2397,7 +2334,6 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
|
|||
if (rc)
|
||||
QETH_DBF_TEXT_(SETUP, 2, "5err%04x", rc);
|
||||
}
|
||||
netif_tx_disable(card->dev);
|
||||
|
||||
rc = qeth_init_qdio_queues(card);
|
||||
if (rc) {
|
||||
|
@ -2410,14 +2346,27 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
|
|||
qeth_set_allowed_threads(card, 0xffffffff, 0);
|
||||
qeth_l3_recover_ip(card);
|
||||
|
||||
qeth_enable_hw_features(card->dev);
|
||||
if (recover_flag == CARD_STATE_RECOVER) {
|
||||
if (!qeth_netdev_is_registered(dev)) {
|
||||
rc = qeth_l3_setup_netdev(card, carrier_ok);
|
||||
if (rc)
|
||||
goto out_remove;
|
||||
} else {
|
||||
rtnl_lock();
|
||||
if (recovery_mode) {
|
||||
__qeth_l3_open(card->dev);
|
||||
qeth_l3_set_rx_mode(card->dev);
|
||||
} else {
|
||||
dev_open(card->dev, NULL);
|
||||
if (carrier_ok)
|
||||
netif_carrier_on(dev);
|
||||
else
|
||||
netif_carrier_off(dev);
|
||||
|
||||
netif_device_attach(dev);
|
||||
qeth_enable_hw_features(dev);
|
||||
|
||||
if (recover_flag == CARD_STATE_RECOVER) {
|
||||
if (recovery_mode) {
|
||||
qeth_open(dev);
|
||||
qeth_l3_set_rx_mode(dev);
|
||||
} else {
|
||||
dev_open(dev, NULL);
|
||||
}
|
||||
}
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
@ -2459,7 +2408,11 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev,
|
|||
QETH_DBF_TEXT(SETUP, 3, "setoffl");
|
||||
QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *));
|
||||
|
||||
rtnl_lock();
|
||||
netif_device_detach(card->dev);
|
||||
netif_carrier_off(card->dev);
|
||||
rtnl_unlock();
|
||||
|
||||
recover_flag = card->state;
|
||||
if ((!recovery_mode && card->info.hwtrap) || card->info.hwtrap == 2) {
|
||||
qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
|
||||
|
@ -2506,7 +2459,6 @@ static int qeth_l3_recover(void *ptr)
|
|||
QETH_CARD_TEXT(card, 2, "recover2");
|
||||
dev_warn(&card->gdev->dev,
|
||||
"A recovery process has been started for the device\n");
|
||||
qeth_set_recovery_task(card);
|
||||
__qeth_l3_set_offline(card->gdev, 1);
|
||||
rc = __qeth_l3_set_online(card->gdev, 1);
|
||||
if (!rc)
|
||||
|
@ -2517,7 +2469,6 @@ static int qeth_l3_recover(void *ptr)
|
|||
dev_warn(&card->gdev->dev, "The qeth device driver "
|
||||
"failed to recover an error on the device\n");
|
||||
}
|
||||
qeth_clear_recovery_task(card);
|
||||
qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
|
||||
qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
|
||||
return 0;
|
||||
|
@ -2527,7 +2478,6 @@ static int qeth_l3_pm_suspend(struct ccwgroup_device *gdev)
|
|||
{
|
||||
struct qeth_card *card = dev_get_drvdata(&gdev->dev);
|
||||
|
||||
netif_device_detach(card->dev);
|
||||
qeth_set_allowed_threads(card, 0, 1);
|
||||
wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
|
||||
if (gdev->state == CCWGROUP_OFFLINE)
|
||||
|
@ -2557,7 +2507,6 @@ static int qeth_l3_pm_resume(struct ccwgroup_device *gdev)
|
|||
rc = __qeth_l3_set_online(card->gdev, 0);
|
||||
|
||||
qeth_set_allowed_threads(card, 0xffffffff, 0);
|
||||
netif_device_attach(card->dev);
|
||||
if (rc)
|
||||
dev_warn(&card->gdev->dev, "The qeth device driver "
|
||||
"failed to recover an error on the device\n");
|
||||
|
|
Loading…
Reference in New Issue