aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x_link.c
diff options
context:
space:
mode:
authorEilon Greenstein <eilong@broadcom.com>2009-07-21 01:47:47 -0400
committerDavid S. Miller <davem@davemloft.net>2009-07-21 14:18:30 -0400
commit4d295db0efd2ccf06edb7a45ad885b40c56b7161 (patch)
treefb545833c5c3618d58754d50ba899b62dd37abef /drivers/net/bnx2x_link.c
parent5316bc0b9adbefe24f149b12caeddc30df6f04e1 (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.c1095
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
2174static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port, 2184static 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
2244static 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
2253static 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
2232static void bnx2x_bcm8726_external_rom_boot(struct link_params *params) 2263static 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
2288static void bnx2x_bcm8726_set_transmitter(struct bnx2x *bp, u8 port, 2320static 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 2348static u8 bnx2x_8726_read_sfp_module_eeprom(struct link_params *params,
2316static 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
2433static 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
2400static 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
2538u8 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
2552static 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 */
2466static u8 bnx2x_verify_sfp_module(struct link_params *params, 2634static 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
2522static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params, 2689static 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
2755static 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
2603static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params) 2805static 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
2824static 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
2622static u8 bnx2x_sfp_module_detection(struct link_params *params) 2863static 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
2679void bnx2x_handle_module_detect_int(struct link_params *params) 2934void 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
4012static 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
3565static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, 4106static 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
4851u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, 5552u8 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
5940static 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
5220static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base) 6009static 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 */