mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
Merge branch 'cxgb4-net'
Anish Bhatt says: ==================== cxgb4 : DCBx fixes for apps/host lldp agents This patchset contains some minor fixes for cxgb4 DCBx code. Chiefly, cxgb4 was not cleaning up any apps added to kernel app table when link was lost. Disabling DCBx in firmware would automatically set DCBx state to host-managed and enabled, we now wait for an explicit enable call from an lldp agent instead First patch was originally sent to net-next, but considering it applies to correcting behaviour of code already in net, I think it qualifies as a bug fix. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
8ae3c911b9
2 changed files with 56 additions and 5 deletions
|
@ -60,6 +60,42 @@ void cxgb4_dcb_version_init(struct net_device *dev)
|
|||
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.
|
||||
*/
|
||||
void cxgb4_dcb_state_fsm(struct net_device *dev,
|
||||
|
@ -80,7 +116,6 @@ void cxgb4_dcb_state_fsm(struct net_device *dev,
|
|||
/* we're going to use Host DCB */
|
||||
dcb->state = CXGB4_DCB_STATE_HOST;
|
||||
dcb->supported = CXGB4_DCBX_HOST_SUPPORT;
|
||||
dcb->enabled = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -145,6 +180,7 @@ void cxgb4_dcb_state_fsm(struct net_device *dev,
|
|||
* state. We need to reset back to a ground state
|
||||
* of incomplete.
|
||||
*/
|
||||
cxgb4_dcb_cleanup_apps(dev);
|
||||
cxgb4_dcb_state_init(dev);
|
||||
dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE;
|
||||
dcb->supported = CXGB4_DCBX_FW_SUPPORT;
|
||||
|
@ -349,6 +385,12 @@ static u8 cxgb4_setstate(struct net_device *dev, u8 enabled)
|
|||
{
|
||||
struct port_info *pi = netdev2pinfo(dev);
|
||||
|
||||
/* If DCBx is host-managed, dcb is enabled by outside lldp agents */
|
||||
if (pi->dcb.state == CXGB4_DCB_STATE_HOST) {
|
||||
pi->dcb.enabled = enabled;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Firmware doesn't provide any mechanism to control the DCB state.
|
||||
*/
|
||||
if (enabled != (pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED))
|
||||
|
@ -833,11 +875,16 @@ static int cxgb4_setapp(struct net_device *dev, u8 app_idtype, u16 app_id,
|
|||
|
||||
/* 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_dcb_info *dcb = &pi->dcb;
|
||||
|
||||
if (dcb_subtype && !(dcb->msgs & dcb_subtype))
|
||||
return 0;
|
||||
|
||||
return (dcb->state == CXGB4_DCB_STATE_FW_ALLSYNCED &&
|
||||
(dcb->supported & DCB_CAP_DCBX_VER_IEEE));
|
||||
}
|
||||
|
@ -850,7 +897,7 @@ static int cxgb4_ieee_getapp(struct net_device *dev, struct dcb_app *app)
|
|||
{
|
||||
int prio;
|
||||
|
||||
if (!cxgb4_ieee_negotiation_complete(dev))
|
||||
if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID))
|
||||
return -EINVAL;
|
||||
if (!(app->selector && app->protocol))
|
||||
return -EINVAL;
|
||||
|
@ -872,7 +919,7 @@ static int cxgb4_ieee_setapp(struct net_device *dev, struct dcb_app *app)
|
|||
{
|
||||
int ret;
|
||||
|
||||
if (!cxgb4_ieee_negotiation_complete(dev))
|
||||
if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID))
|
||||
return -EINVAL;
|
||||
if (!(app->selector && app->protocol))
|
||||
return -EINVAL;
|
||||
|
|
|
@ -694,7 +694,11 @@ int cxgb4_dcb_enabled(const struct net_device *dev)
|
|||
#ifdef CONFIG_CHELSIO_T4_DCB
|
||||
struct port_info *pi = netdev_priv(dev);
|
||||
|
||||
return pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED;
|
||||
if (!pi->dcb.enabled)
|
||||
return 0;
|
||||
|
||||
return ((pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED) ||
|
||||
(pi->dcb.state == CXGB4_DCB_STATE_HOST));
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue