aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-10-27 19:00:16 -0400
committerDavid S. Miller <davem@davemloft.net>2014-10-27 19:00:16 -0400
commit8ae3c911b9efcca653c552a9c74957a6cb04a87d (patch)
treef204f4392da57af294b8dea0c1c32277ff260719
parent5d26b1f50a610fb28700cdc3446590495a5f607c (diff)
parent3bb062613b1ecbd0c388106f61344d699f7859ec (diff)
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>
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c55
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c6
2 files changed, 56 insertions, 5 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c
index 8edf0f5bd679..6fe300e316c3 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,
@@ -80,7 +116,6 @@ void cxgb4_dcb_state_fsm(struct net_device *dev,
80 /* we're going to use Host DCB */ 116 /* we're going to use Host DCB */
81 dcb->state = CXGB4_DCB_STATE_HOST; 117 dcb->state = CXGB4_DCB_STATE_HOST;
82 dcb->supported = CXGB4_DCBX_HOST_SUPPORT; 118 dcb->supported = CXGB4_DCBX_HOST_SUPPORT;
83 dcb->enabled = 1;
84 break; 119 break;
85 } 120 }
86 121
@@ -145,6 +180,7 @@ void cxgb4_dcb_state_fsm(struct net_device *dev,
145 * state. We need to reset back to a ground state 180 * state. We need to reset back to a ground state
146 * of incomplete. 181 * of incomplete.
147 */ 182 */
183 cxgb4_dcb_cleanup_apps(dev);
148 cxgb4_dcb_state_init(dev); 184 cxgb4_dcb_state_init(dev);
149 dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE; 185 dcb->state = CXGB4_DCB_STATE_FW_INCOMPLETE;
150 dcb->supported = CXGB4_DCBX_FW_SUPPORT; 186 dcb->supported = CXGB4_DCBX_FW_SUPPORT;
@@ -349,6 +385,12 @@ static u8 cxgb4_setstate(struct net_device *dev, u8 enabled)
349{ 385{
350 struct port_info *pi = netdev2pinfo(dev); 386 struct port_info *pi = netdev2pinfo(dev);
351 387
388 /* If DCBx is host-managed, dcb is enabled by outside lldp agents */
389 if (pi->dcb.state == CXGB4_DCB_STATE_HOST) {
390 pi->dcb.enabled = enabled;
391 return 0;
392 }
393
352 /* Firmware doesn't provide any mechanism to control the DCB state. 394 /* Firmware doesn't provide any mechanism to control the DCB state.
353 */ 395 */
354 if (enabled != (pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED)) 396 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,
833 875
834/* Return whether IEEE Data Center Bridging has been negotiated. 876/* Return whether IEEE Data Center Bridging has been negotiated.
835 */ 877 */
836static inline int cxgb4_ieee_negotiation_complete(struct net_device *dev) 878static inline int
879cxgb4_ieee_negotiation_complete(struct net_device *dev,
880 enum cxgb4_dcb_fw_msgs dcb_subtype)
837{ 881{
838 struct port_info *pi = netdev2pinfo(dev); 882 struct port_info *pi = netdev2pinfo(dev);
839 struct port_dcb_info *dcb = &pi->dcb; 883 struct port_dcb_info *dcb = &pi->dcb;
840 884
885 if (dcb_subtype && !(dcb->msgs & dcb_subtype))
886 return 0;
887
841 return (dcb->state == CXGB4_DCB_STATE_FW_ALLSYNCED && 888 return (dcb->state == CXGB4_DCB_STATE_FW_ALLSYNCED &&
842 (dcb->supported & DCB_CAP_DCBX_VER_IEEE)); 889 (dcb->supported & DCB_CAP_DCBX_VER_IEEE));
843} 890}
@@ -850,7 +897,7 @@ static int cxgb4_ieee_getapp(struct net_device *dev, struct dcb_app *app)
850{ 897{
851 int prio; 898 int prio;
852 899
853 if (!cxgb4_ieee_negotiation_complete(dev)) 900 if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID))
854 return -EINVAL; 901 return -EINVAL;
855 if (!(app->selector && app->protocol)) 902 if (!(app->selector && app->protocol))
856 return -EINVAL; 903 return -EINVAL;
@@ -872,7 +919,7 @@ static int cxgb4_ieee_setapp(struct net_device *dev, struct dcb_app *app)
872{ 919{
873 int ret; 920 int ret;
874 921
875 if (!cxgb4_ieee_negotiation_complete(dev)) 922 if (!cxgb4_ieee_negotiation_complete(dev, CXGB4_DCB_FW_APP_ID))
876 return -EINVAL; 923 return -EINVAL;
877 if (!(app->selector && app->protocol)) 924 if (!(app->selector && app->protocol))
878 return -EINVAL; 925 return -EINVAL;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 3f60070f2519..97683c1c5b69 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -694,7 +694,11 @@ int cxgb4_dcb_enabled(const struct net_device *dev)
694#ifdef CONFIG_CHELSIO_T4_DCB 694#ifdef CONFIG_CHELSIO_T4_DCB
695 struct port_info *pi = netdev_priv(dev); 695 struct port_info *pi = netdev_priv(dev);
696 696
697 return pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED; 697 if (!pi->dcb.enabled)
698 return 0;
699
700 return ((pi->dcb.state == CXGB4_DCB_STATE_FW_ALLSYNCED) ||
701 (pi->dcb.state == CXGB4_DCB_STATE_HOST));
698#else 702#else
699 return 0; 703 return 0;
700#endif 704#endif