Skip to content

Commit

Permalink
bnx2x: use dcb_setapp to manage negotiated application tlvs
Browse files Browse the repository at this point in the history
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: Shmulik Ravid <shmulikr@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Shmulik Ravid authored and David S. Miller committed Feb 28, 2011
1 parent ff938e4 commit 9850767
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 59 deletions.
2 changes: 1 addition & 1 deletion drivers/net/bnx2x/bnx2x.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#define BNX2X_NEW_NAPI

#if defined(CONFIG_DCB)
#define BCM_DCB
#define BCM_DCBNL
#endif
#if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE)
#define BCM_CNIC 1
Expand Down
137 changes: 82 additions & 55 deletions drivers/net/bnx2x/bnx2x_dcb.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
#include <linux/netdevice.h>
#include <linux/types.h>
#include <linux/errno.h>
#ifdef BCM_DCBNL
#include <linux/dcbnl.h>
#endif

#include "bnx2x.h"
#include "bnx2x_cmn.h"
Expand Down Expand Up @@ -508,13 +511,75 @@ static int bnx2x_dcbx_read_shmem_neg_results(struct bnx2x *bp)
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)
{
switch (state) {
case BNX2X_DCBX_STATE_NEG_RECEIVED:
{
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 */
if (bnx2x_dcbx_read_shmem_neg_results(bp))
return;
Expand All @@ -526,10 +591,24 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state)
bp->dcbx_error);

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);
return;
}
/* 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:
DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_TX_PAUSED\n");
Expand Down Expand Up @@ -1505,8 +1584,7 @@ static void bnx2x_pfc_fw_struct_e2(struct bnx2x *bp)
bnx2x_dcbx_print_cos_params(bp, pfc_fw_cfg);
}
/* DCB netlink */
#ifdef BCM_DCB
#include <linux/dcbnl.h>
#ifdef BCM_DCBNL

#define BNX2X_DCBX_CAPS (DCB_CAP_DCBX_LLD_MANAGED | \
DCB_CAP_DCBX_VER_CEE | DCB_CAP_DCBX_STATIC)
Expand Down Expand Up @@ -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);
}

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(
struct bnx2x_admin_priority_app_table *app_ent,
u8 idtype, u16 idval, u8 up)
Expand Down Expand 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);
}

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)
{
struct bnx2x *bp = netdev_priv(netdev);
Expand Down Expand Up @@ -2107,12 +2135,11 @@ const struct dcbnl_rtnl_ops bnx2x_dcbnl_ops = {
.setnumtcs = bnx2x_dcbnl_set_numtcs,
.getpfcstate = bnx2x_dcbnl_get_pfc_state,
.setpfcstate = bnx2x_dcbnl_set_pfc_state,
.getapp = bnx2x_dcbnl_get_app_up,
.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,
};

#endif /* BCM_DCB */
#endif /* BCM_DCBNL */
5 changes: 3 additions & 2 deletions drivers/net/bnx2x/bnx2x_dcb.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,9 @@ enum {
void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state);

/* DCB netlink */
#ifdef BCM_DCB
#ifdef BCM_DCBNL
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 */
7 changes: 6 additions & 1 deletion drivers/net/bnx2x/bnx2x_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_TSO6;

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

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

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

unregister_netdev(dev);

/* Delete all NAPI objects */
Expand Down

0 comments on commit 9850767

Please sign in to comment.