qlcnic: fix memory leaks
[safe/jmp/linux-2.6] / drivers / net / ixgbe / ixgbe_dcb_nl.c
index e05c62a..71da325 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2009 Intel Corporation.
+  Copyright(c) 1999 - 2010 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -36,6 +36,7 @@
 #define BIT_PFC                0x02
 #define BIT_PG_RX      0x04
 #define BIT_PG_TX      0x08
+#define BIT_APP_UPCHG  0x10
 #define BIT_RESETLINK   0x40
 #define BIT_LINKSPEED   0x80
 
@@ -222,7 +223,7 @@ static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id,
 
        if (adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] !=
            adapter->dcb_cfg.bw_percentage[0][bwg_id]) {
-               adapter->dcb_set_bitmap |= BIT_PG_RX;
+               adapter->dcb_set_bitmap |= BIT_PG_TX;
                adapter->dcb_set_bitmap |= BIT_RESETLINK;
        }
 }
@@ -340,6 +341,12 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
        if (!adapter->dcb_set_bitmap)
                return DCB_NO_HW_CHG;
 
+       ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg,
+                                adapter->ring_feature[RING_F_DCB].indices);
+
+       if (ret)
+               return DCB_NO_HW_CHG;
+
        /*
         * Only take down the adapter if the configuration change
         * requires a reset.
@@ -348,16 +355,14 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
                while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
                        msleep(1);
 
-               if (netif_running(netdev))
-                       ixgbe_down(adapter);
-       }
-
-       ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg,
-                                adapter->ring_feature[RING_F_DCB].indices);
-       if (ret) {
-               if (adapter->dcb_set_bitmap & BIT_RESETLINK)
-                       clear_bit(__IXGBE_RESETTING, &adapter->state);
-               return DCB_NO_HW_CHG;
+               if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) {
+                       if (netif_running(netdev))
+                               netdev->netdev_ops->ndo_stop(netdev);
+                       ixgbe_clear_interrupt_scheme(adapter);
+               } else {
+                       if (netif_running(netdev))
+                               ixgbe_down(adapter);
+               }
        }
 
        if (adapter->dcb_cfg.pfc_mode_enable) {
@@ -373,8 +378,14 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
        }
 
        if (adapter->dcb_set_bitmap & BIT_RESETLINK) {
-               if (netif_running(netdev))
-                       ixgbe_up(adapter);
+               if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) {
+                       ixgbe_init_interrupt_scheme(adapter);
+                       if (netif_running(netdev))
+                               netdev->netdev_ops->ndo_open(netdev);
+               } else {
+                       if (netif_running(netdev))
+                               ixgbe_up(adapter);
+               }
                ret = DCB_HW_CHG_RST;
        } else if (adapter->dcb_set_bitmap & BIT_PFC) {
                if (adapter->hw.mac.type == ixgbe_mac_82598EB)
@@ -477,10 +488,79 @@ static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state)
        if (adapter->temp_dcb_cfg.pfc_mode_enable !=
                adapter->dcb_cfg.pfc_mode_enable)
                adapter->dcb_set_bitmap |= BIT_PFC;
-       return;
 }
 
-struct dcbnl_rtnl_ops dcbnl_ops = {
+/**
+ * ixgbe_dcbnl_getapp - retrieve the DCBX application user priority
+ * @netdev : the corresponding netdev
+ * @idtype : identifies the id as ether type or TCP/UDP port number
+ * @id: id is either ether type or TCP/UDP port number
+ *
+ * Returns : on success, returns a non-zero 802.1p user priority bitmap
+ * otherwise returns 0 as the invalid user priority bitmap to indicate an
+ * error.
+ */
+static u8 ixgbe_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id)
+{
+       u8 rval = 0;
+
+       switch (idtype) {
+       case DCB_APP_IDTYPE_ETHTYPE:
+#ifdef IXGBE_FCOE
+               if (id == ETH_P_FCOE)
+                       rval = ixgbe_fcoe_getapp(netdev_priv(netdev));
+#endif
+               break;
+       case DCB_APP_IDTYPE_PORTNUM:
+               break;
+       default:
+               break;
+       }
+       return rval;
+}
+
+/**
+ * ixgbe_dcbnl_setapp - set the DCBX application user priority
+ * @netdev : the corresponding netdev
+ * @idtype : identifies the id as ether type or TCP/UDP port number
+ * @id: id is either ether type or TCP/UDP port number
+ * @up: the 802.1p user priority bitmap
+ *
+ * Returns : 0 on success or 1 on error
+ */
+static u8 ixgbe_dcbnl_setapp(struct net_device *netdev,
+                             u8 idtype, u16 id, u8 up)
+{
+       u8 rval = 1;
+
+       switch (idtype) {
+       case DCB_APP_IDTYPE_ETHTYPE:
+#ifdef IXGBE_FCOE
+               if (id == ETH_P_FCOE) {
+                       u8 tc;
+                       struct ixgbe_adapter *adapter;
+
+                       adapter = netdev_priv(netdev);
+                       tc = adapter->fcoe.tc;
+                       rval = ixgbe_fcoe_setapp(adapter, up);
+                       if ((!rval) && (tc != adapter->fcoe.tc) &&
+                           (adapter->flags & IXGBE_FLAG_DCB_ENABLED) &&
+                           (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) {
+                               adapter->dcb_set_bitmap |= BIT_APP_UPCHG;
+                               adapter->dcb_set_bitmap |= BIT_RESETLINK;
+                       }
+               }
+#endif
+               break;
+       case DCB_APP_IDTYPE_PORTNUM:
+               break;
+       default:
+               break;
+       }
+       return rval;
+}
+
+const struct dcbnl_rtnl_ops dcbnl_ops = {
        .getstate       = ixgbe_dcbnl_get_state,
        .setstate       = ixgbe_dcbnl_set_state,
        .getpermhwaddr  = ixgbe_dcbnl_get_perm_hw_addr,
@@ -500,5 +580,7 @@ struct dcbnl_rtnl_ops dcbnl_ops = {
        .setnumtcs      = ixgbe_dcbnl_setnumtcs,
        .getpfcstate    = ixgbe_dcbnl_getpfcstate,
        .setpfcstate    = ixgbe_dcbnl_setpfcstate,
+       .getapp         = ixgbe_dcbnl_getapp,
+       .setapp         = ixgbe_dcbnl_setapp,
 };