summarylogtreecommitdiffstats
path: root/bnx2x_warpcore+8727_2_5g_sgmii_arch.patch
blob: 897f8082da8099b6d8616e37424ac838f5c04f49 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index 4e85e7dbc2be..717dbb42cf0d 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -151,6 +151,7 @@ typedef int (*read_sfp_module_eeprom_func_p)(struct bnx2x_phy *phy,
 
 #define SFP_EEPROM_CON_TYPE_ADDR		0x2
 	#define SFP_EEPROM_CON_TYPE_VAL_UNKNOWN	0x0
+	#define SFP_EEPROM_CON_TYPE_VAL_SC	0x1
 	#define SFP_EEPROM_CON_TYPE_VAL_LC	0x7
 	#define SFP_EEPROM_CON_TYPE_VAL_COPPER	0x21
 	#define SFP_EEPROM_CON_TYPE_VAL_RJ45	0x22
@@ -4210,6 +4211,16 @@ static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
 					 0x1000);
 		DP(NETIF_MSG_LINK, "set SGMII AUTONEG\n");
 	} else {
+		/* Note that 2.5G works only when used with 1G advertisment */
+		if (fiber_mode && (phy->req_line_speed == SPEED_2500) &&
+			(phy->speed_cap_mask &
+			 (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
+			  PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))) {
+			bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
+				MDIO_WC_REG_SERDESDIGITAL_MISC1,
+					0x6010);
+		}
+
 		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
 				MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
 		val16 &= 0xcebf;
@@ -4220,6 +4231,7 @@ static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
 			val16 |= 0x2000;
 			break;
 		case SPEED_1000:
+		case SPEED_2500:
 			val16 |= 0x0040;
 			break;
 		default:
@@ -8172,6 +8184,7 @@ static int bnx2x_get_edc_mode(struct bnx2x_phy *phy,
 		break;
 	}
 	case SFP_EEPROM_CON_TYPE_VAL_UNKNOWN:
+	case SFP_EEPROM_CON_TYPE_VAL_SC:
 	case SFP_EEPROM_CON_TYPE_VAL_LC:
 	case SFP_EEPROM_CON_TYPE_VAL_RJ45:
 		check_limiting_mode = 1;
@@ -8182,7 +8195,8 @@ static int bnx2x_get_edc_mode(struct bnx2x_phy *phy,
 		    (val[SFP_EEPROM_1G_COMP_CODE_ADDR] != 0)) {
 			DP(NETIF_MSG_LINK, "1G SFP module detected\n");
 			phy->media_type = ETH_PHY_SFP_1G_FIBER;
-			if (phy->req_line_speed != SPEED_1000) {
+			if ((phy->req_line_speed != SPEED_1000) &&
+				(phy->req_line_speed != SPEED_2500)) {
 				u8 gport = params->port;
 				phy->req_line_speed = SPEED_1000;
 				if (!CHIP_IS_E1x(bp)) {
@@ -9236,6 +9250,7 @@ static void bnx2x_8727_config_speed(struct bnx2x_phy *phy,
 	u16 tmp1, val;
 	/* Set option 1G speed */
 	if ((phy->req_line_speed == SPEED_1000) ||
+		(phy->req_line_speed == SPEED_2500) ||
 	    (phy->media_type == ETH_PHY_SFP_1G_FIBER)) {
 		DP(NETIF_MSG_LINK, "Setting 1G force\n");
 		bnx2x_cl45_write(bp, phy,
@@ -9245,6 +9260,22 @@ static void bnx2x_8727_config_speed(struct bnx2x_phy *phy,
 		bnx2x_cl45_read(bp, phy,
 				MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
 		DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1);
+		if ((phy->req_line_speed == SPEED_2500) &&
+			(phy->speed_cap_mask &
+			(PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
+			 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))) {
+			bnx2x_cl45_read_and_write(bp, phy,
+					MDIO_AN_DEVAD,
+					MDIO_AN_REG_8727_MISC_CTRL2,
+					~(1<<5));
+			bnx2x_cl45_write(bp, phy,
+					MDIO_AN_DEVAD,
+					MDIO_AN_REG_8727_MISC_CTRL1, 0x0010);
+		} else {
+			bnx2x_cl45_write(bp, phy,
+					MDIO_AN_DEVAD,
+					MDIO_AN_REG_8727_MISC_CTRL1, 0x001C);
+		}
 		/* Power down the XAUI until link is up in case of dual-media
 		 * and 1G
 		 */
@@ -9266,7 +9297,7 @@ static void bnx2x_8727_config_speed(struct bnx2x_phy *phy,
 
 		DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
 		bnx2x_cl45_write(bp, phy,
-				 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0);
+				 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL2, 0);
 		bnx2x_cl45_write(bp, phy,
 				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
 	} else {
@@ -9274,8 +9305,11 @@ static void bnx2x_8727_config_speed(struct bnx2x_phy *phy,
 		 * registers although it is default
 		 */
 		bnx2x_cl45_write(bp, phy,
-				 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL,
+				 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL2,
 				 0x0020);
+		bnx2x_cl45_write(bp, phy,
+				 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL1,
+				 0x001C);
 		bnx2x_cl45_write(bp, phy,
 				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100);
 		bnx2x_cl45_write(bp, phy,
@@ -9565,6 +9599,11 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
 		vars->line_speed = SPEED_10000;
 		DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
 			   params->port);
+	} else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) {
+		link_up = 1;
+		vars->line_speed = SPEED_2500;
+		DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n",
+			   params->port);
 	} else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
 		link_up = 1;
 		vars->line_speed = SPEED_1000;
@@ -9596,7 +9635,8 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
 	}
 
 	if ((DUAL_MEDIA(params)) &&
-	    (phy->req_line_speed == SPEED_1000)) {
+	    ((phy->req_line_speed == SPEED_1000) ||
+	     (phy->req_line_speed == SPEED_2500))) {
 		bnx2x_cl45_read(bp, phy,
 				MDIO_PMA_DEVAD,
 				MDIO_PMA_REG_8727_PCS_GP, &val1);
@@ -11720,6 +11760,7 @@ static const struct bnx2x_phy phy_warpcore = {
 			   SUPPORTED_100baseT_Full |
 			   SUPPORTED_1000baseT_Full |
 			   SUPPORTED_1000baseKX_Full |
+			   SUPPORTED_2500baseX_Full |
 			   SUPPORTED_10000baseT_Full |
 			   SUPPORTED_10000baseKR_Full |
 			   SUPPORTED_20000baseKR2_Full |
@@ -11906,6 +11947,7 @@ static const struct bnx2x_phy phy_8727 = {
 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
 	.mdio_ctrl	= 0,
 	.supported	= (SUPPORTED_10000baseT_Full |
+			   SUPPORTED_2500baseX_Full |
 			   SUPPORTED_1000baseT_Full |
 			   SUPPORTED_FIBRE |
 			   SUPPORTED_Pause |
@@ -12253,6 +12295,7 @@ static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
 			break;
 		case PORT_HW_CFG_NET_SERDES_IF_SFI:
 			phy->supported &= (SUPPORTED_1000baseT_Full |
+					   SUPPORTED_2500baseX_Full |
 					   SUPPORTED_10000baseT_Full |
 					   SUPPORTED_FIBRE |
 					   SUPPORTED_Pause |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
index 5caa75b41b73..eaeaf4d90b68 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
@@ -7169,7 +7169,8 @@ Theotherbitsarereservedandshouldbezero*/
 #define MDIO_PMA_REG_8727_PCS_GP		0xc842
 #define MDIO_PMA_REG_8727_OPT_CFG_REG		0xc8e4
 
-#define MDIO_AN_REG_8727_MISC_CTRL		0x8309
+#define MDIO_AN_REG_8727_MISC_CTRL1		0x8308
+#define MDIO_AN_REG_8727_MISC_CTRL2		0x8309
 
 #define MDIO_PMA_REG_8073_CHIP_REV			0xc801
 #define MDIO_PMA_REG_8073_SPEED_LINK_STATUS		0xc820