Commit 2376c879 authored by Anish Bhatt's avatar Anish Bhatt Committed by David S. Miller

cxgb4 : Improve handling of DCB negotiation or loss thereof

Clear out any DCB apps we might have added to kernel table when we lose DCB
sync (or IEEE equivalent event). These were previously left behind and not
cleaned up correctly. IEEE allows individual components to work independently,
 so improve check for IEEE completion by specifying individual components.

Fixes: 10b00466 ("cxgb4: IEEE fixes for DCBx state machine")
Signed-off-by: default avatarAnish Bhatt <anish@chelsio.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5d26b1f5
...@@ -60,6 +60,42 @@ void cxgb4_dcb_version_init(struct net_device *dev) ...@@ -60,6 +60,42 @@ void cxgb4_dcb_version_init(struct net_device *dev)
dcb->dcb_version = FW_PORT_DCB_VER_AUTO; dcb->dcb_version = FW_PORT_DCB_VER_AUTO;
} }
static void cxgb4_dcb_cleanup_apps(struct net_device *dev)
{
struct port_info *pi = netdev2pinfo(dev);
struct adapter *adap = pi->adapter;
struct port_dcb_info *dcb = &pi->dcb;
struct dcb_app app;
int i, err;
/* zero priority implies remove */
app.priority = 0;
for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
/* Check if app list is exhausted */
if (!dcb->app_priority[i].protocolid)
break;
app.protocol = dcb->app_priority[i].protocolid;
if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE) {
app.selector = dcb->app_priority[i].sel_field + 1;
err = dcb_ieee_setapp(dev, &app);
} else {
app.selector = !!(dcb->app_priority[i].sel_field);
err = dcb_setapp(dev, &app);
}
if (err) {
dev_err(adap->pdev_dev,
"Failed DCB Clear %s Application Priority: sel=%d, prot=%d, , err=%d\n",
dcb_ver_array[dcb->dcb_version], app.selector,
app.protocol, -err);
break;
}
}
}
/* Finite State machine for Data Center Bridging. /* Finite State machine for Data Center Bridging.
*/ */
void cxgb4_dcb_state_fsm(struct net_device *dev, void cxgb4_dcb_state_fsm(struct net_device *dev,
...@@ -145,6 +181,7 @@ void cxgb4_dcb_state_fsm(struct net_device *dev, ...@@ -145,6 +181,7 @@ void cxgb4_dcb_state_fsm(struct net_device *dev,
* state. We need to reset back to a ground state * state. We need to reset back to a ground state
* of incomplete. * of incomplete.
*/ */
cxgb4_dcb_cleanup_apps(dev);
cxgb4_dcb_state_init(dev); cxgb4_dcb_state_init(dev);
dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE; dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE;
dcb->supported = CXGB4_DCBX_FW_SUPPORT; dcb->supported = CXGB4_DCBX_FW_SUPPORT;
...@@ -833,11 +870,16 @@ static int cxgb4_setapp(struct net_device *dev, u8 app_idtype, u16 app_id, ...@@ -833,11 +870,16 @@ static int cxgb4_setapp(struct net_device *dev, u8 app_idtype, u16 app_id,
/* Return whether IEEE Data Center Bridging has been negotiated. /* Return whether IEEE Data Center Bridging has been negotiated.
*/ */
static inline int cxgb4_ieee_negotiation_complete(struct net_device *dev) static inline int
cxgb4_ieee_negotiation_complete(struct net_device *dev,
enum cxgb4_dcb_fw_msgs dcb_subtype)
{ {
struct port_info *pi = netdev2pinfo(dev); struct port_info *pi = netdev2pinfo(dev);
struct port_dcb_info *dcb = &pi->dcb; struct port_dcb_info *dcb = &pi->dcb;
if (dcb_subtype && !(dcb->msgs & dcb_subtype))
return 0;
return (dcb->state == CXGB4_DCB_STATE_FW_ALLSYNCED && return (dcb->state == CXGB4_DCB_STATE_FW_ALLSYNCED &&
(dcb->supported & DCB_CAP_DCBX_VER_IEEE)); (dcb->supported & DCB_CAP_DCBX_VER_IEEE));
} }
...@@ -850,7 +892,7 @@ static int cxgb4_ieee_getapp(struct net_device *dev, struct dcb_app *app) ...@@ -850,7 +892,7 @@ static int cxgb4_ieee_getapp(struct net_device *dev, struct dcb_app *app)
{ {
int prio; int prio;
if (!cxgb4_ieee_negotiation_complete(dev)) if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID))
return -EINVAL; return -EINVAL;
if (!(app->selector && app->protocol)) if (!(app->selector && app->protocol))
return -EINVAL; return -EINVAL;
...@@ -872,7 +914,7 @@ static int cxgb4_ieee_setapp(struct net_device *dev, struct dcb_app *app) ...@@ -872,7 +914,7 @@ static int cxgb4_ieee_setapp(struct net_device *dev, struct dcb_app *app)
{ {
int ret; int ret;
if (!cxgb4_ieee_negotiation_complete(dev)) if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID))
return -EINVAL; return -EINVAL;
if (!(app->selector && app->protocol)) if (!(app->selector && app->protocol))
return -EINVAL; return -EINVAL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment