diff options
Diffstat (limited to 'drivers/net/bnx2x/bnx2x_dcb.c')
-rw-r--r-- | drivers/net/bnx2x/bnx2x_dcb.c | 202 |
1 files changed, 150 insertions, 52 deletions
diff --git a/drivers/net/bnx2x/bnx2x_dcb.c b/drivers/net/bnx2x/bnx2x_dcb.c index 9a24d79c71d..410a49e571a 100644 --- a/drivers/net/bnx2x/bnx2x_dcb.c +++ b/drivers/net/bnx2x/bnx2x_dcb.c @@ -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 */ |