net: fix DCB setstate to return success/failure
authorDon Skidmore <donald.c.skidmore@intel.com>
Mon, 22 Dec 2008 04:09:50 +0000 (20:09 -0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 22 Dec 2008 04:09:50 +0000 (20:09 -0800)
Data Center Bridging (DCB) had no way to know if setstate had failed in the
driver.  This patch enables dcb netlink code to handle the status for the DCB
setstate interface.  Likewise it allows the driver to return a failed status
if MSI-X isn't enabled.

Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com>
Signed-off-by: Eric W Multanen <eric.w.multanen@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ixgbe/ixgbe_dcb_nl.c
include/net/dcbnl.h
net/dcb/dcbnl.c

index 615c2803202a3d829c6797f50999cf9deb685715..7d158a5c545bb2324fe83506c380207004a22436 100644 (file)
@@ -124,39 +124,45 @@ static u16 ixgbe_dcb_select_queue(struct net_device *dev, struct sk_buff *skb)
        return 0;
 }
 
-static void ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
+static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
 {
+       u8 err = 0;
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 
        DPRINTK(DRV, INFO, "Set DCB Admin Mode.\n");
 
        if (state > 0) {
                /* Turn on DCB */
-               if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
-                       return;
-               } else {
-                       if (netif_running(netdev))
-                               netdev->stop(netdev);
-                       ixgbe_reset_interrupt_capability(adapter);
-                       ixgbe_napi_del_all(adapter);
-                       kfree(adapter->tx_ring);
-                       kfree(adapter->rx_ring);
-                       adapter->tx_ring = NULL;
-                       adapter->rx_ring = NULL;
-                       netdev->select_queue = &ixgbe_dcb_select_queue;
+               if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
+                       goto out;
 
-                       adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
-                       adapter->flags |= IXGBE_FLAG_DCB_ENABLED;
-                       ixgbe_init_interrupt_scheme(adapter);
-                       ixgbe_napi_add_all(adapter);
-                       if (netif_running(netdev))
-                               netdev->open(netdev);
+               if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) {
+                       DPRINTK(DRV, ERR, "Enable failed, needs MSI-X\n");
+                       err = 1;
+                       goto out;
                }
+
+               if (netif_running(netdev))
+                       netdev->netdev_ops->ndo_stop(netdev);
+               ixgbe_reset_interrupt_capability(adapter);
+               ixgbe_napi_del_all(adapter);
+               kfree(adapter->tx_ring);
+               kfree(adapter->rx_ring);
+               adapter->tx_ring = NULL;
+               adapter->rx_ring = NULL;
+               netdev->select_queue = &ixgbe_dcb_select_queue;
+
+               adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
+               adapter->flags |= IXGBE_FLAG_DCB_ENABLED;
+               ixgbe_init_interrupt_scheme(adapter);
+               ixgbe_napi_add_all(adapter);
+               if (netif_running(netdev))
+                       netdev->netdev_ops->ndo_open(netdev);
        } else {
                /* Turn off DCB */
                if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
                        if (netif_running(netdev))
-                               netdev->stop(netdev);
+                               netdev->netdev_ops->ndo_stop(netdev);
                        ixgbe_reset_interrupt_capability(adapter);
                        ixgbe_napi_del_all(adapter);
                        kfree(adapter->tx_ring);
@@ -170,11 +176,11 @@ static void ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
                        ixgbe_init_interrupt_scheme(adapter);
                        ixgbe_napi_add_all(adapter);
                        if (netif_running(netdev))
-                               netdev->open(netdev);
-               } else {
-                       return;
+                               netdev->netdev_ops->ndo_open(netdev);
                }
        }
+out:
+       return err;
 }
 
 static void ixgbe_dcbnl_get_perm_hw_addr(struct net_device *netdev,
index 91e0a3d7faf236c1c0c3e54e0336dee366e74acb..775cfc8055bed122d9e54f30b83c186cccf3a185 100644 (file)
@@ -26,7 +26,7 @@
  */
 struct dcbnl_rtnl_ops {
        u8   (*getstate)(struct net_device *);
-       void (*setstate)(struct net_device *, u8);
+       u8   (*setstate)(struct net_device *, u8);
        void (*getpermhwaddr)(struct net_device *, u8 *);
        void (*setpgtccfgtx)(struct net_device *, int, u8, u8, u8, u8);
        void (*setpgbwgcfgtx)(struct net_device *, int, u8);
index a1254061629f55a1ed3b74cc0b0ac1848ecb9224..fc88fc4d4f63263f01c6d51295073273c11d7ae5 100644 (file)
@@ -714,9 +714,8 @@ static int dcbnl_setstate(struct net_device *netdev, struct nlattr **tb,
 
        value = nla_get_u8(tb[DCB_ATTR_STATE]);
 
-       netdev->dcbnl_ops->setstate(netdev, value);
-
-       ret = dcbnl_reply(0, RTM_SETDCB, DCB_CMD_SSTATE, DCB_ATTR_STATE,
+       ret = dcbnl_reply(netdev->dcbnl_ops->setstate(netdev, value),
+                         RTM_SETDCB, DCB_CMD_SSTATE, DCB_ATTR_STATE,
                          pid, seq, flags);
 
        return ret;