diff options
author | Eilon Greenstein <eilong@broadcom.com> | 2009-07-21 01:47:47 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-07-21 14:18:30 -0400 |
commit | 4d295db0efd2ccf06edb7a45ad885b40c56b7161 (patch) | |
tree | fb545833c5c3618d58754d50ba899b62dd37abef /drivers/net/bnx2x_link.c | |
parent | 5316bc0b9adbefe24f149b12caeddc30df6f04e1 (diff) |
bnx2x: Supporting BCM8727 PHY
Adding support for BCM8727 - a dual port SFP+ PHY. That includes verification of
the optic module vendor and part number - the list of approved modules resides
on the nvram and the module is verified by the FW. Since not all users would
like to use this verification feature, it can be disabled. The default behavior
is to issue a warning if the module is not approved, but still allow using it -
but it is also possible to disable the link if the module is not approved.
Signed-off-by: Yaniv Rosner <yanivr@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x_link.c')
-rw-r--r-- | drivers/net/bnx2x_link.c | 1095 |
1 files changed, 945 insertions, 150 deletions
diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c index ed648acef7cf..b9c85a21457d 100644 --- a/drivers/net/bnx2x_link.c +++ b/drivers/net/bnx2x_link.c | |||
@@ -139,21 +139,26 @@ | |||
139 | #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7 | 139 | #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7 |
140 | #define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21 | 140 | #define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21 |
141 | 141 | ||
142 | |||
143 | #define SFP_EEPROM_COMP_CODE_ADDR 0x3 | ||
144 | #define SFP_EEPROM_COMP_CODE_SR_MASK (1<<4) | ||
145 | #define SFP_EEPROM_COMP_CODE_LR_MASK (1<<5) | ||
146 | #define SFP_EEPROM_COMP_CODE_LRM_MASK (1<<6) | ||
147 | |||
142 | #define SFP_EEPROM_FC_TX_TECH_ADDR 0x8 | 148 | #define SFP_EEPROM_FC_TX_TECH_ADDR 0x8 |
143 | #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4 | 149 | #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4 |
144 | #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE 0x8 | 150 | #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE 0x8 |
145 | #define SFP_EEPROM_VENDOR_NAME_ADDR 0x14 | 151 | |
146 | #define SFP_EEPROM_VENDOR_NAME_SIZE 16 | ||
147 | #define SFP_EEPROM_OPTIONS_ADDR 0x40 | 152 | #define SFP_EEPROM_OPTIONS_ADDR 0x40 |
148 | #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1 | 153 | #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1 |
149 | #define SFP_EEPROM_OPTIONS_SIZE 2 | 154 | #define SFP_EEPROM_OPTIONS_SIZE 2 |
150 | 155 | ||
151 | #define SFP_MODULE_TYPE_UNKNOWN 0x0 | 156 | #define EDC_MODE_LINEAR 0x0022 |
152 | #define SFP_MODULE_TYPE_LC 0x1 | 157 | #define EDC_MODE_LIMITING 0x0044 |
153 | #define SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE 0x2 | 158 | #define EDC_MODE_PASSIVE_DAC 0x0055 |
154 | #define SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE 0x3 | 159 | |
160 | |||
155 | 161 | ||
156 | #define SFP_LIMITING_MODE_VALUE 0x0044 | ||
157 | /**********************************************************/ | 162 | /**********************************************************/ |
158 | /* INTERFACE */ | 163 | /* INTERFACE */ |
159 | /**********************************************************/ | 164 | /**********************************************************/ |
@@ -793,6 +798,7 @@ static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port) | |||
793 | switch (ext_phy_type) { | 798 | switch (ext_phy_type) { |
794 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: | 799 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: |
795 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: | 800 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: |
801 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: | ||
796 | /* All MDC/MDIO is directed through single EMAC */ | 802 | /* All MDC/MDIO is directed through single EMAC */ |
797 | if (REG_RD(bp, NIG_REG_PORT_SWAP)) | 803 | if (REG_RD(bp, NIG_REG_PORT_SWAP)) |
798 | emac_base = GRCBASE_EMAC0; | 804 | emac_base = GRCBASE_EMAC0; |
@@ -1887,6 +1893,10 @@ static void bnx2x_ext_phy_reset(struct link_params *params, | |||
1887 | MDIO_PMA_DEVAD, | 1893 | MDIO_PMA_DEVAD, |
1888 | MDIO_PMA_REG_CTRL, 0xa040); | 1894 | MDIO_PMA_REG_CTRL, 0xa040); |
1889 | break; | 1895 | break; |
1896 | |||
1897 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: | ||
1898 | break; | ||
1899 | |||
1890 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: | 1900 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: |
1891 | 1901 | ||
1892 | /* Restore normal power mode*/ | 1902 | /* Restore normal power mode*/ |
@@ -2171,13 +2181,15 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params) | |||
2171 | 2181 | ||
2172 | } | 2182 | } |
2173 | 2183 | ||
2174 | static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port, | 2184 | static void bnx2x_bcm8073_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port, |
2175 | u8 ext_phy_addr, u32 shmem_base) | 2185 | u8 ext_phy_addr, |
2186 | u32 ext_phy_type, | ||
2187 | u32 shmem_base) | ||
2176 | { | 2188 | { |
2177 | /* Boot port from external ROM */ | 2189 | /* Boot port from external ROM */ |
2178 | /* EDC grst */ | 2190 | /* EDC grst */ |
2179 | bnx2x_cl45_write(bp, port, | 2191 | bnx2x_cl45_write(bp, port, |
2180 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | 2192 | ext_phy_type, |
2181 | ext_phy_addr, | 2193 | ext_phy_addr, |
2182 | MDIO_PMA_DEVAD, | 2194 | MDIO_PMA_DEVAD, |
2183 | MDIO_PMA_REG_GEN_CTRL, | 2195 | MDIO_PMA_REG_GEN_CTRL, |
@@ -2185,21 +2197,21 @@ static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port, | |||
2185 | 2197 | ||
2186 | /* ucode reboot and rst */ | 2198 | /* ucode reboot and rst */ |
2187 | bnx2x_cl45_write(bp, port, | 2199 | bnx2x_cl45_write(bp, port, |
2188 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | 2200 | ext_phy_type, |
2189 | ext_phy_addr, | 2201 | ext_phy_addr, |
2190 | MDIO_PMA_DEVAD, | 2202 | MDIO_PMA_DEVAD, |
2191 | MDIO_PMA_REG_GEN_CTRL, | 2203 | MDIO_PMA_REG_GEN_CTRL, |
2192 | 0x008c); | 2204 | 0x008c); |
2193 | 2205 | ||
2194 | bnx2x_cl45_write(bp, port, | 2206 | bnx2x_cl45_write(bp, port, |
2195 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | 2207 | ext_phy_type, |
2196 | ext_phy_addr, | 2208 | ext_phy_addr, |
2197 | MDIO_PMA_DEVAD, | 2209 | MDIO_PMA_DEVAD, |
2198 | MDIO_PMA_REG_MISC_CTRL1, 0x0001); | 2210 | MDIO_PMA_REG_MISC_CTRL1, 0x0001); |
2199 | 2211 | ||
2200 | /* Reset internal microprocessor */ | 2212 | /* Reset internal microprocessor */ |
2201 | bnx2x_cl45_write(bp, port, | 2213 | bnx2x_cl45_write(bp, port, |
2202 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | 2214 | ext_phy_type, |
2203 | ext_phy_addr, | 2215 | ext_phy_addr, |
2204 | MDIO_PMA_DEVAD, | 2216 | MDIO_PMA_DEVAD, |
2205 | MDIO_PMA_REG_GEN_CTRL, | 2217 | MDIO_PMA_REG_GEN_CTRL, |
@@ -2207,7 +2219,7 @@ static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port, | |||
2207 | 2219 | ||
2208 | /* Release srst bit */ | 2220 | /* Release srst bit */ |
2209 | bnx2x_cl45_write(bp, port, | 2221 | bnx2x_cl45_write(bp, port, |
2210 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | 2222 | ext_phy_type, |
2211 | ext_phy_addr, | 2223 | ext_phy_addr, |
2212 | MDIO_PMA_DEVAD, | 2224 | MDIO_PMA_DEVAD, |
2213 | MDIO_PMA_REG_GEN_CTRL, | 2225 | MDIO_PMA_REG_GEN_CTRL, |
@@ -2218,17 +2230,36 @@ static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port, | |||
2218 | 2230 | ||
2219 | /* Clear ser_boot_ctl bit */ | 2231 | /* Clear ser_boot_ctl bit */ |
2220 | bnx2x_cl45_write(bp, port, | 2232 | bnx2x_cl45_write(bp, port, |
2221 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | 2233 | ext_phy_type, |
2222 | ext_phy_addr, | 2234 | ext_phy_addr, |
2223 | MDIO_PMA_DEVAD, | 2235 | MDIO_PMA_DEVAD, |
2224 | MDIO_PMA_REG_MISC_CTRL1, 0x0000); | 2236 | MDIO_PMA_REG_MISC_CTRL1, 0x0000); |
2225 | 2237 | ||
2226 | bnx2x_save_bcm_spirom_ver(bp, port, | 2238 | bnx2x_save_bcm_spirom_ver(bp, port, |
2227 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | 2239 | ext_phy_type, |
2228 | ext_phy_addr, | 2240 | ext_phy_addr, |
2229 | shmem_base); | 2241 | shmem_base); |
2230 | } | 2242 | } |
2231 | 2243 | ||
2244 | static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port, | ||
2245 | u8 ext_phy_addr, | ||
2246 | u32 shmem_base) | ||
2247 | { | ||
2248 | bnx2x_bcm8073_bcm8727_external_rom_boot(bp, port, ext_phy_addr, | ||
2249 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | ||
2250 | shmem_base); | ||
2251 | } | ||
2252 | |||
2253 | static void bnx2x_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port, | ||
2254 | u8 ext_phy_addr, | ||
2255 | u32 shmem_base) | ||
2256 | { | ||
2257 | bnx2x_bcm8073_bcm8727_external_rom_boot(bp, port, ext_phy_addr, | ||
2258 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, | ||
2259 | shmem_base); | ||
2260 | |||
2261 | } | ||
2262 | |||
2232 | static void bnx2x_bcm8726_external_rom_boot(struct link_params *params) | 2263 | static void bnx2x_bcm8726_external_rom_boot(struct link_params *params) |
2233 | { | 2264 | { |
2234 | struct bnx2x *bp = params->bp; | 2265 | struct bnx2x *bp = params->bp; |
@@ -2258,9 +2289,10 @@ static void bnx2x_bcm8726_external_rom_boot(struct link_params *params) | |||
2258 | MDIO_PMA_REG_GEN_CTRL, | 2289 | MDIO_PMA_REG_GEN_CTRL, |
2259 | MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); | 2290 | MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); |
2260 | 2291 | ||
2292 | /* Set PLL register value to be same like in P13 ver */ | ||
2261 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, | 2293 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, |
2262 | MDIO_PMA_DEVAD, | 2294 | MDIO_PMA_DEVAD, |
2263 | MDIO_PMA_REG_GEN_CTRL2, | 2295 | MDIO_PMA_REG_PLL_CTRL, |
2264 | 0x73A0); | 2296 | 0x73A0); |
2265 | 2297 | ||
2266 | /* Clear soft reset. | 2298 | /* Clear soft reset. |
@@ -2285,15 +2317,16 @@ static void bnx2x_bcm8726_external_rom_boot(struct link_params *params) | |||
2285 | params->shmem_base); | 2317 | params->shmem_base); |
2286 | } | 2318 | } |
2287 | 2319 | ||
2288 | static void bnx2x_bcm8726_set_transmitter(struct bnx2x *bp, u8 port, | 2320 | static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, u8 port, |
2289 | u8 ext_phy_addr, u8 tx_en) | 2321 | u32 ext_phy_type, u8 ext_phy_addr, |
2322 | u8 tx_en) | ||
2290 | { | 2323 | { |
2291 | u16 val; | 2324 | u16 val; |
2292 | DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n", | 2325 | DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n", |
2293 | tx_en, port); | 2326 | tx_en, port); |
2294 | /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/ | 2327 | /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/ |
2295 | bnx2x_cl45_read(bp, port, | 2328 | bnx2x_cl45_read(bp, port, |
2296 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, | 2329 | ext_phy_type, |
2297 | ext_phy_addr, | 2330 | ext_phy_addr, |
2298 | MDIO_PMA_DEVAD, | 2331 | MDIO_PMA_DEVAD, |
2299 | MDIO_PMA_REG_PHY_IDENTIFIER, | 2332 | MDIO_PMA_REG_PHY_IDENTIFIER, |
@@ -2305,18 +2338,19 @@ static void bnx2x_bcm8726_set_transmitter(struct bnx2x *bp, u8 port, | |||
2305 | val |= (1<<15); | 2338 | val |= (1<<15); |
2306 | 2339 | ||
2307 | bnx2x_cl45_write(bp, port, | 2340 | bnx2x_cl45_write(bp, port, |
2308 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, | 2341 | ext_phy_type, |
2309 | ext_phy_addr, | 2342 | ext_phy_addr, |
2310 | MDIO_PMA_DEVAD, | 2343 | MDIO_PMA_DEVAD, |
2311 | MDIO_PMA_REG_PHY_IDENTIFIER, | 2344 | MDIO_PMA_REG_PHY_IDENTIFIER, |
2312 | val); | 2345 | val); |
2313 | } | 2346 | } |
2314 | 2347 | ||
2315 | 2348 | static u8 bnx2x_8726_read_sfp_module_eeprom(struct link_params *params, | |
2316 | static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr, | 2349 | u16 addr, u8 byte_cnt, u8 *o_buf) |
2317 | u8 byte_cnt, u8 *o_buf) { | 2350 | { |
2318 | struct bnx2x *bp = params->bp; | 2351 | struct bnx2x *bp = params->bp; |
2319 | u16 val, i; | 2352 | u16 val = 0; |
2353 | u16 i; | ||
2320 | u8 port = params->port; | 2354 | u8 port = params->port; |
2321 | u8 ext_phy_addr = ((params->ext_phy_config & | 2355 | u8 ext_phy_addr = ((params->ext_phy_config & |
2322 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> | 2356 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> |
@@ -2332,7 +2366,7 @@ static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr, | |||
2332 | ext_phy_type, | 2366 | ext_phy_type, |
2333 | ext_phy_addr, | 2367 | ext_phy_addr, |
2334 | MDIO_PMA_DEVAD, | 2368 | MDIO_PMA_DEVAD, |
2335 | MDIO_PMA_REG_8726_TWO_WIRE_BYTE_CNT, | 2369 | MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT, |
2336 | (byte_cnt | 0xa000)); | 2370 | (byte_cnt | 0xa000)); |
2337 | 2371 | ||
2338 | /* Set the read command address */ | 2372 | /* Set the read command address */ |
@@ -2340,7 +2374,7 @@ static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr, | |||
2340 | ext_phy_type, | 2374 | ext_phy_type, |
2341 | ext_phy_addr, | 2375 | ext_phy_addr, |
2342 | MDIO_PMA_DEVAD, | 2376 | MDIO_PMA_DEVAD, |
2343 | MDIO_PMA_REG_8726_TWO_WIRE_MEM_ADDR, | 2377 | MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR, |
2344 | addr); | 2378 | addr); |
2345 | 2379 | ||
2346 | /* Activate read command */ | 2380 | /* Activate read command */ |
@@ -2348,7 +2382,7 @@ static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr, | |||
2348 | ext_phy_type, | 2382 | ext_phy_type, |
2349 | ext_phy_addr, | 2383 | ext_phy_addr, |
2350 | MDIO_PMA_DEVAD, | 2384 | MDIO_PMA_DEVAD, |
2351 | MDIO_PMA_REG_8726_TWO_WIRE_CTRL, | 2385 | MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, |
2352 | 0x2c0f); | 2386 | 0x2c0f); |
2353 | 2387 | ||
2354 | /* Wait up to 500us for command complete status */ | 2388 | /* Wait up to 500us for command complete status */ |
@@ -2357,18 +2391,18 @@ static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr, | |||
2357 | ext_phy_type, | 2391 | ext_phy_type, |
2358 | ext_phy_addr, | 2392 | ext_phy_addr, |
2359 | MDIO_PMA_DEVAD, | 2393 | MDIO_PMA_DEVAD, |
2360 | MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val); | 2394 | MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); |
2361 | if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) == | 2395 | if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == |
2362 | MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE) | 2396 | MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) |
2363 | break; | 2397 | break; |
2364 | udelay(5); | 2398 | udelay(5); |
2365 | } | 2399 | } |
2366 | 2400 | ||
2367 | if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) != | 2401 | if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) != |
2368 | MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE) { | 2402 | MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) { |
2369 | DP(NETIF_MSG_LINK, | 2403 | DP(NETIF_MSG_LINK, |
2370 | "Got bad status 0x%x when reading from SFP+ EEPROM\n", | 2404 | "Got bad status 0x%x when reading from SFP+ EEPROM\n", |
2371 | (val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK)); | 2405 | (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK)); |
2372 | return -EINVAL; | 2406 | return -EINVAL; |
2373 | } | 2407 | } |
2374 | 2408 | ||
@@ -2387,29 +2421,147 @@ static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr, | |||
2387 | ext_phy_type, | 2421 | ext_phy_type, |
2388 | ext_phy_addr, | 2422 | ext_phy_addr, |
2389 | MDIO_PMA_DEVAD, | 2423 | MDIO_PMA_DEVAD, |
2390 | MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val); | 2424 | MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); |
2391 | if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) == | 2425 | if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == |
2392 | MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IDLE) | 2426 | MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE) |
2393 | return 0;; | 2427 | return 0;; |
2394 | msleep(1); | 2428 | msleep(1); |
2395 | } | 2429 | } |
2396 | return -EINVAL; | 2430 | return -EINVAL; |
2397 | } | 2431 | } |
2398 | 2432 | ||
2433 | static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params, | ||
2434 | u16 addr, u8 byte_cnt, u8 *o_buf) | ||
2435 | { | ||
2436 | struct bnx2x *bp = params->bp; | ||
2437 | u16 val, i; | ||
2438 | u8 port = params->port; | ||
2439 | u8 ext_phy_addr = ((params->ext_phy_config & | ||
2440 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> | ||
2441 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); | ||
2442 | u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); | ||
2443 | |||
2444 | if (byte_cnt > 16) { | ||
2445 | DP(NETIF_MSG_LINK, "Reading from eeprom is" | ||
2446 | " is limited to 0xf\n"); | ||
2447 | return -EINVAL; | ||
2448 | } | ||
2449 | |||
2450 | /* Need to read from 1.8000 to clear it */ | ||
2451 | bnx2x_cl45_read(bp, port, | ||
2452 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, | ||
2453 | ext_phy_addr, | ||
2454 | MDIO_PMA_DEVAD, | ||
2455 | MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, | ||
2456 | &val); | ||
2399 | 2457 | ||
2400 | static u8 bnx2x_get_sfp_module_type(struct link_params *params, | 2458 | /* Set the read command byte count */ |
2401 | u8 *module_type) | 2459 | bnx2x_cl45_write(bp, port, |
2460 | ext_phy_type, | ||
2461 | ext_phy_addr, | ||
2462 | MDIO_PMA_DEVAD, | ||
2463 | MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT, | ||
2464 | ((byte_cnt < 2) ? 2 : byte_cnt)); | ||
2465 | |||
2466 | /* Set the read command address */ | ||
2467 | bnx2x_cl45_write(bp, port, | ||
2468 | ext_phy_type, | ||
2469 | ext_phy_addr, | ||
2470 | MDIO_PMA_DEVAD, | ||
2471 | MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR, | ||
2472 | addr); | ||
2473 | /* Set the destination address */ | ||
2474 | bnx2x_cl45_write(bp, port, | ||
2475 | ext_phy_type, | ||
2476 | ext_phy_addr, | ||
2477 | MDIO_PMA_DEVAD, | ||
2478 | 0x8004, | ||
2479 | MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF); | ||
2480 | |||
2481 | /* Activate read command */ | ||
2482 | bnx2x_cl45_write(bp, port, | ||
2483 | ext_phy_type, | ||
2484 | ext_phy_addr, | ||
2485 | MDIO_PMA_DEVAD, | ||
2486 | MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, | ||
2487 | 0x8002); | ||
2488 | /* Wait appropriate time for two-wire command to finish before | ||
2489 | polling the status register */ | ||
2490 | msleep(1); | ||
2491 | |||
2492 | /* Wait up to 500us for command complete status */ | ||
2493 | for (i = 0; i < 100; i++) { | ||
2494 | bnx2x_cl45_read(bp, port, | ||
2495 | ext_phy_type, | ||
2496 | ext_phy_addr, | ||
2497 | MDIO_PMA_DEVAD, | ||
2498 | MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); | ||
2499 | if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == | ||
2500 | MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) | ||
2501 | break; | ||
2502 | udelay(5); | ||
2503 | } | ||
2504 | |||
2505 | if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) != | ||
2506 | MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) { | ||
2507 | DP(NETIF_MSG_LINK, | ||
2508 | "Got bad status 0x%x when reading from SFP+ EEPROM\n", | ||
2509 | (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK)); | ||
2510 | return -EINVAL; | ||
2511 | } | ||
2512 | |||
2513 | /* Read the buffer */ | ||
2514 | for (i = 0; i < byte_cnt; i++) { | ||
2515 | bnx2x_cl45_read(bp, port, | ||
2516 | ext_phy_type, | ||
2517 | ext_phy_addr, | ||
2518 | MDIO_PMA_DEVAD, | ||
2519 | MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val); | ||
2520 | o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK); | ||
2521 | } | ||
2522 | |||
2523 | for (i = 0; i < 100; i++) { | ||
2524 | bnx2x_cl45_read(bp, port, | ||
2525 | ext_phy_type, | ||
2526 | ext_phy_addr, | ||
2527 | MDIO_PMA_DEVAD, | ||
2528 | MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); | ||
2529 | if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == | ||
2530 | MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE) | ||
2531 | return 0;; | ||
2532 | msleep(1); | ||
2533 | } | ||
2534 | |||
2535 | return -EINVAL; | ||
2536 | } | ||
2537 | |||
2538 | u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr, | ||
2539 | u8 byte_cnt, u8 *o_buf) | ||
2540 | { | ||
2541 | u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); | ||
2542 | |||
2543 | if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) | ||
2544 | return bnx2x_8726_read_sfp_module_eeprom(params, addr, | ||
2545 | byte_cnt, o_buf); | ||
2546 | else if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) | ||
2547 | return bnx2x_8727_read_sfp_module_eeprom(params, addr, | ||
2548 | byte_cnt, o_buf); | ||
2549 | return -EINVAL; | ||
2550 | } | ||
2551 | |||
2552 | static u8 bnx2x_get_edc_mode(struct link_params *params, | ||
2553 | u16 *edc_mode) | ||
2402 | { | 2554 | { |
2403 | struct bnx2x *bp = params->bp; | 2555 | struct bnx2x *bp = params->bp; |
2404 | u8 val; | 2556 | u8 val, check_limiting_mode = 0; |
2405 | *module_type = SFP_MODULE_TYPE_UNKNOWN; | 2557 | *edc_mode = EDC_MODE_LIMITING; |
2406 | 2558 | ||
2407 | /* First check for copper cable */ | 2559 | /* First check for copper cable */ |
2408 | if (bnx2x_read_sfp_module_eeprom(params, | 2560 | if (bnx2x_read_sfp_module_eeprom(params, |
2409 | SFP_EEPROM_CON_TYPE_ADDR, | 2561 | SFP_EEPROM_CON_TYPE_ADDR, |
2410 | 1, | 2562 | 1, |
2411 | &val) != 0) { | 2563 | &val) != 0) { |
2412 | DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM"); | 2564 | DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n"); |
2413 | return -EINVAL; | 2565 | return -EINVAL; |
2414 | } | 2566 | } |
2415 | 2567 | ||
@@ -2433,13 +2585,13 @@ static u8 bnx2x_get_sfp_module_type(struct link_params *params, | |||
2433 | if (copper_module_type & | 2585 | if (copper_module_type & |
2434 | SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) { | 2586 | SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) { |
2435 | DP(NETIF_MSG_LINK, "Active Copper cable detected\n"); | 2587 | DP(NETIF_MSG_LINK, "Active Copper cable detected\n"); |
2436 | *module_type = SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE; | 2588 | check_limiting_mode = 1; |
2437 | } else if (copper_module_type & | 2589 | } else if (copper_module_type & |
2438 | SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) { | 2590 | SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) { |
2439 | DP(NETIF_MSG_LINK, "Passive Copper" | 2591 | DP(NETIF_MSG_LINK, "Passive Copper" |
2440 | " cable detected\n"); | 2592 | " cable detected\n"); |
2441 | *module_type = | 2593 | *edc_mode = |
2442 | SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE; | 2594 | EDC_MODE_PASSIVE_DAC; |
2443 | } else { | 2595 | } else { |
2444 | DP(NETIF_MSG_LINK, "Unknown copper-cable-" | 2596 | DP(NETIF_MSG_LINK, "Unknown copper-cable-" |
2445 | "type 0x%x !!!\n", copper_module_type); | 2597 | "type 0x%x !!!\n", copper_module_type); |
@@ -2449,7 +2601,7 @@ static u8 bnx2x_get_sfp_module_type(struct link_params *params, | |||
2449 | } | 2601 | } |
2450 | case SFP_EEPROM_CON_TYPE_VAL_LC: | 2602 | case SFP_EEPROM_CON_TYPE_VAL_LC: |
2451 | DP(NETIF_MSG_LINK, "Optic module detected\n"); | 2603 | DP(NETIF_MSG_LINK, "Optic module detected\n"); |
2452 | *module_type = SFP_MODULE_TYPE_LC; | 2604 | check_limiting_mode = 1; |
2453 | break; | 2605 | break; |
2454 | 2606 | ||
2455 | default: | 2607 | default: |
@@ -2457,89 +2609,92 @@ static u8 bnx2x_get_sfp_module_type(struct link_params *params, | |||
2457 | val); | 2609 | val); |
2458 | return -EINVAL; | 2610 | return -EINVAL; |
2459 | } | 2611 | } |
2612 | |||
2613 | if (check_limiting_mode) { | ||
2614 | u8 options[SFP_EEPROM_OPTIONS_SIZE]; | ||
2615 | if (bnx2x_read_sfp_module_eeprom(params, | ||
2616 | SFP_EEPROM_OPTIONS_ADDR, | ||
2617 | SFP_EEPROM_OPTIONS_SIZE, | ||
2618 | options) != 0) { | ||
2619 | DP(NETIF_MSG_LINK, "Failed to read Option" | ||
2620 | " field from module EEPROM\n"); | ||
2621 | return -EINVAL; | ||
2622 | } | ||
2623 | if ((options[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK)) | ||
2624 | *edc_mode = EDC_MODE_LINEAR; | ||
2625 | else | ||
2626 | *edc_mode = EDC_MODE_LIMITING; | ||
2627 | } | ||
2628 | DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode); | ||
2460 | return 0; | 2629 | return 0; |
2461 | } | 2630 | } |
2462 | 2631 | ||
2463 | |||
2464 | /* This function read the relevant field from the module ( SFP+ ), | 2632 | /* This function read the relevant field from the module ( SFP+ ), |
2465 | and verify it is compliant with this board */ | 2633 | and verify it is compliant with this board */ |
2466 | static u8 bnx2x_verify_sfp_module(struct link_params *params, | 2634 | static u8 bnx2x_verify_sfp_module(struct link_params *params) |
2467 | u8 module_type) | ||
2468 | { | 2635 | { |
2469 | struct bnx2x *bp = params->bp; | 2636 | struct bnx2x *bp = params->bp; |
2470 | u8 *str_p, *tmp_buf; | 2637 | u32 val; |
2471 | u16 i; | 2638 | u32 fw_resp; |
2472 | 2639 | char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1]; | |
2473 | #define COMPLIANCE_STR_CNT 6 | 2640 | char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1]; |
2474 | u8 *compliance_str[] = {"Broadcom", "JDSU", "Molex Inc", "PICOLIGHT", | 2641 | |
2475 | "FINISAR CORP. ", "Amphenol"}; | 2642 | val = REG_RD(bp, params->shmem_base + |
2476 | u8 buf[SFP_EEPROM_VENDOR_NAME_SIZE]; | 2643 | offsetof(struct shmem_region, dev_info. |
2477 | /* Passive Copper cables are allowed to participate, | 2644 | port_feature_config[params->port].config)); |
2478 | since the module is hardwired to the copper cable */ | 2645 | if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == |
2479 | 2646 | PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) { | |
2480 | if (!(params->feature_config_flags & | ||
2481 | FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) { | ||
2482 | DP(NETIF_MSG_LINK, "NOT enforcing module verification\n"); | 2647 | DP(NETIF_MSG_LINK, "NOT enforcing module verification\n"); |
2483 | return 0; | 2648 | return 0; |
2484 | } | 2649 | } |
2485 | 2650 | ||
2486 | if (module_type != SFP_MODULE_TYPE_LC) { | 2651 | /* Ask the FW to validate the module */ |
2487 | DP(NETIF_MSG_LINK, "No need to verify copper cable\n"); | 2652 | if (!(params->feature_config_flags & |
2653 | FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY)) { | ||
2654 | DP(NETIF_MSG_LINK, "FW does not support OPT MDL " | ||
2655 | "verification\n"); | ||
2656 | return -EINVAL; | ||
2657 | } | ||
2658 | |||
2659 | fw_resp = bnx2x_fw_command(bp, DRV_MSG_CODE_VRFY_OPT_MDL); | ||
2660 | if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) { | ||
2661 | DP(NETIF_MSG_LINK, "Approved module\n"); | ||
2488 | return 0; | 2662 | return 0; |
2489 | } | 2663 | } |
2490 | 2664 | ||
2491 | /* In case of non copper cable or Active copper cable, | 2665 | /* format the warning message */ |
2492 | verify that the SFP+ module is compliant with this board*/ | ||
2493 | if (bnx2x_read_sfp_module_eeprom(params, | 2666 | if (bnx2x_read_sfp_module_eeprom(params, |
2494 | SFP_EEPROM_VENDOR_NAME_ADDR, | 2667 | SFP_EEPROM_VENDOR_NAME_ADDR, |
2495 | SFP_EEPROM_VENDOR_NAME_SIZE, | 2668 | SFP_EEPROM_VENDOR_NAME_SIZE, |
2496 | buf) != 0) { | 2669 | (u8 *)vendor_name)) |
2497 | DP(NETIF_MSG_LINK, "Failed to read Vendor-Name from" | 2670 | vendor_name[0] = '\0'; |
2498 | " module EEPROM\n"); | 2671 | else |
2499 | return -EINVAL; | 2672 | vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0'; |
2500 | } | 2673 | if (bnx2x_read_sfp_module_eeprom(params, |
2501 | for (i = 0; i < COMPLIANCE_STR_CNT; i++) { | 2674 | SFP_EEPROM_PART_NO_ADDR, |
2502 | str_p = compliance_str[i]; | 2675 | SFP_EEPROM_PART_NO_SIZE, |
2503 | tmp_buf = buf; | 2676 | (u8 *)vendor_pn)) |
2504 | while (*str_p) { | 2677 | vendor_pn[0] = '\0'; |
2505 | if ((u8)(*tmp_buf) != (u8)(*str_p)) | 2678 | else |
2506 | break; | 2679 | vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0'; |
2507 | str_p++; | ||
2508 | tmp_buf++; | ||
2509 | } | ||
2510 | 2680 | ||
2511 | if (!(*str_p)) { | 2681 | printk(KERN_INFO PFX "Warning: " |
2512 | DP(NETIF_MSG_LINK, "SFP+ Module verified, " | 2682 | "Unqualified SFP+ module " |
2513 | "index=%x\n", i); | 2683 | "detected on %s, Port %d from %s part number %s\n" |
2514 | return 0; | 2684 | , bp->dev->name, params->port, |
2515 | } | 2685 | vendor_name, vendor_pn); |
2516 | } | ||
2517 | DP(NETIF_MSG_LINK, "Incompliant SFP+ module. Disable module !!!\n"); | ||
2518 | return -EINVAL; | 2686 | return -EINVAL; |
2519 | } | 2687 | } |
2520 | 2688 | ||
2521 | |||
2522 | static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params, | 2689 | static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params, |
2523 | u8 module_type) | 2690 | u16 edc_mode) |
2524 | { | 2691 | { |
2525 | struct bnx2x *bp = params->bp; | 2692 | struct bnx2x *bp = params->bp; |
2526 | u8 port = params->port; | 2693 | u8 port = params->port; |
2527 | u8 options[SFP_EEPROM_OPTIONS_SIZE]; | ||
2528 | u8 limiting_mode; | ||
2529 | u8 ext_phy_addr = ((params->ext_phy_config & | 2694 | u8 ext_phy_addr = ((params->ext_phy_config & |
2530 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> | 2695 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> |
2531 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); | 2696 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); |
2532 | u16 cur_limiting_mode; | 2697 | u16 cur_limiting_mode; |
2533 | if (bnx2x_read_sfp_module_eeprom(params, | ||
2534 | SFP_EEPROM_OPTIONS_ADDR, | ||
2535 | SFP_EEPROM_OPTIONS_SIZE, | ||
2536 | options) != 0) { | ||
2537 | DP(NETIF_MSG_LINK, "Failed to read Option field from" | ||
2538 | " module EEPROM\n"); | ||
2539 | return -EINVAL; | ||
2540 | } | ||
2541 | limiting_mode = !(options[0] & | ||
2542 | SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK); | ||
2543 | 2698 | ||
2544 | bnx2x_cl45_read(bp, port, | 2699 | bnx2x_cl45_read(bp, port, |
2545 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, | 2700 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, |
@@ -2550,26 +2705,23 @@ static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params, | |||
2550 | DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n", | 2705 | DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n", |
2551 | cur_limiting_mode); | 2706 | cur_limiting_mode); |
2552 | 2707 | ||
2553 | if (limiting_mode && | 2708 | if (edc_mode == EDC_MODE_LIMITING) { |
2554 | (module_type != SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE)) { | ||
2555 | DP(NETIF_MSG_LINK, | 2709 | DP(NETIF_MSG_LINK, |
2556 | "Module options = 0x%x.Setting LIMITING MODE\n", | 2710 | "Setting LIMITING MODE\n"); |
2557 | options[0]); | ||
2558 | bnx2x_cl45_write(bp, port, | 2711 | bnx2x_cl45_write(bp, port, |
2559 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, | 2712 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, |
2560 | ext_phy_addr, | 2713 | ext_phy_addr, |
2561 | MDIO_PMA_DEVAD, | 2714 | MDIO_PMA_DEVAD, |
2562 | MDIO_PMA_REG_ROM_VER2, | 2715 | MDIO_PMA_REG_ROM_VER2, |
2563 | SFP_LIMITING_MODE_VALUE); | 2716 | EDC_MODE_LIMITING); |
2564 | } else { /* LRM mode ( default )*/ | 2717 | } else { /* LRM mode ( default )*/ |
2565 | 2718 | ||
2566 | DP(NETIF_MSG_LINK, "Module options = 0x%x.Setting LRM MODE\n", | 2719 | DP(NETIF_MSG_LINK, "Setting LRM MODE\n"); |
2567 | options[0]); | ||
2568 | 2720 | ||
2569 | /* Changing to LRM mode takes quite few seconds. | 2721 | /* Changing to LRM mode takes quite few seconds. |
2570 | So do it only if current mode is limiting | 2722 | So do it only if current mode is limiting |
2571 | ( default is LRM )*/ | 2723 | ( default is LRM )*/ |
2572 | if (cur_limiting_mode != SFP_LIMITING_MODE_VALUE) | 2724 | if (cur_limiting_mode != EDC_MODE_LIMITING) |
2573 | return 0; | 2725 | return 0; |
2574 | 2726 | ||
2575 | bnx2x_cl45_write(bp, port, | 2727 | bnx2x_cl45_write(bp, port, |
@@ -2600,6 +2752,56 @@ static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params, | |||
2600 | return 0; | 2752 | return 0; |
2601 | } | 2753 | } |
2602 | 2754 | ||
2755 | static u8 bnx2x_bcm8727_set_limiting_mode(struct link_params *params, | ||
2756 | u16 edc_mode) | ||
2757 | { | ||
2758 | struct bnx2x *bp = params->bp; | ||
2759 | u8 port = params->port; | ||
2760 | u16 phy_identifier; | ||
2761 | u16 rom_ver2_val; | ||
2762 | u8 ext_phy_addr = ((params->ext_phy_config & | ||
2763 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> | ||
2764 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); | ||
2765 | |||
2766 | bnx2x_cl45_read(bp, port, | ||
2767 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, | ||
2768 | ext_phy_addr, | ||
2769 | MDIO_PMA_DEVAD, | ||
2770 | MDIO_PMA_REG_PHY_IDENTIFIER, | ||
2771 | &phy_identifier); | ||
2772 | |||
2773 | bnx2x_cl45_write(bp, port, | ||
2774 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, | ||
2775 | ext_phy_addr, | ||
2776 | MDIO_PMA_DEVAD, | ||
2777 | MDIO_PMA_REG_PHY_IDENTIFIER, | ||
2778 | (phy_identifier & ~(1<<9))); | ||
2779 | |||
2780 | bnx2x_cl45_read(bp, port, | ||
2781 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, | ||
2782 | ext_phy_addr, | ||
2783 | MDIO_PMA_DEVAD, | ||
2784 | MDIO_PMA_REG_ROM_VER2, | ||
2785 | &rom_ver2_val); | ||
2786 | /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */ | ||
2787 | bnx2x_cl45_write(bp, port, | ||
2788 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, | ||
2789 | ext_phy_addr, | ||
2790 | MDIO_PMA_DEVAD, | ||
2791 | MDIO_PMA_REG_ROM_VER2, | ||
2792 | (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff)); | ||
2793 | |||
2794 | bnx2x_cl45_write(bp, port, | ||
2795 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, | ||
2796 | ext_phy_addr, | ||
2797 | MDIO_PMA_DEVAD, | ||
2798 | MDIO_PMA_REG_PHY_IDENTIFIER, | ||
2799 | (phy_identifier | (1<<9))); | ||
2800 | |||
2801 | return 0; | ||
2802 | } | ||
2803 | |||
2804 | |||
2603 | static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params) | 2805 | static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params) |
2604 | { | 2806 | { |
2605 | u8 val; | 2807 | u8 val; |
@@ -2619,61 +2821,114 @@ static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params) | |||
2619 | return -EINVAL; | 2821 | return -EINVAL; |
2620 | } | 2822 | } |
2621 | 2823 | ||
2824 | static void bnx2x_8727_power_module(struct bnx2x *bp, | ||
2825 | struct link_params *params, | ||
2826 | u8 ext_phy_addr, u8 is_power_up) { | ||
2827 | /* Make sure GPIOs are not using for LED mode */ | ||
2828 | u16 val; | ||
2829 | u8 port = params->port; | ||
2830 | /* | ||
2831 | * In the GPIO register, bit 4 is use to detemine if the GPIOs are | ||
2832 | * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for | ||
2833 | * output | ||
2834 | * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0 | ||
2835 | * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1 | ||
2836 | * where the 1st bit is the over-current(only input), and 2nd bit is | ||
2837 | * for power( only output ) | ||
2838 | */ | ||
2839 | |||
2840 | /* | ||
2841 | * In case of NOC feature is disabled and power is up, set GPIO control | ||
2842 | * as input to enable listening of over-current indication | ||
2843 | */ | ||
2844 | |||
2845 | if (!(params->feature_config_flags & | ||
2846 | FEATURE_CONFIG_BCM8727_NOC) && is_power_up) | ||
2847 | val = (1<<4); | ||
2848 | else | ||
2849 | /* | ||
2850 | * Set GPIO control to OUTPUT, and set the power bit | ||
2851 | * to according to the is_power_up | ||
2852 | */ | ||
2853 | val = ((!(is_power_up)) << 1); | ||
2854 | |||
2855 | bnx2x_cl45_write(bp, port, | ||
2856 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, | ||
2857 | ext_phy_addr, | ||
2858 | MDIO_PMA_DEVAD, | ||
2859 | MDIO_PMA_REG_8727_GPIO_CTRL, | ||
2860 | val); | ||
2861 | } | ||
2862 | |||
2622 | static u8 bnx2x_sfp_module_detection(struct link_params *params) | 2863 | static u8 bnx2x_sfp_module_detection(struct link_params *params) |
2623 | { | 2864 | { |
2624 | struct bnx2x *bp = params->bp; | 2865 | struct bnx2x *bp = params->bp; |
2625 | u8 module_type; | 2866 | u16 edc_mode; |
2867 | u8 rc = 0; | ||
2626 | u8 ext_phy_addr = ((params->ext_phy_config & | 2868 | u8 ext_phy_addr = ((params->ext_phy_config & |
2627 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> | 2869 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> |
2628 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); | 2870 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); |
2629 | u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); | 2871 | u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); |
2630 | 2872 | u32 val = REG_RD(bp, params->shmem_base + | |
2631 | if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) { | 2873 | offsetof(struct shmem_region, dev_info. |
2632 | DP(NETIF_MSG_LINK, "Module detection is not required " | 2874 | port_feature_config[params->port].config)); |
2633 | "for this phy\n"); | ||
2634 | return 0; | ||
2635 | } | ||
2636 | 2875 | ||
2637 | DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n", | 2876 | DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n", |
2638 | params->port); | 2877 | params->port); |
2639 | 2878 | ||
2640 | if (bnx2x_get_sfp_module_type(params, | 2879 | if (bnx2x_get_edc_mode(params, &edc_mode) != 0) { |
2641 | &module_type) != 0) { | ||
2642 | DP(NETIF_MSG_LINK, "Failed to get valid module type\n"); | 2880 | DP(NETIF_MSG_LINK, "Failed to get valid module type\n"); |
2643 | if (!(params->feature_config_flags & | 2881 | return -EINVAL; |
2644 | FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) { | 2882 | } else if (bnx2x_verify_sfp_module(params) != |
2645 | /* In case module detection is disabled, it trys to | ||
2646 | link up. The issue that can happen here is LRM / | ||
2647 | LIMITING mode which set according to the module-type*/ | ||
2648 | DP(NETIF_MSG_LINK, "Unable to read module-type." | ||
2649 | "Probably due to Bit Stretching." | ||
2650 | " Proceeding...\n"); | ||
2651 | } else { | ||
2652 | return -EINVAL; | ||
2653 | } | ||
2654 | } else if (bnx2x_verify_sfp_module(params, module_type) != | ||
2655 | 0) { | 2883 | 0) { |
2656 | /* check SFP+ module compatibility */ | 2884 | /* check SFP+ module compatibility */ |
2657 | DP(NETIF_MSG_LINK, "Module verification failed!!\n"); | 2885 | DP(NETIF_MSG_LINK, "Module verification failed!!\n"); |
2886 | rc = -EINVAL; | ||
2658 | /* Turn on fault module-detected led */ | 2887 | /* Turn on fault module-detected led */ |
2659 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, | 2888 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, |
2660 | MISC_REGISTERS_GPIO_HIGH, | 2889 | MISC_REGISTERS_GPIO_HIGH, |
2661 | params->port); | 2890 | params->port); |
2662 | return -EINVAL; | 2891 | if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) && |
2892 | ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == | ||
2893 | PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) { | ||
2894 | /* Shutdown SFP+ module */ | ||
2895 | DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n"); | ||
2896 | bnx2x_8727_power_module(bp, params, | ||
2897 | ext_phy_addr, 0); | ||
2898 | return rc; | ||
2899 | } | ||
2900 | } else { | ||
2901 | /* Turn off fault module-detected led */ | ||
2902 | DP(NETIF_MSG_LINK, "Turn off fault module-detected led\n"); | ||
2903 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, | ||
2904 | MISC_REGISTERS_GPIO_LOW, | ||
2905 | params->port); | ||
2663 | } | 2906 | } |
2664 | 2907 | ||
2665 | /* Turn off fault module-detected led */ | 2908 | /* power up the SFP module */ |
2666 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, | 2909 | if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) |
2667 | MISC_REGISTERS_GPIO_LOW, | 2910 | bnx2x_8727_power_module(bp, params, ext_phy_addr, 1); |
2668 | params->port); | ||
2669 | 2911 | ||
2670 | /* Check and set limiting mode / LRM mode */ | 2912 | /* Check and set limiting mode / LRM mode on 8726. |
2671 | bnx2x_bcm8726_set_limiting_mode(params, module_type); | 2913 | On 8727 it is done automatically */ |
2914 | if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) | ||
2915 | bnx2x_bcm8726_set_limiting_mode(params, edc_mode); | ||
2916 | else | ||
2917 | bnx2x_bcm8727_set_limiting_mode(params, edc_mode); | ||
2918 | /* | ||
2919 | * Enable transmit for this module if the module is approved, or | ||
2920 | * if unapproved modules should also enable the Tx laser | ||
2921 | */ | ||
2922 | if (rc == 0 || | ||
2923 | (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) != | ||
2924 | PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) | ||
2925 | bnx2x_sfp_set_transmitter(bp, params->port, | ||
2926 | ext_phy_type, ext_phy_addr, 1); | ||
2927 | else | ||
2928 | bnx2x_sfp_set_transmitter(bp, params->port, | ||
2929 | ext_phy_type, ext_phy_addr, 0); | ||
2672 | 2930 | ||
2673 | /* Enable transmit for this module */ | 2931 | return rc; |
2674 | bnx2x_bcm8726_set_transmitter(bp, params->port, | ||
2675 | ext_phy_addr, 1); | ||
2676 | return 0; | ||
2677 | } | 2932 | } |
2678 | 2933 | ||
2679 | void bnx2x_handle_module_detect_int(struct link_params *params) | 2934 | void bnx2x_handle_module_detect_int(struct link_params *params) |
@@ -2696,8 +2951,8 @@ void bnx2x_handle_module_detect_int(struct link_params *params) | |||
2696 | MISC_REGISTERS_GPIO_INT_OUTPUT_CLR, | 2951 | MISC_REGISTERS_GPIO_INT_OUTPUT_CLR, |
2697 | port); | 2952 | port); |
2698 | 2953 | ||
2699 | if (bnx2x_wait_for_sfp_module_initialized(params) | 2954 | if (bnx2x_wait_for_sfp_module_initialized(params) == |
2700 | == 0) | 2955 | 0) |
2701 | bnx2x_sfp_module_detection(params); | 2956 | bnx2x_sfp_module_detection(params); |
2702 | else | 2957 | else |
2703 | DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n"); | 2958 | DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n"); |
@@ -2705,13 +2960,22 @@ void bnx2x_handle_module_detect_int(struct link_params *params) | |||
2705 | u8 ext_phy_addr = ((params->ext_phy_config & | 2960 | u8 ext_phy_addr = ((params->ext_phy_config & |
2706 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> | 2961 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> |
2707 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); | 2962 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); |
2963 | u32 ext_phy_type = | ||
2964 | XGXS_EXT_PHY_TYPE(params->ext_phy_config); | ||
2965 | u32 val = REG_RD(bp, params->shmem_base + | ||
2966 | offsetof(struct shmem_region, dev_info. | ||
2967 | port_feature_config[params->port]. | ||
2968 | config)); | ||
2969 | |||
2708 | bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3, | 2970 | bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3, |
2709 | MISC_REGISTERS_GPIO_INT_OUTPUT_SET, | 2971 | MISC_REGISTERS_GPIO_INT_OUTPUT_SET, |
2710 | port); | 2972 | port); |
2711 | /* Module was plugged out. */ | 2973 | /* Module was plugged out. */ |
2712 | /* Disable transmit for this module */ | 2974 | /* Disable transmit for this module */ |
2713 | bnx2x_bcm8726_set_transmitter(bp, params->port, | 2975 | if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == |
2714 | ext_phy_addr, 0); | 2976 | PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) |
2977 | bnx2x_sfp_set_transmitter(bp, params->port, | ||
2978 | ext_phy_type, ext_phy_addr, 0); | ||
2715 | } | 2979 | } |
2716 | } | 2980 | } |
2717 | 2981 | ||
@@ -3160,6 +3424,9 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
3160 | driver is loaded, it reset all registers, including the | 3424 | driver is loaded, it reset all registers, including the |
3161 | transmitter */ | 3425 | transmitter */ |
3162 | bnx2x_sfp_module_detection(params); | 3426 | bnx2x_sfp_module_detection(params); |
3427 | |||
3428 | /* Set Flow control */ | ||
3429 | bnx2x_ext_phy_set_pause(params, vars); | ||
3163 | if (params->req_line_speed == SPEED_1000) { | 3430 | if (params->req_line_speed == SPEED_1000) { |
3164 | DP(NETIF_MSG_LINK, "Setting 1G force\n"); | 3431 | DP(NETIF_MSG_LINK, "Setting 1G force\n"); |
3165 | bnx2x_cl45_write(bp, params->port, ext_phy_type, | 3432 | bnx2x_cl45_write(bp, params->port, ext_phy_type, |
@@ -3450,6 +3717,187 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
3450 | ((val & (1<<7)) > 0)); | 3717 | ((val & (1<<7)) > 0)); |
3451 | break; | 3718 | break; |
3452 | } | 3719 | } |
3720 | |||
3721 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: | ||
3722 | { | ||
3723 | u16 tmp1; | ||
3724 | u16 rx_alarm_ctrl_val; | ||
3725 | u16 lasi_ctrl_val; | ||
3726 | |||
3727 | /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */ | ||
3728 | |||
3729 | u16 mod_abs; | ||
3730 | rx_alarm_ctrl_val = (1<<2) | (1<<5) ; | ||
3731 | lasi_ctrl_val = 0x0004; | ||
3732 | |||
3733 | DP(NETIF_MSG_LINK, "Initializing BCM8727\n"); | ||
3734 | /* enable LASI */ | ||
3735 | bnx2x_cl45_write(bp, params->port, | ||
3736 | ext_phy_type, | ||
3737 | ext_phy_addr, | ||
3738 | MDIO_PMA_DEVAD, | ||
3739 | MDIO_PMA_REG_RX_ALARM_CTRL, | ||
3740 | rx_alarm_ctrl_val); | ||
3741 | |||
3742 | bnx2x_cl45_write(bp, params->port, | ||
3743 | ext_phy_type, | ||
3744 | ext_phy_addr, | ||
3745 | MDIO_PMA_DEVAD, | ||
3746 | MDIO_PMA_REG_LASI_CTRL, | ||
3747 | lasi_ctrl_val); | ||
3748 | |||
3749 | /* Initially configure MOD_ABS to interrupt when | ||
3750 | module is presence( bit 8) */ | ||
3751 | bnx2x_cl45_read(bp, params->port, | ||
3752 | ext_phy_type, | ||
3753 | ext_phy_addr, | ||
3754 | MDIO_PMA_DEVAD, | ||
3755 | MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs); | ||
3756 | /* Set EDC off by setting OPTXLOS signal input to low | ||
3757 | (bit 9). | ||
3758 | When the EDC is off it locks onto a reference clock and | ||
3759 | avoids becoming 'lost'.*/ | ||
3760 | mod_abs &= ~((1<<8) | (1<<9)); | ||
3761 | bnx2x_cl45_write(bp, params->port, | ||
3762 | ext_phy_type, | ||
3763 | ext_phy_addr, | ||
3764 | MDIO_PMA_DEVAD, | ||
3765 | MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); | ||
3766 | |||
3767 | /* Make MOD_ABS give interrupt on change */ | ||
3768 | bnx2x_cl45_read(bp, params->port, | ||
3769 | ext_phy_type, | ||
3770 | ext_phy_addr, | ||
3771 | MDIO_PMA_DEVAD, | ||
3772 | MDIO_PMA_REG_8727_PCS_OPT_CTRL, | ||
3773 | &val); | ||
3774 | val |= (1<<12); | ||
3775 | bnx2x_cl45_write(bp, params->port, | ||
3776 | ext_phy_type, | ||
3777 | ext_phy_addr, | ||
3778 | MDIO_PMA_DEVAD, | ||
3779 | MDIO_PMA_REG_8727_PCS_OPT_CTRL, | ||
3780 | val); | ||
3781 | |||
3782 | /* Set 8727 GPIOs to input to allow reading from the | ||
3783 | 8727 GPIO0 status which reflect SFP+ module | ||
3784 | over-current */ | ||
3785 | |||
3786 | bnx2x_cl45_read(bp, params->port, | ||
3787 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, | ||
3788 | ext_phy_addr, | ||
3789 | MDIO_PMA_DEVAD, | ||
3790 | MDIO_PMA_REG_8727_PCS_OPT_CTRL, | ||
3791 | &val); | ||
3792 | val &= 0xff8f; /* Reset bits 4-6 */ | ||
3793 | bnx2x_cl45_write(bp, params->port, | ||
3794 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, | ||
3795 | ext_phy_addr, | ||
3796 | MDIO_PMA_DEVAD, | ||
3797 | MDIO_PMA_REG_8727_PCS_OPT_CTRL, | ||
3798 | val); | ||
3799 | |||
3800 | bnx2x_8727_power_module(bp, params, ext_phy_addr, 1); | ||
3801 | bnx2x_bcm8073_set_xaui_low_power_mode(params); | ||
3802 | |||
3803 | bnx2x_cl45_read(bp, params->port, | ||
3804 | ext_phy_type, | ||
3805 | ext_phy_addr, | ||
3806 | MDIO_PMA_DEVAD, | ||
3807 | MDIO_PMA_REG_M8051_MSGOUT_REG, | ||
3808 | &tmp1); | ||
3809 | |||
3810 | bnx2x_cl45_read(bp, params->port, | ||
3811 | ext_phy_type, | ||
3812 | ext_phy_addr, | ||
3813 | MDIO_PMA_DEVAD, | ||
3814 | MDIO_PMA_REG_RX_ALARM, &tmp1); | ||
3815 | |||
3816 | /* Set option 1G speed */ | ||
3817 | if (params->req_line_speed == SPEED_1000) { | ||
3818 | |||
3819 | DP(NETIF_MSG_LINK, "Setting 1G force\n"); | ||
3820 | bnx2x_cl45_write(bp, params->port, | ||
3821 | ext_phy_type, | ||
3822 | ext_phy_addr, | ||
3823 | MDIO_PMA_DEVAD, | ||
3824 | MDIO_PMA_REG_CTRL, 0x40); | ||
3825 | bnx2x_cl45_write(bp, params->port, | ||
3826 | ext_phy_type, | ||
3827 | ext_phy_addr, | ||
3828 | MDIO_PMA_DEVAD, | ||
3829 | MDIO_PMA_REG_10G_CTRL2, 0xD); | ||
3830 | bnx2x_cl45_read(bp, params->port, | ||
3831 | ext_phy_type, | ||
3832 | ext_phy_addr, | ||
3833 | MDIO_PMA_DEVAD, | ||
3834 | MDIO_PMA_REG_10G_CTRL2, &tmp1); | ||
3835 | DP(NETIF_MSG_LINK, "1.7 = 0x%x \n", tmp1); | ||
3836 | |||
3837 | } else if ((params->req_line_speed == | ||
3838 | SPEED_AUTO_NEG) && | ||
3839 | ((params->speed_cap_mask & | ||
3840 | PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) { | ||
3841 | |||
3842 | DP(NETIF_MSG_LINK, "Setting 1G clause37 \n"); | ||
3843 | bnx2x_cl45_write(bp, params->port, ext_phy_type, | ||
3844 | ext_phy_addr, MDIO_AN_DEVAD, | ||
3845 | MDIO_PMA_REG_8727_MISC_CTRL, 0); | ||
3846 | bnx2x_cl45_write(bp, params->port, ext_phy_type, | ||
3847 | ext_phy_addr, MDIO_AN_DEVAD, | ||
3848 | MDIO_AN_REG_CL37_AN, 0x1300); | ||
3849 | } else { | ||
3850 | /* Since the 8727 has only single reset pin, | ||
3851 | need to set the 10G registers although it is | ||
3852 | default */ | ||
3853 | bnx2x_cl45_write(bp, params->port, ext_phy_type, | ||
3854 | ext_phy_addr, MDIO_AN_DEVAD, | ||
3855 | MDIO_AN_REG_CTRL, 0x0020); | ||
3856 | bnx2x_cl45_write(bp, params->port, ext_phy_type, | ||
3857 | ext_phy_addr, MDIO_AN_DEVAD, | ||
3858 | 0x7, 0x0100); | ||
3859 | bnx2x_cl45_write(bp, params->port, ext_phy_type, | ||
3860 | ext_phy_addr, MDIO_PMA_DEVAD, | ||
3861 | MDIO_PMA_REG_CTRL, 0x2040); | ||
3862 | bnx2x_cl45_write(bp, params->port, ext_phy_type, | ||
3863 | ext_phy_addr, MDIO_PMA_DEVAD, | ||
3864 | MDIO_PMA_REG_10G_CTRL2, 0x0008); | ||
3865 | } | ||
3866 | |||
3867 | /* Set 2-wire transfer rate to 400Khz since 100Khz | ||
3868 | is not operational */ | ||
3869 | bnx2x_cl45_write(bp, params->port, | ||
3870 | ext_phy_type, | ||
3871 | ext_phy_addr, | ||
3872 | MDIO_PMA_DEVAD, | ||
3873 | MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR, | ||
3874 | 0xa101); | ||
3875 | |||
3876 | /* Set TX PreEmphasis if needed */ | ||
3877 | if ((params->feature_config_flags & | ||
3878 | FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { | ||
3879 | DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x," | ||
3880 | "TX_CTRL2 0x%x\n", | ||
3881 | params->xgxs_config_tx[0], | ||
3882 | params->xgxs_config_tx[1]); | ||
3883 | bnx2x_cl45_write(bp, params->port, | ||
3884 | ext_phy_type, | ||
3885 | ext_phy_addr, | ||
3886 | MDIO_PMA_DEVAD, | ||
3887 | MDIO_PMA_REG_8727_TX_CTRL1, | ||
3888 | params->xgxs_config_tx[0]); | ||
3889 | |||
3890 | bnx2x_cl45_write(bp, params->port, | ||
3891 | ext_phy_type, | ||
3892 | ext_phy_addr, | ||
3893 | MDIO_PMA_DEVAD, | ||
3894 | MDIO_PMA_REG_8727_TX_CTRL2, | ||
3895 | params->xgxs_config_tx[1]); | ||
3896 | } | ||
3897 | |||
3898 | break; | ||
3899 | } | ||
3900 | |||
3453 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: | 3901 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: |
3454 | { | 3902 | { |
3455 | u16 fw_ver1, fw_ver2; | 3903 | u16 fw_ver1, fw_ver2; |
@@ -3561,6 +4009,99 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
3561 | return rc; | 4009 | return rc; |
3562 | } | 4010 | } |
3563 | 4011 | ||
4012 | static void bnx2x_8727_handle_mod_abs(struct link_params *params) | ||
4013 | { | ||
4014 | struct bnx2x *bp = params->bp; | ||
4015 | u16 mod_abs, rx_alarm_status; | ||
4016 | u8 ext_phy_addr = ((params->ext_phy_config & | ||
4017 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> | ||
4018 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); | ||
4019 | u32 val = REG_RD(bp, params->shmem_base + | ||
4020 | offsetof(struct shmem_region, dev_info. | ||
4021 | port_feature_config[params->port]. | ||
4022 | config)); | ||
4023 | bnx2x_cl45_read(bp, params->port, | ||
4024 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, | ||
4025 | ext_phy_addr, | ||
4026 | MDIO_PMA_DEVAD, | ||
4027 | MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs); | ||
4028 | if (mod_abs & (1<<8)) { | ||
4029 | |||
4030 | /* Module is absent */ | ||
4031 | DP(NETIF_MSG_LINK, "MOD_ABS indication " | ||
4032 | "show module is absent\n"); | ||
4033 | |||
4034 | /* 1. Set mod_abs to detect next module | ||
4035 | presence event | ||
4036 | 2. Set EDC off by setting OPTXLOS signal input to low | ||
4037 | (bit 9). | ||
4038 | When the EDC is off it locks onto a reference clock and | ||
4039 | avoids becoming 'lost'.*/ | ||
4040 | mod_abs &= ~((1<<8)|(1<<9)); | ||
4041 | bnx2x_cl45_write(bp, params->port, | ||
4042 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, | ||
4043 | ext_phy_addr, | ||
4044 | MDIO_PMA_DEVAD, | ||
4045 | MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); | ||
4046 | |||
4047 | /* Clear RX alarm since it stays up as long as | ||
4048 | the mod_abs wasn't changed */ | ||
4049 | bnx2x_cl45_read(bp, params->port, | ||
4050 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, | ||
4051 | ext_phy_addr, | ||
4052 | MDIO_PMA_DEVAD, | ||
4053 | MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); | ||
4054 | |||
4055 | } else { | ||
4056 | /* Module is present */ | ||
4057 | DP(NETIF_MSG_LINK, "MOD_ABS indication " | ||
4058 | "show module is present\n"); | ||
4059 | /* First thing, disable transmitter, | ||
4060 | and if the module is ok, the | ||
4061 | module_detection will enable it*/ | ||
4062 | |||
4063 | /* 1. Set mod_abs to detect next module | ||
4064 | absent event ( bit 8) | ||
4065 | 2. Restore the default polarity of the OPRXLOS signal and | ||
4066 | this signal will then correctly indicate the presence or | ||
4067 | absence of the Rx signal. (bit 9) */ | ||
4068 | mod_abs |= ((1<<8)|(1<<9)); | ||
4069 | bnx2x_cl45_write(bp, params->port, | ||
4070 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, | ||
4071 | ext_phy_addr, | ||
4072 | MDIO_PMA_DEVAD, | ||
4073 | MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); | ||
4074 | |||
4075 | /* Clear RX alarm since it stays up as long as | ||
4076 | the mod_abs wasn't changed. This is need to be done | ||
4077 | before calling the module detection, otherwise it will clear | ||
4078 | the link update alarm */ | ||
4079 | bnx2x_cl45_read(bp, params->port, | ||
4080 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, | ||
4081 | ext_phy_addr, | ||
4082 | MDIO_PMA_DEVAD, | ||
4083 | MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); | ||
4084 | |||
4085 | |||
4086 | if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == | ||
4087 | PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) | ||
4088 | bnx2x_sfp_set_transmitter(bp, params->port, | ||
4089 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, | ||
4090 | ext_phy_addr, 0); | ||
4091 | |||
4092 | if (bnx2x_wait_for_sfp_module_initialized(params) | ||
4093 | == 0) | ||
4094 | bnx2x_sfp_module_detection(params); | ||
4095 | else | ||
4096 | DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n"); | ||
4097 | } | ||
4098 | |||
4099 | DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", | ||
4100 | rx_alarm_status); | ||
4101 | /* No need to check link status in case of | ||
4102 | module plugged in/out */ | ||
4103 | } | ||
4104 | |||
3564 | 4105 | ||
3565 | static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, | 4106 | static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, |
3566 | struct link_vars *vars) | 4107 | struct link_vars *vars) |
@@ -3602,8 +4143,19 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, | |||
3602 | ext_phy_addr, | 4143 | ext_phy_addr, |
3603 | MDIO_PMA_DEVAD, | 4144 | MDIO_PMA_DEVAD, |
3604 | MDIO_PMA_REG_RX_SD, &rx_sd); | 4145 | MDIO_PMA_REG_RX_SD, &rx_sd); |
3605 | DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd); | 4146 | |
3606 | ext_phy_link_up = (rx_sd & 0x1); | 4147 | bnx2x_cl45_read(bp, params->port, ext_phy_type, |
4148 | ext_phy_addr, | ||
4149 | 1, | ||
4150 | 0xc809, &val1); | ||
4151 | bnx2x_cl45_read(bp, params->port, ext_phy_type, | ||
4152 | ext_phy_addr, | ||
4153 | 1, | ||
4154 | 0xc809, &val1); | ||
4155 | |||
4156 | DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1); | ||
4157 | ext_phy_link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) | ||
4158 | && ((val1 & (1<<8)) == 0)); | ||
3607 | if (ext_phy_link_up) | 4159 | if (ext_phy_link_up) |
3608 | vars->line_speed = SPEED_10000; | 4160 | vars->line_speed = SPEED_10000; |
3609 | break; | 4161 | break; |
@@ -3678,8 +4230,160 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, | |||
3678 | else | 4230 | else |
3679 | vars->line_speed = SPEED_10000; | 4231 | vars->line_speed = SPEED_10000; |
3680 | } | 4232 | } |
4233 | break; | ||
4234 | |||
4235 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: | ||
4236 | { | ||
4237 | u16 link_status = 0; | ||
4238 | u16 rx_alarm_status; | ||
4239 | /* Check the LASI */ | ||
4240 | bnx2x_cl45_read(bp, params->port, | ||
4241 | ext_phy_type, | ||
4242 | ext_phy_addr, | ||
4243 | MDIO_PMA_DEVAD, | ||
4244 | MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); | ||
4245 | |||
4246 | DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", | ||
4247 | rx_alarm_status); | ||
4248 | |||
4249 | bnx2x_cl45_read(bp, params->port, | ||
4250 | ext_phy_type, | ||
4251 | ext_phy_addr, | ||
4252 | MDIO_PMA_DEVAD, | ||
4253 | MDIO_PMA_REG_LASI_STATUS, &val1); | ||
4254 | |||
4255 | DP(NETIF_MSG_LINK, | ||
4256 | "8727 LASI status 0x%x\n", | ||
4257 | val1); | ||
4258 | |||
4259 | /* Clear MSG-OUT */ | ||
4260 | bnx2x_cl45_read(bp, params->port, | ||
4261 | ext_phy_type, | ||
4262 | ext_phy_addr, | ||
4263 | MDIO_PMA_DEVAD, | ||
4264 | MDIO_PMA_REG_M8051_MSGOUT_REG, | ||
4265 | &val1); | ||
4266 | |||
4267 | /* | ||
4268 | * If a module is present and there is need to check | ||
4269 | * for over current | ||
4270 | */ | ||
4271 | if (!(params->feature_config_flags & | ||
4272 | FEATURE_CONFIG_BCM8727_NOC) && | ||
4273 | !(rx_alarm_status & (1<<5))) { | ||
4274 | /* Check over-current using 8727 GPIO0 input*/ | ||
4275 | bnx2x_cl45_read(bp, params->port, | ||
4276 | ext_phy_type, | ||
4277 | ext_phy_addr, | ||
4278 | MDIO_PMA_DEVAD, | ||
4279 | MDIO_PMA_REG_8727_GPIO_CTRL, | ||
4280 | &val1); | ||
4281 | |||
4282 | if ((val1 & (1<<8)) == 0) { | ||
4283 | DP(NETIF_MSG_LINK, "8727 Power fault" | ||
4284 | " has been detected on port" | ||
4285 | " %d\n", params->port); | ||
4286 | printk(KERN_ERR PFX "Error: Power" | ||
4287 | " fault on %s Port %d has" | ||
4288 | " been detected and the" | ||
4289 | " power to that SFP+ module" | ||
4290 | " has been removed to prevent" | ||
4291 | " failure of the card. Please" | ||
4292 | " remove the SFP+ module and" | ||
4293 | " restart the system to clear" | ||
4294 | " this error.\n" | ||
4295 | , bp->dev->name, params->port); | ||
4296 | /* | ||
4297 | * Disable all RX_ALARMs except for | ||
4298 | * mod_abs | ||
4299 | */ | ||
4300 | bnx2x_cl45_write(bp, params->port, | ||
4301 | ext_phy_type, | ||
4302 | ext_phy_addr, | ||
4303 | MDIO_PMA_DEVAD, | ||
4304 | MDIO_PMA_REG_RX_ALARM_CTRL, | ||
4305 | (1<<5)); | ||
4306 | |||
4307 | bnx2x_cl45_read(bp, params->port, | ||
4308 | ext_phy_type, | ||
4309 | ext_phy_addr, | ||
4310 | MDIO_PMA_DEVAD, | ||
4311 | MDIO_PMA_REG_PHY_IDENTIFIER, | ||
4312 | &val1); | ||
4313 | /* Wait for module_absent_event */ | ||
4314 | val1 |= (1<<8); | ||
4315 | bnx2x_cl45_write(bp, params->port, | ||
4316 | ext_phy_type, | ||
4317 | ext_phy_addr, | ||
4318 | MDIO_PMA_DEVAD, | ||
4319 | MDIO_PMA_REG_PHY_IDENTIFIER, | ||
4320 | val1); | ||
4321 | /* Clear RX alarm */ | ||
4322 | bnx2x_cl45_read(bp, params->port, | ||
4323 | ext_phy_type, | ||
4324 | ext_phy_addr, | ||
4325 | MDIO_PMA_DEVAD, | ||
4326 | MDIO_PMA_REG_RX_ALARM, | ||
4327 | &rx_alarm_status); | ||
4328 | break; | ||
4329 | } | ||
4330 | } /* Over current check */ | ||
4331 | |||
4332 | /* When module absent bit is set, check module */ | ||
4333 | if (rx_alarm_status & (1<<5)) { | ||
4334 | bnx2x_8727_handle_mod_abs(params); | ||
4335 | /* Enable all mod_abs and link detection bits */ | ||
4336 | bnx2x_cl45_write(bp, params->port, | ||
4337 | ext_phy_type, | ||
4338 | ext_phy_addr, | ||
4339 | MDIO_PMA_DEVAD, | ||
4340 | MDIO_PMA_REG_RX_ALARM_CTRL, | ||
4341 | ((1<<5) | (1<<2))); | ||
4342 | } | ||
4343 | |||
4344 | /* If transmitter is disabled, | ||
4345 | ignore false link up indication */ | ||
4346 | bnx2x_cl45_read(bp, params->port, | ||
4347 | ext_phy_type, | ||
4348 | ext_phy_addr, | ||
4349 | MDIO_PMA_DEVAD, | ||
4350 | MDIO_PMA_REG_PHY_IDENTIFIER, | ||
4351 | &val1); | ||
4352 | if (val1 & (1<<15)) { | ||
4353 | DP(NETIF_MSG_LINK, "Tx is disabled\n"); | ||
4354 | ext_phy_link_up = 0; | ||
4355 | break; | ||
4356 | } | ||
4357 | |||
4358 | bnx2x_cl45_read(bp, params->port, | ||
4359 | ext_phy_type, | ||
4360 | ext_phy_addr, | ||
4361 | MDIO_PMA_DEVAD, | ||
4362 | MDIO_PMA_REG_8073_SPEED_LINK_STATUS, | ||
4363 | &link_status); | ||
3681 | 4364 | ||
4365 | /* Bits 0..2 --> speed detected, | ||
4366 | bits 13..15--> link is down */ | ||
4367 | if ((link_status & (1<<2)) && | ||
4368 | (!(link_status & (1<<15)))) { | ||
4369 | ext_phy_link_up = 1; | ||
4370 | vars->line_speed = SPEED_10000; | ||
4371 | } else if ((link_status & (1<<0)) && | ||
4372 | (!(link_status & (1<<13)))) { | ||
4373 | ext_phy_link_up = 1; | ||
4374 | vars->line_speed = SPEED_1000; | ||
4375 | DP(NETIF_MSG_LINK, | ||
4376 | "port %x: External link" | ||
4377 | " up in 1G\n", params->port); | ||
4378 | } else { | ||
4379 | ext_phy_link_up = 0; | ||
4380 | DP(NETIF_MSG_LINK, | ||
4381 | "port %x: External link" | ||
4382 | " is down\n", params->port); | ||
4383 | } | ||
3682 | break; | 4384 | break; |
4385 | } | ||
4386 | |||
3683 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: | 4387 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: |
3684 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: | 4388 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: |
3685 | { | 4389 | { |
@@ -4241,6 +4945,7 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, | |||
4241 | break; | 4945 | break; |
4242 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: | 4946 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: |
4243 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: | 4947 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: |
4948 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: | ||
4244 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: | 4949 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: |
4245 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: | 4950 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: |
4246 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: | 4951 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: |
@@ -4842,10 +5547,6 @@ static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr) | |||
4842 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr, | 5547 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr, |
4843 | MDIO_PMA_DEVAD, | 5548 | MDIO_PMA_DEVAD, |
4844 | MDIO_PMA_REG_GEN_CTRL, 0x0001); | 5549 | MDIO_PMA_REG_GEN_CTRL, 0x0001); |
4845 | |||
4846 | /* Disable Transmitter */ | ||
4847 | bnx2x_bcm8726_set_transmitter(bp, port, ext_phy_addr, 0); | ||
4848 | |||
4849 | } | 5550 | } |
4850 | 5551 | ||
4851 | u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, | 5552 | u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, |
@@ -4858,6 +5559,11 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, | |||
4858 | u32 chip_id = params->chip_id; | 5559 | u32 chip_id = params->chip_id; |
4859 | u8 port = params->port; | 5560 | u8 port = params->port; |
4860 | u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config); | 5561 | u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config); |
5562 | u32 val = REG_RD(bp, params->shmem_base + | ||
5563 | offsetof(struct shmem_region, dev_info. | ||
5564 | port_feature_config[params->port]. | ||
5565 | config)); | ||
5566 | |||
4861 | /* disable attentions */ | 5567 | /* disable attentions */ |
4862 | 5568 | ||
4863 | vars->link_status = 0; | 5569 | vars->link_status = 0; |
@@ -4892,6 +5598,21 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, | |||
4892 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: | 5598 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: |
4893 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: | 5599 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: |
4894 | break; | 5600 | break; |
5601 | |||
5602 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: | ||
5603 | { | ||
5604 | |||
5605 | /* Disable Transmitter */ | ||
5606 | u8 ext_phy_addr = ((params->ext_phy_config & | ||
5607 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> | ||
5608 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); | ||
5609 | if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == | ||
5610 | PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) | ||
5611 | bnx2x_sfp_set_transmitter(bp, port, | ||
5612 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, | ||
5613 | ext_phy_addr, 0); | ||
5614 | break; | ||
5615 | } | ||
4895 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: | 5616 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: |
4896 | DP(NETIF_MSG_LINK, "Setting 8073 port %d into " | 5617 | DP(NETIF_MSG_LINK, "Setting 8073 port %d into " |
4897 | "low power mode\n", | 5618 | "low power mode\n", |
@@ -5216,6 +5937,74 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) | |||
5216 | 5937 | ||
5217 | } | 5938 | } |
5218 | 5939 | ||
5940 | static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base) | ||
5941 | { | ||
5942 | u8 ext_phy_addr[PORT_MAX]; | ||
5943 | s8 port; | ||
5944 | u32 swap_val, swap_override; | ||
5945 | DP(NETIF_MSG_LINK, "Executing BCM8727 common init\n"); | ||
5946 | swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); | ||
5947 | swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); | ||
5948 | |||
5949 | bnx2x_hw_reset(bp, 1 ^ (swap_val && swap_override)); | ||
5950 | msleep(5); | ||
5951 | |||
5952 | /* PART1 - Reset both phys */ | ||
5953 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { | ||
5954 | /* Extract the ext phy address for the port */ | ||
5955 | u32 ext_phy_config = REG_RD(bp, shmem_base + | ||
5956 | offsetof(struct shmem_region, | ||
5957 | dev_info.port_hw_config[port].external_phy_config)); | ||
5958 | |||
5959 | /* disable attentions */ | ||
5960 | bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, | ||
5961 | (NIG_MASK_XGXS0_LINK_STATUS | | ||
5962 | NIG_MASK_XGXS0_LINK10G | | ||
5963 | NIG_MASK_SERDES0_LINK_STATUS | | ||
5964 | NIG_MASK_MI_INT)); | ||
5965 | |||
5966 | ext_phy_addr[port] = ((ext_phy_config & | ||
5967 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> | ||
5968 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); | ||
5969 | |||
5970 | /* Reset the phy */ | ||
5971 | bnx2x_cl45_write(bp, port, | ||
5972 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, | ||
5973 | ext_phy_addr[port], | ||
5974 | MDIO_PMA_DEVAD, | ||
5975 | MDIO_PMA_REG_CTRL, | ||
5976 | 1<<15); | ||
5977 | } | ||
5978 | |||
5979 | /* Add delay of 150ms after reset */ | ||
5980 | msleep(150); | ||
5981 | |||
5982 | /* PART2 - Download firmware to both phys */ | ||
5983 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { | ||
5984 | u16 fw_ver1; | ||
5985 | |||
5986 | bnx2x_bcm8727_external_rom_boot(bp, port, | ||
5987 | ext_phy_addr[port], shmem_base); | ||
5988 | |||
5989 | bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, | ||
5990 | ext_phy_addr[port], | ||
5991 | MDIO_PMA_DEVAD, | ||
5992 | MDIO_PMA_REG_ROM_VER1, &fw_ver1); | ||
5993 | if (fw_ver1 == 0 || fw_ver1 == 0x4321) { | ||
5994 | DP(NETIF_MSG_LINK, | ||
5995 | "bnx2x_8073_common_init_phy port %x:" | ||
5996 | "Download failed. fw version = 0x%x\n", | ||
5997 | port, fw_ver1); | ||
5998 | return -EINVAL; | ||
5999 | } | ||
6000 | |||
6001 | } | ||
6002 | |||
6003 | |||
6004 | |||
6005 | return 0; | ||
6006 | } | ||
6007 | |||
5219 | 6008 | ||
5220 | static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base) | 6009 | static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base) |
5221 | { | 6010 | { |
@@ -5274,6 +6063,12 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base) | |||
5274 | rc = bnx2x_8073_common_init_phy(bp, shmem_base); | 6063 | rc = bnx2x_8073_common_init_phy(bp, shmem_base); |
5275 | break; | 6064 | break; |
5276 | } | 6065 | } |
6066 | |||
6067 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: | ||
6068 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC: | ||
6069 | rc = bnx2x_8727_common_init_phy(bp, shmem_base); | ||
6070 | break; | ||
6071 | |||
5277 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: | 6072 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: |
5278 | /* GPIO1 affects both ports, so there's need to pull | 6073 | /* GPIO1 affects both ports, so there's need to pull |
5279 | it for single port alone */ | 6074 | it for single port alone */ |