aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnish Bhatt <anish@chelsio.com>2014-10-23 17:37:30 -0400
committerDavid S. Miller <davem@davemloft.net>2014-10-27 19:00:09 -0400
commit2376c879b80c83424a3013834be97fb9fe2d4180 (patch)
tree65c9c7eec3c7fcea5a001ffd031619bda7f92d1a
parent5d26b1f50a610fb28700cdc3446590495a5f607c (diff)
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: 10b0046685ab ("cxgb4: IEEE fixes for DCBx state machine") Signed-off-by: Anish Bhatt <anish@chelsio.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c48
1 files changed, 45 insertions, 3 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c
index 8edf0f5bd679..ee819fd12bd2 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c
@@ -60,6 +60,42 @@ void cxgb4_dcb_version_init(struct net_device *dev)
60 dcb->dcb_version = FW_PORT_DCB_VER_AUTO; 60 dcb->dcb_version = FW_PORT_DCB_VER_AUTO;
61} 61}
62 62
63static void cxgb4_dcb_cleanup_apps(struct net_device *dev)
64{
65 struct port_info *pi = netdev2pinfo(dev);
66 struct adapter *adap = pi->adapter;
67 struct port_dcb_info *dcb = &pi->dcb;
68 struct dcb_app app;
69 int i, err;
70
71 /* zero priority implies remove */
72 app.priority = 0;
73
74 for (i = 0; i < CXGB4_MAX_DCBX_APP_SUPPORTED; i++) {
75 /* Check if app list is exhausted */
76 if (!dcb->app_priority[i].protocolid)
77 break;
78
79 app.protocol = dcb->app_priority[i].protocolid;
80
81 if (dcb->dcb_version == FW_PORT_DCB_VER_IEEE) {
82 app.selector = dcb->app_priority[i].sel_field + 1;
83 err = dcb_ieee_setapp(dev, &app);
84 } else {
85 app.selector = !!(dcb->app_priority[i].sel_field);
86 err = dcb_setapp(dev, &app);
87 }
88
89 if (err) {
90 dev_err(adap->pdev_dev,
91 "Failed DCB Clear %s Application Priority: sel=%d, prot=%d, , err=%d\n",
92 dcb_ver_array[dcb->dcb_version], app.selector,
93 app.protocol, -err);
94 break;
95 }
96 }
97}
98
63/* Finite State machine for Data Center Bridging. 99/* Finite State machine for Data Center Bridging.
64 */ 100 */
65void cxgb4_dcb_state_fsm(struct net_device *dev, 101void cxgb4_dcb_state_fsm(struct net_device *dev,
@@ -145,6 +181,7 @@ void cxgb4_dcb_state_fsm(struct net_device *dev,
145 * state. We need to reset back to a ground state 181 * state. We need to reset back to a ground state
146 * of incomplete. 182 * of incomplete.
147 */ 183 */
184 cxgb4_dcb_cleanup_apps(dev);
148 cxgb4_dcb_state_init(dev); 185 cxgb4_dcb_state_init(dev);
149 dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE; 186 dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE;
150 dcb->supported = CXGB4_DCBX_FW_SUPPORT; 187 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 870
834/* Return whether IEEE Data Center Bridging has been negotiated. 871/* Return whether IEEE Data Center Bridging has been negotiated.
835 */ 872 */
836static inline int cxgb4_ieee_negotiation_complete(struct net_device *dev) 873static inline int
874cxgb4_ieee_negotiation_complete(struct net_device *dev,
875 enum cxgb4_dcb_fw_msgs dcb_subtype)
837{ 876{
838 struct port_info *pi = netdev2pinfo(dev); 877 struct port_info *pi = netdev2pinfo(dev);
839 struct port_dcb_info *dcb = &pi->dcb; 878 struct port_dcb_info *dcb = &pi->dcb;
840 879
880 if (dcb_subtype && !(dcb->msgs & dcb_subtype))
881 return 0;
882
841 return (dcb->state == CXGB4_DCB_STATE_FW_ALLSYNCED && 883 return (dcb->state == CXGB4_DCB_STATE_FW_ALLSYNCED &&
842 (dcb->supported & DCB_CAP_DCBX_VER_IEEE)); 884 (dcb->supported & DCB_CAP_DCBX_VER_IEEE));
843} 885}
@@ -850,7 +892,7 @@ static int cxgb4_ieee_getapp(struct net_device *dev, struct dcb_app *app)
850{ 892{
851 int prio; 893 int prio;
852 894
853 if (!cxgb4_ieee_negotiation_complete(dev)) 895 if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID))
854 return -EINVAL; 896 return -EINVAL;
855 if (!(app->selector && app->protocol)) 897 if (!(app->selector && app->protocol))
856 return -EINVAL; 898 return -EINVAL;
@@ -872,7 +914,7 @@ static int cxgb4_ieee_setapp(struct net_device *dev, struct dcb_app *app)
872{ 914{
873 int ret; 915 int ret;
874 916
875 if (!cxgb4_ieee_negotiation_complete(dev)) 917 if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID))
876 return -EINVAL; 918 return -EINVAL;
877 if (!(app->selector && app->protocol)) 919 if (!(app->selector && app->protocol))
878 return -EINVAL; 920 return -EINVAL;