diff options
Diffstat (limited to 'drivers/s390/net/qeth_l2_main.c')
-rw-r--r-- | drivers/s390/net/qeth_l2_main.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 641dc17e3b79..1491281600c2 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -161,10 +161,8 @@ static void qeth_l2_drain_rx_mode_cache(struct qeth_card *card) } } -static int qeth_l2_get_cast_type(struct qeth_card *card, struct sk_buff *skb) +static int qeth_l2_get_cast_type(struct sk_buff *skb) { - if (card->info.type == QETH_CARD_TYPE_OSN) - return RTN_UNICAST; if (is_broadcast_ether_addr(skb->data)) return RTN_BROADCAST; if (is_multicast_ether_addr(skb->data)) @@ -603,26 +601,29 @@ static netdev_tx_t qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct qeth_card *card = dev->ml_priv; - int cast_type = qeth_l2_get_cast_type(card, skb); + u16 txq = skb_get_queue_mapping(skb); int ipv = qeth_get_ip_version(skb); struct qeth_qdio_out_q *queue; int tx_bytes = skb->len; int rc; - queue = qeth_get_tx_queue(card, skb, ipv, cast_type); + if (IS_IQD(card)) + queue = card->qdio.out_qs[qeth_iqd_translate_txq(dev, txq)]; + else + queue = qeth_get_tx_queue(card, skb, ipv); - netif_stop_queue(dev); + netif_stop_subqueue(dev, txq); if (IS_OSN(card)) rc = qeth_l2_xmit_osn(card, skb, queue); else - rc = qeth_xmit(card, skb, queue, ipv, cast_type, - qeth_l2_fill_header); + rc = qeth_xmit(card, skb, queue, ipv, + qeth_l2_get_cast_type(skb), qeth_l2_fill_header); if (!rc) { QETH_TXQ_STAT_INC(queue, tx_packets); QETH_TXQ_STAT_ADD(queue, tx_bytes, tx_bytes); - netif_wake_queue(dev); + netif_wake_subqueue(dev, txq); return NETDEV_TX_OK; } else if (rc == -EBUSY) { return NETDEV_TX_BUSY; @@ -630,10 +631,17 @@ static netdev_tx_t qeth_l2_hard_start_xmit(struct sk_buff *skb, QETH_TXQ_STAT_INC(queue, tx_dropped); kfree_skb(skb); - netif_wake_queue(dev); + netif_wake_subqueue(dev, txq); return NETDEV_TX_OK; } +static u16 qeth_l2_select_queue(struct net_device *dev, struct sk_buff *skb, + struct net_device *sb_dev) +{ + return qeth_iqd_select_queue(dev, skb, qeth_l2_get_cast_type(skb), + sb_dev); +} + static const struct device_type qeth_l2_devtype = { .name = "qeth_layer2", .groups = qeth_l2_attr_groups, @@ -687,6 +695,7 @@ static const struct net_device_ops qeth_l2_netdev_ops = { .ndo_get_stats64 = qeth_get_stats64, .ndo_start_xmit = qeth_l2_hard_start_xmit, .ndo_features_check = qeth_features_check, + .ndo_select_queue = qeth_l2_select_queue, .ndo_validate_addr = qeth_l2_validate_addr, .ndo_set_rx_mode = qeth_l2_set_rx_mode, .ndo_do_ioctl = qeth_do_ioctl, |