]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/net/mlx4/en_netdev.c
Merge branch 'master' into tk71
[mv-sheeva.git] / drivers / net / mlx4 / en_netdev.c
index a0d8a26f5a025be35c67ff29b4a124f34ceb1c78..897f576b8b17d7499c16148fd36ee2178a139737 100644 (file)
@@ -69,6 +69,7 @@ static void mlx4_en_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
        struct mlx4_en_priv *priv = netdev_priv(dev);
        struct mlx4_en_dev *mdev = priv->mdev;
        int err;
+       int idx;
 
        if (!priv->vlgrp)
                return;
@@ -83,7 +84,10 @@ static void mlx4_en_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
                if (err)
                        en_err(priv, "Failed configuring VLAN filter\n");
        }
+       if (mlx4_register_vlan(mdev->dev, priv->port, vid, &idx))
+               en_err(priv, "failed adding vlan %d\n", vid);
        mutex_unlock(&mdev->state_lock);
+
 }
 
 static void mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
@@ -91,6 +95,7 @@ static void mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
        struct mlx4_en_priv *priv = netdev_priv(dev);
        struct mlx4_en_dev *mdev = priv->mdev;
        int err;
+       int idx;
 
        if (!priv->vlgrp)
                return;
@@ -101,6 +106,11 @@ static void mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
 
        /* Remove VID from port VLAN filter */
        mutex_lock(&mdev->state_lock);
+       if (!mlx4_find_cached_vlan(mdev->dev, priv->port, vid, &idx))
+               mlx4_unregister_vlan(mdev->dev, priv->port, idx);
+       else
+               en_err(priv, "could not find vid %d in cache\n", vid);
+
        if (mdev->device_up && priv->port_up) {
                err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp);
                if (err)
@@ -109,7 +119,7 @@ static void mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
        mutex_unlock(&mdev->state_lock);
 }
 
-static u64 mlx4_en_mac_to_u64(u8 *addr)
+u64 mlx4_en_mac_to_u64(u8 *addr)
 {
        u64 mac = 0;
        int i;
@@ -513,6 +523,10 @@ static void mlx4_en_do_get_stats(struct work_struct *work)
 
                queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
        }
+       if (mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port]) {
+               queue_work(mdev->workqueue, &priv->mac_task);
+               mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port] = 0;
+       }
        mutex_unlock(&mdev->state_lock);
 }
 
@@ -528,10 +542,10 @@ static void mlx4_en_linkstate(struct work_struct *work)
         * report to system log */
        if (priv->last_link_state != linkstate) {
                if (linkstate == MLX4_DEV_EVENT_PORT_DOWN) {
-                       en_dbg(LINK, priv, "Link Down\n");
+                       en_info(priv, "Link Down\n");
                        netif_carrier_off(priv->dev);
                } else {
-                       en_dbg(LINK, priv, "Link Up\n");
+                       en_info(priv, "Link Up\n");
                        netif_carrier_on(priv->dev);
                }
        }
@@ -653,6 +667,7 @@ int mlx4_en_start_port(struct net_device *dev)
                en_err(priv, "Failed setting port mac\n");
                goto tx_err;
        }
+       mdev->mac_removed[priv->port] = 0;
 
        /* Init port */
        en_dbg(HW, priv, "Initializing port\n");
@@ -704,12 +719,12 @@ void mlx4_en_stop_port(struct net_device *dev)
        netif_tx_stop_all_queues(dev);
        netif_tx_unlock_bh(dev);
 
-       /* close port*/
+       /* Set port as not active */
        priv->port_up = false;
-       mlx4_CLOSE_PORT(mdev->dev, priv->port);
 
        /* Unregister Mac address for the port */
        mlx4_unregister_mac(mdev->dev, priv->port, priv->mac_index);
+       mdev->mac_removed[priv->port] = 1;
 
        /* Free TX Rings */
        for (i = 0; i < priv->tx_ring_num; i++) {
@@ -731,6 +746,9 @@ void mlx4_en_stop_port(struct net_device *dev)
                        msleep(1);
                mlx4_en_deactivate_cq(priv, &priv->rx_cq[i]);
        }
+
+       /* close port*/
+       mlx4_CLOSE_PORT(mdev->dev, priv->port);
 }
 
 static void mlx4_en_restart(struct work_struct *work)
@@ -954,7 +972,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
        int i;
        int err;
 
-       dev = alloc_etherdev_mq(sizeof(struct mlx4_en_priv), prof->tx_ring_num);
+       dev = alloc_etherdev_mqs(sizeof(struct mlx4_en_priv),
+           prof->tx_ring_num, prof->rx_ring_num);
        if (dev == NULL) {
                mlx4_err(mdev, "Net device allocation failed\n");
                return -ENOMEM;
@@ -1017,15 +1036,17 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
         */
        dev->netdev_ops = &mlx4_netdev_ops;
        dev->watchdog_timeo = MLX4_EN_WATCHDOG_TIMEOUT;
-       dev->real_num_tx_queues = MLX4_EN_NUM_TX_RINGS;
+       netif_set_real_num_tx_queues(dev, priv->tx_ring_num);
+       netif_set_real_num_rx_queues(dev, priv->rx_ring_num);
 
        SET_ETHTOOL_OPS(dev, &mlx4_en_ethtool_ops);
 
        /* Set defualt MAC */
        dev->addr_len = ETH_ALEN;
-       for (i = 0; i < ETH_ALEN; i++)
-               dev->dev_addr[ETH_ALEN - 1 - i] =
-               (u8) (priv->mac >> (8 * i));
+       for (i = 0; i < ETH_ALEN; i++) {
+               dev->dev_addr[ETH_ALEN - 1 - i] = (u8) (priv->mac >> (8 * i));
+               dev->perm_addr[ETH_ALEN - 1 - i] = (u8) (priv->mac >> (8 * i));
+       }
 
        /*
         * Set driver features
@@ -1038,8 +1059,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
        dev->features |= NETIF_F_HW_VLAN_TX |
                         NETIF_F_HW_VLAN_RX |
                         NETIF_F_HW_VLAN_FILTER;
-       if (mdev->profile.num_lro)
-               dev->features |= NETIF_F_LRO;
+       dev->features |= NETIF_F_GRO;
        if (mdev->LSO_support) {
                dev->features |= NETIF_F_TSO;
                dev->features |= NETIF_F_TSO6;