Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[pandora-kernel.git] / drivers / net / bnx2x / bnx2x_dcb.c
index 9a24d79..410a49e 100644 (file)
@@ -1,6 +1,6 @@
 /* bnx2x_dcb.c: Broadcom Everest network driver.
  *
- * Copyright 2009-2010 Broadcom Corporation
+ * Copyright 2009-2011 Broadcom Corporation
  *
  * Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -485,6 +485,36 @@ static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp)
        }
 }
 
+#ifdef BCM_DCBNL
+static int bnx2x_dcbx_read_shmem_remote_mib(struct bnx2x *bp)
+{
+       struct lldp_remote_mib remote_mib = {0};
+       u32 dcbx_remote_mib_offset = SHMEM2_RD(bp, dcbx_remote_mib_offset);
+       int rc;
+
+       DP(NETIF_MSG_LINK, "dcbx_remote_mib_offset 0x%x\n",
+          dcbx_remote_mib_offset);
+
+       if (SHMEM_DCBX_REMOTE_MIB_NONE == dcbx_remote_mib_offset) {
+               BNX2X_ERR("FW doesn't support dcbx_remote_mib_offset\n");
+               return -EINVAL;
+       }
+
+       rc = bnx2x_dcbx_read_mib(bp, (u32 *)&remote_mib, dcbx_remote_mib_offset,
+                                DCBX_READ_REMOTE_MIB);
+
+       if (rc) {
+               BNX2X_ERR("Faild to read remote mib from FW\n");
+               return rc;
+       }
+
+       /* save features and flags */
+       bp->dcbx_remote_feat = remote_mib.features;
+       bp->dcbx_remote_flags = remote_mib.flags;
+       return 0;
+}
+#endif
+
 static int bnx2x_dcbx_read_shmem_neg_results(struct bnx2x *bp)
 {
        struct lldp_local_mib local_mib = {0};
@@ -571,6 +601,28 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state)
 {
        switch (state) {
        case BNX2X_DCBX_STATE_NEG_RECEIVED:
+#ifdef BCM_CNIC
+               if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD) {
+                       struct cnic_ops *c_ops;
+                       struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
+                       bp->flags |= NO_ISCSI_OOO_FLAG | NO_ISCSI_FLAG;
+                       cp->drv_state |= CNIC_DRV_STATE_NO_ISCSI_OOO;
+                       cp->drv_state |= CNIC_DRV_STATE_NO_ISCSI;
+
+                       rcu_read_lock();
+                       c_ops = rcu_dereference(bp->cnic_ops);
+                       if (c_ops) {
+                               bnx2x_cnic_notify(bp, CNIC_CTL_STOP_ISCSI_CMD);
+                               rcu_read_unlock();
+                               return;
+                       }
+                       rcu_read_unlock();
+               }
+
+               /* fall through if no CNIC initialized  */
+       case BNX2X_DCBX_STATE_ISCSI_STOPPED:
+#endif
+
                {
                        DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_NEG_RECEIVED\n");
 #ifdef BCM_DCBNL
@@ -579,6 +631,10 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state)
                         * negotiation results
                         */
                        bnx2x_dcbnl_update_applist(bp, true);
+
+                       /* Read rmeote mib if dcbx is in the FW */
+                       if (bnx2x_dcbx_read_shmem_remote_mib(bp))
+                               return;
 #endif
                        /* Read neg results if dcbx is in the FW */
                        if (bnx2x_dcbx_read_shmem_neg_results(bp))
@@ -1057,12 +1113,6 @@ static void bnx2x_dcbx_get_num_pg_traf_type(struct bnx2x *bp,
        }
 }
 
-
-/*******************************************************************************
- * Description: single priority group
- *
- * Return:
- ******************************************************************************/
 static void bnx2x_dcbx_ets_disabled_entry_data(struct bnx2x *bp,
                                               struct cos_help_data *cos_data,
                                               u32 pri_join_mask)
@@ -1075,11 +1125,6 @@ static void bnx2x_dcbx_ets_disabled_entry_data(struct bnx2x *bp,
        cos_data->num_of_cos = 1;
 }
 
-/*******************************************************************************
- * Description: updating the cos bw
- *
- * Return:
- ******************************************************************************/
 static inline void bnx2x_dcbx_add_to_cos_bw(struct bnx2x *bp,
                                            struct cos_entry_help_data *data,
                                            u8 pg_bw)
@@ -1090,11 +1135,6 @@ static inline void bnx2x_dcbx_add_to_cos_bw(struct bnx2x *bp,
                data->cos_bw += pg_bw;
 }
 
-/*******************************************************************************
- * Description: single priority group
- *
- * Return:
- ******************************************************************************/
 static void bnx2x_dcbx_separate_pauseable_from_non(struct bnx2x *bp,
                        struct cos_help_data *cos_data,
                        u32 *pg_pri_orginal_spread,
@@ -1347,11 +1387,6 @@ static void bnx2x_dcbx_two_pg_to_cos_params(
        }
 }
 
-/*******************************************************************************
- * Description: Still
- *
- * Return:
- ******************************************************************************/
 static void bnx2x_dcbx_three_pg_to_cos_params(
                              struct bnx2x              *bp,
                              struct pg_help_data       *pg_help_data,
@@ -1539,11 +1574,6 @@ static void bnx2x_dcbx_get_ets_pri_pg_tbl(struct bnx2x *bp,
        }
 }
 
-/*******************************************************************************
- * Description: Fill pfc_config struct that will be sent in DCBX start ramrod
- *
- * Return:
- ******************************************************************************/
 static void bnx2x_pfc_fw_struct_e2(struct bnx2x *bp)
 {
        struct flow_control_configuration   *pfc_fw_cfg = NULL;
@@ -2035,7 +2065,6 @@ static u8 bnx2x_dcbnl_set_dcbx(struct net_device *netdev, u8 state)
        return 0;
 }
 
-
 static u8 bnx2x_dcbnl_get_featcfg(struct net_device *netdev, int featid,
                                  u8 *flags)
 {
@@ -2115,31 +2144,100 @@ static u8 bnx2x_dcbnl_set_featcfg(struct net_device *netdev, int featid,
        return rval;
 }
 
+static int bnx2x_peer_appinfo(struct net_device *netdev,
+                             struct dcb_peer_app_info *info, u16* app_count)
+{
+       int i;
+       struct bnx2x *bp = netdev_priv(netdev);
+
+       DP(NETIF_MSG_LINK, "APP-INFO\n");
+
+       info->willing = (bp->dcbx_remote_flags & DCBX_APP_REM_WILLING) ?: 0;
+       info->error = (bp->dcbx_remote_flags & DCBX_APP_RX_ERROR) ?: 0;
+       *app_count = 0;
+
+       for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++)
+               if (bp->dcbx_remote_feat.app.app_pri_tbl[i].appBitfield &
+                   DCBX_APP_ENTRY_VALID)
+                       (*app_count)++;
+       return 0;
+}
+
+static int bnx2x_peer_apptable(struct net_device *netdev,
+                              struct dcb_app *table)
+{
+       int i, j;
+       struct bnx2x *bp = netdev_priv(netdev);
+
+       DP(NETIF_MSG_LINK, "APP-TABLE\n");
+
+       for (i = 0, j = 0; i < DCBX_MAX_APP_PROTOCOL; i++) {
+               struct dcbx_app_priority_entry *ent =
+                       &bp->dcbx_remote_feat.app.app_pri_tbl[i];
+
+               if (ent->appBitfield & DCBX_APP_ENTRY_VALID) {
+                       table[j].selector = bnx2x_dcbx_dcbnl_app_idtype(ent);
+                       table[j].priority = bnx2x_dcbx_dcbnl_app_up(ent);
+                       table[j++].protocol = ent->app_id;
+               }
+       }
+       return 0;
+}
+
+static int bnx2x_cee_peer_getpg(struct net_device *netdev, struct cee_pg *pg)
+{
+       int i;
+       struct bnx2x *bp = netdev_priv(netdev);
+
+       pg->willing = (bp->dcbx_remote_flags & DCBX_ETS_REM_WILLING) ?: 0;
+
+       for (i = 0; i < CEE_DCBX_MAX_PGS; i++) {
+               pg->pg_bw[i] =
+                       DCBX_PG_BW_GET(bp->dcbx_remote_feat.ets.pg_bw_tbl, i);
+               pg->prio_pg[i] =
+                       DCBX_PRI_PG_GET(bp->dcbx_remote_feat.ets.pri_pg_tbl, i);
+       }
+       return 0;
+}
+
+static int bnx2x_cee_peer_getpfc(struct net_device *netdev,
+                                struct cee_pfc *pfc)
+{
+       struct bnx2x *bp = netdev_priv(netdev);
+       pfc->tcs_supported = bp->dcbx_remote_feat.pfc.pfc_caps;
+       pfc->pfc_en = bp->dcbx_remote_feat.pfc.pri_en_bitmap;
+       return 0;
+}
+
 const struct dcbnl_rtnl_ops bnx2x_dcbnl_ops = {
-       .getstate       = bnx2x_dcbnl_get_state,
-       .setstate       = bnx2x_dcbnl_set_state,
-       .getpermhwaddr  = bnx2x_dcbnl_get_perm_hw_addr,
-       .setpgtccfgtx   = bnx2x_dcbnl_set_pg_tccfg_tx,
-       .setpgbwgcfgtx  = bnx2x_dcbnl_set_pg_bwgcfg_tx,
-       .setpgtccfgrx   = bnx2x_dcbnl_set_pg_tccfg_rx,
-       .setpgbwgcfgrx  = bnx2x_dcbnl_set_pg_bwgcfg_rx,
-       .getpgtccfgtx   = bnx2x_dcbnl_get_pg_tccfg_tx,
-       .getpgbwgcfgtx  = bnx2x_dcbnl_get_pg_bwgcfg_tx,
-       .getpgtccfgrx   = bnx2x_dcbnl_get_pg_tccfg_rx,
-       .getpgbwgcfgrx  = bnx2x_dcbnl_get_pg_bwgcfg_rx,
-       .setpfccfg      = bnx2x_dcbnl_set_pfc_cfg,
-       .getpfccfg      = bnx2x_dcbnl_get_pfc_cfg,
-       .setall         = bnx2x_dcbnl_set_all,
-       .getcap         = bnx2x_dcbnl_get_cap,
-       .getnumtcs      = bnx2x_dcbnl_get_numtcs,
-       .setnumtcs      = bnx2x_dcbnl_set_numtcs,
-       .getpfcstate    = bnx2x_dcbnl_get_pfc_state,
-       .setpfcstate    = bnx2x_dcbnl_set_pfc_state,
-       .setapp         = bnx2x_dcbnl_set_app_up,
-       .getdcbx        = bnx2x_dcbnl_get_dcbx,
-       .setdcbx        = bnx2x_dcbnl_set_dcbx,
-       .getfeatcfg     = bnx2x_dcbnl_get_featcfg,
-       .setfeatcfg     = bnx2x_dcbnl_set_featcfg,
+       .getstate               = bnx2x_dcbnl_get_state,
+       .setstate               = bnx2x_dcbnl_set_state,
+       .getpermhwaddr          = bnx2x_dcbnl_get_perm_hw_addr,
+       .setpgtccfgtx           = bnx2x_dcbnl_set_pg_tccfg_tx,
+       .setpgbwgcfgtx          = bnx2x_dcbnl_set_pg_bwgcfg_tx,
+       .setpgtccfgrx           = bnx2x_dcbnl_set_pg_tccfg_rx,
+       .setpgbwgcfgrx          = bnx2x_dcbnl_set_pg_bwgcfg_rx,
+       .getpgtccfgtx           = bnx2x_dcbnl_get_pg_tccfg_tx,
+       .getpgbwgcfgtx          = bnx2x_dcbnl_get_pg_bwgcfg_tx,
+       .getpgtccfgrx           = bnx2x_dcbnl_get_pg_tccfg_rx,
+       .getpgbwgcfgrx          = bnx2x_dcbnl_get_pg_bwgcfg_rx,
+       .setpfccfg              = bnx2x_dcbnl_set_pfc_cfg,
+       .getpfccfg              = bnx2x_dcbnl_get_pfc_cfg,
+       .setall                 = bnx2x_dcbnl_set_all,
+       .getcap                 = bnx2x_dcbnl_get_cap,
+       .getnumtcs              = bnx2x_dcbnl_get_numtcs,
+       .setnumtcs              = bnx2x_dcbnl_set_numtcs,
+       .getpfcstate            = bnx2x_dcbnl_get_pfc_state,
+       .setpfcstate            = bnx2x_dcbnl_set_pfc_state,
+       .setapp                 = bnx2x_dcbnl_set_app_up,
+       .getdcbx                = bnx2x_dcbnl_get_dcbx,
+       .setdcbx                = bnx2x_dcbnl_set_dcbx,
+       .getfeatcfg             = bnx2x_dcbnl_get_featcfg,
+       .setfeatcfg             = bnx2x_dcbnl_set_featcfg,
+       .peer_getappinfo        = bnx2x_peer_appinfo,
+       .peer_getapptable       = bnx2x_peer_apptable,
+       .cee_peer_getpg         = bnx2x_cee_peer_getpg,
+       .cee_peer_getpfc        = bnx2x_cee_peer_getpfc,
 };
 
 #endif /* BCM_DCBNL */