Merge remote-tracking branch 'net-next/master'
[linux] / drivers / s390 / net / qeth_core_main.c
index e7f4652..4922ff6 100644 (file)
@@ -192,23 +192,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)
 {
@@ -235,15 +218,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;
@@ -1432,7 +1406,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);
@@ -3566,8 +3539,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;
@@ -3936,7 +3907,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);
 
@@ -3957,24 +3927,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,
@@ -3990,7 +3958,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;
@@ -4048,10 +4015,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))
@@ -5163,13 +5129,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;
@@ -5946,9 +5905,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;
 
@@ -6259,8 +6215,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;
@@ -6543,8 +6497,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
@@ -6554,17 +6506,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);
 
@@ -6633,10 +6588,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;
 }
@@ -6668,6 +6620,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;