diff options
author | Yaniv Rosner <yanivr@broadcom.com> | 2011-06-13 21:34:12 -0400 |
---|---|---|
committer | David S. Miller <davem@conan.davemloft.net> | 2011-06-15 10:56:57 -0400 |
commit | 3c9ada227c56c6f41e24b01d183b00b007c7ac93 (patch) | |
tree | a6aeae7cdf2ae66cf43b033ebe437beb27a07fbc | |
parent | 9380bb9e88831bd3d85636b3e4fec30e330d5266 (diff) |
bnx2x: Add Warpcore support for 578xx
Signed-off-by: Yaniv Rosner <yanivr@broadcom.com>
Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@conan.davemloft.net>
-rw-r--r-- | drivers/net/bnx2x/bnx2x_link.c | 1812 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_link.h | 40 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_main.c | 3 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_reg.h | 163 |
4 files changed, 1825 insertions, 193 deletions
diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 873463966a0e..b777d2c9633f 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c | |||
@@ -37,6 +37,13 @@ | |||
37 | #define ETH_MAX_JUMBO_PACKET_SIZE 9600 | 37 | #define ETH_MAX_JUMBO_PACKET_SIZE 9600 |
38 | #define MDIO_ACCESS_TIMEOUT 1000 | 38 | #define MDIO_ACCESS_TIMEOUT 1000 |
39 | #define BMAC_CONTROL_RX_ENABLE 2 | 39 | #define BMAC_CONTROL_RX_ENABLE 2 |
40 | #define WC_LANE_MAX 4 | ||
41 | #define I2C_SWITCH_WIDTH 2 | ||
42 | #define I2C_BSC0 0 | ||
43 | #define I2C_BSC1 1 | ||
44 | #define I2C_WA_RETRY_CNT 3 | ||
45 | #define MCPR_IMC_COMMAND_READ_OP 1 | ||
46 | #define MCPR_IMC_COMMAND_WRITE_OP 2 | ||
40 | 47 | ||
41 | /***********************************************************/ | 48 | /***********************************************************/ |
42 | /* Shortcut definitions */ | 49 | /* Shortcut definitions */ |
@@ -108,7 +115,10 @@ | |||
108 | #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX | 115 | #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX |
109 | #define GP_STATUS_10G_KX4 \ | 116 | #define GP_STATUS_10G_KX4 \ |
110 | MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4 | 117 | MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4 |
111 | 118 | #define GP_STATUS_10G_KR MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KR | |
119 | #define GP_STATUS_10G_XFI MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI | ||
120 | #define GP_STATUS_20G_DXGXS MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS | ||
121 | #define GP_STATUS_10G_SFI MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI | ||
112 | #define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD | 122 | #define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD |
113 | #define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD | 123 | #define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD |
114 | #define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD | 124 | #define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD |
@@ -122,11 +132,8 @@ | |||
122 | #define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD | 132 | #define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD |
123 | #define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD | 133 | #define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD |
124 | #define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD | 134 | #define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD |
125 | 135 | #define LINK_20GTFD LINK_STATUS_SPEED_AND_DUPLEX_20GTFD | |
126 | #define PHY_XGXS_FLAG 0x1 | 136 | #define LINK_20GXFD LINK_STATUS_SPEED_AND_DUPLEX_20GXFD |
127 | #define PHY_SGMII_FLAG 0x2 | ||
128 | #define PHY_SERDES_FLAG 0x4 | ||
129 | |||
130 | /* */ | 137 | /* */ |
131 | #define SFP_EEPROM_CON_TYPE_ADDR 0x2 | 138 | #define SFP_EEPROM_CON_TYPE_ADDR 0x2 |
132 | #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7 | 139 | #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7 |
@@ -247,6 +254,7 @@ | |||
247 | #define ETS_E3B0_PBF_MIN_W_VAL (10000) | 254 | #define ETS_E3B0_PBF_MIN_W_VAL (10000) |
248 | 255 | ||
249 | #define MAX_PACKET_SIZE (9700) | 256 | #define MAX_PACKET_SIZE (9700) |
257 | #define WC_UC_TIMEOUT 100 | ||
250 | 258 | ||
251 | /**********************************************************/ | 259 | /**********************************************************/ |
252 | /* INTERFACE */ | 260 | /* INTERFACE */ |
@@ -283,6 +291,47 @@ static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits) | |||
283 | } | 291 | } |
284 | 292 | ||
285 | /******************************************************************/ | 293 | /******************************************************************/ |
294 | /* EPIO/GPIO section */ | ||
295 | /******************************************************************/ | ||
296 | static void bnx2x_set_epio(struct bnx2x *bp, u32 epio_pin, u32 en) | ||
297 | { | ||
298 | u32 epio_mask, gp_output, gp_oenable; | ||
299 | |||
300 | /* Sanity check */ | ||
301 | if (epio_pin > 31) { | ||
302 | DP(NETIF_MSG_LINK, "Invalid EPIO pin %d to set\n", epio_pin); | ||
303 | return; | ||
304 | } | ||
305 | DP(NETIF_MSG_LINK, "Setting EPIO pin %d to %d\n", epio_pin, en); | ||
306 | epio_mask = 1 << epio_pin; | ||
307 | /* Set this EPIO to output */ | ||
308 | gp_output = REG_RD(bp, MCP_REG_MCPR_GP_OUTPUTS); | ||
309 | if (en) | ||
310 | gp_output |= epio_mask; | ||
311 | else | ||
312 | gp_output &= ~epio_mask; | ||
313 | |||
314 | REG_WR(bp, MCP_REG_MCPR_GP_OUTPUTS, gp_output); | ||
315 | |||
316 | /* Set the value for this EPIO */ | ||
317 | gp_oenable = REG_RD(bp, MCP_REG_MCPR_GP_OENABLE); | ||
318 | REG_WR(bp, MCP_REG_MCPR_GP_OENABLE, gp_oenable | epio_mask); | ||
319 | } | ||
320 | |||
321 | static void bnx2x_set_cfg_pin(struct bnx2x *bp, u32 pin_cfg, u32 val) | ||
322 | { | ||
323 | if (pin_cfg == PIN_CFG_NA) | ||
324 | return; | ||
325 | if (pin_cfg >= PIN_CFG_EPIO0) { | ||
326 | bnx2x_set_epio(bp, pin_cfg - PIN_CFG_EPIO0, val); | ||
327 | } else { | ||
328 | u8 gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3; | ||
329 | u8 gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2; | ||
330 | bnx2x_set_gpio(bp, gpio_num, (u8)val, gpio_port); | ||
331 | } | ||
332 | } | ||
333 | |||
334 | /******************************************************************/ | ||
286 | /* ETS section */ | 335 | /* ETS section */ |
287 | /******************************************************************/ | 336 | /******************************************************************/ |
288 | void bnx2x_ets_disabled(struct link_params *params) | 337 | void bnx2x_ets_disabled(struct link_params *params) |
@@ -607,7 +656,10 @@ static void bnx2x_set_mdio_clk(struct bnx2x *bp, u32 chip_id, u8 port) | |||
607 | mode = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); | 656 | mode = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); |
608 | mode &= ~(EMAC_MDIO_MODE_AUTO_POLL | | 657 | mode &= ~(EMAC_MDIO_MODE_AUTO_POLL | |
609 | EMAC_MDIO_MODE_CLOCK_CNT); | 658 | EMAC_MDIO_MODE_CLOCK_CNT); |
610 | mode |= (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT); | 659 | if (USES_WARPCORE(bp)) |
660 | mode |= (74L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT); | ||
661 | else | ||
662 | mode |= (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT); | ||
611 | 663 | ||
612 | mode |= (EMAC_MDIO_MODE_CLAUSE_45); | 664 | mode |= (EMAC_MDIO_MODE_CLAUSE_45); |
613 | REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE, mode); | 665 | REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE, mode); |
@@ -729,7 +781,7 @@ static void bnx2x_umac_enable(struct link_params *params, | |||
729 | /* Enable RX and TX */ | 781 | /* Enable RX and TX */ |
730 | val &= ~UMAC_COMMAND_CONFIG_REG_PAD_EN; | 782 | val &= ~UMAC_COMMAND_CONFIG_REG_PAD_EN; |
731 | val |= UMAC_COMMAND_CONFIG_REG_TX_ENA | | 783 | val |= UMAC_COMMAND_CONFIG_REG_TX_ENA | |
732 | UMAC_COMMAND_CONFIG_REG_RX_ENA; | 784 | UMAC_COMMAND_CONFIG_REG_RX_ENA; |
733 | REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val); | 785 | REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val); |
734 | udelay(50); | 786 | udelay(50); |
735 | 787 | ||
@@ -1649,7 +1701,7 @@ int bnx2x_update_pfc(struct link_params *params, | |||
1649 | else { | 1701 | else { |
1650 | val = REG_RD(bp, MISC_REG_RESET_REG_2); | 1702 | val = REG_RD(bp, MISC_REG_RESET_REG_2); |
1651 | if ((val & | 1703 | if ((val & |
1652 | (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) | 1704 | (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) |
1653 | == 0) { | 1705 | == 0) { |
1654 | DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n"); | 1706 | DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n"); |
1655 | bnx2x_emac_enable(params, vars, 0); | 1707 | bnx2x_emac_enable(params, vars, 0); |
@@ -1940,18 +1992,6 @@ static int bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl, | |||
1940 | case SPEED_10000: | 1992 | case SPEED_10000: |
1941 | init_crd = thresh + 553 - 22; | 1993 | init_crd = thresh + 553 - 22; |
1942 | break; | 1994 | break; |
1943 | |||
1944 | case SPEED_12000: | ||
1945 | init_crd = thresh + 664 - 22; | ||
1946 | break; | ||
1947 | |||
1948 | case SPEED_13000: | ||
1949 | init_crd = thresh + 742 - 22; | ||
1950 | break; | ||
1951 | |||
1952 | case SPEED_16000: | ||
1953 | init_crd = thresh + 778 - 22; | ||
1954 | break; | ||
1955 | default: | 1995 | default: |
1956 | DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", | 1996 | DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", |
1957 | line_speed); | 1997 | line_speed); |
@@ -2073,6 +2113,14 @@ static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, | |||
2073 | rc = -EFAULT; | 2113 | rc = -EFAULT; |
2074 | } | 2114 | } |
2075 | } | 2115 | } |
2116 | /* Work around for E3 A0 */ | ||
2117 | if (phy->flags & FLAGS_MDC_MDIO_WA) { | ||
2118 | phy->flags ^= FLAGS_DUMMY_READ; | ||
2119 | if (phy->flags & FLAGS_DUMMY_READ) { | ||
2120 | u16 temp_val; | ||
2121 | bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val); | ||
2122 | } | ||
2123 | } | ||
2076 | 2124 | ||
2077 | return rc; | 2125 | return rc; |
2078 | } | 2126 | } |
@@ -2128,11 +2176,149 @@ static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, | |||
2128 | rc = -EFAULT; | 2176 | rc = -EFAULT; |
2129 | } | 2177 | } |
2130 | } | 2178 | } |
2179 | /* Work around for E3 A0 */ | ||
2180 | if (phy->flags & FLAGS_MDC_MDIO_WA) { | ||
2181 | phy->flags ^= FLAGS_DUMMY_READ; | ||
2182 | if (phy->flags & FLAGS_DUMMY_READ) { | ||
2183 | u16 temp_val; | ||
2184 | bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val); | ||
2185 | } | ||
2186 | } | ||
2187 | |||
2188 | return rc; | ||
2189 | } | ||
2190 | |||
2191 | |||
2192 | /******************************************************************/ | ||
2193 | /* BSC access functions from E3 */ | ||
2194 | /******************************************************************/ | ||
2195 | static void bnx2x_bsc_module_sel(struct link_params *params) | ||
2196 | { | ||
2197 | int idx; | ||
2198 | u32 board_cfg, sfp_ctrl; | ||
2199 | u32 i2c_pins[I2C_SWITCH_WIDTH], i2c_val[I2C_SWITCH_WIDTH]; | ||
2200 | struct bnx2x *bp = params->bp; | ||
2201 | u8 port = params->port; | ||
2202 | /* Read I2C output PINs */ | ||
2203 | board_cfg = REG_RD(bp, params->shmem_base + | ||
2204 | offsetof(struct shmem_region, | ||
2205 | dev_info.shared_hw_config.board)); | ||
2206 | i2c_pins[I2C_BSC0] = board_cfg & SHARED_HW_CFG_E3_I2C_MUX0_MASK; | ||
2207 | i2c_pins[I2C_BSC1] = (board_cfg & SHARED_HW_CFG_E3_I2C_MUX1_MASK) >> | ||
2208 | SHARED_HW_CFG_E3_I2C_MUX1_SHIFT; | ||
2209 | |||
2210 | /* Read I2C output value */ | ||
2211 | sfp_ctrl = REG_RD(bp, params->shmem_base + | ||
2212 | offsetof(struct shmem_region, | ||
2213 | dev_info.port_hw_config[port].e3_cmn_pin_cfg)); | ||
2214 | i2c_val[I2C_BSC0] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX0_MASK) > 0; | ||
2215 | i2c_val[I2C_BSC1] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX1_MASK) > 0; | ||
2216 | DP(NETIF_MSG_LINK, "Setting BSC switch\n"); | ||
2217 | for (idx = 0; idx < I2C_SWITCH_WIDTH; idx++) | ||
2218 | bnx2x_set_cfg_pin(bp, i2c_pins[idx], i2c_val[idx]); | ||
2219 | } | ||
2220 | |||
2221 | static int bnx2x_bsc_read(struct link_params *params, | ||
2222 | struct bnx2x_phy *phy, | ||
2223 | u8 sl_devid, | ||
2224 | u16 sl_addr, | ||
2225 | u8 lc_addr, | ||
2226 | u8 xfer_cnt, | ||
2227 | u32 *data_array) | ||
2228 | { | ||
2229 | u32 val, i; | ||
2230 | int rc = 0; | ||
2231 | struct bnx2x *bp = params->bp; | ||
2232 | |||
2233 | if ((sl_devid != 0xa0) && (sl_devid != 0xa2)) { | ||
2234 | DP(NETIF_MSG_LINK, "invalid sl_devid 0x%x\n", sl_devid); | ||
2235 | return -EINVAL; | ||
2236 | } | ||
2237 | |||
2238 | if (xfer_cnt > 16) { | ||
2239 | DP(NETIF_MSG_LINK, "invalid xfer_cnt %d. Max is 16 bytes\n", | ||
2240 | xfer_cnt); | ||
2241 | return -EINVAL; | ||
2242 | } | ||
2243 | bnx2x_bsc_module_sel(params); | ||
2244 | |||
2245 | xfer_cnt = 16 - lc_addr; | ||
2246 | |||
2247 | /* enable the engine */ | ||
2248 | val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND); | ||
2249 | val |= MCPR_IMC_COMMAND_ENABLE; | ||
2250 | REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val); | ||
2251 | |||
2252 | /* program slave device ID */ | ||
2253 | val = (sl_devid << 16) | sl_addr; | ||
2254 | REG_WR(bp, MCP_REG_MCPR_IMC_SLAVE_CONTROL, val); | ||
2255 | |||
2256 | /* start xfer with 0 byte to update the address pointer ???*/ | ||
2257 | val = (MCPR_IMC_COMMAND_ENABLE) | | ||
2258 | (MCPR_IMC_COMMAND_WRITE_OP << | ||
2259 | MCPR_IMC_COMMAND_OPERATION_BITSHIFT) | | ||
2260 | (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) | (0); | ||
2261 | REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val); | ||
2262 | |||
2263 | /* poll for completion */ | ||
2264 | i = 0; | ||
2265 | val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND); | ||
2266 | while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) { | ||
2267 | udelay(10); | ||
2268 | val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND); | ||
2269 | if (i++ > 1000) { | ||
2270 | DP(NETIF_MSG_LINK, "wr 0 byte timed out after %d try\n", | ||
2271 | i); | ||
2272 | rc = -EFAULT; | ||
2273 | break; | ||
2274 | } | ||
2275 | } | ||
2276 | if (rc == -EFAULT) | ||
2277 | return rc; | ||
2131 | 2278 | ||
2279 | /* start xfer with read op */ | ||
2280 | val = (MCPR_IMC_COMMAND_ENABLE) | | ||
2281 | (MCPR_IMC_COMMAND_READ_OP << | ||
2282 | MCPR_IMC_COMMAND_OPERATION_BITSHIFT) | | ||
2283 | (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) | | ||
2284 | (xfer_cnt); | ||
2285 | REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val); | ||
2286 | |||
2287 | /* poll for completion */ | ||
2288 | i = 0; | ||
2289 | val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND); | ||
2290 | while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) { | ||
2291 | udelay(10); | ||
2292 | val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND); | ||
2293 | if (i++ > 1000) { | ||
2294 | DP(NETIF_MSG_LINK, "rd op timed out after %d try\n", i); | ||
2295 | rc = -EFAULT; | ||
2296 | break; | ||
2297 | } | ||
2298 | } | ||
2299 | if (rc == -EFAULT) | ||
2300 | return rc; | ||
2132 | 2301 | ||
2302 | for (i = (lc_addr >> 2); i < 4; i++) { | ||
2303 | data_array[i] = REG_RD(bp, (MCP_REG_MCPR_IMC_DATAREG0 + i*4)); | ||
2304 | #ifdef __BIG_ENDIAN | ||
2305 | data_array[i] = ((data_array[i] & 0x000000ff) << 24) | | ||
2306 | ((data_array[i] & 0x0000ff00) << 8) | | ||
2307 | ((data_array[i] & 0x00ff0000) >> 8) | | ||
2308 | ((data_array[i] & 0xff000000) >> 24); | ||
2309 | #endif | ||
2310 | } | ||
2133 | return rc; | 2311 | return rc; |
2134 | } | 2312 | } |
2135 | 2313 | ||
2314 | static void bnx2x_cl45_read_or_write(struct bnx2x *bp, struct bnx2x_phy *phy, | ||
2315 | u8 devad, u16 reg, u16 or_val) | ||
2316 | { | ||
2317 | u16 val; | ||
2318 | bnx2x_cl45_read(bp, phy, devad, reg, &val); | ||
2319 | bnx2x_cl45_write(bp, phy, devad, reg, val | or_val); | ||
2320 | } | ||
2321 | |||
2136 | int bnx2x_phy_read(struct link_params *params, u8 phy_addr, | 2322 | int bnx2x_phy_read(struct link_params *params, u8 phy_addr, |
2137 | u8 devad, u16 reg, u16 *ret_val) | 2323 | u8 devad, u16 reg, u16 *ret_val) |
2138 | { | 2324 | { |
@@ -2168,6 +2354,59 @@ int bnx2x_phy_write(struct link_params *params, u8 phy_addr, | |||
2168 | } | 2354 | } |
2169 | return -EINVAL; | 2355 | return -EINVAL; |
2170 | } | 2356 | } |
2357 | static u8 bnx2x_get_warpcore_lane(struct bnx2x_phy *phy, | ||
2358 | struct link_params *params) | ||
2359 | { | ||
2360 | u8 lane = 0; | ||
2361 | struct bnx2x *bp = params->bp; | ||
2362 | u32 path_swap, path_swap_ovr; | ||
2363 | u8 path, port; | ||
2364 | |||
2365 | path = BP_PATH(bp); | ||
2366 | port = params->port; | ||
2367 | |||
2368 | if (bnx2x_is_4_port_mode(bp)) { | ||
2369 | u32 port_swap, port_swap_ovr; | ||
2370 | |||
2371 | /*figure out path swap value */ | ||
2372 | path_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP_OVWR); | ||
2373 | if (path_swap_ovr & 0x1) | ||
2374 | path_swap = (path_swap_ovr & 0x2); | ||
2375 | else | ||
2376 | path_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP); | ||
2377 | |||
2378 | if (path_swap) | ||
2379 | path = path ^ 1; | ||
2380 | |||
2381 | /*figure out port swap value */ | ||
2382 | port_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP_OVWR); | ||
2383 | if (port_swap_ovr & 0x1) | ||
2384 | port_swap = (port_swap_ovr & 0x2); | ||
2385 | else | ||
2386 | port_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP); | ||
2387 | |||
2388 | if (port_swap) | ||
2389 | port = port ^ 1; | ||
2390 | |||
2391 | lane = (port<<1) + path; | ||
2392 | } else { /* two port mode - no port swap */ | ||
2393 | |||
2394 | /*figure out path swap value */ | ||
2395 | path_swap_ovr = | ||
2396 | REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP_OVWR); | ||
2397 | if (path_swap_ovr & 0x1) { | ||
2398 | path_swap = (path_swap_ovr & 0x2); | ||
2399 | } else { | ||
2400 | path_swap = | ||
2401 | REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP); | ||
2402 | } | ||
2403 | if (path_swap) | ||
2404 | path = path ^ 1; | ||
2405 | |||
2406 | lane = path << 1 ; | ||
2407 | } | ||
2408 | return lane; | ||
2409 | } | ||
2171 | 2410 | ||
2172 | static void bnx2x_set_aer_mmd(struct link_params *params, | 2411 | static void bnx2x_set_aer_mmd(struct link_params *params, |
2173 | struct bnx2x_phy *phy) | 2412 | struct bnx2x_phy *phy) |
@@ -2182,7 +2421,18 @@ static void bnx2x_set_aer_mmd(struct link_params *params, | |||
2182 | offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ? | 2421 | offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ? |
2183 | (phy->addr + ser_lane) : 0; | 2422 | (phy->addr + ser_lane) : 0; |
2184 | 2423 | ||
2185 | if (CHIP_IS_E2(bp)) | 2424 | if (USES_WARPCORE(bp)) { |
2425 | aer_val = bnx2x_get_warpcore_lane(phy, params); | ||
2426 | /* | ||
2427 | * In Dual-lane mode, two lanes are joined together, | ||
2428 | * so in order to configure them, the AER broadcast method is | ||
2429 | * used here. | ||
2430 | * 0x200 is the broadcast address for lanes 0,1 | ||
2431 | * 0x201 is the broadcast address for lanes 2,3 | ||
2432 | */ | ||
2433 | if (phy->flags & FLAGS_WC_DUAL_MODE) | ||
2434 | aer_val = (aer_val >> 1) | 0x200; | ||
2435 | } else if (CHIP_IS_E2(bp)) | ||
2186 | aer_val = 0x3800 + offset - 1; | 2436 | aer_val = 0x3800 + offset - 1; |
2187 | else | 2437 | else |
2188 | aer_val = 0x3800 + offset; | 2438 | aer_val = 0x3800 + offset; |
@@ -2415,6 +2665,778 @@ static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy, | |||
2415 | } | 2665 | } |
2416 | return ret; | 2666 | return ret; |
2417 | } | 2667 | } |
2668 | /******************************************************************/ | ||
2669 | /* Warpcore section */ | ||
2670 | /******************************************************************/ | ||
2671 | /* The init_internal_warpcore should mirror the xgxs, | ||
2672 | * i.e. reset the lane (if needed), set aer for the | ||
2673 | * init configuration, and set/clear SGMII flag. Internal | ||
2674 | * phy init is done purely in phy_init stage. | ||
2675 | */ | ||
2676 | static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, | ||
2677 | struct link_params *params, | ||
2678 | struct link_vars *vars) { | ||
2679 | u16 val16 = 0, lane; | ||
2680 | struct bnx2x *bp = params->bp; | ||
2681 | DP(NETIF_MSG_LINK, "Enable Auto Negotiation for KR\n"); | ||
2682 | /* Check adding advertisement for 1G KX */ | ||
2683 | if (((vars->line_speed == SPEED_AUTO_NEG) && | ||
2684 | (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) || | ||
2685 | (vars->line_speed == SPEED_1000)) { | ||
2686 | u16 sd_digital; | ||
2687 | val16 |= (1<<5); | ||
2688 | |||
2689 | /* Enable CL37 1G Parallel Detect */ | ||
2690 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
2691 | MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &sd_digital); | ||
2692 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2693 | MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, | ||
2694 | (sd_digital | 0x1)); | ||
2695 | |||
2696 | DP(NETIF_MSG_LINK, "Advertize 1G\n"); | ||
2697 | } | ||
2698 | if (((vars->line_speed == SPEED_AUTO_NEG) && | ||
2699 | (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) || | ||
2700 | (vars->line_speed == SPEED_10000)) { | ||
2701 | /* Check adding advertisement for 10G KR */ | ||
2702 | val16 |= (1<<7); | ||
2703 | /* Enable 10G Parallel Detect */ | ||
2704 | bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, | ||
2705 | MDIO_WC_REG_PAR_DET_10G_CTRL, 1); | ||
2706 | |||
2707 | DP(NETIF_MSG_LINK, "Advertize 10G\n"); | ||
2708 | } | ||
2709 | |||
2710 | /* Set Transmit PMD settings */ | ||
2711 | lane = bnx2x_get_warpcore_lane(phy, params); | ||
2712 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2713 | MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, | ||
2714 | ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | | ||
2715 | (0x06 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | | ||
2716 | (0x09 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET))); | ||
2717 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2718 | MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL, | ||
2719 | 0x03f0); | ||
2720 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2721 | MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL, | ||
2722 | 0x03f0); | ||
2723 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2724 | MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, | ||
2725 | 0x383f); | ||
2726 | |||
2727 | /* Advertised speeds */ | ||
2728 | bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, | ||
2729 | MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, val16); | ||
2730 | |||
2731 | /* Advertise pause */ | ||
2732 | bnx2x_ext_phy_set_pause(params, phy, vars); | ||
2733 | |||
2734 | /* Enable Autoneg */ | ||
2735 | bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, | ||
2736 | MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1000); | ||
2737 | |||
2738 | /* Over 1G - AN local device user page 1 */ | ||
2739 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2740 | MDIO_WC_REG_DIGITAL3_UP1, 0x1f); | ||
2741 | |||
2742 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
2743 | MDIO_WC_REG_DIGITAL5_MISC7, &val16); | ||
2744 | |||
2745 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2746 | MDIO_WC_REG_DIGITAL5_MISC7, val16 | 0x100); | ||
2747 | } | ||
2748 | |||
2749 | static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy, | ||
2750 | struct link_params *params, | ||
2751 | struct link_vars *vars) | ||
2752 | { | ||
2753 | struct bnx2x *bp = params->bp; | ||
2754 | u16 val; | ||
2755 | |||
2756 | /* Disable Autoneg */ | ||
2757 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2758 | MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7); | ||
2759 | |||
2760 | bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, | ||
2761 | MDIO_WC_REG_PAR_DET_10G_CTRL, 0); | ||
2762 | |||
2763 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2764 | MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0x3f00); | ||
2765 | |||
2766 | bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, | ||
2767 | MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0); | ||
2768 | |||
2769 | bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, | ||
2770 | MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0); | ||
2771 | |||
2772 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2773 | MDIO_WC_REG_DIGITAL3_UP1, 0x1); | ||
2774 | |||
2775 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2776 | MDIO_WC_REG_DIGITAL5_MISC7, 0xa); | ||
2777 | |||
2778 | /* Disable CL36 PCS Tx */ | ||
2779 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2780 | MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0x0); | ||
2781 | |||
2782 | /* Double Wide Single Data Rate @ pll rate */ | ||
2783 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2784 | MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0xFFFF); | ||
2785 | |||
2786 | /* Leave cl72 training enable, needed for KR */ | ||
2787 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, | ||
2788 | MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150, | ||
2789 | 0x2); | ||
2790 | |||
2791 | /* Leave CL72 enabled */ | ||
2792 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
2793 | MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, | ||
2794 | &val); | ||
2795 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2796 | MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, | ||
2797 | val | 0x3800); | ||
2798 | |||
2799 | /* Set speed via PMA/PMD register */ | ||
2800 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, | ||
2801 | MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040); | ||
2802 | |||
2803 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, | ||
2804 | MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0xB); | ||
2805 | |||
2806 | /*Enable encoded forced speed */ | ||
2807 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2808 | MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x30); | ||
2809 | |||
2810 | /* Turn TX scramble payload only the 64/66 scrambler */ | ||
2811 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2812 | MDIO_WC_REG_TX66_CONTROL, 0x9); | ||
2813 | |||
2814 | /* Turn RX scramble payload only the 64/66 scrambler */ | ||
2815 | bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, | ||
2816 | MDIO_WC_REG_RX66_CONTROL, 0xF9); | ||
2817 | |||
2818 | /* set and clear loopback to cause a reset to 64/66 decoder */ | ||
2819 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2820 | MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x4000); | ||
2821 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2822 | MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0); | ||
2823 | |||
2824 | } | ||
2825 | |||
2826 | static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, | ||
2827 | struct link_params *params, | ||
2828 | u8 is_xfi) | ||
2829 | { | ||
2830 | struct bnx2x *bp = params->bp; | ||
2831 | u16 misc1_val, tap_val, tx_driver_val, lane, val; | ||
2832 | /* Hold rxSeqStart */ | ||
2833 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
2834 | MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val); | ||
2835 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2836 | MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val | 0x8000)); | ||
2837 | |||
2838 | /* Hold tx_fifo_reset */ | ||
2839 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
2840 | MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val); | ||
2841 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2842 | MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, (val | 0x1)); | ||
2843 | |||
2844 | /* Disable CL73 AN */ | ||
2845 | bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0); | ||
2846 | |||
2847 | /* Disable 100FX Enable and Auto-Detect */ | ||
2848 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
2849 | MDIO_WC_REG_FX100_CTRL1, &val); | ||
2850 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2851 | MDIO_WC_REG_FX100_CTRL1, (val & 0xFFFA)); | ||
2852 | |||
2853 | /* Disable 100FX Idle detect */ | ||
2854 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
2855 | MDIO_WC_REG_FX100_CTRL3, &val); | ||
2856 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2857 | MDIO_WC_REG_FX100_CTRL3, (val | 0x0080)); | ||
2858 | |||
2859 | /* Set Block address to Remote PHY & Clear forced_speed[5] */ | ||
2860 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
2861 | MDIO_WC_REG_DIGITAL4_MISC3, &val); | ||
2862 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2863 | MDIO_WC_REG_DIGITAL4_MISC3, (val & 0xFF7F)); | ||
2864 | |||
2865 | /* Turn off auto-detect & fiber mode */ | ||
2866 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
2867 | MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val); | ||
2868 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2869 | MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, | ||
2870 | (val & 0xFFEE)); | ||
2871 | |||
2872 | /* Set filter_force_link, disable_false_link and parallel_detect */ | ||
2873 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
2874 | MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &val); | ||
2875 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2876 | MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, | ||
2877 | ((val | 0x0006) & 0xFFFE)); | ||
2878 | |||
2879 | /* Set XFI / SFI */ | ||
2880 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
2881 | MDIO_WC_REG_SERDESDIGITAL_MISC1, &misc1_val); | ||
2882 | |||
2883 | misc1_val &= ~(0x1f); | ||
2884 | |||
2885 | if (is_xfi) { | ||
2886 | misc1_val |= 0x5; | ||
2887 | tap_val = ((0x08 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | | ||
2888 | (0x37 << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | | ||
2889 | (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET)); | ||
2890 | tx_driver_val = | ||
2891 | ((0x00 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | | ||
2892 | (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | | ||
2893 | (0x03 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)); | ||
2894 | |||
2895 | } else { | ||
2896 | misc1_val |= 0x9; | ||
2897 | tap_val = ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | | ||
2898 | (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | | ||
2899 | (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET)); | ||
2900 | tx_driver_val = | ||
2901 | ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | | ||
2902 | (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | | ||
2903 | (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)); | ||
2904 | } | ||
2905 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2906 | MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val); | ||
2907 | |||
2908 | /* Set Transmit PMD settings */ | ||
2909 | lane = bnx2x_get_warpcore_lane(phy, params); | ||
2910 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2911 | MDIO_WC_REG_TX_FIR_TAP, | ||
2912 | tap_val | MDIO_WC_REG_TX_FIR_TAP_ENABLE); | ||
2913 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2914 | MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, | ||
2915 | tx_driver_val); | ||
2916 | |||
2917 | /* Enable fiber mode, enable and invert sig_det */ | ||
2918 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
2919 | MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val); | ||
2920 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2921 | MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, val | 0xd); | ||
2922 | |||
2923 | /* Set Block address to Remote PHY & Set forced_speed[5], 40bit mode */ | ||
2924 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
2925 | MDIO_WC_REG_DIGITAL4_MISC3, &val); | ||
2926 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2927 | MDIO_WC_REG_DIGITAL4_MISC3, val | 0x8080); | ||
2928 | |||
2929 | /* 10G XFI Full Duplex */ | ||
2930 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2931 | MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x100); | ||
2932 | |||
2933 | /* Release tx_fifo_reset */ | ||
2934 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
2935 | MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val); | ||
2936 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2937 | MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, val & 0xFFFE); | ||
2938 | |||
2939 | /* Release rxSeqStart */ | ||
2940 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
2941 | MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val); | ||
2942 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2943 | MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val & 0x7FFF)); | ||
2944 | } | ||
2945 | |||
2946 | static void bnx2x_warpcore_set_20G_KR2(struct bnx2x *bp, | ||
2947 | struct bnx2x_phy *phy) | ||
2948 | { | ||
2949 | DP(NETIF_MSG_LINK, "KR2 still not supported !!!\n"); | ||
2950 | } | ||
2951 | |||
2952 | static void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x *bp, | ||
2953 | struct bnx2x_phy *phy, | ||
2954 | u16 lane) | ||
2955 | { | ||
2956 | /* Rx0 anaRxControl1G */ | ||
2957 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2958 | MDIO_WC_REG_RX0_ANARXCONTROL1G, 0x90); | ||
2959 | |||
2960 | /* Rx2 anaRxControl1G */ | ||
2961 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2962 | MDIO_WC_REG_RX2_ANARXCONTROL1G, 0x90); | ||
2963 | |||
2964 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2965 | MDIO_WC_REG_RX66_SCW0, 0xE070); | ||
2966 | |||
2967 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2968 | MDIO_WC_REG_RX66_SCW1, 0xC0D0); | ||
2969 | |||
2970 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2971 | MDIO_WC_REG_RX66_SCW2, 0xA0B0); | ||
2972 | |||
2973 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2974 | MDIO_WC_REG_RX66_SCW3, 0x8090); | ||
2975 | |||
2976 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2977 | MDIO_WC_REG_RX66_SCW0_MASK, 0xF0F0); | ||
2978 | |||
2979 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2980 | MDIO_WC_REG_RX66_SCW1_MASK, 0xF0F0); | ||
2981 | |||
2982 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2983 | MDIO_WC_REG_RX66_SCW2_MASK, 0xF0F0); | ||
2984 | |||
2985 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2986 | MDIO_WC_REG_RX66_SCW3_MASK, 0xF0F0); | ||
2987 | |||
2988 | /* Serdes Digital Misc1 */ | ||
2989 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2990 | MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6008); | ||
2991 | |||
2992 | /* Serdes Digital4 Misc3 */ | ||
2993 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2994 | MDIO_WC_REG_DIGITAL4_MISC3, 0x8088); | ||
2995 | |||
2996 | /* Set Transmit PMD settings */ | ||
2997 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
2998 | MDIO_WC_REG_TX_FIR_TAP, | ||
2999 | ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | | ||
3000 | (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) | | ||
3001 | (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET) | | ||
3002 | MDIO_WC_REG_TX_FIR_TAP_ENABLE)); | ||
3003 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3004 | MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, | ||
3005 | ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | | ||
3006 | (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | | ||
3007 | (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET))); | ||
3008 | } | ||
3009 | |||
3010 | static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy, | ||
3011 | struct link_params *params, | ||
3012 | u8 fiber_mode) | ||
3013 | { | ||
3014 | struct bnx2x *bp = params->bp; | ||
3015 | u16 val16, digctrl_kx1, digctrl_kx2; | ||
3016 | u8 lane; | ||
3017 | |||
3018 | lane = bnx2x_get_warpcore_lane(phy, params); | ||
3019 | |||
3020 | /* Clear XFI clock comp in non-10G single lane mode. */ | ||
3021 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
3022 | MDIO_WC_REG_RX66_CONTROL, &val16); | ||
3023 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3024 | MDIO_WC_REG_RX66_CONTROL, val16 & ~(3<<13)); | ||
3025 | |||
3026 | if (phy->req_line_speed == SPEED_AUTO_NEG) { | ||
3027 | /* SGMII Autoneg */ | ||
3028 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
3029 | MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16); | ||
3030 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3031 | MDIO_WC_REG_COMBO_IEEE0_MIICTRL, | ||
3032 | val16 | 0x1000); | ||
3033 | DP(NETIF_MSG_LINK, "set SGMII AUTONEG\n"); | ||
3034 | } else { | ||
3035 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
3036 | MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16); | ||
3037 | val16 &= 0xcfbf; | ||
3038 | switch (phy->req_line_speed) { | ||
3039 | case SPEED_10: | ||
3040 | break; | ||
3041 | case SPEED_100: | ||
3042 | val16 |= 0x2000; | ||
3043 | break; | ||
3044 | case SPEED_1000: | ||
3045 | val16 |= 0x0040; | ||
3046 | break; | ||
3047 | default: | ||
3048 | DP(NETIF_MSG_LINK, "Speed not supported: 0x%x" | ||
3049 | "\n", phy->req_line_speed); | ||
3050 | return; | ||
3051 | } | ||
3052 | |||
3053 | if (phy->req_duplex == DUPLEX_FULL) | ||
3054 | val16 |= 0x0100; | ||
3055 | |||
3056 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3057 | MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16); | ||
3058 | |||
3059 | DP(NETIF_MSG_LINK, "set SGMII force speed %d\n", | ||
3060 | phy->req_line_speed); | ||
3061 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
3062 | MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16); | ||
3063 | DP(NETIF_MSG_LINK, " (readback) %x\n", val16); | ||
3064 | } | ||
3065 | |||
3066 | /* SGMII Slave mode and disable signal detect */ | ||
3067 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
3068 | MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &digctrl_kx1); | ||
3069 | if (fiber_mode) | ||
3070 | digctrl_kx1 = 1; | ||
3071 | else | ||
3072 | digctrl_kx1 &= 0xff4a; | ||
3073 | |||
3074 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3075 | MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, | ||
3076 | digctrl_kx1); | ||
3077 | |||
3078 | /* Turn off parallel detect */ | ||
3079 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
3080 | MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &digctrl_kx2); | ||
3081 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3082 | MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, | ||
3083 | (digctrl_kx2 & ~(1<<2))); | ||
3084 | |||
3085 | /* Re-enable parallel detect */ | ||
3086 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3087 | MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, | ||
3088 | (digctrl_kx2 | (1<<2))); | ||
3089 | |||
3090 | /* Enable autodet */ | ||
3091 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3092 | MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, | ||
3093 | (digctrl_kx1 | 0x10)); | ||
3094 | } | ||
3095 | |||
3096 | static void bnx2x_warpcore_reset_lane(struct bnx2x *bp, | ||
3097 | struct bnx2x_phy *phy, | ||
3098 | u8 reset) | ||
3099 | { | ||
3100 | u16 val; | ||
3101 | /* Take lane out of reset after configuration is finished */ | ||
3102 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
3103 | MDIO_WC_REG_DIGITAL5_MISC6, &val); | ||
3104 | if (reset) | ||
3105 | val |= 0xC000; | ||
3106 | else | ||
3107 | val &= 0x3FFF; | ||
3108 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3109 | MDIO_WC_REG_DIGITAL5_MISC6, val); | ||
3110 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
3111 | MDIO_WC_REG_DIGITAL5_MISC6, &val); | ||
3112 | } | ||
3113 | |||
3114 | |||
3115 | /* Clear SFI/XFI link settings registers */ | ||
3116 | static void bnx2x_warpcore_clear_regs(struct bnx2x_phy *phy, | ||
3117 | struct link_params *params, | ||
3118 | u16 lane) | ||
3119 | { | ||
3120 | struct bnx2x *bp = params->bp; | ||
3121 | u16 val16; | ||
3122 | |||
3123 | /* Set XFI clock comp as default. */ | ||
3124 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
3125 | MDIO_WC_REG_RX66_CONTROL, &val16); | ||
3126 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3127 | MDIO_WC_REG_RX66_CONTROL, val16 | (3<<13)); | ||
3128 | |||
3129 | bnx2x_warpcore_reset_lane(bp, phy, 1); | ||
3130 | bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0); | ||
3131 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3132 | MDIO_WC_REG_FX100_CTRL1, 0x014a); | ||
3133 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3134 | MDIO_WC_REG_FX100_CTRL3, 0x0800); | ||
3135 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3136 | MDIO_WC_REG_DIGITAL4_MISC3, 0x8008); | ||
3137 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3138 | MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0x0195); | ||
3139 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3140 | MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x0007); | ||
3141 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3142 | MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, 0x0002); | ||
3143 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3144 | MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6000); | ||
3145 | lane = bnx2x_get_warpcore_lane(phy, params); | ||
3146 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3147 | MDIO_WC_REG_TX_FIR_TAP, 0x0000); | ||
3148 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3149 | MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, 0x0990); | ||
3150 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3151 | MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040); | ||
3152 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3153 | MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0x0140); | ||
3154 | bnx2x_warpcore_reset_lane(bp, phy, 0); | ||
3155 | } | ||
3156 | |||
3157 | static int bnx2x_get_mod_abs_int_cfg(struct bnx2x *bp, | ||
3158 | u32 chip_id, | ||
3159 | u32 shmem_base, u8 port, | ||
3160 | u8 *gpio_num, u8 *gpio_port) | ||
3161 | { | ||
3162 | u32 cfg_pin; | ||
3163 | *gpio_num = 0; | ||
3164 | *gpio_port = 0; | ||
3165 | if (CHIP_IS_E3(bp)) { | ||
3166 | cfg_pin = (REG_RD(bp, shmem_base + | ||
3167 | offsetof(struct shmem_region, | ||
3168 | dev_info.port_hw_config[port].e3_sfp_ctrl)) & | ||
3169 | PORT_HW_CFG_E3_MOD_ABS_MASK) >> | ||
3170 | PORT_HW_CFG_E3_MOD_ABS_SHIFT; | ||
3171 | |||
3172 | /* | ||
3173 | * Should not happen. This function called upon interrupt | ||
3174 | * triggered by GPIO ( since EPIO can only generate interrupts | ||
3175 | * to MCP). | ||
3176 | * So if this function was called and none of the GPIOs was set, | ||
3177 | * it means the shit hit the fan. | ||
3178 | */ | ||
3179 | if ((cfg_pin < PIN_CFG_GPIO0_P0) || | ||
3180 | (cfg_pin > PIN_CFG_GPIO3_P1)) { | ||
3181 | DP(NETIF_MSG_LINK, "ERROR: Invalid cfg pin %x for " | ||
3182 | "module detect indication\n", | ||
3183 | cfg_pin); | ||
3184 | return -EINVAL; | ||
3185 | } | ||
3186 | |||
3187 | *gpio_num = (cfg_pin - PIN_CFG_GPIO0_P0) & 0x3; | ||
3188 | *gpio_port = (cfg_pin - PIN_CFG_GPIO0_P0) >> 2; | ||
3189 | } else { | ||
3190 | *gpio_num = MISC_REGISTERS_GPIO_3; | ||
3191 | *gpio_port = port; | ||
3192 | } | ||
3193 | DP(NETIF_MSG_LINK, "MOD_ABS int GPIO%d_P%d\n", *gpio_num, *gpio_port); | ||
3194 | return 0; | ||
3195 | } | ||
3196 | |||
3197 | static int bnx2x_is_sfp_module_plugged(struct bnx2x_phy *phy, | ||
3198 | struct link_params *params) | ||
3199 | { | ||
3200 | struct bnx2x *bp = params->bp; | ||
3201 | u8 gpio_num, gpio_port; | ||
3202 | u32 gpio_val; | ||
3203 | if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id, | ||
3204 | params->shmem_base, params->port, | ||
3205 | &gpio_num, &gpio_port) != 0) | ||
3206 | return 0; | ||
3207 | gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port); | ||
3208 | |||
3209 | /* Call the handling function in case module is detected */ | ||
3210 | if (gpio_val == 0) | ||
3211 | return 1; | ||
3212 | else | ||
3213 | return 0; | ||
3214 | } | ||
3215 | |||
3216 | static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy, | ||
3217 | struct link_params *params, | ||
3218 | struct link_vars *vars) | ||
3219 | { | ||
3220 | struct bnx2x *bp = params->bp; | ||
3221 | u32 serdes_net_if; | ||
3222 | u8 fiber_mode; | ||
3223 | u16 lane = bnx2x_get_warpcore_lane(phy, params); | ||
3224 | serdes_net_if = (REG_RD(bp, params->shmem_base + | ||
3225 | offsetof(struct shmem_region, dev_info. | ||
3226 | port_hw_config[params->port].default_cfg)) & | ||
3227 | PORT_HW_CFG_NET_SERDES_IF_MASK); | ||
3228 | DP(NETIF_MSG_LINK, "Begin Warpcore init, link_speed %d, " | ||
3229 | "serdes_net_if = 0x%x\n", | ||
3230 | vars->line_speed, serdes_net_if); | ||
3231 | bnx2x_set_aer_mmd(params, phy); | ||
3232 | |||
3233 | vars->phy_flags |= PHY_XGXS_FLAG; | ||
3234 | if ((serdes_net_if == PORT_HW_CFG_NET_SERDES_IF_SGMII) || | ||
3235 | (phy->req_line_speed && | ||
3236 | ((phy->req_line_speed == SPEED_100) || | ||
3237 | (phy->req_line_speed == SPEED_10)))) { | ||
3238 | vars->phy_flags |= PHY_SGMII_FLAG; | ||
3239 | DP(NETIF_MSG_LINK, "Setting SGMII mode\n"); | ||
3240 | bnx2x_warpcore_clear_regs(phy, params, lane); | ||
3241 | bnx2x_warpcore_set_sgmii_speed(phy, params, 0); | ||
3242 | } else { | ||
3243 | switch (serdes_net_if) { | ||
3244 | case PORT_HW_CFG_NET_SERDES_IF_KR: | ||
3245 | /* Enable KR Auto Neg */ | ||
3246 | if (params->loopback_mode == LOOPBACK_NONE) | ||
3247 | bnx2x_warpcore_enable_AN_KR(phy, params, vars); | ||
3248 | else { | ||
3249 | DP(NETIF_MSG_LINK, "Setting KR 10G-Force\n"); | ||
3250 | bnx2x_warpcore_set_10G_KR(phy, params, vars); | ||
3251 | } | ||
3252 | break; | ||
3253 | |||
3254 | case PORT_HW_CFG_NET_SERDES_IF_XFI: | ||
3255 | bnx2x_warpcore_clear_regs(phy, params, lane); | ||
3256 | if (vars->line_speed == SPEED_10000) { | ||
3257 | DP(NETIF_MSG_LINK, "Setting 10G XFI\n"); | ||
3258 | bnx2x_warpcore_set_10G_XFI(phy, params, 1); | ||
3259 | } else { | ||
3260 | if (SINGLE_MEDIA_DIRECT(params)) { | ||
3261 | DP(NETIF_MSG_LINK, "1G Fiber\n"); | ||
3262 | fiber_mode = 1; | ||
3263 | } else { | ||
3264 | DP(NETIF_MSG_LINK, "10/100/1G SGMII\n"); | ||
3265 | fiber_mode = 0; | ||
3266 | } | ||
3267 | bnx2x_warpcore_set_sgmii_speed(phy, | ||
3268 | params, | ||
3269 | fiber_mode); | ||
3270 | } | ||
3271 | |||
3272 | break; | ||
3273 | |||
3274 | case PORT_HW_CFG_NET_SERDES_IF_SFI: | ||
3275 | |||
3276 | bnx2x_warpcore_clear_regs(phy, params, lane); | ||
3277 | if (vars->line_speed == SPEED_10000) { | ||
3278 | DP(NETIF_MSG_LINK, "Setting 10G SFI\n"); | ||
3279 | bnx2x_warpcore_set_10G_XFI(phy, params, 0); | ||
3280 | } else if (vars->line_speed == SPEED_1000) { | ||
3281 | DP(NETIF_MSG_LINK, "Setting 1G Fiber\n"); | ||
3282 | bnx2x_warpcore_set_sgmii_speed(phy, params, 1); | ||
3283 | } | ||
3284 | /* Issue Module detection */ | ||
3285 | if (bnx2x_is_sfp_module_plugged(phy, params)) | ||
3286 | bnx2x_sfp_module_detection(phy, params); | ||
3287 | break; | ||
3288 | |||
3289 | case PORT_HW_CFG_NET_SERDES_IF_DXGXS: | ||
3290 | if (vars->line_speed != SPEED_20000) { | ||
3291 | DP(NETIF_MSG_LINK, "Speed not supported yet\n"); | ||
3292 | return; | ||
3293 | } | ||
3294 | DP(NETIF_MSG_LINK, "Setting 20G DXGXS\n"); | ||
3295 | bnx2x_warpcore_set_20G_DXGXS(bp, phy, lane); | ||
3296 | /* Issue Module detection */ | ||
3297 | |||
3298 | bnx2x_sfp_module_detection(phy, params); | ||
3299 | break; | ||
3300 | |||
3301 | case PORT_HW_CFG_NET_SERDES_IF_KR2: | ||
3302 | if (vars->line_speed != SPEED_20000) { | ||
3303 | DP(NETIF_MSG_LINK, "Speed not supported yet\n"); | ||
3304 | return; | ||
3305 | } | ||
3306 | DP(NETIF_MSG_LINK, "Setting 20G KR2\n"); | ||
3307 | bnx2x_warpcore_set_20G_KR2(bp, phy); | ||
3308 | break; | ||
3309 | |||
3310 | default: | ||
3311 | DP(NETIF_MSG_LINK, "Unsupported Serdes Net Interface " | ||
3312 | "0x%x\n", serdes_net_if); | ||
3313 | return; | ||
3314 | } | ||
3315 | } | ||
3316 | |||
3317 | /* Take lane out of reset after configuration is finished */ | ||
3318 | bnx2x_warpcore_reset_lane(bp, phy, 0); | ||
3319 | DP(NETIF_MSG_LINK, "Exit config init\n"); | ||
3320 | } | ||
3321 | |||
3322 | static void bnx2x_sfp_e3_set_transmitter(struct link_params *params, | ||
3323 | struct bnx2x_phy *phy, | ||
3324 | u8 tx_en) | ||
3325 | { | ||
3326 | struct bnx2x *bp = params->bp; | ||
3327 | u32 cfg_pin; | ||
3328 | u8 port = params->port; | ||
3329 | |||
3330 | cfg_pin = REG_RD(bp, params->shmem_base + | ||
3331 | offsetof(struct shmem_region, | ||
3332 | dev_info.port_hw_config[port].e3_sfp_ctrl)) & | ||
3333 | PORT_HW_CFG_TX_LASER_MASK; | ||
3334 | /* Set the !tx_en since this pin is DISABLE_TX_LASER */ | ||
3335 | DP(NETIF_MSG_LINK, "Setting WC TX to %d\n", tx_en); | ||
3336 | /* For 20G, the expected pin to be used is 3 pins after the current */ | ||
3337 | |||
3338 | bnx2x_set_cfg_pin(bp, cfg_pin, tx_en ^ 1); | ||
3339 | if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G) | ||
3340 | bnx2x_set_cfg_pin(bp, cfg_pin + 3, tx_en ^ 1); | ||
3341 | } | ||
3342 | |||
3343 | static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy, | ||
3344 | struct link_params *params) | ||
3345 | { | ||
3346 | struct bnx2x *bp = params->bp; | ||
3347 | u16 val16; | ||
3348 | bnx2x_sfp_e3_set_transmitter(params, phy, 0); | ||
3349 | bnx2x_set_mdio_clk(bp, params->chip_id, params->port); | ||
3350 | bnx2x_set_aer_mmd(params, phy); | ||
3351 | /* Global register */ | ||
3352 | bnx2x_warpcore_reset_lane(bp, phy, 1); | ||
3353 | |||
3354 | /* Clear loopback settings (if any) */ | ||
3355 | /* 10G & 20G */ | ||
3356 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
3357 | MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16); | ||
3358 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3359 | MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 & | ||
3360 | 0xBFFF); | ||
3361 | |||
3362 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
3363 | MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16); | ||
3364 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3365 | MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 & 0xfffe); | ||
3366 | |||
3367 | /* Update those 1-copy registers */ | ||
3368 | CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, | ||
3369 | MDIO_AER_BLOCK_AER_REG, 0); | ||
3370 | /* Enable 1G MDIO (1-copy) */ | ||
3371 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
3372 | MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, | ||
3373 | &val16); | ||
3374 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3375 | MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, | ||
3376 | val16 & ~0x10); | ||
3377 | |||
3378 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
3379 | MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16); | ||
3380 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3381 | MDIO_WC_REG_XGXSBLK1_LANECTRL2, | ||
3382 | val16 & 0xff00); | ||
3383 | |||
3384 | } | ||
3385 | |||
3386 | static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy, | ||
3387 | struct link_params *params) | ||
3388 | { | ||
3389 | struct bnx2x *bp = params->bp; | ||
3390 | u16 val16; | ||
3391 | u32 lane; | ||
3392 | DP(NETIF_MSG_LINK, "Setting Warpcore loopback type %x, speed %d\n", | ||
3393 | params->loopback_mode, phy->req_line_speed); | ||
3394 | |||
3395 | if (phy->req_line_speed < SPEED_10000) { | ||
3396 | /* 10/100/1000 */ | ||
3397 | |||
3398 | /* Update those 1-copy registers */ | ||
3399 | CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, | ||
3400 | MDIO_AER_BLOCK_AER_REG, 0); | ||
3401 | /* Enable 1G MDIO (1-copy) */ | ||
3402 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
3403 | MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, | ||
3404 | &val16); | ||
3405 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3406 | MDIO_WC_REG_XGXSBLK0_XGXSCONTROL, | ||
3407 | val16 | 0x10); | ||
3408 | /* Set 1G loopback based on lane (1-copy) */ | ||
3409 | lane = bnx2x_get_warpcore_lane(phy, params); | ||
3410 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
3411 | MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16); | ||
3412 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3413 | MDIO_WC_REG_XGXSBLK1_LANECTRL2, | ||
3414 | val16 | (1<<lane)); | ||
3415 | |||
3416 | /* Switch back to 4-copy registers */ | ||
3417 | bnx2x_set_aer_mmd(params, phy); | ||
3418 | /* Global loopback, not recommended. */ | ||
3419 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
3420 | MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16); | ||
3421 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3422 | MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 | | ||
3423 | 0x4000); | ||
3424 | } else { | ||
3425 | /* 10G & 20G */ | ||
3426 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
3427 | MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16); | ||
3428 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3429 | MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 | | ||
3430 | 0x4000); | ||
3431 | |||
3432 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
3433 | MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16); | ||
3434 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
3435 | MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 | 0x1); | ||
3436 | } | ||
3437 | } | ||
3438 | |||
3439 | |||
2418 | void bnx2x_link_status_update(struct link_params *params, | 3440 | void bnx2x_link_status_update(struct link_params *params, |
2419 | struct link_vars *vars) | 3441 | struct link_vars *vars) |
2420 | { | 3442 | { |
@@ -2470,7 +3492,9 @@ void bnx2x_link_status_update(struct link_params *params, | |||
2470 | case LINK_10GTFD: | 3492 | case LINK_10GTFD: |
2471 | vars->line_speed = SPEED_10000; | 3493 | vars->line_speed = SPEED_10000; |
2472 | break; | 3494 | break; |
2473 | 3495 | case LINK_20GTFD: | |
3496 | vars->line_speed = SPEED_20000; | ||
3497 | break; | ||
2474 | default: | 3498 | default: |
2475 | break; | 3499 | break; |
2476 | } | 3500 | } |
@@ -2491,7 +3515,10 @@ void bnx2x_link_status_update(struct link_params *params, | |||
2491 | } else { | 3515 | } else { |
2492 | vars->phy_flags &= ~PHY_SGMII_FLAG; | 3516 | vars->phy_flags &= ~PHY_SGMII_FLAG; |
2493 | } | 3517 | } |
2494 | 3518 | if (vars->line_speed && | |
3519 | USES_WARPCORE(bp) && | ||
3520 | (vars->line_speed == SPEED_1000)) | ||
3521 | vars->phy_flags |= PHY_SGMII_FLAG; | ||
2495 | /* anything 10 and over uses the bmac */ | 3522 | /* anything 10 and over uses the bmac */ |
2496 | link_10g_plus = (vars->line_speed >= SPEED_10000); | 3523 | link_10g_plus = (vars->line_speed >= SPEED_10000); |
2497 | 3524 | ||
@@ -2499,12 +3526,12 @@ void bnx2x_link_status_update(struct link_params *params, | |||
2499 | if (USES_WARPCORE(bp)) | 3526 | if (USES_WARPCORE(bp)) |
2500 | vars->mac_type = MAC_TYPE_XMAC; | 3527 | vars->mac_type = MAC_TYPE_XMAC; |
2501 | else | 3528 | else |
2502 | vars->mac_type = MAC_TYPE_BMAC; | 3529 | vars->mac_type = MAC_TYPE_BMAC; |
2503 | } else { | 3530 | } else { |
2504 | if (USES_WARPCORE(bp)) | 3531 | if (USES_WARPCORE(bp)) |
2505 | vars->mac_type = MAC_TYPE_UMAC; | 3532 | vars->mac_type = MAC_TYPE_UMAC; |
2506 | else | 3533 | else |
2507 | vars->mac_type = MAC_TYPE_EMAC; | 3534 | vars->mac_type = MAC_TYPE_EMAC; |
2508 | } | 3535 | } |
2509 | } else { /* link down */ | 3536 | } else { /* link down */ |
2510 | DP(NETIF_MSG_LINK, "phy link down\n"); | 3537 | DP(NETIF_MSG_LINK, "phy link down\n"); |
@@ -2860,9 +3887,6 @@ static void bnx2x_program_serdes(struct bnx2x_phy *phy, | |||
2860 | if (vars->line_speed == SPEED_10000) | 3887 | if (vars->line_speed == SPEED_10000) |
2861 | reg_val |= | 3888 | reg_val |= |
2862 | MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4; | 3889 | MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4; |
2863 | if (vars->line_speed == SPEED_13000) | ||
2864 | reg_val |= | ||
2865 | MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G; | ||
2866 | } | 3890 | } |
2867 | 3891 | ||
2868 | CL22_WR_OVER_CL45(bp, phy, | 3892 | CL22_WR_OVER_CL45(bp, phy, |
@@ -3212,45 +4236,25 @@ static void bnx2x_xgxs_an_resolve(struct bnx2x_phy *phy, | |||
3212 | vars->link_status |= | 4236 | vars->link_status |= |
3213 | LINK_STATUS_PARALLEL_DETECTION_USED; | 4237 | LINK_STATUS_PARALLEL_DETECTION_USED; |
3214 | } | 4238 | } |
3215 | 4239 | static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy, | |
3216 | static int bnx2x_link_settings_status(struct bnx2x_phy *phy, | 4240 | struct link_params *params, |
3217 | struct link_params *params, | 4241 | struct link_vars *vars, |
3218 | struct link_vars *vars) | 4242 | u16 is_link_up, |
4243 | u16 speed_mask, | ||
4244 | u16 is_duplex) | ||
3219 | { | 4245 | { |
3220 | struct bnx2x *bp = params->bp; | 4246 | struct bnx2x *bp = params->bp; |
3221 | u16 new_line_speed, gp_status; | ||
3222 | int rc = 0; | ||
3223 | |||
3224 | /* Read gp_status */ | ||
3225 | CL22_RD_OVER_CL45(bp, phy, | ||
3226 | MDIO_REG_BANK_GP_STATUS, | ||
3227 | MDIO_GP_STATUS_TOP_AN_STATUS1, | ||
3228 | &gp_status); | ||
3229 | |||
3230 | if (phy->req_line_speed == SPEED_AUTO_NEG) | 4247 | if (phy->req_line_speed == SPEED_AUTO_NEG) |
3231 | vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED; | 4248 | vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED; |
3232 | if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { | 4249 | if (is_link_up) { |
3233 | DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n", | 4250 | DP(NETIF_MSG_LINK, "phy link up\n"); |
3234 | gp_status); | ||
3235 | 4251 | ||
3236 | vars->phy_link_up = 1; | 4252 | vars->phy_link_up = 1; |
3237 | vars->link_status |= LINK_STATUS_LINK_UP; | 4253 | vars->link_status |= LINK_STATUS_LINK_UP; |
3238 | 4254 | ||
3239 | if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS) | 4255 | switch (speed_mask) { |
3240 | vars->duplex = DUPLEX_FULL; | ||
3241 | else | ||
3242 | vars->duplex = DUPLEX_HALF; | ||
3243 | |||
3244 | if (SINGLE_MEDIA_DIRECT(params)) { | ||
3245 | bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status); | ||
3246 | if (phy->req_line_speed == SPEED_AUTO_NEG) | ||
3247 | bnx2x_xgxs_an_resolve(phy, params, vars, | ||
3248 | gp_status); | ||
3249 | } | ||
3250 | |||
3251 | switch (gp_status & GP_STATUS_SPEED_MASK) { | ||
3252 | case GP_STATUS_10M: | 4256 | case GP_STATUS_10M: |
3253 | new_line_speed = SPEED_10; | 4257 | vars->line_speed = SPEED_10; |
3254 | if (vars->duplex == DUPLEX_FULL) | 4258 | if (vars->duplex == DUPLEX_FULL) |
3255 | vars->link_status |= LINK_10TFD; | 4259 | vars->link_status |= LINK_10TFD; |
3256 | else | 4260 | else |
@@ -3258,7 +4262,7 @@ static int bnx2x_link_settings_status(struct bnx2x_phy *phy, | |||
3258 | break; | 4262 | break; |
3259 | 4263 | ||
3260 | case GP_STATUS_100M: | 4264 | case GP_STATUS_100M: |
3261 | new_line_speed = SPEED_100; | 4265 | vars->line_speed = SPEED_100; |
3262 | if (vars->duplex == DUPLEX_FULL) | 4266 | if (vars->duplex == DUPLEX_FULL) |
3263 | vars->link_status |= LINK_100TXFD; | 4267 | vars->link_status |= LINK_100TXFD; |
3264 | else | 4268 | else |
@@ -3267,7 +4271,7 @@ static int bnx2x_link_settings_status(struct bnx2x_phy *phy, | |||
3267 | 4271 | ||
3268 | case GP_STATUS_1G: | 4272 | case GP_STATUS_1G: |
3269 | case GP_STATUS_1G_KX: | 4273 | case GP_STATUS_1G_KX: |
3270 | new_line_speed = SPEED_1000; | 4274 | vars->line_speed = SPEED_1000; |
3271 | if (vars->duplex == DUPLEX_FULL) | 4275 | if (vars->duplex == DUPLEX_FULL) |
3272 | vars->link_status |= LINK_1000TFD; | 4276 | vars->link_status |= LINK_1000TFD; |
3273 | else | 4277 | else |
@@ -3275,7 +4279,7 @@ static int bnx2x_link_settings_status(struct bnx2x_phy *phy, | |||
3275 | break; | 4279 | break; |
3276 | 4280 | ||
3277 | case GP_STATUS_2_5G: | 4281 | case GP_STATUS_2_5G: |
3278 | new_line_speed = SPEED_2500; | 4282 | vars->line_speed = SPEED_2500; |
3279 | if (vars->duplex == DUPLEX_FULL) | 4283 | if (vars->duplex == DUPLEX_FULL) |
3280 | vars->link_status |= LINK_2500TFD; | 4284 | vars->link_status |= LINK_2500TFD; |
3281 | else | 4285 | else |
@@ -3286,25 +4290,28 @@ static int bnx2x_link_settings_status(struct bnx2x_phy *phy, | |||
3286 | case GP_STATUS_6G: | 4290 | case GP_STATUS_6G: |
3287 | DP(NETIF_MSG_LINK, | 4291 | DP(NETIF_MSG_LINK, |
3288 | "link speed unsupported gp_status 0x%x\n", | 4292 | "link speed unsupported gp_status 0x%x\n", |
3289 | gp_status); | 4293 | speed_mask); |
3290 | return -EINVAL; | 4294 | return -EINVAL; |
3291 | 4295 | ||
3292 | case GP_STATUS_10G_KX4: | 4296 | case GP_STATUS_10G_KX4: |
3293 | case GP_STATUS_10G_HIG: | 4297 | case GP_STATUS_10G_HIG: |
3294 | case GP_STATUS_10G_CX4: | 4298 | case GP_STATUS_10G_CX4: |
3295 | new_line_speed = SPEED_10000; | 4299 | case GP_STATUS_10G_KR: |
4300 | case GP_STATUS_10G_SFI: | ||
4301 | case GP_STATUS_10G_XFI: | ||
4302 | vars->line_speed = SPEED_10000; | ||
3296 | vars->link_status |= LINK_10GTFD; | 4303 | vars->link_status |= LINK_10GTFD; |
3297 | break; | 4304 | break; |
3298 | 4305 | case GP_STATUS_20G_DXGXS: | |
4306 | vars->line_speed = SPEED_20000; | ||
4307 | vars->link_status |= LINK_20GTFD; | ||
4308 | break; | ||
3299 | default: | 4309 | default: |
3300 | DP(NETIF_MSG_LINK, | 4310 | DP(NETIF_MSG_LINK, |
3301 | "link speed unsupported gp_status 0x%x\n", | 4311 | "link speed unsupported gp_status 0x%x\n", |
3302 | gp_status); | 4312 | speed_mask); |
3303 | return -EINVAL; | 4313 | return -EINVAL; |
3304 | } | 4314 | } |
3305 | |||
3306 | vars->line_speed = new_line_speed; | ||
3307 | |||
3308 | } else { /* link_down */ | 4315 | } else { /* link_down */ |
3309 | DP(NETIF_MSG_LINK, "phy link down\n"); | 4316 | DP(NETIF_MSG_LINK, "phy link down\n"); |
3310 | 4317 | ||
@@ -3313,7 +4320,47 @@ static int bnx2x_link_settings_status(struct bnx2x_phy *phy, | |||
3313 | vars->duplex = DUPLEX_FULL; | 4320 | vars->duplex = DUPLEX_FULL; |
3314 | vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; | 4321 | vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; |
3315 | vars->mac_type = MAC_TYPE_NONE; | 4322 | vars->mac_type = MAC_TYPE_NONE; |
4323 | } | ||
4324 | DP(NETIF_MSG_LINK, " phy_link_up %x line_speed %d\n", | ||
4325 | vars->phy_link_up, vars->line_speed); | ||
4326 | return 0; | ||
4327 | } | ||
4328 | |||
4329 | static int bnx2x_link_settings_status(struct bnx2x_phy *phy, | ||
4330 | struct link_params *params, | ||
4331 | struct link_vars *vars) | ||
4332 | { | ||
4333 | |||
4334 | struct bnx2x *bp = params->bp; | ||
4335 | |||
4336 | u16 gp_status, duplex = DUPLEX_HALF, link_up = 0, speed_mask; | ||
4337 | int rc = 0; | ||
3316 | 4338 | ||
4339 | /* Read gp_status */ | ||
4340 | CL22_RD_OVER_CL45(bp, phy, | ||
4341 | MDIO_REG_BANK_GP_STATUS, | ||
4342 | MDIO_GP_STATUS_TOP_AN_STATUS1, | ||
4343 | &gp_status); | ||
4344 | if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS) | ||
4345 | duplex = DUPLEX_FULL; | ||
4346 | if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) | ||
4347 | link_up = 1; | ||
4348 | speed_mask = gp_status & GP_STATUS_SPEED_MASK; | ||
4349 | DP(NETIF_MSG_LINK, "gp_status 0x%x, is_link_up %d, speed_mask 0x%x\n", | ||
4350 | gp_status, link_up, speed_mask); | ||
4351 | rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, speed_mask, | ||
4352 | duplex); | ||
4353 | if (rc == -EINVAL) | ||
4354 | return rc; | ||
4355 | |||
4356 | if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { | ||
4357 | if (SINGLE_MEDIA_DIRECT(params)) { | ||
4358 | bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status); | ||
4359 | if (phy->req_line_speed == SPEED_AUTO_NEG) | ||
4360 | bnx2x_xgxs_an_resolve(phy, params, vars, | ||
4361 | gp_status); | ||
4362 | } | ||
4363 | } else { /* link_down */ | ||
3317 | if ((phy->req_line_speed == SPEED_AUTO_NEG) && | 4364 | if ((phy->req_line_speed == SPEED_AUTO_NEG) && |
3318 | SINGLE_MEDIA_DIRECT(params)) { | 4365 | SINGLE_MEDIA_DIRECT(params)) { |
3319 | /* Check signal is detected */ | 4366 | /* Check signal is detected */ |
@@ -3321,13 +4368,86 @@ static int bnx2x_link_settings_status(struct bnx2x_phy *phy, | |||
3321 | } | 4368 | } |
3322 | } | 4369 | } |
3323 | 4370 | ||
3324 | DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %x line_speed %x\n", | ||
3325 | gp_status, vars->phy_link_up, vars->line_speed); | ||
3326 | DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x link_status 0x%x\n", | 4371 | DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x link_status 0x%x\n", |
3327 | vars->duplex, vars->flow_ctrl, vars->link_status); | 4372 | vars->duplex, vars->flow_ctrl, vars->link_status); |
3328 | return rc; | 4373 | return rc; |
3329 | } | 4374 | } |
3330 | 4375 | ||
4376 | static int bnx2x_warpcore_read_status(struct bnx2x_phy *phy, | ||
4377 | struct link_params *params, | ||
4378 | struct link_vars *vars) | ||
4379 | { | ||
4380 | |||
4381 | struct bnx2x *bp = params->bp; | ||
4382 | |||
4383 | u8 lane; | ||
4384 | u16 gp_status1, gp_speed, link_up, duplex = DUPLEX_FULL; | ||
4385 | int rc = 0; | ||
4386 | lane = bnx2x_get_warpcore_lane(phy, params); | ||
4387 | /* Read gp_status */ | ||
4388 | if (phy->req_line_speed > SPEED_10000) { | ||
4389 | u16 temp_link_up; | ||
4390 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
4391 | 1, &temp_link_up); | ||
4392 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
4393 | 1, &link_up); | ||
4394 | DP(NETIF_MSG_LINK, "PCS RX link status = 0x%x-->0x%x\n", | ||
4395 | temp_link_up, link_up); | ||
4396 | link_up &= (1<<2); | ||
4397 | if (link_up) | ||
4398 | bnx2x_ext_phy_resolve_fc(phy, params, vars); | ||
4399 | } else { | ||
4400 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
4401 | MDIO_WC_REG_GP2_STATUS_GP_2_1, &gp_status1); | ||
4402 | DP(NETIF_MSG_LINK, "0x81d1 = 0x%x\n", gp_status1); | ||
4403 | /* Check for either KR or generic link up. */ | ||
4404 | gp_status1 = ((gp_status1 >> 8) & 0xf) | | ||
4405 | ((gp_status1 >> 12) & 0xf); | ||
4406 | link_up = gp_status1 & (1 << lane); | ||
4407 | if (link_up && SINGLE_MEDIA_DIRECT(params)) { | ||
4408 | u16 pd, gp_status4; | ||
4409 | if (phy->req_line_speed == SPEED_AUTO_NEG) { | ||
4410 | /* Check Autoneg complete */ | ||
4411 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
4412 | MDIO_WC_REG_GP2_STATUS_GP_2_4, | ||
4413 | &gp_status4); | ||
4414 | if (gp_status4 & ((1<<12)<<lane)) | ||
4415 | vars->link_status |= | ||
4416 | LINK_STATUS_AUTO_NEGOTIATE_COMPLETE; | ||
4417 | |||
4418 | /* Check parallel detect used */ | ||
4419 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
4420 | MDIO_WC_REG_PAR_DET_10G_STATUS, | ||
4421 | &pd); | ||
4422 | if (pd & (1<<15)) | ||
4423 | vars->link_status |= | ||
4424 | LINK_STATUS_PARALLEL_DETECTION_USED; | ||
4425 | } | ||
4426 | bnx2x_ext_phy_resolve_fc(phy, params, vars); | ||
4427 | } | ||
4428 | } | ||
4429 | |||
4430 | if (lane < 2) { | ||
4431 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
4432 | MDIO_WC_REG_GP2_STATUS_GP_2_2, &gp_speed); | ||
4433 | } else { | ||
4434 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
4435 | MDIO_WC_REG_GP2_STATUS_GP_2_3, &gp_speed); | ||
4436 | } | ||
4437 | DP(NETIF_MSG_LINK, "lane %d gp_speed 0x%x\n", lane, gp_speed); | ||
4438 | |||
4439 | if ((lane & 1) == 0) | ||
4440 | gp_speed <<= 8; | ||
4441 | gp_speed &= 0x3f00; | ||
4442 | |||
4443 | |||
4444 | rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, gp_speed, | ||
4445 | duplex); | ||
4446 | |||
4447 | DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x link_status 0x%x\n", | ||
4448 | vars->duplex, vars->flow_ctrl, vars->link_status); | ||
4449 | return rc; | ||
4450 | } | ||
3331 | static void bnx2x_set_gmii_tx_driver(struct link_params *params) | 4451 | static void bnx2x_set_gmii_tx_driver(struct link_params *params) |
3332 | { | 4452 | { |
3333 | struct bnx2x *bp = params->bp; | 4453 | struct bnx2x *bp = params->bp; |
@@ -3555,7 +4675,11 @@ static void bnx2x_link_int_enable(struct link_params *params) | |||
3555 | struct bnx2x *bp = params->bp; | 4675 | struct bnx2x *bp = params->bp; |
3556 | 4676 | ||
3557 | /* Setting the status to report on link up for either XGXS or SerDes */ | 4677 | /* Setting the status to report on link up for either XGXS or SerDes */ |
3558 | if (params->switch_cfg == SWITCH_CFG_10G) { | 4678 | if (CHIP_IS_E3(bp)) { |
4679 | mask = NIG_MASK_XGXS0_LINK_STATUS; | ||
4680 | if (!(SINGLE_MEDIA_DIRECT(params))) | ||
4681 | mask |= NIG_MASK_MI_INT; | ||
4682 | } else if (params->switch_cfg == SWITCH_CFG_10G) { | ||
3559 | mask = (NIG_MASK_XGXS0_LINK10G | | 4683 | mask = (NIG_MASK_XGXS0_LINK10G | |
3560 | NIG_MASK_XGXS0_LINK_STATUS); | 4684 | NIG_MASK_XGXS0_LINK_STATUS); |
3561 | DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n"); | 4685 | DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n"); |
@@ -3628,11 +4752,11 @@ static void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port, | |||
3628 | } | 4752 | } |
3629 | 4753 | ||
3630 | static void bnx2x_link_int_ack(struct link_params *params, | 4754 | static void bnx2x_link_int_ack(struct link_params *params, |
3631 | struct link_vars *vars, u8 is_10g) | 4755 | struct link_vars *vars, u8 is_10g_plus) |
3632 | { | 4756 | { |
3633 | struct bnx2x *bp = params->bp; | 4757 | struct bnx2x *bp = params->bp; |
3634 | u8 port = params->port; | 4758 | u8 port = params->port; |
3635 | 4759 | u32 mask; | |
3636 | /* | 4760 | /* |
3637 | * First reset all status we assume only one line will be | 4761 | * First reset all status we assume only one line will be |
3638 | * change at a time | 4762 | * change at a time |
@@ -3642,43 +4766,30 @@ static void bnx2x_link_int_ack(struct link_params *params, | |||
3642 | NIG_STATUS_XGXS0_LINK_STATUS | | 4766 | NIG_STATUS_XGXS0_LINK_STATUS | |
3643 | NIG_STATUS_SERDES0_LINK_STATUS)); | 4767 | NIG_STATUS_SERDES0_LINK_STATUS)); |
3644 | if (vars->phy_link_up) { | 4768 | if (vars->phy_link_up) { |
3645 | if (is_10g) { | 4769 | if (USES_WARPCORE(bp)) |
3646 | /* | 4770 | mask = NIG_STATUS_XGXS0_LINK_STATUS; |
3647 | * Disable the 10G link interrupt by writing 1 to the | 4771 | else { |
3648 | * status register | 4772 | if (is_10g_plus) |
3649 | */ | 4773 | mask = NIG_STATUS_XGXS0_LINK10G; |
3650 | DP(NETIF_MSG_LINK, "10G XGXS phy link up\n"); | 4774 | else if (params->switch_cfg == SWITCH_CFG_10G) { |
3651 | bnx2x_bits_en(bp, | 4775 | /* |
3652 | NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, | 4776 | * Disable the link interrupt by writing 1 to |
3653 | NIG_STATUS_XGXS0_LINK10G); | 4777 | * the relevant lane in the status register |
3654 | 4778 | */ | |
3655 | } else if (params->switch_cfg == SWITCH_CFG_10G) { | 4779 | u32 ser_lane = |
3656 | /* | 4780 | ((params->lane_config & |
3657 | * Disable the link interrupt by writing 1 to the | ||
3658 | * relevant lane in the status register | ||
3659 | */ | ||
3660 | u32 ser_lane = ((params->lane_config & | ||
3661 | PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> | 4781 | PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> |
3662 | PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); | 4782 | PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); |
3663 | 4783 | mask = ((1 << ser_lane) << | |
3664 | DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n", | 4784 | NIG_STATUS_XGXS0_LINK_STATUS_SIZE); |
3665 | vars->line_speed); | 4785 | } else |
3666 | bnx2x_bits_en(bp, | 4786 | mask = NIG_STATUS_SERDES0_LINK_STATUS; |
3667 | NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, | ||
3668 | ((1 << ser_lane) << | ||
3669 | NIG_STATUS_XGXS0_LINK_STATUS_SIZE)); | ||
3670 | |||
3671 | } else { /* SerDes */ | ||
3672 | DP(NETIF_MSG_LINK, "SerDes phy link up\n"); | ||
3673 | /* | ||
3674 | * Disable the link interrupt by writing 1 to the status | ||
3675 | * register | ||
3676 | */ | ||
3677 | bnx2x_bits_en(bp, | ||
3678 | NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, | ||
3679 | NIG_STATUS_SERDES0_LINK_STATUS); | ||
3680 | } | 4787 | } |
3681 | 4788 | DP(NETIF_MSG_LINK, "Ack link up interrupt with mask 0x%x\n", | |
4789 | mask); | ||
4790 | bnx2x_bits_en(bp, | ||
4791 | NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, | ||
4792 | mask); | ||
3682 | } | 4793 | } |
3683 | } | 4794 | } |
3684 | 4795 | ||
@@ -3775,15 +4886,18 @@ static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy, | |||
3775 | struct bnx2x *bp = params->bp; | 4886 | struct bnx2x *bp = params->bp; |
3776 | 4887 | ||
3777 | if (phy->req_line_speed != SPEED_1000) { | 4888 | if (phy->req_line_speed != SPEED_1000) { |
3778 | u32 md_devad; | 4889 | u32 md_devad = 0; |
3779 | 4890 | ||
3780 | DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n"); | 4891 | DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n"); |
3781 | 4892 | ||
3782 | /* change the uni_phy_addr in the nig */ | 4893 | if (!CHIP_IS_E3(bp)) { |
3783 | md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD + | 4894 | /* change the uni_phy_addr in the nig */ |
3784 | port*0x18)); | 4895 | md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD + |
4896 | port*0x18)); | ||
3785 | 4897 | ||
3786 | REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5); | 4898 | REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, |
4899 | 0x5); | ||
4900 | } | ||
3787 | 4901 | ||
3788 | bnx2x_cl45_write(bp, phy, | 4902 | bnx2x_cl45_write(bp, phy, |
3789 | 5, | 4903 | 5, |
@@ -3800,8 +4914,11 @@ static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy, | |||
3800 | /* set aer mmd back */ | 4914 | /* set aer mmd back */ |
3801 | bnx2x_set_aer_mmd(params, phy); | 4915 | bnx2x_set_aer_mmd(params, phy); |
3802 | 4916 | ||
3803 | /* and md_devad */ | 4917 | if (!CHIP_IS_E3(bp)) { |
3804 | REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, md_devad); | 4918 | /* and md_devad */ |
4919 | REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, | ||
4920 | md_devad); | ||
4921 | } | ||
3805 | } else { | 4922 | } else { |
3806 | u16 mii_ctrl; | 4923 | u16 mii_ctrl; |
3807 | DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n"); | 4924 | DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n"); |
@@ -3875,7 +4992,9 @@ int bnx2x_set_led(struct link_params *params, | |||
3875 | (tmp | EMAC_LED_OVERRIDE)); | 4992 | (tmp | EMAC_LED_OVERRIDE)); |
3876 | return rc; | 4993 | return rc; |
3877 | } | 4994 | } |
3878 | } else if (SINGLE_MEDIA_DIRECT(params)) { | 4995 | } else if (SINGLE_MEDIA_DIRECT(params) && |
4996 | (CHIP_IS_E1x(bp) || | ||
4997 | CHIP_IS_E2(bp))) { | ||
3879 | /* | 4998 | /* |
3880 | * This is a work-around for HW issue found when link | 4999 | * This is a work-around for HW issue found when link |
3881 | * is up in CL73 | 5000 | * is up in CL73 |
@@ -3934,14 +5053,42 @@ int bnx2x_test_link(struct link_params *params, struct link_vars *vars, | |||
3934 | u16 gp_status = 0, phy_index = 0; | 5053 | u16 gp_status = 0, phy_index = 0; |
3935 | u8 ext_phy_link_up = 0, serdes_phy_type; | 5054 | u8 ext_phy_link_up = 0, serdes_phy_type; |
3936 | struct link_vars temp_vars; | 5055 | struct link_vars temp_vars; |
3937 | 5056 | struct bnx2x_phy *int_phy = ¶ms->phy[INT_PHY]; | |
3938 | CL22_RD_OVER_CL45(bp, ¶ms->phy[INT_PHY], | 5057 | |
5058 | if (CHIP_IS_E3(bp)) { | ||
5059 | u16 link_up; | ||
5060 | if (params->req_line_speed[LINK_CONFIG_IDX(INT_PHY)] | ||
5061 | > SPEED_10000) { | ||
5062 | /* Check 20G link */ | ||
5063 | bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD, | ||
5064 | 1, &link_up); | ||
5065 | bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD, | ||
5066 | 1, &link_up); | ||
5067 | link_up &= (1<<2); | ||
5068 | } else { | ||
5069 | /* Check 10G link and below*/ | ||
5070 | u8 lane = bnx2x_get_warpcore_lane(int_phy, params); | ||
5071 | bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD, | ||
5072 | MDIO_WC_REG_GP2_STATUS_GP_2_1, | ||
5073 | &gp_status); | ||
5074 | gp_status = ((gp_status >> 8) & 0xf) | | ||
5075 | ((gp_status >> 12) & 0xf); | ||
5076 | link_up = gp_status & (1 << lane); | ||
5077 | } | ||
5078 | if (!link_up) | ||
5079 | return -ESRCH; | ||
5080 | } else { | ||
5081 | CL22_RD_OVER_CL45(bp, int_phy, | ||
3939 | MDIO_REG_BANK_GP_STATUS, | 5082 | MDIO_REG_BANK_GP_STATUS, |
3940 | MDIO_GP_STATUS_TOP_AN_STATUS1, | 5083 | MDIO_GP_STATUS_TOP_AN_STATUS1, |
3941 | &gp_status); | 5084 | &gp_status); |
3942 | /* link is up only if both local phy and external phy are up */ | 5085 | /* link is up only if both local phy and external phy are up */ |
3943 | if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)) | 5086 | if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)) |
3944 | return -ESRCH; | 5087 | return -ESRCH; |
5088 | } | ||
5089 | /* In XGXS loopback mode, do not check external PHY */ | ||
5090 | if (params->loopback_mode == LOOPBACK_XGXS) | ||
5091 | return 0; | ||
3945 | 5092 | ||
3946 | switch (params->num_phys) { | 5093 | switch (params->num_phys) { |
3947 | case 1: | 5094 | case 1: |
@@ -3997,8 +5144,8 @@ static int bnx2x_link_initialize(struct link_params *params, | |||
3997 | * (no external phys), or this board has external phy which requires | 5144 | * (no external phys), or this board has external phy which requires |
3998 | * to first. | 5145 | * to first. |
3999 | */ | 5146 | */ |
4000 | 5147 | if (!USES_WARPCORE(bp)) | |
4001 | bnx2x_prepare_xgxs(¶ms->phy[INT_PHY], params, vars); | 5148 | bnx2x_prepare_xgxs(¶ms->phy[INT_PHY], params, vars); |
4002 | /* init ext phy and enable link state int */ | 5149 | /* init ext phy and enable link state int */ |
4003 | non_ext_phy = (SINGLE_MEDIA_DIRECT(params) || | 5150 | non_ext_phy = (SINGLE_MEDIA_DIRECT(params) || |
4004 | (params->loopback_mode == LOOPBACK_XGXS)); | 5151 | (params->loopback_mode == LOOPBACK_XGXS)); |
@@ -4007,7 +5154,9 @@ static int bnx2x_link_initialize(struct link_params *params, | |||
4007 | (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) || | 5154 | (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) || |
4008 | (params->loopback_mode == LOOPBACK_EXT_PHY)) { | 5155 | (params->loopback_mode == LOOPBACK_EXT_PHY)) { |
4009 | struct bnx2x_phy *phy = ¶ms->phy[INT_PHY]; | 5156 | struct bnx2x_phy *phy = ¶ms->phy[INT_PHY]; |
4010 | if (vars->line_speed == SPEED_AUTO_NEG) | 5157 | if (vars->line_speed == SPEED_AUTO_NEG && |
5158 | (CHIP_IS_E1x(bp) || | ||
5159 | CHIP_IS_E2(bp))) | ||
4011 | bnx2x_set_parallel_detection(phy, params); | 5160 | bnx2x_set_parallel_detection(phy, params); |
4012 | if (params->phy[INT_PHY].config_init) | 5161 | if (params->phy[INT_PHY].config_init) |
4013 | params->phy[INT_PHY].config_init(phy, | 5162 | params->phy[INT_PHY].config_init(phy, |
@@ -4203,7 +5352,7 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) | |||
4203 | struct bnx2x *bp = params->bp; | 5352 | struct bnx2x *bp = params->bp; |
4204 | struct link_vars phy_vars[MAX_PHYS]; | 5353 | struct link_vars phy_vars[MAX_PHYS]; |
4205 | u8 port = params->port; | 5354 | u8 port = params->port; |
4206 | u8 link_10g, phy_index; | 5355 | u8 link_10g_plus, phy_index; |
4207 | u8 ext_phy_link_up = 0, cur_link_up; | 5356 | u8 ext_phy_link_up = 0, cur_link_up; |
4208 | int rc = 0; | 5357 | int rc = 0; |
4209 | u8 is_mi_int = 0; | 5358 | u8 is_mi_int = 0; |
@@ -4221,6 +5370,9 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) | |||
4221 | phy_vars[phy_index].fault_detected = 0; | 5370 | phy_vars[phy_index].fault_detected = 0; |
4222 | } | 5371 | } |
4223 | 5372 | ||
5373 | if (USES_WARPCORE(bp)) | ||
5374 | bnx2x_set_aer_mmd(params, ¶ms->phy[INT_PHY]); | ||
5375 | |||
4224 | DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n", | 5376 | DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n", |
4225 | port, (vars->phy_flags & PHY_XGXS_FLAG), | 5377 | port, (vars->phy_flags & PHY_XGXS_FLAG), |
4226 | REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4)); | 5378 | REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4)); |
@@ -4392,14 +5544,9 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) | |||
4392 | } | 5544 | } |
4393 | 5545 | ||
4394 | /* anything 10 and over uses the bmac */ | 5546 | /* anything 10 and over uses the bmac */ |
4395 | link_10g = ((vars->line_speed == SPEED_10000) || | 5547 | link_10g_plus = (vars->line_speed >= SPEED_10000); |
4396 | (vars->line_speed == SPEED_12000) || | ||
4397 | (vars->line_speed == SPEED_12500) || | ||
4398 | (vars->line_speed == SPEED_13000) || | ||
4399 | (vars->line_speed == SPEED_15000) || | ||
4400 | (vars->line_speed == SPEED_16000)); | ||
4401 | 5548 | ||
4402 | bnx2x_link_int_ack(params, vars, link_10g); | 5549 | bnx2x_link_int_ack(params, vars, link_10g_plus); |
4403 | 5550 | ||
4404 | /* | 5551 | /* |
4405 | * In case external phy link is up, and internal link is down | 5552 | * In case external phy link is up, and internal link is down |
@@ -4440,7 +5587,7 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) | |||
4440 | (phy_vars[active_external_phy].fault_detected == 0)); | 5587 | (phy_vars[active_external_phy].fault_detected == 0)); |
4441 | 5588 | ||
4442 | if (vars->link_up) | 5589 | if (vars->link_up) |
4443 | rc = bnx2x_update_link_up(params, vars, link_10g); | 5590 | rc = bnx2x_update_link_up(params, vars, link_10g_plus); |
4444 | else | 5591 | else |
4445 | rc = bnx2x_update_link_down(params, vars); | 5592 | rc = bnx2x_update_link_down(params, vars); |
4446 | 5593 | ||
@@ -5135,9 +6282,10 @@ static u8 bnx2x_get_gpio_port(struct link_params *params) | |||
5135 | swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); | 6282 | swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); |
5136 | return gpio_port ^ (swap_val && swap_override); | 6283 | return gpio_port ^ (swap_val && swap_override); |
5137 | } | 6284 | } |
5138 | static void bnx2x_sfp_set_transmitter(struct link_params *params, | 6285 | |
5139 | struct bnx2x_phy *phy, | 6286 | static void bnx2x_sfp_e1e2_set_transmitter(struct link_params *params, |
5140 | u8 tx_en) | 6287 | struct bnx2x_phy *phy, |
6288 | u8 tx_en) | ||
5141 | { | 6289 | { |
5142 | u16 val; | 6290 | u16 val; |
5143 | u8 port = params->port; | 6291 | u8 port = params->port; |
@@ -5192,6 +6340,18 @@ static void bnx2x_sfp_set_transmitter(struct link_params *params, | |||
5192 | } | 6340 | } |
5193 | } | 6341 | } |
5194 | 6342 | ||
6343 | static void bnx2x_sfp_set_transmitter(struct link_params *params, | ||
6344 | struct bnx2x_phy *phy, | ||
6345 | u8 tx_en) | ||
6346 | { | ||
6347 | struct bnx2x *bp = params->bp; | ||
6348 | DP(NETIF_MSG_LINK, "Setting SFP+ transmitter to %d\n", tx_en); | ||
6349 | if (CHIP_IS_E3(bp)) | ||
6350 | bnx2x_sfp_e3_set_transmitter(params, phy, tx_en); | ||
6351 | else | ||
6352 | bnx2x_sfp_e1e2_set_transmitter(params, phy, tx_en); | ||
6353 | } | ||
6354 | |||
5195 | static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, | 6355 | static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, |
5196 | struct link_params *params, | 6356 | struct link_params *params, |
5197 | u16 addr, u8 byte_cnt, u8 *o_buf) | 6357 | u16 addr, u8 byte_cnt, u8 *o_buf) |
@@ -5258,6 +6418,42 @@ static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, | |||
5258 | return -EINVAL; | 6418 | return -EINVAL; |
5259 | } | 6419 | } |
5260 | 6420 | ||
6421 | static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, | ||
6422 | struct link_params *params, | ||
6423 | u16 addr, u8 byte_cnt, | ||
6424 | u8 *o_buf) | ||
6425 | { | ||
6426 | int rc = 0; | ||
6427 | u8 i, j = 0, cnt = 0; | ||
6428 | u32 data_array[4]; | ||
6429 | u16 addr32; | ||
6430 | struct bnx2x *bp = params->bp; | ||
6431 | /*DP(NETIF_MSG_LINK, "bnx2x_direct_read_sfp_module_eeprom:" | ||
6432 | " addr %d, cnt %d\n", | ||
6433 | addr, byte_cnt);*/ | ||
6434 | if (byte_cnt > 16) { | ||
6435 | DP(NETIF_MSG_LINK, "Reading from eeprom is" | ||
6436 | " is limited to 16 bytes\n"); | ||
6437 | return -EINVAL; | ||
6438 | } | ||
6439 | |||
6440 | /* 4 byte aligned address */ | ||
6441 | addr32 = addr & (~0x3); | ||
6442 | do { | ||
6443 | rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt, | ||
6444 | data_array); | ||
6445 | } while ((rc != 0) && (++cnt < I2C_WA_RETRY_CNT)); | ||
6446 | |||
6447 | if (rc == 0) { | ||
6448 | for (i = (addr - addr32); i < byte_cnt + (addr - addr32); i++) { | ||
6449 | o_buf[j] = *((u8 *)data_array + i); | ||
6450 | j++; | ||
6451 | } | ||
6452 | } | ||
6453 | |||
6454 | return rc; | ||
6455 | } | ||
6456 | |||
5261 | static int bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, | 6457 | static int bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, |
5262 | struct link_params *params, | 6458 | struct link_params *params, |
5263 | u16 addr, u8 byte_cnt, u8 *o_buf) | 6459 | u16 addr, u8 byte_cnt, u8 *o_buf) |
@@ -5360,6 +6556,10 @@ int bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, | |||
5360 | rc = bnx2x_8727_read_sfp_module_eeprom(phy, params, addr, | 6556 | rc = bnx2x_8727_read_sfp_module_eeprom(phy, params, addr, |
5361 | byte_cnt, o_buf); | 6557 | byte_cnt, o_buf); |
5362 | break; | 6558 | break; |
6559 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: | ||
6560 | rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, params, addr, | ||
6561 | byte_cnt, o_buf); | ||
6562 | break; | ||
5363 | } | 6563 | } |
5364 | return rc; | 6564 | return rc; |
5365 | } | 6565 | } |
@@ -5573,8 +6773,8 @@ static void bnx2x_8727_power_module(struct bnx2x *bp, | |||
5573 | * In the GPIO register, bit 4 is use to determine if the GPIOs are | 6773 | * In the GPIO register, bit 4 is use to determine if the GPIOs are |
5574 | * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for | 6774 | * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for |
5575 | * output | 6775 | * output |
5576 | * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0 | 6776 | * Bits 0-1 determine the GPIOs value for OUTPUT in case bit 4 val is 0 |
5577 | * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1 | 6777 | * Bits 8-9 determine the GPIOs value for INPUT in case bit 4 val is 1 |
5578 | * where the 1st bit is the over-current(only input), and 2nd bit is | 6778 | * where the 1st bit is the over-current(only input), and 2nd bit is |
5579 | * for power( only output ) | 6779 | * for power( only output ) |
5580 | * | 6780 | * |
@@ -5703,7 +6903,7 @@ static void bnx2x_8727_specific_func(struct bnx2x_phy *phy, | |||
5703 | } | 6903 | } |
5704 | } | 6904 | } |
5705 | 6905 | ||
5706 | static void bnx2x_set_sfp_module_fault_led(struct link_params *params, | 6906 | static void bnx2x_set_e1e2_module_fault_led(struct link_params *params, |
5707 | u8 gpio_mode) | 6907 | u8 gpio_mode) |
5708 | { | 6908 | { |
5709 | struct bnx2x *bp = params->bp; | 6909 | struct bnx2x *bp = params->bp; |
@@ -5735,6 +6935,58 @@ static void bnx2x_set_sfp_module_fault_led(struct link_params *params, | |||
5735 | } | 6935 | } |
5736 | } | 6936 | } |
5737 | 6937 | ||
6938 | static void bnx2x_set_e3_module_fault_led(struct link_params *params, | ||
6939 | u8 gpio_mode) | ||
6940 | { | ||
6941 | u32 pin_cfg; | ||
6942 | u8 port = params->port; | ||
6943 | struct bnx2x *bp = params->bp; | ||
6944 | pin_cfg = (REG_RD(bp, params->shmem_base + | ||
6945 | offsetof(struct shmem_region, | ||
6946 | dev_info.port_hw_config[port].e3_sfp_ctrl)) & | ||
6947 | PORT_HW_CFG_E3_FAULT_MDL_LED_MASK) >> | ||
6948 | PORT_HW_CFG_E3_FAULT_MDL_LED_SHIFT; | ||
6949 | DP(NETIF_MSG_LINK, "Setting Fault LED to %d using pin cfg %d\n", | ||
6950 | gpio_mode, pin_cfg); | ||
6951 | bnx2x_set_cfg_pin(bp, pin_cfg, gpio_mode); | ||
6952 | } | ||
6953 | |||
6954 | static void bnx2x_set_sfp_module_fault_led(struct link_params *params, | ||
6955 | u8 gpio_mode) | ||
6956 | { | ||
6957 | struct bnx2x *bp = params->bp; | ||
6958 | DP(NETIF_MSG_LINK, "Setting SFP+ module fault LED to %d\n", gpio_mode); | ||
6959 | if (CHIP_IS_E3(bp)) { | ||
6960 | /* | ||
6961 | * Low ==> if SFP+ module is supported otherwise | ||
6962 | * High ==> if SFP+ module is not on the approved vendor list | ||
6963 | */ | ||
6964 | bnx2x_set_e3_module_fault_led(params, gpio_mode); | ||
6965 | } else | ||
6966 | bnx2x_set_e1e2_module_fault_led(params, gpio_mode); | ||
6967 | } | ||
6968 | |||
6969 | static void bnx2x_warpcore_power_module(struct link_params *params, | ||
6970 | struct bnx2x_phy *phy, | ||
6971 | u8 power) | ||
6972 | { | ||
6973 | u32 pin_cfg; | ||
6974 | struct bnx2x *bp = params->bp; | ||
6975 | |||
6976 | pin_cfg = (REG_RD(bp, params->shmem_base + | ||
6977 | offsetof(struct shmem_region, | ||
6978 | dev_info.port_hw_config[params->port].e3_sfp_ctrl)) & | ||
6979 | PORT_HW_CFG_E3_PWR_DIS_MASK) >> | ||
6980 | PORT_HW_CFG_E3_PWR_DIS_SHIFT; | ||
6981 | DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n", | ||
6982 | power, pin_cfg); | ||
6983 | /* | ||
6984 | * Low ==> corresponding SFP+ module is powered | ||
6985 | * high ==> the SFP+ module is powered down | ||
6986 | */ | ||
6987 | bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1); | ||
6988 | } | ||
6989 | |||
5738 | static void bnx2x_power_sfp_module(struct link_params *params, | 6990 | static void bnx2x_power_sfp_module(struct link_params *params, |
5739 | struct bnx2x_phy *phy, | 6991 | struct bnx2x_phy *phy, |
5740 | u8 power) | 6992 | u8 power) |
@@ -5747,10 +6999,48 @@ static void bnx2x_power_sfp_module(struct link_params *params, | |||
5747 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722: | 6999 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722: |
5748 | bnx2x_8727_power_module(params->bp, phy, power); | 7000 | bnx2x_8727_power_module(params->bp, phy, power); |
5749 | break; | 7001 | break; |
7002 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: | ||
7003 | bnx2x_warpcore_power_module(params, phy, power); | ||
7004 | break; | ||
5750 | default: | 7005 | default: |
5751 | break; | 7006 | break; |
5752 | } | 7007 | } |
5753 | } | 7008 | } |
7009 | static void bnx2x_warpcore_set_limiting_mode(struct link_params *params, | ||
7010 | struct bnx2x_phy *phy, | ||
7011 | u16 edc_mode) | ||
7012 | { | ||
7013 | u16 val = 0; | ||
7014 | u16 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT; | ||
7015 | struct bnx2x *bp = params->bp; | ||
7016 | |||
7017 | u8 lane = bnx2x_get_warpcore_lane(phy, params); | ||
7018 | /* This is a global register which controls all lanes */ | ||
7019 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
7020 | MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val); | ||
7021 | val &= ~(0xf << (lane << 2)); | ||
7022 | |||
7023 | switch (edc_mode) { | ||
7024 | case EDC_MODE_LINEAR: | ||
7025 | case EDC_MODE_LIMITING: | ||
7026 | mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT; | ||
7027 | break; | ||
7028 | case EDC_MODE_PASSIVE_DAC: | ||
7029 | mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_DAC; | ||
7030 | break; | ||
7031 | default: | ||
7032 | break; | ||
7033 | } | ||
7034 | |||
7035 | val |= (mode << (lane << 2)); | ||
7036 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | ||
7037 | MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, val); | ||
7038 | /* A must read */ | ||
7039 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | ||
7040 | MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val); | ||
7041 | |||
7042 | |||
7043 | } | ||
5754 | 7044 | ||
5755 | static void bnx2x_set_limiting_mode(struct link_params *params, | 7045 | static void bnx2x_set_limiting_mode(struct link_params *params, |
5756 | struct bnx2x_phy *phy, | 7046 | struct bnx2x_phy *phy, |
@@ -5764,6 +7054,9 @@ static void bnx2x_set_limiting_mode(struct link_params *params, | |||
5764 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722: | 7054 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722: |
5765 | bnx2x_8727_set_limiting_mode(params->bp, phy, edc_mode); | 7055 | bnx2x_8727_set_limiting_mode(params->bp, phy, edc_mode); |
5766 | break; | 7056 | break; |
7057 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: | ||
7058 | bnx2x_warpcore_set_limiting_mode(params, phy, edc_mode); | ||
7059 | break; | ||
5767 | } | 7060 | } |
5768 | } | 7061 | } |
5769 | 7062 | ||
@@ -5828,23 +7121,33 @@ int bnx2x_sfp_module_detection(struct bnx2x_phy *phy, | |||
5828 | void bnx2x_handle_module_detect_int(struct link_params *params) | 7121 | void bnx2x_handle_module_detect_int(struct link_params *params) |
5829 | { | 7122 | { |
5830 | struct bnx2x *bp = params->bp; | 7123 | struct bnx2x *bp = params->bp; |
5831 | struct bnx2x_phy *phy = ¶ms->phy[EXT_PHY1]; | 7124 | struct bnx2x_phy *phy; |
5832 | u32 gpio_val; | 7125 | u32 gpio_val; |
5833 | u8 port = params->port; | 7126 | u8 gpio_num, gpio_port; |
7127 | if (CHIP_IS_E3(bp)) | ||
7128 | phy = ¶ms->phy[INT_PHY]; | ||
7129 | else | ||
7130 | phy = ¶ms->phy[EXT_PHY1]; | ||
7131 | |||
7132 | if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id, params->shmem_base, | ||
7133 | params->port, &gpio_num, &gpio_port) == | ||
7134 | -EINVAL) { | ||
7135 | DP(NETIF_MSG_LINK, "Failed to get MOD_ABS interrupt config\n"); | ||
7136 | return; | ||
7137 | } | ||
5834 | 7138 | ||
5835 | /* Set valid module led off */ | 7139 | /* Set valid module led off */ |
5836 | bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_HIGH); | 7140 | bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_HIGH); |
5837 | 7141 | ||
5838 | /* Get current gpio val reflecting module plugged in / out*/ | 7142 | /* Get current gpio val reflecting module plugged in / out*/ |
5839 | gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port); | 7143 | gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port); |
5840 | 7144 | ||
5841 | /* Call the handling function in case module is detected */ | 7145 | /* Call the handling function in case module is detected */ |
5842 | if (gpio_val == 0) { | 7146 | if (gpio_val == 0) { |
5843 | bnx2x_power_sfp_module(params, phy, 1); | 7147 | bnx2x_power_sfp_module(params, phy, 1); |
5844 | bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3, | 7148 | bnx2x_set_gpio_int(bp, gpio_num, |
5845 | MISC_REGISTERS_GPIO_INT_OUTPUT_CLR, | 7149 | MISC_REGISTERS_GPIO_INT_OUTPUT_CLR, |
5846 | port); | 7150 | gpio_port); |
5847 | |||
5848 | if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0) | 7151 | if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0) |
5849 | bnx2x_sfp_module_detection(phy, params); | 7152 | bnx2x_sfp_module_detection(phy, params); |
5850 | else | 7153 | else |
@@ -5855,9 +7158,9 @@ void bnx2x_handle_module_detect_int(struct link_params *params) | |||
5855 | port_feature_config[params->port]. | 7158 | port_feature_config[params->port]. |
5856 | config)); | 7159 | config)); |
5857 | 7160 | ||
5858 | bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3, | 7161 | bnx2x_set_gpio_int(bp, gpio_num, |
5859 | MISC_REGISTERS_GPIO_INT_OUTPUT_SET, | 7162 | MISC_REGISTERS_GPIO_INT_OUTPUT_SET, |
5860 | port); | 7163 | gpio_port); |
5861 | /* | 7164 | /* |
5862 | * Module was plugged out. | 7165 | * Module was plugged out. |
5863 | * Disable transmit for this module | 7166 | * Disable transmit for this module |
@@ -7762,6 +9065,43 @@ static struct bnx2x_phy phy_xgxs = { | |||
7762 | .set_link_led = (set_link_led_t)NULL, | 9065 | .set_link_led = (set_link_led_t)NULL, |
7763 | .phy_specific_func = (phy_specific_func_t)NULL | 9066 | .phy_specific_func = (phy_specific_func_t)NULL |
7764 | }; | 9067 | }; |
9068 | static struct bnx2x_phy phy_warpcore = { | ||
9069 | .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT, | ||
9070 | .addr = 0xff, | ||
9071 | .def_md_devad = 0, | ||
9072 | .flags = FLAGS_HW_LOCK_REQUIRED, | ||
9073 | .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, | ||
9074 | .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, | ||
9075 | .mdio_ctrl = 0, | ||
9076 | .supported = (SUPPORTED_10baseT_Half | | ||
9077 | SUPPORTED_10baseT_Full | | ||
9078 | SUPPORTED_100baseT_Half | | ||
9079 | SUPPORTED_100baseT_Full | | ||
9080 | SUPPORTED_1000baseT_Full | | ||
9081 | SUPPORTED_10000baseT_Full | | ||
9082 | SUPPORTED_20000baseKR2_Full | | ||
9083 | SUPPORTED_20000baseMLD2_Full | | ||
9084 | SUPPORTED_FIBRE | | ||
9085 | SUPPORTED_Autoneg | | ||
9086 | SUPPORTED_Pause | | ||
9087 | SUPPORTED_Asym_Pause), | ||
9088 | .media_type = ETH_PHY_UNSPECIFIED, | ||
9089 | .ver_addr = 0, | ||
9090 | .req_flow_ctrl = 0, | ||
9091 | .req_line_speed = 0, | ||
9092 | .speed_cap_mask = 0, | ||
9093 | /* req_duplex = */0, | ||
9094 | /* rsrv = */0, | ||
9095 | .config_init = (config_init_t)bnx2x_warpcore_config_init, | ||
9096 | .read_status = (read_status_t)bnx2x_warpcore_read_status, | ||
9097 | .link_reset = (link_reset_t)bnx2x_warpcore_link_reset, | ||
9098 | .config_loopback = (config_loopback_t)bnx2x_set_warpcore_loopback, | ||
9099 | .format_fw_ver = (format_fw_ver_t)NULL, | ||
9100 | .hw_reset = (hw_reset_t)NULL, | ||
9101 | .set_link_led = (set_link_led_t)NULL, | ||
9102 | .phy_specific_func = (phy_specific_func_t)NULL | ||
9103 | }; | ||
9104 | |||
7765 | 9105 | ||
7766 | static struct bnx2x_phy phy_7101 = { | 9106 | static struct bnx2x_phy phy_7101 = { |
7767 | .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, | 9107 | .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, |
@@ -8126,22 +9466,105 @@ static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, | |||
8126 | dev_info.port_feature_config[port].link_config)) & | 9466 | dev_info.port_feature_config[port].link_config)) & |
8127 | PORT_FEATURE_CONNECTED_SWITCH_MASK); | 9467 | PORT_FEATURE_CONNECTED_SWITCH_MASK); |
8128 | chip_id = REG_RD(bp, MISC_REG_CHIP_NUM) << 16; | 9468 | chip_id = REG_RD(bp, MISC_REG_CHIP_NUM) << 16; |
8129 | switch (switch_cfg) { | 9469 | DP(NETIF_MSG_LINK, ":chip_id = 0x%x\n", chip_id); |
8130 | case SWITCH_CFG_1G: | 9470 | if (USES_WARPCORE(bp)) { |
8131 | phy_addr = REG_RD(bp, | 9471 | u32 serdes_net_if; |
8132 | NIG_REG_SERDES0_CTRL_PHY_ADDR + | ||
8133 | port * 0x10); | ||
8134 | *phy = phy_serdes; | ||
8135 | break; | ||
8136 | case SWITCH_CFG_10G: | ||
8137 | phy_addr = REG_RD(bp, | 9472 | phy_addr = REG_RD(bp, |
8138 | NIG_REG_XGXS0_CTRL_PHY_ADDR + | 9473 | MISC_REG_WC0_CTRL_PHY_ADDR); |
8139 | port * 0x18); | 9474 | *phy = phy_warpcore; |
8140 | *phy = phy_xgxs; | 9475 | if (REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR) == 0x3) |
8141 | break; | 9476 | phy->flags |= FLAGS_4_PORT_MODE; |
8142 | default: | 9477 | else |
8143 | DP(NETIF_MSG_LINK, "Invalid switch_cfg\n"); | 9478 | phy->flags &= ~FLAGS_4_PORT_MODE; |
8144 | return -EINVAL; | 9479 | /* Check Dual mode */ |
9480 | serdes_net_if = (REG_RD(bp, shmem_base + | ||
9481 | offsetof(struct shmem_region, dev_info. | ||
9482 | port_hw_config[port].default_cfg)) & | ||
9483 | PORT_HW_CFG_NET_SERDES_IF_MASK); | ||
9484 | /* | ||
9485 | * Set the appropriate supported and flags indications per | ||
9486 | * interface type of the chip | ||
9487 | */ | ||
9488 | switch (serdes_net_if) { | ||
9489 | case PORT_HW_CFG_NET_SERDES_IF_SGMII: | ||
9490 | phy->supported &= (SUPPORTED_10baseT_Half | | ||
9491 | SUPPORTED_10baseT_Full | | ||
9492 | SUPPORTED_100baseT_Half | | ||
9493 | SUPPORTED_100baseT_Full | | ||
9494 | SUPPORTED_1000baseT_Full | | ||
9495 | SUPPORTED_FIBRE | | ||
9496 | SUPPORTED_Autoneg | | ||
9497 | SUPPORTED_Pause | | ||
9498 | SUPPORTED_Asym_Pause); | ||
9499 | phy->media_type = ETH_PHY_BASE_T; | ||
9500 | break; | ||
9501 | case PORT_HW_CFG_NET_SERDES_IF_XFI: | ||
9502 | phy->media_type = ETH_PHY_XFP_FIBER; | ||
9503 | break; | ||
9504 | case PORT_HW_CFG_NET_SERDES_IF_SFI: | ||
9505 | phy->supported &= (SUPPORTED_1000baseT_Full | | ||
9506 | SUPPORTED_10000baseT_Full | | ||
9507 | SUPPORTED_FIBRE | | ||
9508 | SUPPORTED_Pause | | ||
9509 | SUPPORTED_Asym_Pause); | ||
9510 | phy->media_type = ETH_PHY_SFP_FIBER; | ||
9511 | break; | ||
9512 | case PORT_HW_CFG_NET_SERDES_IF_KR: | ||
9513 | phy->media_type = ETH_PHY_KR; | ||
9514 | phy->supported &= (SUPPORTED_1000baseT_Full | | ||
9515 | SUPPORTED_10000baseT_Full | | ||
9516 | SUPPORTED_FIBRE | | ||
9517 | SUPPORTED_Autoneg | | ||
9518 | SUPPORTED_Pause | | ||
9519 | SUPPORTED_Asym_Pause); | ||
9520 | break; | ||
9521 | case PORT_HW_CFG_NET_SERDES_IF_DXGXS: | ||
9522 | phy->media_type = ETH_PHY_KR; | ||
9523 | phy->flags |= FLAGS_WC_DUAL_MODE; | ||
9524 | phy->supported &= (SUPPORTED_20000baseMLD2_Full | | ||
9525 | SUPPORTED_FIBRE | | ||
9526 | SUPPORTED_Pause | | ||
9527 | SUPPORTED_Asym_Pause); | ||
9528 | break; | ||
9529 | case PORT_HW_CFG_NET_SERDES_IF_KR2: | ||
9530 | phy->media_type = ETH_PHY_KR; | ||
9531 | phy->flags |= FLAGS_WC_DUAL_MODE; | ||
9532 | phy->supported &= (SUPPORTED_20000baseKR2_Full | | ||
9533 | SUPPORTED_FIBRE | | ||
9534 | SUPPORTED_Pause | | ||
9535 | SUPPORTED_Asym_Pause); | ||
9536 | break; | ||
9537 | default: | ||
9538 | DP(NETIF_MSG_LINK, "Unknown WC interface type 0x%x\n", | ||
9539 | serdes_net_if); | ||
9540 | break; | ||
9541 | } | ||
9542 | |||
9543 | /* | ||
9544 | * Enable MDC/MDIO work-around for E3 A0 since free running MDC | ||
9545 | * was not set as expected. For B0, ECO will be enabled so there | ||
9546 | * won't be an issue there | ||
9547 | */ | ||
9548 | if (CHIP_REV(bp) == CHIP_REV_Ax) | ||
9549 | phy->flags |= FLAGS_MDC_MDIO_WA; | ||
9550 | } else { | ||
9551 | switch (switch_cfg) { | ||
9552 | case SWITCH_CFG_1G: | ||
9553 | phy_addr = REG_RD(bp, | ||
9554 | NIG_REG_SERDES0_CTRL_PHY_ADDR + | ||
9555 | port * 0x10); | ||
9556 | *phy = phy_serdes; | ||
9557 | break; | ||
9558 | case SWITCH_CFG_10G: | ||
9559 | phy_addr = REG_RD(bp, | ||
9560 | NIG_REG_XGXS0_CTRL_PHY_ADDR + | ||
9561 | port * 0x18); | ||
9562 | *phy = phy_xgxs; | ||
9563 | break; | ||
9564 | default: | ||
9565 | DP(NETIF_MSG_LINK, "Invalid switch_cfg\n"); | ||
9566 | return -EINVAL; | ||
9567 | } | ||
8145 | } | 9568 | } |
8146 | phy->addr = (u8)phy_addr; | 9569 | phy->addr = (u8)phy_addr; |
8147 | phy->mdio_ctrl = bnx2x_get_emac_base(bp, | 9570 | phy->mdio_ctrl = bnx2x_get_emac_base(bp, |
@@ -8509,7 +9932,13 @@ void bnx2x_init_xmac_loopback(struct link_params *params, | |||
8509 | * Set WC to loopback mode since link is required to provide clock | 9932 | * Set WC to loopback mode since link is required to provide clock |
8510 | * to the XMAC in 20G mode | 9933 | * to the XMAC in 20G mode |
8511 | */ | 9934 | */ |
8512 | 9935 | if (vars->line_speed == SPEED_20000) { | |
9936 | bnx2x_set_aer_mmd(params, ¶ms->phy[0]); | ||
9937 | bnx2x_warpcore_reset_lane(bp, ¶ms->phy[0], 0); | ||
9938 | params->phy[INT_PHY].config_loopback( | ||
9939 | ¶ms->phy[INT_PHY], | ||
9940 | params); | ||
9941 | } | ||
8513 | bnx2x_xmac_enable(params, vars, 1); | 9942 | bnx2x_xmac_enable(params, vars, 1); |
8514 | REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); | 9943 | REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); |
8515 | } | 9944 | } |
@@ -8718,6 +10147,7 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars, | |||
8718 | REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0); | 10147 | REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0); |
8719 | } | 10148 | } |
8720 | vars->link_up = 0; | 10149 | vars->link_up = 0; |
10150 | vars->phy_flags = 0; | ||
8721 | return 0; | 10151 | return 0; |
8722 | } | 10152 | } |
8723 | 10153 | ||
@@ -8743,14 +10173,14 @@ static int bnx2x_8073_common_init_phy(struct bnx2x *bp, | |||
8743 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { | 10173 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { |
8744 | u32 shmem_base, shmem2_base; | 10174 | u32 shmem_base, shmem2_base; |
8745 | /* In E2, same phy is using for port0 of the two paths */ | 10175 | /* In E2, same phy is using for port0 of the two paths */ |
8746 | if (CHIP_IS_E2(bp)) { | 10176 | if (CHIP_IS_E1x(bp)) { |
8747 | shmem_base = shmem_base_path[port]; | ||
8748 | shmem2_base = shmem2_base_path[port]; | ||
8749 | port_of_path = 0; | ||
8750 | } else { | ||
8751 | shmem_base = shmem_base_path[0]; | 10177 | shmem_base = shmem_base_path[0]; |
8752 | shmem2_base = shmem2_base_path[0]; | 10178 | shmem2_base = shmem2_base_path[0]; |
8753 | port_of_path = port; | 10179 | port_of_path = port; |
10180 | } else { | ||
10181 | shmem_base = shmem_base_path[port]; | ||
10182 | shmem2_base = shmem2_base_path[port]; | ||
10183 | port_of_path = 0; | ||
8754 | } | 10184 | } |
8755 | 10185 | ||
8756 | /* Extract the ext phy address for the port */ | 10186 | /* Extract the ext phy address for the port */ |
@@ -8794,10 +10224,10 @@ static int bnx2x_8073_common_init_phy(struct bnx2x *bp, | |||
8794 | 10224 | ||
8795 | /* PART2 - Download firmware to both phys */ | 10225 | /* PART2 - Download firmware to both phys */ |
8796 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { | 10226 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { |
8797 | if (CHIP_IS_E2(bp)) | 10227 | if (CHIP_IS_E1x(bp)) |
8798 | port_of_path = 0; | ||
8799 | else | ||
8800 | port_of_path = port; | 10228 | port_of_path = port; |
10229 | else | ||
10230 | port_of_path = 0; | ||
8801 | 10231 | ||
8802 | DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n", | 10232 | DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n", |
8803 | phy_blk[port]->addr); | 10233 | phy_blk[port]->addr); |
@@ -8871,12 +10301,12 @@ static int bnx2x_8726_common_init_phy(struct bnx2x *bp, | |||
8871 | u32 shmem_base, shmem2_base; | 10301 | u32 shmem_base, shmem2_base; |
8872 | 10302 | ||
8873 | /* In E2, same phy is using for port0 of the two paths */ | 10303 | /* In E2, same phy is using for port0 of the two paths */ |
8874 | if (CHIP_IS_E2(bp)) { | 10304 | if (CHIP_IS_E1x(bp)) { |
8875 | shmem_base = shmem_base_path[port]; | ||
8876 | shmem2_base = shmem2_base_path[port]; | ||
8877 | } else { | ||
8878 | shmem_base = shmem_base_path[0]; | 10305 | shmem_base = shmem_base_path[0]; |
8879 | shmem2_base = shmem2_base_path[0]; | 10306 | shmem2_base = shmem2_base_path[0]; |
10307 | } else { | ||
10308 | shmem_base = shmem_base_path[port]; | ||
10309 | shmem2_base = shmem2_base_path[port]; | ||
8880 | } | 10310 | } |
8881 | /* Extract the ext phy address for the port */ | 10311 | /* Extract the ext phy address for the port */ |
8882 | if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, | 10312 | if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, |
@@ -8985,14 +10415,14 @@ static int bnx2x_8727_common_init_phy(struct bnx2x *bp, | |||
8985 | u32 shmem_base, shmem2_base; | 10415 | u32 shmem_base, shmem2_base; |
8986 | 10416 | ||
8987 | /* In E2, same phy is using for port0 of the two paths */ | 10417 | /* In E2, same phy is using for port0 of the two paths */ |
8988 | if (CHIP_IS_E2(bp)) { | 10418 | if (CHIP_IS_E1x(bp)) { |
8989 | shmem_base = shmem_base_path[port]; | ||
8990 | shmem2_base = shmem2_base_path[port]; | ||
8991 | port_of_path = 0; | ||
8992 | } else { | ||
8993 | shmem_base = shmem_base_path[0]; | 10419 | shmem_base = shmem_base_path[0]; |
8994 | shmem2_base = shmem2_base_path[0]; | 10420 | shmem2_base = shmem2_base_path[0]; |
8995 | port_of_path = port; | 10421 | port_of_path = port; |
10422 | } else { | ||
10423 | shmem_base = shmem_base_path[port]; | ||
10424 | shmem2_base = shmem2_base_path[port]; | ||
10425 | port_of_path = 0; | ||
8996 | } | 10426 | } |
8997 | 10427 | ||
8998 | /* Extract the ext phy address for the port */ | 10428 | /* Extract the ext phy address for the port */ |
@@ -9027,10 +10457,10 @@ static int bnx2x_8727_common_init_phy(struct bnx2x *bp, | |||
9027 | } | 10457 | } |
9028 | /* PART2 - Download firmware to both phys */ | 10458 | /* PART2 - Download firmware to both phys */ |
9029 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { | 10459 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { |
9030 | if (CHIP_IS_E2(bp)) | 10460 | if (CHIP_IS_E1x(bp)) |
9031 | port_of_path = 0; | ||
9032 | else | ||
9033 | port_of_path = port; | 10461 | port_of_path = port; |
10462 | else | ||
10463 | port_of_path = 0; | ||
9034 | DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n", | 10464 | DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n", |
9035 | phy_blk[port]->addr); | 10465 | phy_blk[port]->addr); |
9036 | if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], | 10466 | if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], |
@@ -9091,13 +10521,17 @@ int bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[], | |||
9091 | u32 shmem2_base_path[], u32 chip_id) | 10521 | u32 shmem2_base_path[], u32 chip_id) |
9092 | { | 10522 | { |
9093 | int rc = 0; | 10523 | int rc = 0; |
9094 | u32 phy_ver; | 10524 | u32 phy_ver, val; |
9095 | u8 phy_index; | 10525 | u8 phy_index = 0; |
9096 | u32 ext_phy_type, ext_phy_config; | 10526 | u32 ext_phy_type, ext_phy_config; |
9097 | bnx2x_set_mdio_clk(bp, chip_id, PORT_0); | 10527 | bnx2x_set_mdio_clk(bp, chip_id, PORT_0); |
9098 | bnx2x_set_mdio_clk(bp, chip_id, PORT_1); | 10528 | bnx2x_set_mdio_clk(bp, chip_id, PORT_1); |
9099 | DP(NETIF_MSG_LINK, "Begin common phy init\n"); | 10529 | DP(NETIF_MSG_LINK, "Begin common phy init\n"); |
9100 | 10530 | if (CHIP_IS_E3(bp)) { | |
10531 | /* Enable EPIO */ | ||
10532 | val = REG_RD(bp, MISC_REG_GEN_PURP_HWG); | ||
10533 | REG_WR(bp, MISC_REG_GEN_PURP_HWG, val | 1); | ||
10534 | } | ||
9101 | /* Check if common init was already done */ | 10535 | /* Check if common init was already done */ |
9102 | phy_ver = REG_RD(bp, shmem_base_path[0] + | 10536 | phy_ver = REG_RD(bp, shmem_base_path[0] + |
9103 | offsetof(struct shmem_region, | 10537 | offsetof(struct shmem_region, |
@@ -9183,8 +10617,14 @@ void bnx2x_init_mod_abs_int(struct bnx2x *bp, struct link_vars *vars, | |||
9183 | u8 gpio_num = 0xff, gpio_port = 0xff, phy_index; | 10617 | u8 gpio_num = 0xff, gpio_port = 0xff, phy_index; |
9184 | u32 val; | 10618 | u32 val; |
9185 | u32 offset, aeu_mask, swap_val, swap_override, sync_offset; | 10619 | u32 offset, aeu_mask, swap_val, swap_override, sync_offset; |
9186 | 10620 | if (CHIP_IS_E3(bp)) { | |
9187 | { | 10621 | if (bnx2x_get_mod_abs_int_cfg(bp, chip_id, |
10622 | shmem_base, | ||
10623 | port, | ||
10624 | &gpio_num, | ||
10625 | &gpio_port) != 0) | ||
10626 | return; | ||
10627 | } else { | ||
9188 | struct bnx2x_phy phy; | 10628 | struct bnx2x_phy phy; |
9189 | for (phy_index = EXT_PHY1; phy_index < MAX_PHYS; | 10629 | for (phy_index = EXT_PHY1; phy_index < MAX_PHYS; |
9190 | phy_index++) { | 10630 | phy_index++) { |
diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index 12602f18fae8..82bc021bdf07 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h | |||
@@ -33,12 +33,13 @@ | |||
33 | #define BNX2X_FLOW_CTRL_BOTH PORT_FEATURE_FLOW_CONTROL_BOTH | 33 | #define BNX2X_FLOW_CTRL_BOTH PORT_FEATURE_FLOW_CONTROL_BOTH |
34 | #define BNX2X_FLOW_CTRL_NONE PORT_FEATURE_FLOW_CONTROL_NONE | 34 | #define BNX2X_FLOW_CTRL_NONE PORT_FEATURE_FLOW_CONTROL_NONE |
35 | 35 | ||
36 | #define NET_SERDES_IF_XFI 1 | ||
37 | #define NET_SERDES_IF_SFI 2 | ||
38 | #define NET_SERDES_IF_KR 3 | ||
39 | #define NET_SERDES_IF_DXGXS 4 | ||
40 | |||
36 | #define SPEED_AUTO_NEG 0 | 41 | #define SPEED_AUTO_NEG 0 |
37 | #define SPEED_12000 12000 | 42 | #define SPEED_20000 20000 |
38 | #define SPEED_12500 12500 | ||
39 | #define SPEED_13000 13000 | ||
40 | #define SPEED_15000 15000 | ||
41 | #define SPEED_16000 16000 | ||
42 | 43 | ||
43 | #define SFP_EEPROM_VENDOR_NAME_ADDR 0x14 | 44 | #define SFP_EEPROM_VENDOR_NAME_ADDR 0x14 |
44 | #define SFP_EEPROM_VENDOR_NAME_SIZE 16 | 45 | #define SFP_EEPROM_VENDOR_NAME_SIZE 16 |
@@ -46,6 +47,12 @@ | |||
46 | #define SFP_EEPROM_VENDOR_OUI_SIZE 3 | 47 | #define SFP_EEPROM_VENDOR_OUI_SIZE 3 |
47 | #define SFP_EEPROM_PART_NO_ADDR 0x28 | 48 | #define SFP_EEPROM_PART_NO_ADDR 0x28 |
48 | #define SFP_EEPROM_PART_NO_SIZE 16 | 49 | #define SFP_EEPROM_PART_NO_SIZE 16 |
50 | #define SFP_EEPROM_REVISION_ADDR 0x38 | ||
51 | #define SFP_EEPROM_REVISION_SIZE 4 | ||
52 | #define SFP_EEPROM_SERIAL_ADDR 0x44 | ||
53 | #define SFP_EEPROM_SERIAL_SIZE 16 | ||
54 | #define SFP_EEPROM_DATE_ADDR 0x54 /* ASCII YYMMDD */ | ||
55 | #define SFP_EEPROM_DATE_SIZE 6 | ||
49 | #define PWR_FLT_ERR_MSG_LEN 250 | 56 | #define PWR_FLT_ERR_MSG_LEN 250 |
50 | 57 | ||
51 | #define XGXS_EXT_PHY_TYPE(ext_phy_config) \ | 58 | #define XGXS_EXT_PHY_TYPE(ext_phy_config) \ |
@@ -62,7 +69,18 @@ | |||
62 | #define SINGLE_MEDIA(params) (params->num_phys == 2) | 69 | #define SINGLE_MEDIA(params) (params->num_phys == 2) |
63 | /* Dual Media board contains two external phy with different media */ | 70 | /* Dual Media board contains two external phy with different media */ |
64 | #define DUAL_MEDIA(params) (params->num_phys == 3) | 71 | #define DUAL_MEDIA(params) (params->num_phys == 3) |
72 | |||
73 | #define FW_PARAM_PHY_ADDR_MASK 0x000000FF | ||
74 | #define FW_PARAM_PHY_TYPE_MASK 0x0000FF00 | ||
75 | #define FW_PARAM_MDIO_CTRL_MASK 0xFFFF0000 | ||
65 | #define FW_PARAM_MDIO_CTRL_OFFSET 16 | 76 | #define FW_PARAM_MDIO_CTRL_OFFSET 16 |
77 | #define FW_PARAM_PHY_ADDR(fw_param) (fw_param & \ | ||
78 | FW_PARAM_PHY_ADDR_MASK) | ||
79 | #define FW_PARAM_PHY_TYPE(fw_param) (fw_param & \ | ||
80 | FW_PARAM_PHY_TYPE_MASK) | ||
81 | #define FW_PARAM_MDIO_CTRL(fw_param) ((fw_param & \ | ||
82 | FW_PARAM_MDIO_CTRL_MASK) >> \ | ||
83 | FW_PARAM_MDIO_CTRL_OFFSET) | ||
66 | #define FW_PARAM_SET(phy_addr, phy_type, mdio_access) \ | 84 | #define FW_PARAM_SET(phy_addr, phy_type, mdio_access) \ |
67 | (phy_addr | phy_type | mdio_access << FW_PARAM_MDIO_CTRL_OFFSET) | 85 | (phy_addr | phy_type | mdio_access << FW_PARAM_MDIO_CTRL_OFFSET) |
68 | 86 | ||
@@ -121,9 +139,12 @@ struct bnx2x_phy { | |||
121 | #define FLAGS_FAN_FAILURE_DET_REQ (1<<2) | 139 | #define FLAGS_FAN_FAILURE_DET_REQ (1<<2) |
122 | /* Initialize first the XGXS and only then the phy itself */ | 140 | /* Initialize first the XGXS and only then the phy itself */ |
123 | #define FLAGS_INIT_XGXS_FIRST (1<<3) | 141 | #define FLAGS_INIT_XGXS_FIRST (1<<3) |
142 | #define FLAGS_WC_DUAL_MODE (1<<4) | ||
124 | #define FLAGS_4_PORT_MODE (1<<5) | 143 | #define FLAGS_4_PORT_MODE (1<<5) |
125 | #define FLAGS_REARM_LATCH_SIGNAL (1<<6) | 144 | #define FLAGS_REARM_LATCH_SIGNAL (1<<6) |
126 | #define FLAGS_SFP_NOT_APPROVED (1<<7) | 145 | #define FLAGS_SFP_NOT_APPROVED (1<<7) |
146 | #define FLAGS_MDC_MDIO_WA (1<<8) | ||
147 | #define FLAGS_DUMMY_READ (1<<9) | ||
127 | 148 | ||
128 | /* preemphasis values for the rx side */ | 149 | /* preemphasis values for the rx side */ |
129 | u16 rx_preemphasis[4]; | 150 | u16 rx_preemphasis[4]; |
@@ -142,8 +163,8 @@ struct bnx2x_phy { | |||
142 | #define ETH_PHY_XFP_FIBER 0x2 | 163 | #define ETH_PHY_XFP_FIBER 0x2 |
143 | #define ETH_PHY_DA_TWINAX 0x3 | 164 | #define ETH_PHY_DA_TWINAX 0x3 |
144 | #define ETH_PHY_BASE_T 0x4 | 165 | #define ETH_PHY_BASE_T 0x4 |
145 | #define ETH_PHY_KR 0xf0 | 166 | #define ETH_PHY_KR 0xf0 |
146 | #define ETH_PHY_CX4 0xf1 | 167 | #define ETH_PHY_CX4 0xf1 |
147 | #define ETH_PHY_NOT_PRESENT 0xff | 168 | #define ETH_PHY_NOT_PRESENT 0xff |
148 | 169 | ||
149 | /* The address in which version is located*/ | 170 | /* The address in which version is located*/ |
@@ -248,6 +269,8 @@ struct link_params { | |||
248 | /* Output parameters */ | 269 | /* Output parameters */ |
249 | struct link_vars { | 270 | struct link_vars { |
250 | u8 phy_flags; | 271 | u8 phy_flags; |
272 | #define PHY_XGXS_FLAG (1<<0) | ||
273 | #define PHY_SGMII_FLAG (1<<1) | ||
251 | 274 | ||
252 | u8 mac_type; | 275 | u8 mac_type; |
253 | #define MAC_TYPE_NONE 0 | 276 | #define MAC_TYPE_NONE 0 |
@@ -414,4 +437,7 @@ void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars, | |||
414 | void bnx2x_init_mod_abs_int(struct bnx2x *bp, struct link_vars *vars, | 437 | void bnx2x_init_mod_abs_int(struct bnx2x *bp, struct link_vars *vars, |
415 | u32 chip_id, u32 shmem_base, u32 shmem2_base, | 438 | u32 chip_id, u32 shmem_base, u32 shmem2_base, |
416 | u8 port); | 439 | u8 port); |
440 | |||
441 | int bnx2x_sfp_module_detection(struct bnx2x_phy *phy, | ||
442 | struct link_params *params); | ||
417 | #endif /* BNX2X_LINK_H */ | 443 | #endif /* BNX2X_LINK_H */ |
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 6237e4aba82f..0dddba9532c1 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c | |||
@@ -8586,7 +8586,10 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) | |||
8586 | return; | 8586 | return; |
8587 | } | 8587 | } |
8588 | break; | 8588 | break; |
8589 | case PORT_FEATURE_LINK_SPEED_20G: | ||
8590 | bp->link_params.req_line_speed[idx] = SPEED_20000; | ||
8589 | 8591 | ||
8592 | break; | ||
8590 | default: | 8593 | default: |
8591 | BNX2X_ERR("NVRAM config error. " | 8594 | BNX2X_ERR("NVRAM config error. " |
8592 | "BAD link speed link_config 0x%x\n", | 8595 | "BAD link speed link_config 0x%x\n", |
diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 65f3b1260766..23c89a863a58 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h | |||
@@ -981,6 +981,13 @@ | |||
981 | #define IGU_REG_WRITE_DONE_PENDING 0x130480 | 981 | #define IGU_REG_WRITE_DONE_PENDING 0x130480 |
982 | #define MCP_A_REG_MCPR_SCRATCH 0x3a0000 | 982 | #define MCP_A_REG_MCPR_SCRATCH 0x3a0000 |
983 | #define MCP_REG_MCPR_CPU_PROGRAM_COUNTER 0x8501c | 983 | #define MCP_REG_MCPR_CPU_PROGRAM_COUNTER 0x8501c |
984 | #define MCP_REG_MCPR_GP_INPUTS 0x800c0 | ||
985 | #define MCP_REG_MCPR_GP_OENABLE 0x800c8 | ||
986 | #define MCP_REG_MCPR_GP_OUTPUTS 0x800c4 | ||
987 | #define MCP_REG_MCPR_IMC_COMMAND 0x85900 | ||
988 | #define MCP_REG_MCPR_IMC_DATAREG0 0x85920 | ||
989 | #define MCP_REG_MCPR_IMC_SLAVE_CONTROL 0x85904 | ||
990 | #define MCP_REG_MCPR_CPU_PROGRAM_COUNTER 0x8501c | ||
984 | #define MCP_REG_MCPR_NVM_ACCESS_ENABLE 0x86424 | 991 | #define MCP_REG_MCPR_NVM_ACCESS_ENABLE 0x86424 |
985 | #define MCP_REG_MCPR_NVM_ADDR 0x8640c | 992 | #define MCP_REG_MCPR_NVM_ADDR 0x8640c |
986 | #define MCP_REG_MCPR_NVM_CFG4 0x8642c | 993 | #define MCP_REG_MCPR_NVM_CFG4 0x8642c |
@@ -1477,11 +1484,37 @@ | |||
1477 | /* [RW 1] e1hmf for WOL. If clr WOL signal o the PXP will be send on bit 0 | 1484 | /* [RW 1] e1hmf for WOL. If clr WOL signal o the PXP will be send on bit 0 |
1478 | only. */ | 1485 | only. */ |
1479 | #define MISC_REG_E1HMF_MODE 0xa5f8 | 1486 | #define MISC_REG_E1HMF_MODE 0xa5f8 |
1487 | /* [R 1] Status of four port mode path swap input pin. */ | ||
1488 | #define MISC_REG_FOUR_PORT_PATH_SWAP 0xa75c | ||
1489 | /* [RW 2] 4 port path swap overwrite.[0] - Overwrite control; if it is 0 - | ||
1490 | the path_swap output is equal to 4 port mode path swap input pin; if it | ||
1491 | is 1 - the path_swap output is equal to bit[1] of this register; [1] - | ||
1492 | Overwrite value. If bit[0] of this register is 1 this is the value that | ||
1493 | receives the path_swap output. Reset on Hard reset. */ | ||
1494 | #define MISC_REG_FOUR_PORT_PATH_SWAP_OVWR 0xa738 | ||
1495 | /* [R 1] Status of 4 port mode port swap input pin. */ | ||
1496 | #define MISC_REG_FOUR_PORT_PORT_SWAP 0xa754 | ||
1497 | /* [RW 2] 4 port port swap overwrite.[0] - Overwrite control; if it is 0 - | ||
1498 | the port_swap output is equal to 4 port mode port swap input pin; if it | ||
1499 | is 1 - the port_swap output is equal to bit[1] of this register; [1] - | ||
1500 | Overwrite value. If bit[0] of this register is 1 this is the value that | ||
1501 | receives the port_swap output. Reset on Hard reset. */ | ||
1502 | #define MISC_REG_FOUR_PORT_PORT_SWAP_OVWR 0xa734 | ||
1480 | /* [RW 32] Debug only: spare RW register reset by core reset */ | 1503 | /* [RW 32] Debug only: spare RW register reset by core reset */ |
1481 | #define MISC_REG_GENERIC_CR_0 0xa460 | 1504 | #define MISC_REG_GENERIC_CR_0 0xa460 |
1482 | #define MISC_REG_GENERIC_CR_1 0xa464 | 1505 | #define MISC_REG_GENERIC_CR_1 0xa464 |
1483 | /* [RW 32] Debug only: spare RW register reset by por reset */ | 1506 | /* [RW 32] Debug only: spare RW register reset by por reset */ |
1484 | #define MISC_REG_GENERIC_POR_1 0xa474 | 1507 | #define MISC_REG_GENERIC_POR_1 0xa474 |
1508 | /* [RW 32] Bit[0]: EPIO MODE SEL: Setting this bit to 1 will allow SW/FW to | ||
1509 | use all of the 32 Extended GPIO pins. Without setting this bit; an EPIO | ||
1510 | can not be configured as an output. Each output has its output enable in | ||
1511 | the MCP register space; but this bit needs to be set to make use of that. | ||
1512 | Bit[3:1] spare. Bit[4]: WCVTMON_PWRDN: Powerdown for Warpcore VTMON. When | ||
1513 | set to 1 - Powerdown. Bit[5]: WCVTMON_RESETB: Reset for Warpcore VTMON. | ||
1514 | When set to 0 - vTMON is in reset. Bit[6]: setting this bit will change | ||
1515 | the i/o to an output and will drive the TimeSync output. Bit[31:7]: | ||
1516 | spare. Global register. Reset by hard reset. */ | ||
1517 | #define MISC_REG_GEN_PURP_HWG 0xa9a0 | ||
1485 | /* [RW 32] GPIO. [31-28] FLOAT port 0; [27-24] FLOAT port 0; When any of | 1518 | /* [RW 32] GPIO. [31-28] FLOAT port 0; [27-24] FLOAT port 0; When any of |
1486 | these bits is written as a '1'; the corresponding SPIO bit will turn off | 1519 | these bits is written as a '1'; the corresponding SPIO bit will turn off |
1487 | it's drivers and become an input. This is the reset state of all GPIO | 1520 | it's drivers and become an input. This is the reset state of all GPIO |
@@ -1684,6 +1717,14 @@ | |||
1684 | in this register. address 0 - timer 1; address 1 - timer 2, ... address 7 - | 1717 | in this register. address 0 - timer 1; address 1 - timer 2, ... address 7 - |
1685 | timer 8 */ | 1718 | timer 8 */ |
1686 | #define MISC_REG_SW_TIMER_VAL 0xa5c0 | 1719 | #define MISC_REG_SW_TIMER_VAL 0xa5c0 |
1720 | /* [R 1] Status of two port mode path swap input pin. */ | ||
1721 | #define MISC_REG_TWO_PORT_PATH_SWAP 0xa758 | ||
1722 | /* [RW 2] 2 port swap overwrite.[0] - Overwrite control; if it is 0 - the | ||
1723 | path_swap output is equal to 2 port mode path swap input pin; if it is 1 | ||
1724 | - the path_swap output is equal to bit[1] of this register; [1] - | ||
1725 | Overwrite value. If bit[0] of this register is 1 this is the value that | ||
1726 | receives the path_swap output. Reset on Hard reset. */ | ||
1727 | #define MISC_REG_TWO_PORT_PATH_SWAP_OVWR 0xa72c | ||
1687 | /* [RW 1] Set by the MCP to remember if one or more of the drivers is/are | 1728 | /* [RW 1] Set by the MCP to remember if one or more of the drivers is/are |
1688 | loaded; 0-prepare; -unprepare */ | 1729 | loaded; 0-prepare; -unprepare */ |
1689 | #define MISC_REG_UNPREPARED 0xa424 | 1730 | #define MISC_REG_UNPREPARED 0xa424 |
@@ -1955,6 +1996,10 @@ | |||
1955 | /* [RC 32] Parity register #0 read clear */ | 1996 | /* [RC 32] Parity register #0 read clear */ |
1956 | #define NIG_REG_NIG_PRTY_STS_CLR_0 0x183c0 | 1997 | #define NIG_REG_NIG_PRTY_STS_CLR_0 0x183c0 |
1957 | #define NIG_REG_NIG_PRTY_STS_CLR_1 0x183d0 | 1998 | #define NIG_REG_NIG_PRTY_STS_CLR_1 0x183d0 |
1999 | #define MCPR_IMC_COMMAND_ENABLE (1L<<31) | ||
2000 | #define MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT 16 | ||
2001 | #define MCPR_IMC_COMMAND_OPERATION_BITSHIFT 28 | ||
2002 | #define MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT 8 | ||
1958 | /* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic | 2003 | /* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic |
1959 | * Ethernet header. */ | 2004 | * Ethernet header. */ |
1960 | #define NIG_REG_P0_HDRS_AFTER_BASIC 0x18038 | 2005 | #define NIG_REG_P0_HDRS_AFTER_BASIC 0x18038 |
@@ -6232,6 +6277,10 @@ | |||
6232 | #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G 0x0C00 | 6277 | #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G 0x0C00 |
6233 | #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX 0x0D00 | 6278 | #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX 0x0D00 |
6234 | #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4 0x0E00 | 6279 | #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4 0x0E00 |
6280 | #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KR 0x0F00 | ||
6281 | #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI 0x1B00 | ||
6282 | #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS 0x1E00 | ||
6283 | #define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI 0x1F00 | ||
6235 | 6284 | ||
6236 | 6285 | ||
6237 | #define MDIO_REG_BANK_10G_PARALLEL_DETECT 0x8130 | 6286 | #define MDIO_REG_BANK_10G_PARALLEL_DETECT 0x8130 |
@@ -6574,6 +6623,120 @@ Theotherbitsarereservedandshouldbezero*/ | |||
6574 | #define PHY84833_CMD_CLEAR_COMPLETE 0x0080 | 6623 | #define PHY84833_CMD_CLEAR_COMPLETE 0x0080 |
6575 | #define PHY84833_CMD_OPEN_OVERRIDE 0xa5a5 | 6624 | #define PHY84833_CMD_OPEN_OVERRIDE 0xa5a5 |
6576 | 6625 | ||
6626 | /* Warpcore clause 45 addressing */ | ||
6627 | #define MDIO_WC_DEVAD 0x3 | ||
6628 | #define MDIO_WC_REG_IEEE0BLK_MIICNTL 0x0 | ||
6629 | #define MDIO_WC_REG_IEEE0BLK_AUTONEGNP 0x7 | ||
6630 | #define MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT0 0x10 | ||
6631 | #define MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1 0x11 | ||
6632 | #define MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150 0x96 | ||
6633 | #define MDIO_WC_REG_XGXSBLK0_XGXSCONTROL 0x8000 | ||
6634 | #define MDIO_WC_REG_XGXSBLK0_MISCCONTROL1 0x800e | ||
6635 | #define MDIO_WC_REG_XGXSBLK1_DESKEW 0x8010 | ||
6636 | #define MDIO_WC_REG_XGXSBLK1_LANECTRL0 0x8015 | ||
6637 | #define MDIO_WC_REG_XGXSBLK1_LANECTRL1 0x8016 | ||
6638 | #define MDIO_WC_REG_XGXSBLK1_LANECTRL2 0x8017 | ||
6639 | #define MDIO_WC_REG_TX0_ANA_CTRL0 0x8061 | ||
6640 | #define MDIO_WC_REG_TX1_ANA_CTRL0 0x8071 | ||
6641 | #define MDIO_WC_REG_TX2_ANA_CTRL0 0x8081 | ||
6642 | #define MDIO_WC_REG_TX3_ANA_CTRL0 0x8091 | ||
6643 | #define MDIO_WC_REG_TX0_TX_DRIVER 0x8067 | ||
6644 | #define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET 0x04 | ||
6645 | #define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_MASK 0x00f0 | ||
6646 | #define MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET 0x08 | ||
6647 | #define MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_MASK 0x0f00 | ||
6648 | #define MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET 0x0c | ||
6649 | #define MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_MASK 0x7000 | ||
6650 | #define MDIO_WC_REG_TX1_TX_DRIVER 0x8077 | ||
6651 | #define MDIO_WC_REG_TX2_TX_DRIVER 0x8087 | ||
6652 | #define MDIO_WC_REG_TX3_TX_DRIVER 0x8097 | ||
6653 | #define MDIO_WC_REG_RX0_ANARXCONTROL1G 0x80b9 | ||
6654 | #define MDIO_WC_REG_RX2_ANARXCONTROL1G 0x80d9 | ||
6655 | #define MDIO_WC_REG_RX0_PCI_CTRL 0x80ba | ||
6656 | #define MDIO_WC_REG_RX1_PCI_CTRL 0x80ca | ||
6657 | #define MDIO_WC_REG_RX2_PCI_CTRL 0x80da | ||
6658 | #define MDIO_WC_REG_RX3_PCI_CTRL 0x80ea | ||
6659 | #define MDIO_WC_REG_XGXSBLK2_UNICORE_MODE_10G 0x8104 | ||
6660 | #define MDIO_WC_REG_XGXS_STATUS3 0x8129 | ||
6661 | #define MDIO_WC_REG_PAR_DET_10G_STATUS 0x8130 | ||
6662 | #define MDIO_WC_REG_PAR_DET_10G_CTRL 0x8131 | ||
6663 | #define MDIO_WC_REG_XGXS_X2_CONTROL2 0x8141 | ||
6664 | #define MDIO_WC_REG_XGXS_RX_LN_SWAP1 0x816B | ||
6665 | #define MDIO_WC_REG_XGXS_TX_LN_SWAP1 0x8169 | ||
6666 | #define MDIO_WC_REG_GP2_STATUS_GP_2_0 0x81d0 | ||
6667 | #define MDIO_WC_REG_GP2_STATUS_GP_2_1 0x81d1 | ||
6668 | #define MDIO_WC_REG_GP2_STATUS_GP_2_2 0x81d2 | ||
6669 | #define MDIO_WC_REG_GP2_STATUS_GP_2_3 0x81d3 | ||
6670 | #define MDIO_WC_REG_GP2_STATUS_GP_2_4 0x81d4 | ||
6671 | #define MDIO_WC_REG_UC_INFO_B0_DEAD_TRAP 0x81EE | ||
6672 | #define MDIO_WC_REG_UC_INFO_B1_VERSION 0x81F0 | ||
6673 | #define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE 0x81F2 | ||
6674 | #define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_LANE0_OFFSET 0x0 | ||
6675 | #define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT 0x0 | ||
6676 | #define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_OPT_LR 0x1 | ||
6677 | #define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_DAC 0x2 | ||
6678 | #define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_XLAUI 0x3 | ||
6679 | #define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_LONG_CH_6G 0x4 | ||
6680 | #define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_LANE1_OFFSET 0x4 | ||
6681 | #define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_LANE2_OFFSET 0x8 | ||
6682 | #define MDIO_WC_REG_UC_INFO_B1_FIRMWARE_LANE3_OFFSET 0xc | ||
6683 | #define MDIO_WC_REG_UC_INFO_B1_CRC 0x81FE | ||
6684 | #define MDIO_WC_REG_DSC_SMC 0x8213 | ||
6685 | #define MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0 0x821e | ||
6686 | #define MDIO_WC_REG_TX_FIR_TAP 0x82e2 | ||
6687 | #define MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET 0x00 | ||
6688 | #define MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_MASK 0x000f | ||
6689 | #define MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET 0x04 | ||
6690 | #define MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_MASK 0x03f0 | ||
6691 | #define MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET 0x0a | ||
6692 | #define MDIO_WC_REG_TX_FIR_TAP_POST_TAP_MASK 0x7c00 | ||
6693 | #define MDIO_WC_REG_TX_FIR_TAP_ENABLE 0x8000 | ||
6694 | #define MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL 0x82e3 | ||
6695 | #define MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL 0x82e6 | ||
6696 | #define MDIO_WC_REG_CL72_USERB0_CL72_BR_DEF_CTRL 0x82e7 | ||
6697 | #define MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL 0x82e8 | ||
6698 | #define MDIO_WC_REG_CL72_USERB0_CL72_MISC4_CONTROL 0x82ec | ||
6699 | #define MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1 0x8300 | ||
6700 | #define MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2 0x8301 | ||
6701 | #define MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3 0x8302 | ||
6702 | #define MDIO_WC_REG_SERDESDIGITAL_STATUS1000X1 0x8304 | ||
6703 | #define MDIO_WC_REG_SERDESDIGITAL_MISC1 0x8308 | ||
6704 | #define MDIO_WC_REG_SERDESDIGITAL_MISC2 0x8309 | ||
6705 | #define MDIO_WC_REG_DIGITAL3_UP1 0x8329 | ||
6706 | #define MDIO_WC_REG_DIGITAL4_MISC3 0x833c | ||
6707 | #define MDIO_WC_REG_DIGITAL5_MISC6 0x8345 | ||
6708 | #define MDIO_WC_REG_DIGITAL5_MISC7 0x8349 | ||
6709 | #define MDIO_WC_REG_DIGITAL5_ACTUAL_SPEED 0x834e | ||
6710 | #define MDIO_WC_REG_CL49_USERB0_CTRL 0x8368 | ||
6711 | #define MDIO_WC_REG_TX66_CONTROL 0x83b0 | ||
6712 | #define MDIO_WC_REG_RX66_CONTROL 0x83c0 | ||
6713 | #define MDIO_WC_REG_RX66_SCW0 0x83c2 | ||
6714 | #define MDIO_WC_REG_RX66_SCW1 0x83c3 | ||
6715 | #define MDIO_WC_REG_RX66_SCW2 0x83c4 | ||
6716 | #define MDIO_WC_REG_RX66_SCW3 0x83c5 | ||
6717 | #define MDIO_WC_REG_RX66_SCW0_MASK 0x83c6 | ||
6718 | #define MDIO_WC_REG_RX66_SCW1_MASK 0x83c7 | ||
6719 | #define MDIO_WC_REG_RX66_SCW2_MASK 0x83c8 | ||
6720 | #define MDIO_WC_REG_RX66_SCW3_MASK 0x83c9 | ||
6721 | #define MDIO_WC_REG_FX100_CTRL1 0x8400 | ||
6722 | #define MDIO_WC_REG_FX100_CTRL3 0x8402 | ||
6723 | |||
6724 | #define MDIO_WC_REG_MICROBLK_CMD 0xffc2 | ||
6725 | #define MDIO_WC_REG_MICROBLK_DL_STATUS 0xffc5 | ||
6726 | #define MDIO_WC_REG_MICROBLK_CMD3 0xffcc | ||
6727 | |||
6728 | #define MDIO_WC_REG_AERBLK_AER 0xffde | ||
6729 | #define MDIO_WC_REG_COMBO_IEEE0_MIICTRL 0xffe0 | ||
6730 | #define MDIO_WC_REG_COMBO_IEEE0_MIIISTAT 0xffe1 | ||
6731 | |||
6732 | #define MDIO_WC0_XGXS_BLK2_LANE_RESET 0x810A | ||
6733 | #define MDIO_WC0_XGXS_BLK2_LANE_RESET_RX_BITSHIFT 0 | ||
6734 | #define MDIO_WC0_XGXS_BLK2_LANE_RESET_TX_BITSHIFT 4 | ||
6735 | |||
6736 | #define MDIO_WC0_XGXS_BLK6_XGXS_X2_CONTROL2 0x8141 | ||
6737 | |||
6738 | #define DIGITAL5_ACTUAL_SPEED_TX_MASK 0x003f | ||
6739 | |||
6577 | #define IGU_FUNC_BASE 0x0400 | 6740 | #define IGU_FUNC_BASE 0x0400 |
6578 | 6741 | ||
6579 | #define IGU_ADDR_MSIX 0x0000 | 6742 | #define IGU_ADDR_MSIX 0x0000 |