aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x
diff options
context:
space:
mode:
authorDmitry Kravkov <dmitry@broadcom.com>2011-07-18 21:42:04 -0400
committerDavid S. Miller <davem@davemloft.net>2011-07-19 12:57:48 -0400
commit6debea870a66be4aac2e28be0e3952dad6c7fcdb (patch)
tree60bf7bed2d6350ada4f0802f6d59d73c2ca6b372 /drivers/net/bnx2x
parentf13ac41f5165c0ac0441f9d42f7d6f6f9ee7c075 (diff)
bnx2x: DCB rework
create DCB related states in function state-machine allow handling of DCB errors from FW allow disablement of DCB in FW, when peer disappears or error clean up unused functions/variables as pointed by David Binderman <dcb314@hotmail.com> Reported-by: David Binderman <dcb314@hotmail.com> Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x')
-rw-r--r--drivers/net/bnx2x/bnx2x.h7
-rw-r--r--drivers/net/bnx2x/bnx2x_dcb.c171
-rw-r--r--drivers/net/bnx2x/bnx2x_hsi.h1
-rw-r--r--drivers/net/bnx2x/bnx2x_main.c98
-rw-r--r--drivers/net/bnx2x/bnx2x_sp.c90
-rw-r--r--drivers/net/bnx2x/bnx2x_sp.h13
6 files changed, 268 insertions, 112 deletions
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index 53fa8ea983e9..333f5d6c6b81 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -966,6 +966,8 @@ struct bnx2x_slowpath {
966 966
967 union { 967 union {
968 struct function_start_data func_start; 968 struct function_start_data func_start;
969 /* pfc configuration for DCBX ramrod */
970 struct flow_control_configuration pfc_config;
969 } func_rdata; 971 } func_rdata;
970 972
971 /* used by dmae command executer */ 973 /* used by dmae command executer */
@@ -980,8 +982,6 @@ struct bnx2x_slowpath {
980 982
981 u32 wb_comp; 983 u32 wb_comp;
982 u32 wb_data[4]; 984 u32 wb_data[4];
983 /* pfc configuration for DCBX ramrod */
984 struct flow_control_configuration pfc_config;
985}; 985};
986 986
987#define bnx2x_sp(bp, var) (&bp->slowpath->var) 987#define bnx2x_sp(bp, var) (&bp->slowpath->var)
@@ -1417,9 +1417,6 @@ struct bnx2x {
1417 char fw_ver[32]; 1417 char fw_ver[32];
1418 const struct firmware *firmware; 1418 const struct firmware *firmware;
1419 1419
1420 /* LLDP params */
1421 struct bnx2x_config_lldp_params lldp_config_params;
1422
1423 /* DCB support on/off */ 1420 /* DCB support on/off */
1424 u16 dcb_state; 1421 u16 dcb_state;
1425#define BNX2X_DCB_STATE_OFF 0 1422#define BNX2X_DCB_STATE_OFF 0
diff --git a/drivers/net/bnx2x/bnx2x_dcb.c b/drivers/net/bnx2x/bnx2x_dcb.c
index 3bfba44961d3..d028794a2298 100644
--- a/drivers/net/bnx2x/bnx2x_dcb.c
+++ b/drivers/net/bnx2x/bnx2x_dcb.c
@@ -29,10 +29,10 @@
29#endif 29#endif
30 30
31/* forward declarations of dcbx related functions */ 31/* forward declarations of dcbx related functions */
32static void bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp); 32static int bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp);
33static void bnx2x_pfc_set_pfc(struct bnx2x *bp); 33static void bnx2x_pfc_set_pfc(struct bnx2x *bp);
34static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp); 34static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp);
35static void bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp); 35static int bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp);
36static void bnx2x_dcbx_get_ets_pri_pg_tbl(struct bnx2x *bp, 36static void bnx2x_dcbx_get_ets_pri_pg_tbl(struct bnx2x *bp,
37 u32 *set_configuration_ets_pg, 37 u32 *set_configuration_ets_pg,
38 u32 *pri_pg_tbl); 38 u32 *pri_pg_tbl);
@@ -47,8 +47,25 @@ static void bnx2x_dcbx_separate_pauseable_from_non(struct bnx2x *bp,
47 struct cos_help_data *cos_data, 47 struct cos_help_data *cos_data,
48 u32 *pg_pri_orginal_spread, 48 u32 *pg_pri_orginal_spread,
49 struct dcbx_ets_feature *ets); 49 struct dcbx_ets_feature *ets);
50static void bnx2x_dcbx_fw_struct(struct bnx2x *bp); 50static void bnx2x_dcbx_fw_struct(struct bnx2x *bp,
51 struct bnx2x_func_tx_start_params*);
51 52
53/* helpers: read/write len bytes from addr into buff by REG_RD/REG_WR */
54static void bnx2x_read_data(struct bnx2x *bp, u32 *buff,
55 u32 addr, u32 len)
56{
57 int i;
58 for (i = 0; i < len; i += 4, buff++)
59 *buff = REG_RD(bp, addr + i);
60}
61
62static void bnx2x_write_data(struct bnx2x *bp, u32 *buff,
63 u32 addr, u32 len)
64{
65 int i;
66 for (i = 0; i < len; i += 4, buff++)
67 REG_WR(bp, addr + i, *buff);
68}
52 69
53static void bnx2x_pfc_set(struct bnx2x *bp) 70static void bnx2x_pfc_set(struct bnx2x *bp)
54{ 71{
@@ -205,7 +222,11 @@ static void bnx2x_dcbx_get_ap_feature(struct bnx2x *bp,
205 if (GET_FLAGS(error, DCBX_LOCAL_APP_ERROR)) 222 if (GET_FLAGS(error, DCBX_LOCAL_APP_ERROR))
206 DP(NETIF_MSG_LINK, "DCBX_LOCAL_APP_ERROR\n"); 223 DP(NETIF_MSG_LINK, "DCBX_LOCAL_APP_ERROR\n");
207 224
208 if (app->enabled && !GET_FLAGS(error, DCBX_LOCAL_APP_ERROR)) { 225 if (GET_FLAGS(error, DCBX_LOCAL_APP_MISMATCH))
226 DP(NETIF_MSG_LINK, "DCBX_LOCAL_APP_MISMATCH\n");
227
228 if (app->enabled &&
229 !GET_FLAGS(error, DCBX_LOCAL_APP_ERROR | DCBX_LOCAL_APP_MISMATCH)) {
209 230
210 bp->dcbx_port_params.app.enabled = true; 231 bp->dcbx_port_params.app.enabled = true;
211 232
@@ -300,7 +321,7 @@ static void bnx2x_dcbx_get_pfc_feature(struct bnx2x *bp,
300 DP(NETIF_MSG_LINK, "DCBX_LOCAL_PFC_ERROR\n"); 321 DP(NETIF_MSG_LINK, "DCBX_LOCAL_PFC_ERROR\n");
301 322
302 if (bp->dcbx_port_params.app.enabled && 323 if (bp->dcbx_port_params.app.enabled &&
303 !GET_FLAGS(error, DCBX_LOCAL_PFC_ERROR) && 324 !GET_FLAGS(error, DCBX_LOCAL_PFC_ERROR | DCBX_LOCAL_PFC_MISMATCH) &&
304 pfc->enabled) { 325 pfc->enabled) {
305 bp->dcbx_port_params.pfc.enabled = true; 326 bp->dcbx_port_params.pfc.enabled = true;
306 bp->dcbx_port_params.pfc.priority_non_pauseable_mask = 327 bp->dcbx_port_params.pfc.priority_non_pauseable_mask =
@@ -329,8 +350,8 @@ static int bnx2x_dcbx_read_mib(struct bnx2x *bp,
329 u32 offset, 350 u32 offset,
330 int read_mib_type) 351 int read_mib_type)
331{ 352{
332 int max_try_read = 0, i; 353 int max_try_read = 0;
333 u32 *buff, mib_size, prefix_seq_num, suffix_seq_num; 354 u32 mib_size, prefix_seq_num, suffix_seq_num;
334 struct lldp_remote_mib *remote_mib ; 355 struct lldp_remote_mib *remote_mib ;
335 struct lldp_local_mib *local_mib; 356 struct lldp_local_mib *local_mib;
336 357
@@ -349,9 +370,7 @@ static int bnx2x_dcbx_read_mib(struct bnx2x *bp,
349 offset += BP_PORT(bp) * mib_size; 370 offset += BP_PORT(bp) * mib_size;
350 371
351 do { 372 do {
352 buff = base_mib_addr; 373 bnx2x_read_data(bp, base_mib_addr, offset, mib_size);
353 for (i = 0; i < mib_size; i += 4, buff++)
354 *buff = REG_RD(bp, offset + i);
355 374
356 max_try_read++; 375 max_try_read++;
357 376
@@ -382,12 +401,8 @@ static int bnx2x_dcbx_read_mib(struct bnx2x *bp,
382 401
383static void bnx2x_pfc_set_pfc(struct bnx2x *bp) 402static void bnx2x_pfc_set_pfc(struct bnx2x *bp)
384{ 403{
385 if (BP_PORT(bp)) { 404 if (bp->dcbx_port_params.pfc.enabled &&
386 BNX2X_ERR("4 port mode is not supported"); 405 !(bp->dcbx_error & DCBX_REMOTE_MIB_ERROR))
387 return;
388 }
389
390 if (bp->dcbx_port_params.pfc.enabled)
391 /* 406 /*
392 * 1. Fills up common PFC structures if required 407 * 1. Fills up common PFC structures if required
393 * 2. Configure NIG, MAC and BRB via the elink 408 * 2. Configure NIG, MAC and BRB via the elink
@@ -397,25 +412,30 @@ static void bnx2x_pfc_set_pfc(struct bnx2x *bp)
397 bnx2x_pfc_clear(bp); 412 bnx2x_pfc_clear(bp);
398} 413}
399 414
400static void bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp) 415static int bnx2x_dcbx_stop_hw_tx(struct bnx2x *bp)
401{ 416{
402 DP(NETIF_MSG_LINK, "sending STOP TRAFFIC\n"); 417 struct bnx2x_func_state_params func_params = {0};
403 bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_STOP_TRAFFIC, 418
404 0 /* connectionless */, 419 func_params.f_obj = &bp->func_obj;
405 0 /* dataHi is zero */, 420 func_params.cmd = BNX2X_F_CMD_TX_STOP;
406 0 /* dataLo is zero */, 421
407 NONE_CONNECTION_TYPE); 422 DP(NETIF_MSG_LINK, "STOP TRAFFIC\n");
423 return bnx2x_func_state_change(bp, &func_params);
408} 424}
409 425
410static void bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp) 426static int bnx2x_dcbx_resume_hw_tx(struct bnx2x *bp)
411{ 427{
412 bnx2x_dcbx_fw_struct(bp); 428 struct bnx2x_func_state_params func_params = {0};
413 DP(NETIF_MSG_LINK, "sending START TRAFFIC\n"); 429 struct bnx2x_func_tx_start_params *tx_params =
414 bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_START_TRAFFIC, 430 &func_params.params.tx_start;
415 0, /* connectionless */ 431
416 U64_HI(bnx2x_sp_mapping(bp, pfc_config)), 432 func_params.f_obj = &bp->func_obj;
417 U64_LO(bnx2x_sp_mapping(bp, pfc_config)), 433 func_params.cmd = BNX2X_F_CMD_TX_START;
418 NONE_CONNECTION_TYPE); 434
435 bnx2x_dcbx_fw_struct(bp, tx_params);
436
437 DP(NETIF_MSG_LINK, "START TRAFFIC\n");
438 return bnx2x_func_state_change(bp, &func_params);
419} 439}
420 440
421static void bnx2x_dcbx_2cos_limit_update_ets_config(struct bnx2x *bp) 441static void bnx2x_dcbx_2cos_limit_update_ets_config(struct bnx2x *bp)
@@ -522,7 +542,8 @@ static void bnx2x_dcbx_update_ets_params(struct bnx2x *bp)
522{ 542{
523 bnx2x_ets_disabled(&bp->link_params, &bp->link_vars); 543 bnx2x_ets_disabled(&bp->link_params, &bp->link_vars);
524 544
525 if (!bp->dcbx_port_params.ets.enabled) 545 if (!bp->dcbx_port_params.ets.enabled ||
546 (bp->dcbx_error & DCBX_REMOTE_MIB_ERROR))
526 return; 547 return;
527 548
528 if (CHIP_IS_E3B0(bp)) 549 if (CHIP_IS_E3B0(bp))
@@ -739,61 +760,14 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state)
739 } 760 }
740} 761}
741 762
742
743#define LLDP_STATS_OFFSET(bp) (BP_PORT(bp)*\
744 sizeof(struct lldp_dcbx_stat))
745
746/* calculate struct offset in array according to chip information */
747#define LLDP_PARAMS_OFFSET(bp) (BP_PORT(bp)*sizeof(struct lldp_params))
748
749#define LLDP_ADMIN_MIB_OFFSET(bp) (PORT_MAX*sizeof(struct lldp_params) + \ 763#define LLDP_ADMIN_MIB_OFFSET(bp) (PORT_MAX*sizeof(struct lldp_params) + \
750 BP_PORT(bp)*sizeof(struct lldp_admin_mib)) 764 BP_PORT(bp)*sizeof(struct lldp_admin_mib))
751 765
752static void bnx2x_dcbx_lldp_updated_params(struct bnx2x *bp,
753 u32 dcbx_lldp_params_offset)
754{
755 struct lldp_params lldp_params = {0};
756 u32 i = 0, *buff = NULL;
757 u32 offset = dcbx_lldp_params_offset + LLDP_PARAMS_OFFSET(bp);
758
759 DP(NETIF_MSG_LINK, "lldp_offset 0x%x\n", offset);
760
761 if ((bp->lldp_config_params.overwrite_settings ==
762 BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE)) {
763 /* Read the data first */
764 buff = (u32 *)&lldp_params;
765 for (i = 0; i < sizeof(struct lldp_params); i += 4, buff++)
766 *buff = REG_RD(bp, (offset + i));
767
768 lldp_params.msg_tx_hold =
769 (u8)bp->lldp_config_params.msg_tx_hold;
770 lldp_params.msg_fast_tx_interval =
771 (u8)bp->lldp_config_params.msg_fast_tx;
772 lldp_params.tx_crd_max =
773 (u8)bp->lldp_config_params.tx_credit_max;
774 lldp_params.msg_tx_interval =
775 (u8)bp->lldp_config_params.msg_tx_interval;
776 lldp_params.tx_fast =
777 (u8)bp->lldp_config_params.tx_fast;
778
779 /* Write the data.*/
780 buff = (u32 *)&lldp_params;
781 for (i = 0; i < sizeof(struct lldp_params); i += 4, buff++)
782 REG_WR(bp, (offset + i) , *buff);
783
784
785 } else if (BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE ==
786 bp->lldp_config_params.overwrite_settings)
787 bp->lldp_config_params.overwrite_settings =
788 BNX2X_DCBX_OVERWRITE_SETTINGS_INVALID;
789}
790
791static void bnx2x_dcbx_admin_mib_updated_params(struct bnx2x *bp, 766static void bnx2x_dcbx_admin_mib_updated_params(struct bnx2x *bp,
792 u32 dcbx_lldp_params_offset) 767 u32 dcbx_lldp_params_offset)
793{ 768{
794 struct lldp_admin_mib admin_mib; 769 struct lldp_admin_mib admin_mib;
795 u32 i, other_traf_type = PREDEFINED_APP_IDX_MAX, traf_type = 0; 770 u32 i, other_traf_type = PREDEFINED_APP_IDX_MAX, traf_type = 0;
796 u32 *buff;
797 u32 offset = dcbx_lldp_params_offset + LLDP_ADMIN_MIB_OFFSET(bp); 771 u32 offset = dcbx_lldp_params_offset + LLDP_ADMIN_MIB_OFFSET(bp);
798 772
799 /*shortcuts*/ 773 /*shortcuts*/
@@ -801,18 +775,18 @@ static void bnx2x_dcbx_admin_mib_updated_params(struct bnx2x *bp,
801 struct bnx2x_config_dcbx_params *dp = &bp->dcbx_config_params; 775 struct bnx2x_config_dcbx_params *dp = &bp->dcbx_config_params;
802 776
803 memset(&admin_mib, 0, sizeof(struct lldp_admin_mib)); 777 memset(&admin_mib, 0, sizeof(struct lldp_admin_mib));
804 buff = (u32 *)&admin_mib; 778
805 /* Read the data first */ 779 /* Read the data first */
806 for (i = 0; i < sizeof(struct lldp_admin_mib); i += 4, buff++) 780 bnx2x_read_data(bp, (u32 *)&admin_mib, offset,
807 *buff = REG_RD(bp, (offset + i)); 781 sizeof(struct lldp_admin_mib));
808 782
809 if (bp->dcbx_enabled == BNX2X_DCBX_ENABLED_ON_NEG_ON) 783 if (bp->dcbx_enabled == BNX2X_DCBX_ENABLED_ON_NEG_ON)
810 SET_FLAGS(admin_mib.ver_cfg_flags, DCBX_DCBX_ENABLED); 784 SET_FLAGS(admin_mib.ver_cfg_flags, DCBX_DCBX_ENABLED);
811 else 785 else
812 RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_DCBX_ENABLED); 786 RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_DCBX_ENABLED);
813 787
814 if ((BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE == 788 if (dp->overwrite_settings == BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE) {
815 dp->overwrite_settings)) { 789
816 RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_CEE_VERSION_MASK); 790 RESET_FLAGS(admin_mib.ver_cfg_flags, DCBX_CEE_VERSION_MASK);
817 admin_mib.ver_cfg_flags |= 791 admin_mib.ver_cfg_flags |=
818 (dp->admin_dcbx_version << DCBX_CEE_VERSION_SHIFT) & 792 (dp->admin_dcbx_version << DCBX_CEE_VERSION_SHIFT) &
@@ -908,19 +882,17 @@ static void bnx2x_dcbx_admin_mib_updated_params(struct bnx2x *bp,
908 882
909 af->app.default_pri = (u8)dp->admin_default_priority; 883 af->app.default_pri = (u8)dp->admin_default_priority;
910 884
911 } else if (BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE == 885 }
912 dp->overwrite_settings)
913 dp->overwrite_settings = BNX2X_DCBX_OVERWRITE_SETTINGS_INVALID;
914 886
915 /* Write the data. */ 887 /* Write the data. */
916 buff = (u32 *)&admin_mib; 888 bnx2x_write_data(bp, (u32 *)&admin_mib, offset,
917 for (i = 0; i < sizeof(struct lldp_admin_mib); i += 4, buff++) 889 sizeof(struct lldp_admin_mib));
918 REG_WR(bp, (offset + i), *buff); 890
919} 891}
920 892
921void bnx2x_dcbx_set_state(struct bnx2x *bp, bool dcb_on, u32 dcbx_enabled) 893void bnx2x_dcbx_set_state(struct bnx2x *bp, bool dcb_on, u32 dcbx_enabled)
922{ 894{
923 if (!CHIP_IS_E1x(bp) && !CHIP_MODE_IS_4_PORT(bp)) { 895 if (!CHIP_IS_E1x(bp)) {
924 bp->dcb_state = dcb_on; 896 bp->dcb_state = dcb_on;
925 bp->dcbx_enabled = dcbx_enabled; 897 bp->dcbx_enabled = dcbx_enabled;
926 } else { 898 } else {
@@ -1029,9 +1001,6 @@ void bnx2x_dcbx_init(struct bnx2x *bp)
1029 bnx2x_update_drv_flags(bp, DRV_FLAGS_DCB_CONFIGURED, 0); 1001 bnx2x_update_drv_flags(bp, DRV_FLAGS_DCB_CONFIGURED, 0);
1030 1002
1031 if (SHMEM_LLDP_DCBX_PARAMS_NONE != dcbx_lldp_params_offset) { 1003 if (SHMEM_LLDP_DCBX_PARAMS_NONE != dcbx_lldp_params_offset) {
1032 bnx2x_dcbx_lldp_updated_params(bp,
1033 dcbx_lldp_params_offset);
1034
1035 bnx2x_dcbx_admin_mib_updated_params(bp, 1004 bnx2x_dcbx_admin_mib_updated_params(bp,
1036 dcbx_lldp_params_offset); 1005 dcbx_lldp_params_offset);
1037 1006
@@ -1043,7 +1012,7 @@ void bnx2x_dcbx_init(struct bnx2x *bp)
1043} 1012}
1044static void 1013static void
1045bnx2x_dcbx_print_cos_params(struct bnx2x *bp, 1014bnx2x_dcbx_print_cos_params(struct bnx2x *bp,
1046 struct flow_control_configuration *pfc_fw_cfg) 1015 struct bnx2x_func_tx_start_params *pfc_fw_cfg)
1047{ 1016{
1048 u8 pri = 0; 1017 u8 pri = 0;
1049 u8 cos = 0; 1018 u8 cos = 0;
@@ -1821,17 +1790,19 @@ static void bnx2x_dcbx_get_ets_pri_pg_tbl(struct bnx2x *bp,
1821 } 1790 }
1822} 1791}
1823 1792
1824static void bnx2x_dcbx_fw_struct(struct bnx2x *bp) 1793static void bnx2x_dcbx_fw_struct(struct bnx2x *bp,
1794 struct bnx2x_func_tx_start_params *pfc_fw_cfg)
1825{ 1795{
1826 struct flow_control_configuration *pfc_fw_cfg = NULL;
1827 u16 pri_bit = 0; 1796 u16 pri_bit = 0;
1828 u8 cos = 0, pri = 0; 1797 u8 cos = 0, pri = 0;
1829 struct priority_cos *tt2cos; 1798 struct priority_cos *tt2cos;
1830 u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority; 1799 u32 *ttp = bp->dcbx_port_params.app.traffic_type_priority;
1831 1800
1832 pfc_fw_cfg = (struct flow_control_configuration *) 1801 memset(pfc_fw_cfg, 0, sizeof(*pfc_fw_cfg));
1833 bnx2x_sp(bp, pfc_config); 1802
1834 memset(pfc_fw_cfg, 0, sizeof(struct flow_control_configuration)); 1803 /* to disable DCB - the structure must be zeroed */
1804 if (bp->dcbx_error & DCBX_REMOTE_MIB_ERROR)
1805 return;
1835 1806
1836 /*shortcut*/ 1807 /*shortcut*/
1837 tt2cos = pfc_fw_cfg->traffic_type_to_priority_cos; 1808 tt2cos = pfc_fw_cfg->traffic_type_to_priority_cos;
diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h
index ce3b5662ca5a..06727f32e505 100644
--- a/drivers/net/bnx2x/bnx2x_hsi.h
+++ b/drivers/net/bnx2x/bnx2x_hsi.h
@@ -1834,6 +1834,7 @@ struct lldp_local_mib {
1834 #define DCBX_LOCAL_APP_ERROR 0x00000004 1834 #define DCBX_LOCAL_APP_ERROR 0x00000004
1835 #define DCBX_LOCAL_PFC_MISMATCH 0x00000010 1835 #define DCBX_LOCAL_PFC_MISMATCH 0x00000010
1836 #define DCBX_LOCAL_APP_MISMATCH 0x00000020 1836 #define DCBX_LOCAL_APP_MISMATCH 0x00000020
1837 #define DCBX_REMOTE_MIB_ERROR 0x00000040
1837 struct dcbx_features features; 1838 struct dcbx_features features;
1838 u32 suffix_seq_num; 1839 u32 suffix_seq_num;
1839}; 1840};
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index 8a374a77cdc9..a86517cffd4a 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -4403,11 +4403,17 @@ static void bnx2x_eq_int(struct bnx2x *bp)
4403 4403
4404 case EVENT_RING_OPCODE_STOP_TRAFFIC: 4404 case EVENT_RING_OPCODE_STOP_TRAFFIC:
4405 DP(NETIF_MSG_IFUP, "got STOP TRAFFIC\n"); 4405 DP(NETIF_MSG_IFUP, "got STOP TRAFFIC\n");
4406 if (f_obj->complete_cmd(bp, f_obj,
4407 BNX2X_F_CMD_TX_STOP))
4408 break;
4406 bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_PAUSED); 4409 bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_PAUSED);
4407 goto next_spqe; 4410 goto next_spqe;
4408 4411
4409 case EVENT_RING_OPCODE_START_TRAFFIC: 4412 case EVENT_RING_OPCODE_START_TRAFFIC:
4410 DP(NETIF_MSG_IFUP, "got START TRAFFIC\n"); 4413 DP(NETIF_MSG_IFUP, "got START TRAFFIC\n");
4414 if (f_obj->complete_cmd(bp, f_obj,
4415 BNX2X_F_CMD_TX_START))
4416 break;
4411 bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_RELEASED); 4417 bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_TX_RELEASED);
4412 goto next_spqe; 4418 goto next_spqe;
4413 case EVENT_RING_OPCODE_FUNCTION_START: 4419 case EVENT_RING_OPCODE_FUNCTION_START:
@@ -7536,6 +7542,71 @@ void bnx2x_send_unload_done(struct bnx2x *bp)
7536 bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); 7542 bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0);
7537} 7543}
7538 7544
7545static inline int bnx2x_func_wait_started(struct bnx2x *bp)
7546{
7547 int tout = 50;
7548 int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
7549
7550 if (!bp->port.pmf)
7551 return 0;
7552
7553 /*
7554 * (assumption: No Attention from MCP at this stage)
7555 * PMF probably in the middle of TXdisable/enable transaction
7556 * 1. Sync IRS for default SB
7557 * 2. Sync SP queue - this guarantes us that attention handling started
7558 * 3. Wait, that TXdisable/enable transaction completes
7559 *
7560 * 1+2 guranty that if DCBx attention was scheduled it already changed
7561 * pending bit of transaction from STARTED-->TX_STOPPED, if we alredy
7562 * received complettion for the transaction the state is TX_STOPPED.
7563 * State will return to STARTED after completion of TX_STOPPED-->STARTED
7564 * transaction.
7565 */
7566
7567 /* make sure default SB ISR is done */
7568 if (msix)
7569 synchronize_irq(bp->msix_table[0].vector);
7570 else
7571 synchronize_irq(bp->pdev->irq);
7572
7573 flush_workqueue(bnx2x_wq);
7574
7575 while (bnx2x_func_get_state(bp, &bp->func_obj) !=
7576 BNX2X_F_STATE_STARTED && tout--)
7577 msleep(20);
7578
7579 if (bnx2x_func_get_state(bp, &bp->func_obj) !=
7580 BNX2X_F_STATE_STARTED) {
7581#ifdef BNX2X_STOP_ON_ERROR
7582 return -EBUSY;
7583#else
7584 /*
7585 * Failed to complete the transaction in a "good way"
7586 * Force both transactions with CLR bit
7587 */
7588 struct bnx2x_func_state_params func_params = {0};
7589
7590 DP(BNX2X_MSG_SP, "Hmmm... unexpected function state! "
7591 "Forcing STARTED-->TX_ST0PPED-->STARTED\n");
7592
7593 func_params.f_obj = &bp->func_obj;
7594 __set_bit(RAMROD_DRV_CLR_ONLY,
7595 &func_params.ramrod_flags);
7596
7597 /* STARTED-->TX_ST0PPED */
7598 func_params.cmd = BNX2X_F_CMD_TX_STOP;
7599 bnx2x_func_state_change(bp, &func_params);
7600
7601 /* TX_ST0PPED-->STARTED */
7602 func_params.cmd = BNX2X_F_CMD_TX_START;
7603 return bnx2x_func_state_change(bp, &func_params);
7604#endif
7605 }
7606
7607 return 0;
7608}
7609
7539void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) 7610void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode)
7540{ 7611{
7541 int port = BP_PORT(bp); 7612 int port = BP_PORT(bp);
@@ -7595,6 +7666,26 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode)
7595 netif_addr_unlock_bh(bp->dev); 7666 netif_addr_unlock_bh(bp->dev);
7596 7667
7597 7668
7669
7670 /*
7671 * Send the UNLOAD_REQUEST to the MCP. This will return if
7672 * this function should perform FUNC, PORT or COMMON HW
7673 * reset.
7674 */
7675 reset_code = bnx2x_send_unload_req(bp, unload_mode);
7676
7677 /*
7678 * (assumption: No Attention from MCP at this stage)
7679 * PMF probably in the middle of TXdisable/enable transaction
7680 */
7681 rc = bnx2x_func_wait_started(bp);
7682 if (rc) {
7683 BNX2X_ERR("bnx2x_func_wait_started failed\n");
7684#ifdef BNX2X_STOP_ON_ERROR
7685 return;
7686#endif
7687 }
7688
7598 /* Close multi and leading connections 7689 /* Close multi and leading connections
7599 * Completions for ramrods are collected in a synchronous way 7690 * Completions for ramrods are collected in a synchronous way
7600 */ 7691 */
@@ -7622,13 +7713,6 @@ unload_error:
7622#endif 7713#endif
7623 } 7714 }
7624 7715
7625 /*
7626 * Send the UNLOAD_REQUEST to the MCP. This will return if
7627 * this function should perform FUNC, PORT or COMMON HW
7628 * reset.
7629 */
7630 reset_code = bnx2x_send_unload_req(bp, unload_mode);
7631
7632 /* Disable HW interrupts, NAPI */ 7716 /* Disable HW interrupts, NAPI */
7633 bnx2x_netif_stop(bp, 1); 7717 bnx2x_netif_stop(bp, 1);
7634 7718
diff --git a/drivers/net/bnx2x/bnx2x_sp.c b/drivers/net/bnx2x/bnx2x_sp.c
index 358c33997536..6306ff59de0c 100644
--- a/drivers/net/bnx2x/bnx2x_sp.c
+++ b/drivers/net/bnx2x/bnx2x_sp.c
@@ -4874,6 +4874,22 @@ static int bnx2x_queue_chk_transition(struct bnx2x *bp,
4874 &params->params.update; 4874 &params->params.update;
4875 u8 next_tx_only = o->num_tx_only; 4875 u8 next_tx_only = o->num_tx_only;
4876 4876
4877 /*
4878 * Forget all pending for completion commands if a driver only state
4879 * transition has been requested.
4880 */
4881 if (test_bit(RAMROD_DRV_CLR_ONLY, &params->ramrod_flags)) {
4882 o->pending = 0;
4883 o->next_state = BNX2X_Q_STATE_MAX;
4884 }
4885
4886 /*
4887 * Don't allow a next state transition if we are in the middle of
4888 * the previous one.
4889 */
4890 if (o->pending)
4891 return -EBUSY;
4892
4877 switch (state) { 4893 switch (state) {
4878 case BNX2X_Q_STATE_RESET: 4894 case BNX2X_Q_STATE_RESET:
4879 if (cmd == BNX2X_Q_CMD_INIT) 4895 if (cmd == BNX2X_Q_CMD_INIT)
@@ -5053,6 +5069,21 @@ void bnx2x_queue_set_cos_cid(struct bnx2x *bp,
5053} 5069}
5054 5070
5055/********************** Function state object *********************************/ 5071/********************** Function state object *********************************/
5072enum bnx2x_func_state bnx2x_func_get_state(struct bnx2x *bp,
5073 struct bnx2x_func_sp_obj *o)
5074{
5075 /* in the middle of transaction - return INVALID state */
5076 if (o->pending)
5077 return BNX2X_F_STATE_MAX;
5078
5079 /*
5080 * unsure the order of reading of o->pending and o->state
5081 * o->pending should be read first
5082 */
5083 rmb();
5084
5085 return o->state;
5086}
5056 5087
5057static int bnx2x_func_wait_comp(struct bnx2x *bp, 5088static int bnx2x_func_wait_comp(struct bnx2x *bp,
5058 struct bnx2x_func_sp_obj *o, 5089 struct bnx2x_func_sp_obj *o,
@@ -5143,6 +5174,22 @@ static int bnx2x_func_chk_transition(struct bnx2x *bp,
5143 enum bnx2x_func_state state = o->state, next_state = BNX2X_F_STATE_MAX; 5174 enum bnx2x_func_state state = o->state, next_state = BNX2X_F_STATE_MAX;
5144 enum bnx2x_func_cmd cmd = params->cmd; 5175 enum bnx2x_func_cmd cmd = params->cmd;
5145 5176
5177 /*
5178 * Forget all pending for completion commands if a driver only state
5179 * transition has been requested.
5180 */
5181 if (test_bit(RAMROD_DRV_CLR_ONLY, &params->ramrod_flags)) {
5182 o->pending = 0;
5183 o->next_state = BNX2X_F_STATE_MAX;
5184 }
5185
5186 /*
5187 * Don't allow a next state transition if we are in the middle of
5188 * the previous one.
5189 */
5190 if (o->pending)
5191 return -EBUSY;
5192
5146 switch (state) { 5193 switch (state) {
5147 case BNX2X_F_STATE_RESET: 5194 case BNX2X_F_STATE_RESET:
5148 if (cmd == BNX2X_F_CMD_HW_INIT) 5195 if (cmd == BNX2X_F_CMD_HW_INIT)
@@ -5160,6 +5207,13 @@ static int bnx2x_func_chk_transition(struct bnx2x *bp,
5160 case BNX2X_F_STATE_STARTED: 5207 case BNX2X_F_STATE_STARTED:
5161 if (cmd == BNX2X_F_CMD_STOP) 5208 if (cmd == BNX2X_F_CMD_STOP)
5162 next_state = BNX2X_F_STATE_INITIALIZED; 5209 next_state = BNX2X_F_STATE_INITIALIZED;
5210 else if (cmd == BNX2X_F_CMD_TX_STOP)
5211 next_state = BNX2X_F_STATE_TX_STOPPED;
5212
5213 break;
5214 case BNX2X_F_STATE_TX_STOPPED:
5215 if (cmd == BNX2X_F_CMD_TX_START)
5216 next_state = BNX2X_F_STATE_STARTED;
5163 5217
5164 break; 5218 break;
5165 default: 5219 default:
@@ -5444,6 +5498,38 @@ static inline int bnx2x_func_send_stop(struct bnx2x *bp,
5444 NONE_CONNECTION_TYPE); 5498 NONE_CONNECTION_TYPE);
5445} 5499}
5446 5500
5501static inline int bnx2x_func_send_tx_stop(struct bnx2x *bp,
5502 struct bnx2x_func_state_params *params)
5503{
5504 return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_STOP_TRAFFIC, 0, 0, 0,
5505 NONE_CONNECTION_TYPE);
5506}
5507static inline int bnx2x_func_send_tx_start(struct bnx2x *bp,
5508 struct bnx2x_func_state_params *params)
5509{
5510 struct bnx2x_func_sp_obj *o = params->f_obj;
5511 struct flow_control_configuration *rdata =
5512 (struct flow_control_configuration *)o->rdata;
5513 dma_addr_t data_mapping = o->rdata_mapping;
5514 struct bnx2x_func_tx_start_params *tx_start_params =
5515 &params->params.tx_start;
5516 int i;
5517
5518 memset(rdata, 0, sizeof(*rdata));
5519
5520 rdata->dcb_enabled = tx_start_params->dcb_enabled;
5521 rdata->dcb_version = tx_start_params->dcb_version;
5522 rdata->dont_add_pri_0_en = tx_start_params->dont_add_pri_0_en;
5523
5524 for (i = 0; i < ARRAY_SIZE(rdata->traffic_type_to_priority_cos); i++)
5525 rdata->traffic_type_to_priority_cos[i] =
5526 tx_start_params->traffic_type_to_priority_cos[i];
5527
5528 return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_START_TRAFFIC, 0,
5529 U64_HI(data_mapping),
5530 U64_LO(data_mapping), NONE_CONNECTION_TYPE);
5531}
5532
5447static int bnx2x_func_send_cmd(struct bnx2x *bp, 5533static int bnx2x_func_send_cmd(struct bnx2x *bp,
5448 struct bnx2x_func_state_params *params) 5534 struct bnx2x_func_state_params *params)
5449{ 5535{
@@ -5456,6 +5542,10 @@ static int bnx2x_func_send_cmd(struct bnx2x *bp,
5456 return bnx2x_func_send_stop(bp, params); 5542 return bnx2x_func_send_stop(bp, params);
5457 case BNX2X_F_CMD_HW_RESET: 5543 case BNX2X_F_CMD_HW_RESET:
5458 return bnx2x_func_hw_reset(bp, params); 5544 return bnx2x_func_hw_reset(bp, params);
5545 case BNX2X_F_CMD_TX_STOP:
5546 return bnx2x_func_send_tx_stop(bp, params);
5547 case BNX2X_F_CMD_TX_START:
5548 return bnx2x_func_send_tx_start(bp, params);
5459 default: 5549 default:
5460 BNX2X_ERR("Unknown command: %d\n", params->cmd); 5550 BNX2X_ERR("Unknown command: %d\n", params->cmd);
5461 return -EINVAL; 5551 return -EINVAL;
diff --git a/drivers/net/bnx2x/bnx2x_sp.h b/drivers/net/bnx2x/bnx2x_sp.h
index 83f3b0b44211..73400dd77b2f 100644
--- a/drivers/net/bnx2x/bnx2x_sp.h
+++ b/drivers/net/bnx2x/bnx2x_sp.h
@@ -996,6 +996,7 @@ enum bnx2x_func_state {
996 BNX2X_F_STATE_RESET, 996 BNX2X_F_STATE_RESET,
997 BNX2X_F_STATE_INITIALIZED, 997 BNX2X_F_STATE_INITIALIZED,
998 BNX2X_F_STATE_STARTED, 998 BNX2X_F_STATE_STARTED,
999 BNX2X_F_STATE_TX_STOPPED,
999 BNX2X_F_STATE_MAX, 1000 BNX2X_F_STATE_MAX,
1000}; 1001};
1001 1002
@@ -1005,6 +1006,8 @@ enum bnx2x_func_cmd {
1005 BNX2X_F_CMD_START, 1006 BNX2X_F_CMD_START,
1006 BNX2X_F_CMD_STOP, 1007 BNX2X_F_CMD_STOP,
1007 BNX2X_F_CMD_HW_RESET, 1008 BNX2X_F_CMD_HW_RESET,
1009 BNX2X_F_CMD_TX_STOP,
1010 BNX2X_F_CMD_TX_START,
1008 BNX2X_F_CMD_MAX, 1011 BNX2X_F_CMD_MAX,
1009}; 1012};
1010 1013
@@ -1047,6 +1050,13 @@ struct bnx2x_func_start_params {
1047 u8 network_cos_mode; 1050 u8 network_cos_mode;
1048}; 1051};
1049 1052
1053struct bnx2x_func_tx_start_params {
1054 struct priority_cos traffic_type_to_priority_cos[MAX_TRAFFIC_TYPES];
1055 u8 dcb_enabled;
1056 u8 dcb_version;
1057 u8 dont_add_pri_0_en;
1058};
1059
1050struct bnx2x_func_state_params { 1060struct bnx2x_func_state_params {
1051 struct bnx2x_func_sp_obj *f_obj; 1061 struct bnx2x_func_sp_obj *f_obj;
1052 1062
@@ -1061,6 +1071,7 @@ struct bnx2x_func_state_params {
1061 struct bnx2x_func_hw_init_params hw_init; 1071 struct bnx2x_func_hw_init_params hw_init;
1062 struct bnx2x_func_hw_reset_params hw_reset; 1072 struct bnx2x_func_hw_reset_params hw_reset;
1063 struct bnx2x_func_start_params start; 1073 struct bnx2x_func_start_params start;
1074 struct bnx2x_func_tx_start_params tx_start;
1064 } params; 1075 } params;
1065}; 1076};
1066 1077
@@ -1152,6 +1163,8 @@ void bnx2x_init_func_obj(struct bnx2x *bp,
1152int bnx2x_func_state_change(struct bnx2x *bp, 1163int bnx2x_func_state_change(struct bnx2x *bp,
1153 struct bnx2x_func_state_params *params); 1164 struct bnx2x_func_state_params *params);
1154 1165
1166enum bnx2x_func_state bnx2x_func_get_state(struct bnx2x *bp,
1167 struct bnx2x_func_sp_obj *o);
1155/******************* Queue State **************/ 1168/******************* Queue State **************/
1156void bnx2x_init_queue_obj(struct bnx2x *bp, 1169void bnx2x_init_queue_obj(struct bnx2x *bp,
1157 struct bnx2x_queue_sp_obj *obj, u8 cl_id, u32 *cids, 1170 struct bnx2x_queue_sp_obj *obj, u8 cl_id, u32 *cids,