fm10k: Correctly set the number of Tx queues
[cascardo/linux.git] / drivers / net / ethernet / intel / fm10k / fm10k_netdev.c
index 268966b..bf44a8f 100644 (file)
@@ -243,6 +243,9 @@ void fm10k_clean_all_tx_rings(struct fm10k_intfc *interface)
 
        for (i = 0; i < interface->num_tx_queues; i++)
                fm10k_clean_tx_ring(interface->tx_ring[i]);
+
+       /* remove any stale timestamp buffers and free them */
+       skb_queue_purge(&interface->ts_tx_skb_queue);
 }
 
 /**
@@ -368,7 +371,21 @@ static void fm10k_request_glort_range(struct fm10k_intfc *interface)
        if (hw->mac.dglort_map == FM10K_DGLORTMAP_NONE)
                return;
 
-       interface->glort_count = mask + 1;
+       /* we support 3 possible GLORT configurations.
+        * 1: VFs consume all but the last 1
+        * 2: VFs and PF split glorts with possible gap between
+        * 3: VFs allocated first 64, all others belong to PF
+        */
+       if (mask <= hw->iov.total_vfs) {
+               interface->glort_count = 1;
+               interface->glort += mask;
+       } else if (mask < 64) {
+               interface->glort_count = (mask + 1) / 2;
+               interface->glort += interface->glort_count;
+       } else {
+               interface->glort_count = mask - 63;
+               interface->glort += 64;
+       }
 }
 
 /**
@@ -529,6 +546,10 @@ int fm10k_open(struct net_device *netdev)
        fm10k_request_glort_range(interface);
 
        /* Notify the stack of the actual queue counts */
+       err = netif_set_real_num_tx_queues(netdev,
+                                          interface->num_tx_queues);
+       if (err)
+               goto err_set_queues;
 
        err = netif_set_real_num_rx_queues(netdev,
                                           interface->num_rx_queues);
@@ -584,7 +605,7 @@ int fm10k_close(struct net_device *netdev)
 static netdev_tx_t fm10k_xmit_frame(struct sk_buff *skb, struct net_device *dev)
 {
        struct fm10k_intfc *interface = netdev_priv(dev);
-       unsigned int r_idx = 0;
+       unsigned int r_idx = skb->queue_mapping;
        int err;
 
        if ((skb->protocol ==  htons(ETH_P_8021Q)) &&
@@ -637,6 +658,10 @@ static netdev_tx_t fm10k_xmit_frame(struct sk_buff *skb, struct net_device *dev)
                __skb_put(skb, pad_len);
        }
 
+       /* prepare packet for hardware time stamping */
+       if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
+               fm10k_ts_tx_enqueue(interface, skb);
+
        if (r_idx >= interface->num_tx_queues)
                r_idx %= interface->num_tx_queues;
 
@@ -976,6 +1001,21 @@ void fm10k_restore_rx_state(struct fm10k_intfc *interface)
        int xcast_mode;
        u16 vid, glort;
 
+       /* restore our address if perm_addr is set */
+       if (hw->mac.type == fm10k_mac_vf) {
+               if (is_valid_ether_addr(hw->mac.perm_addr)) {
+                       ether_addr_copy(hw->mac.addr, hw->mac.perm_addr);
+                       ether_addr_copy(netdev->perm_addr, hw->mac.perm_addr);
+                       ether_addr_copy(netdev->dev_addr, hw->mac.perm_addr);
+                       netdev->addr_assign_type &= ~NET_ADDR_RANDOM;
+               }
+
+               if (hw->mac.vlan_override)
+                       netdev->features &= ~NETIF_F_HW_VLAN_CTAG_RX;
+               else
+                       netdev->features |= NETIF_F_HW_VLAN_CTAG_RX;
+       }
+
        /* record glort for this interface */
        glort = interface->glort;
 
@@ -1148,6 +1188,18 @@ int fm10k_setup_tc(struct net_device *dev, u8 tc)
        return 0;
 }
 
+static int fm10k_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+       switch (cmd) {
+       case SIOCGHWTSTAMP:
+               return fm10k_get_ts_config(netdev, ifr);
+       case SIOCSHWTSTAMP:
+               return fm10k_set_ts_config(netdev, ifr);
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
 static void fm10k_assign_l2_accel(struct fm10k_intfc *interface,
                                  struct fm10k_l2_accel *l2_accel)
 {
@@ -1310,8 +1362,13 @@ static const struct net_device_ops fm10k_netdev_ops = {
        .ndo_set_rx_mode        = fm10k_set_rx_mode,
        .ndo_get_stats64        = fm10k_get_stats64,
        .ndo_setup_tc           = fm10k_setup_tc,
+       .ndo_set_vf_mac         = fm10k_ndo_set_vf_mac,
+       .ndo_set_vf_vlan        = fm10k_ndo_set_vf_vlan,
+       .ndo_set_vf_rate        = fm10k_ndo_set_vf_bw,
+       .ndo_get_vf_config      = fm10k_ndo_get_vf_config,
        .ndo_add_vxlan_port     = fm10k_add_vxlan_port,
        .ndo_del_vxlan_port     = fm10k_del_vxlan_port,
+       .ndo_do_ioctl           = fm10k_ioctl,
        .ndo_dfwd_add_station   = fm10k_dfwd_add_station,
        .ndo_dfwd_del_station   = fm10k_dfwd_del_station,
 };