Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 98507672 authored by Shmulik Ravid's avatar Shmulik Ravid Committed by David S. Miller
Browse files

bnx2x: use dcb_setapp to manage negotiated application tlvs



With this patch the bnx2x uses the generic dcbnl application tlv list
instead of implementing its own get-app handler. When the driver is
alerted to a change in the DCB negotiated parameters, it calls
dcb_setapp to update the dcbnl application tlvs list making it available
to user mode applications and registered notifiers.   

Signed-off-by: default avatarShmulik Ravid <shmulikr@broadcom.com>
Signed-off-by: default avatarEilon Greenstein <eilong@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ff938e43
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -31,7 +31,7 @@
#define BNX2X_NEW_NAPI
#define BNX2X_NEW_NAPI


#if defined(CONFIG_DCB)
#if defined(CONFIG_DCB)
#define BCM_DCB
#define BCM_DCBNL
#endif
#endif
#if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE)
#if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE)
#define BCM_CNIC 1
#define BCM_CNIC 1
+82 −55
Original line number Original line Diff line number Diff line
@@ -19,6 +19,9 @@
#include <linux/netdevice.h>
#include <linux/netdevice.h>
#include <linux/types.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/errno.h>
#ifdef BCM_DCBNL
#include <linux/dcbnl.h>
#endif


#include "bnx2x.h"
#include "bnx2x.h"
#include "bnx2x_cmn.h"
#include "bnx2x_cmn.h"
@@ -508,13 +511,75 @@ static int bnx2x_dcbx_read_shmem_neg_results(struct bnx2x *bp)
	return 0;
	return 0;
}
}



#ifdef BCM_DCBNL
static inline
u8 bnx2x_dcbx_dcbnl_app_up(struct dcbx_app_priority_entry *ent)
{
	u8 pri;

	/* Choose the highest priority */
	for (pri = MAX_PFC_PRIORITIES - 1; pri > 0; pri--)
		if (ent->pri_bitmap & (1 << pri))
			break;
	return pri;
}

static inline
u8 bnx2x_dcbx_dcbnl_app_idtype(struct dcbx_app_priority_entry *ent)
{
	return ((ent->appBitfield & DCBX_APP_ENTRY_SF_MASK) ==
		DCBX_APP_SF_PORT) ? DCB_APP_IDTYPE_PORTNUM :
		DCB_APP_IDTYPE_ETHTYPE;
}

static inline
void bnx2x_dcbx_invalidate_local_apps(struct bnx2x *bp)
{
	int i;
	for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++)
		bp->dcbx_local_feat.app.app_pri_tbl[i].appBitfield &=
							~DCBX_APP_ENTRY_VALID;
}

int bnx2x_dcbnl_update_applist(struct bnx2x *bp, bool delall)
{
	int i, err = 0;

	for (i = 0; i < DCBX_MAX_APP_PROTOCOL && err == 0; i++) {
		struct dcbx_app_priority_entry *ent =
			&bp->dcbx_local_feat.app.app_pri_tbl[i];

		if (ent->appBitfield & DCBX_APP_ENTRY_VALID) {
			u8 up = bnx2x_dcbx_dcbnl_app_up(ent);

			/* avoid invalid user-priority */
			if (up) {
				struct dcb_app app;
				app.selector = bnx2x_dcbx_dcbnl_app_idtype(ent);
				app.protocol = ent->app_id;
				app.priority = delall ? 0 : up;
				err = dcb_setapp(bp->dev, &app);
			}
		}
	}
	return err;
}
#endif

void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state)
void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state)
{
{
	switch (state) {
	switch (state) {
	case BNX2X_DCBX_STATE_NEG_RECEIVED:
	case BNX2X_DCBX_STATE_NEG_RECEIVED:
		{
		{
			DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_NEG_RECEIVED\n");
			DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_NEG_RECEIVED\n");

#ifdef BCM_DCBNL
			/**
			 * Delete app tlvs from dcbnl before reading new
			 * negotiation results
			 */
			bnx2x_dcbnl_update_applist(bp, true);
#endif
			/* Read neg results if dcbx is in the FW */
			/* Read neg results if dcbx is in the FW */
			if (bnx2x_dcbx_read_shmem_neg_results(bp))
			if (bnx2x_dcbx_read_shmem_neg_results(bp))
				return;
				return;
@@ -526,10 +591,24 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state)
						 bp->dcbx_error);
						 bp->dcbx_error);


			if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD) {
			if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD) {
#ifdef BCM_DCBNL
				/**
				 * Add new app tlvs to dcbnl
				 */
				bnx2x_dcbnl_update_applist(bp, false);
#endif
				bnx2x_dcbx_stop_hw_tx(bp);
				bnx2x_dcbx_stop_hw_tx(bp);
				return;
				return;
			}
			}
			/* fall through */
			/* fall through */
#ifdef BCM_DCBNL
			/**
			 * Invalidate the local app tlvs if they are not added
			 * to the dcbnl app list to avoid deleting them from
			 * the list later on
			 */
			bnx2x_dcbx_invalidate_local_apps(bp);
#endif
		}
		}
	case BNX2X_DCBX_STATE_TX_PAUSED:
	case BNX2X_DCBX_STATE_TX_PAUSED:
		DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_TX_PAUSED\n");
		DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_TX_PAUSED\n");
@@ -1505,8 +1584,7 @@ static void bnx2x_pfc_fw_struct_e2(struct bnx2x *bp)
	bnx2x_dcbx_print_cos_params(bp,	pfc_fw_cfg);
	bnx2x_dcbx_print_cos_params(bp,	pfc_fw_cfg);
}
}
/* DCB netlink */
/* DCB netlink */
#ifdef BCM_DCB
#ifdef BCM_DCBNL
#include <linux/dcbnl.h>


#define BNX2X_DCBX_CAPS		(DCB_CAP_DCBX_LLD_MANAGED | \
#define BNX2X_DCBX_CAPS		(DCB_CAP_DCBX_LLD_MANAGED | \
				DCB_CAP_DCBX_VER_CEE | DCB_CAP_DCBX_STATIC)
				DCB_CAP_DCBX_VER_CEE | DCB_CAP_DCBX_STATIC)
@@ -1816,32 +1894,6 @@ static void bnx2x_dcbnl_set_pfc_state(struct net_device *netdev, u8 state)
	bp->dcbx_config_params.admin_pfc_enable = (state ? 1 : 0);
	bp->dcbx_config_params.admin_pfc_enable = (state ? 1 : 0);
}
}


static bool bnx2x_app_is_equal(struct dcbx_app_priority_entry *app_ent,
			       u8 idtype, u16 idval)
{
	if (!(app_ent->appBitfield & DCBX_APP_ENTRY_VALID))
		return false;

	switch (idtype) {
	case DCB_APP_IDTYPE_ETHTYPE:
		if ((app_ent->appBitfield & DCBX_APP_ENTRY_SF_MASK) !=
			DCBX_APP_SF_ETH_TYPE)
			return false;
		break;
	case DCB_APP_IDTYPE_PORTNUM:
		if ((app_ent->appBitfield & DCBX_APP_ENTRY_SF_MASK) !=
			DCBX_APP_SF_PORT)
			return false;
		break;
	default:
		return false;
	}
	if (app_ent->app_id != idval)
		return false;

	return true;
}

static void bnx2x_admin_app_set_ent(
static void bnx2x_admin_app_set_ent(
	struct bnx2x_admin_priority_app_table *app_ent,
	struct bnx2x_admin_priority_app_table *app_ent,
	u8 idtype, u16 idval, u8 up)
	u8 idtype, u16 idval, u8 up)
@@ -1943,30 +1995,6 @@ static u8 bnx2x_dcbnl_set_app_up(struct net_device *netdev, u8 idtype,
	return bnx2x_set_admin_app_up(bp, idtype, idval, up);
	return bnx2x_set_admin_app_up(bp, idtype, idval, up);
}
}


static u8 bnx2x_dcbnl_get_app_up(struct net_device *netdev, u8 idtype,
				 u16 idval)
{
	int i;
	u8 up = 0;

	struct bnx2x *bp = netdev_priv(netdev);
	DP(NETIF_MSG_LINK, "app_type %d, app_id 0x%x\n", idtype, idval);

	/* iterate over the app entries looking for idtype and idval */
	for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++)
		if (bnx2x_app_is_equal(&bp->dcbx_local_feat.app.app_pri_tbl[i],
				       idtype, idval))
			break;

	if (i < DCBX_MAX_APP_PROTOCOL)
		/* if found return up */
		up = bp->dcbx_local_feat.app.app_pri_tbl[i].pri_bitmap;
	else
		DP(NETIF_MSG_LINK, "app not found\n");

	return up;
}

static u8 bnx2x_dcbnl_get_dcbx(struct net_device *netdev)
static u8 bnx2x_dcbnl_get_dcbx(struct net_device *netdev)
{
{
	struct bnx2x *bp = netdev_priv(netdev);
	struct bnx2x *bp = netdev_priv(netdev);
@@ -2107,7 +2135,6 @@ const struct dcbnl_rtnl_ops bnx2x_dcbnl_ops = {
	.setnumtcs      = bnx2x_dcbnl_set_numtcs,
	.setnumtcs      = bnx2x_dcbnl_set_numtcs,
	.getpfcstate    = bnx2x_dcbnl_get_pfc_state,
	.getpfcstate    = bnx2x_dcbnl_get_pfc_state,
	.setpfcstate    = bnx2x_dcbnl_set_pfc_state,
	.setpfcstate    = bnx2x_dcbnl_set_pfc_state,
	.getapp         = bnx2x_dcbnl_get_app_up,
	.setapp         = bnx2x_dcbnl_set_app_up,
	.setapp         = bnx2x_dcbnl_set_app_up,
	.getdcbx        = bnx2x_dcbnl_get_dcbx,
	.getdcbx        = bnx2x_dcbnl_get_dcbx,
	.setdcbx        = bnx2x_dcbnl_set_dcbx,
	.setdcbx        = bnx2x_dcbnl_set_dcbx,
@@ -2115,4 +2142,4 @@ const struct dcbnl_rtnl_ops bnx2x_dcbnl_ops = {
	.setfeatcfg     = bnx2x_dcbnl_set_featcfg,
	.setfeatcfg     = bnx2x_dcbnl_set_featcfg,
};
};


#endif /* BCM_DCB */
#endif /* BCM_DCBNL */
+3 −2
Original line number Original line Diff line number Diff line
@@ -189,8 +189,9 @@ enum {
void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state);
void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state);


/* DCB netlink */
/* DCB netlink */
#ifdef BCM_DCB
#ifdef BCM_DCBNL
extern const struct dcbnl_rtnl_ops bnx2x_dcbnl_ops;
extern const struct dcbnl_rtnl_ops bnx2x_dcbnl_ops;
#endif /* BCM_DCB */
int bnx2x_dcbnl_update_applist(struct bnx2x *bp, bool delall);
#endif /* BCM_DCBNL */


#endif /* BNX2X_DCB_H */
#endif /* BNX2X_DCB_H */
+6 −1
Original line number Original line Diff line number Diff line
@@ -9441,7 +9441,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,
	dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
	dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
	dev->vlan_features |= NETIF_F_TSO6;
	dev->vlan_features |= NETIF_F_TSO6;


#ifdef BCM_DCB
#ifdef BCM_DCBNL
	dev->dcbnl_ops = &bnx2x_dcbnl_ops;
	dev->dcbnl_ops = &bnx2x_dcbnl_ops;
#endif
#endif


@@ -9848,6 +9848,11 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev)
	}
	}
#endif
#endif


#ifdef BCM_DCBNL
	/* Delete app tlvs from dcbnl */
	bnx2x_dcbnl_update_applist(bp, true);
#endif

	unregister_netdev(dev);
	unregister_netdev(dev);


	/* Delete all NAPI objects */
	/* Delete all NAPI objects */