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 */  |