Commit c8c60d88 authored by Yuval Mintz's avatar Yuval Mintz Committed by David S. Miller

bnx2x: Added EEE support

This patch adds energy efficient energy support (802.3az) to bnx2x
boards with 84833 phys (and sufficiently new BC and external FW).
Signed-off-by: default avatarYuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: default avatarEilon Greenstein <eilong@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 80f12ecc
...@@ -1067,8 +1067,18 @@ struct port_feat_cfg { /* port 0: 0x454 port 1: 0x4c8 */ ...@@ -1067,8 +1067,18 @@ struct port_feat_cfg { /* port 0: 0x454 port 1: 0x4c8 */
uses the same defines as link_config */ uses the same defines as link_config */
u32 mfw_wol_link_cfg2; /* 0x480 */ u32 mfw_wol_link_cfg2; /* 0x480 */
u32 Reserved2[17]; /* 0x484 */
/* EEE power saving mode */
u32 eee_power_mode; /* 0x484 */
#define PORT_FEAT_CFG_EEE_POWER_MODE_MASK 0x000000FF
#define PORT_FEAT_CFG_EEE_POWER_MODE_SHIFT 0
#define PORT_FEAT_CFG_EEE_POWER_MODE_DISABLED 0x00000000
#define PORT_FEAT_CFG_EEE_POWER_MODE_BALANCED 0x00000001
#define PORT_FEAT_CFG_EEE_POWER_MODE_AGGRESSIVE 0x00000002
#define PORT_FEAT_CFG_EEE_POWER_MODE_LOW_LATENCY 0x00000003
u32 Reserved2[16]; /* 0x488 */
}; };
...@@ -1255,6 +1265,8 @@ struct drv_func_mb { ...@@ -1255,6 +1265,8 @@ struct drv_func_mb {
#define DRV_MSG_CODE_DRV_INFO_ACK 0xd8000000 #define DRV_MSG_CODE_DRV_INFO_ACK 0xd8000000
#define DRV_MSG_CODE_DRV_INFO_NACK 0xd9000000 #define DRV_MSG_CODE_DRV_INFO_NACK 0xd9000000
#define DRV_MSG_CODE_EEE_RESULTS_ACK 0xda000000
#define DRV_MSG_CODE_SET_MF_BW 0xe0000000 #define DRV_MSG_CODE_SET_MF_BW 0xe0000000
#define REQ_BC_VER_4_SET_MF_BW 0x00060202 #define REQ_BC_VER_4_SET_MF_BW 0x00060202
#define DRV_MSG_CODE_SET_MF_BW_ACK 0xe1000000 #define DRV_MSG_CODE_SET_MF_BW_ACK 0xe1000000
...@@ -1320,6 +1332,8 @@ struct drv_func_mb { ...@@ -1320,6 +1332,8 @@ struct drv_func_mb {
#define FW_MSG_CODE_DRV_INFO_ACK 0xd8100000 #define FW_MSG_CODE_DRV_INFO_ACK 0xd8100000
#define FW_MSG_CODE_DRV_INFO_NACK 0xd9100000 #define FW_MSG_CODE_DRV_INFO_NACK 0xd9100000
#define FW_MSG_CODE_EEE_RESULS_ACK 0xda100000
#define FW_MSG_CODE_SET_MF_BW_SENT 0xe0000000 #define FW_MSG_CODE_SET_MF_BW_SENT 0xe0000000
#define FW_MSG_CODE_SET_MF_BW_DONE 0xe1000000 #define FW_MSG_CODE_SET_MF_BW_DONE 0xe1000000
...@@ -1383,6 +1397,8 @@ struct drv_func_mb { ...@@ -1383,6 +1397,8 @@ struct drv_func_mb {
#define DRV_STATUS_DRV_INFO_REQ 0x04000000 #define DRV_STATUS_DRV_INFO_REQ 0x04000000
#define DRV_STATUS_EEE_NEGOTIATION_RESULTS 0x08000000
u32 virt_mac_upper; u32 virt_mac_upper;
#define VIRT_MAC_SIGN_MASK 0xffff0000 #define VIRT_MAC_SIGN_MASK 0xffff0000
#define VIRT_MAC_SIGNATURE 0x564d0000 #define VIRT_MAC_SIGNATURE 0x564d0000
...@@ -1613,6 +1629,11 @@ struct fw_flr_mb { ...@@ -1613,6 +1629,11 @@ struct fw_flr_mb {
struct fw_flr_ack ack; struct fw_flr_ack ack;
}; };
struct eee_remote_vals {
u32 tx_tw;
u32 rx_tw;
};
/**** SUPPORT FOR SHMEM ARRRAYS *** /**** SUPPORT FOR SHMEM ARRRAYS ***
* The SHMEM HSI is aligned on 32 bit boundaries which makes it difficult to * The SHMEM HSI is aligned on 32 bit boundaries which makes it difficult to
* define arrays with storage types smaller then unsigned dwords. * define arrays with storage types smaller then unsigned dwords.
...@@ -2053,6 +2074,41 @@ struct shmem2_region { ...@@ -2053,6 +2074,41 @@ struct shmem2_region {
#define DRV_INFO_CONTROL_OP_CODE_MASK 0x0000ff00 #define DRV_INFO_CONTROL_OP_CODE_MASK 0x0000ff00
#define DRV_INFO_CONTROL_OP_CODE_SHIFT 8 #define DRV_INFO_CONTROL_OP_CODE_SHIFT 8
u32 ibft_host_addr; /* initialized by option ROM */ u32 ibft_host_addr; /* initialized by option ROM */
struct eee_remote_vals eee_remote_vals[PORT_MAX];
u32 reserved[E2_FUNC_MAX];
/* the status of EEE auto-negotiation
* bits 15:0 the configured tx-lpi entry timer value. Depends on bit 31.
* bits 19:16 the supported modes for EEE.
* bits 23:20 the speeds advertised for EEE.
* bits 27:24 the speeds the Link partner advertised for EEE.
* The supported/adv. modes in bits 27:19 originate from the
* SHMEM_EEE_XXX_ADV definitions (where XXX is replaced by speed).
* bit 28 when 1'b1 EEE was requested.
* bit 29 when 1'b1 tx lpi was requested.
* bit 30 when 1'b1 EEE was negotiated. Tx lpi will be asserted iff
* 30:29 are 2'b11.
* bit 31 when 1'b0 bits 15:0 contain a PORT_FEAT_CFG_EEE_ define as
* value. When 1'b1 those bits contains a value times 16 microseconds.
*/
u32 eee_status[PORT_MAX];
#define SHMEM_EEE_TIMER_MASK 0x0000ffff
#define SHMEM_EEE_SUPPORTED_MASK 0x000f0000
#define SHMEM_EEE_SUPPORTED_SHIFT 16
#define SHMEM_EEE_ADV_STATUS_MASK 0x00f00000
#define SHMEM_EEE_100M_ADV (1<<0)
#define SHMEM_EEE_1G_ADV (1<<1)
#define SHMEM_EEE_10G_ADV (1<<2)
#define SHMEM_EEE_ADV_STATUS_SHIFT 20
#define SHMEM_EEE_LP_ADV_STATUS_MASK 0x0f000000
#define SHMEM_EEE_LP_ADV_STATUS_SHIFT 24
#define SHMEM_EEE_REQUESTED_BIT 0x10000000
#define SHMEM_EEE_LPI_REQUESTED_BIT 0x20000000
#define SHMEM_EEE_ACTIVE_BIT 0x40000000
#define SHMEM_EEE_TIME_OUTPUT_BIT 0x80000000
u32 sizeof_port_stats;
}; };
...@@ -2599,6 +2655,9 @@ struct host_port_stats { ...@@ -2599,6 +2655,9 @@ struct host_port_stats {
u32 pfc_frames_tx_lo; u32 pfc_frames_tx_lo;
u32 pfc_frames_rx_hi; u32 pfc_frames_rx_hi;
u32 pfc_frames_rx_lo; u32 pfc_frames_rx_lo;
u32 eee_lpi_count_hi;
u32 eee_lpi_count_lo;
}; };
......
...@@ -149,6 +149,7 @@ struct bnx2x_phy { ...@@ -149,6 +149,7 @@ struct bnx2x_phy {
#define FLAGS_DUMMY_READ (1<<9) #define FLAGS_DUMMY_READ (1<<9)
#define FLAGS_MDC_MDIO_WA_B0 (1<<10) #define FLAGS_MDC_MDIO_WA_B0 (1<<10)
#define FLAGS_TX_ERROR_CHECK (1<<12) #define FLAGS_TX_ERROR_CHECK (1<<12)
#define FLAGS_EEE_10GBT (1<<13)
/* preemphasis values for the rx side */ /* preemphasis values for the rx side */
u16 rx_preemphasis[4]; u16 rx_preemphasis[4];
...@@ -265,6 +266,30 @@ struct link_params { ...@@ -265,6 +266,30 @@ struct link_params {
u8 num_phys; u8 num_phys;
u8 rsrv; u8 rsrv;
/* Used to configure the EEE Tx LPI timer, has several modes of
* operation, according to bits 29:28 -
* 2'b00: Timer will be configured by nvram, output will be the value
* from nvram.
* 2'b01: Timer will be configured by nvram, output will be in
* microseconds.
* 2'b10: bits 1:0 contain an nvram value which will be used instead
* of the one located in the nvram. Output will be that value.
* 2'b11: bits 19:0 contain the idle timer in microseconds; output
* will be in microseconds.
* Bits 31:30 should be 2'b11 in order for EEE to be enabled.
*/
u32 eee_mode;
#define EEE_MODE_NVRAM_BALANCED_TIME (0xa00)
#define EEE_MODE_NVRAM_AGGRESSIVE_TIME (0x100)
#define EEE_MODE_NVRAM_LATENCY_TIME (0x6000)
#define EEE_MODE_NVRAM_MASK (0x3)
#define EEE_MODE_TIMER_MASK (0xfffff)
#define EEE_MODE_OUTPUT_TIME (1<<28)
#define EEE_MODE_OVERRIDE_NVRAM (1<<29)
#define EEE_MODE_ENABLE_LPI (1<<30)
#define EEE_MODE_ADV_LPI (1<<31)
u16 hw_led_mode; /* part of the hw_config read from the shmem */ u16 hw_led_mode; /* part of the hw_config read from the shmem */
u32 multi_phy_config; u32 multi_phy_config;
...@@ -301,6 +326,7 @@ struct link_vars { ...@@ -301,6 +326,7 @@ struct link_vars {
/* The same definitions as the shmem parameter */ /* The same definitions as the shmem parameter */
u32 link_status; u32 link_status;
u32 eee_status;
u8 fault_detected; u8 fault_detected;
u8 rsrv1; u8 rsrv1;
u16 periodic_flags; u16 periodic_flags;
......
...@@ -3176,6 +3176,12 @@ static void bnx2x_set_mf_bw(struct bnx2x *bp) ...@@ -3176,6 +3176,12 @@ static void bnx2x_set_mf_bw(struct bnx2x *bp)
bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW_ACK, 0); bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW_ACK, 0);
} }
static void bnx2x_handle_eee_event(struct bnx2x *bp)
{
DP(BNX2X_MSG_MCP, "EEE - LLDP event\n");
bnx2x_fw_command(bp, DRV_MSG_CODE_EEE_RESULTS_ACK, 0);
}
static void bnx2x_handle_drv_info_req(struct bnx2x *bp) static void bnx2x_handle_drv_info_req(struct bnx2x *bp)
{ {
enum drv_info_opcode op_code; enum drv_info_opcode op_code;
...@@ -3742,6 +3748,8 @@ static void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) ...@@ -3742,6 +3748,8 @@ static void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn)
if (val & DRV_STATUS_AFEX_EVENT_MASK) if (val & DRV_STATUS_AFEX_EVENT_MASK)
bnx2x_handle_afex_cmd(bp, bnx2x_handle_afex_cmd(bp,
val & DRV_STATUS_AFEX_EVENT_MASK); val & DRV_STATUS_AFEX_EVENT_MASK);
if (val & DRV_STATUS_EEE_NEGOTIATION_RESULTS)
bnx2x_handle_eee_event(bp);
if (bp->link_vars.periodic_flags & if (bp->link_vars.periodic_flags &
PERIODIC_FLAGS_LINK_EVENT) { PERIODIC_FLAGS_LINK_EVENT) {
/* sync with link */ /* sync with link */
...@@ -10082,7 +10090,7 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) ...@@ -10082,7 +10090,7 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
{ {
int port = BP_PORT(bp); int port = BP_PORT(bp);
u32 config; u32 config;
u32 ext_phy_type, ext_phy_config; u32 ext_phy_type, ext_phy_config, eee_mode;
bp->link_params.bp = bp; bp->link_params.bp = bp;
bp->link_params.port = port; bp->link_params.port = port;
...@@ -10149,6 +10157,19 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) ...@@ -10149,6 +10157,19 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, bp->port.need_hw_lock = bnx2x_hw_lock_required(bp,
bp->common.shmem_base, bp->common.shmem_base,
bp->common.shmem2_base); bp->common.shmem2_base);
/* Configure link feature according to nvram value */
eee_mode = (((SHMEM_RD(bp, dev_info.
port_feature_config[port].eee_power_mode)) &
PORT_FEAT_CFG_EEE_POWER_MODE_MASK) >>
PORT_FEAT_CFG_EEE_POWER_MODE_SHIFT);
if (eee_mode != PORT_FEAT_CFG_EEE_POWER_MODE_DISABLED) {
bp->link_params.eee_mode = EEE_MODE_ADV_LPI |
EEE_MODE_ENABLE_LPI |
EEE_MODE_OUTPUT_TIME;
} else {
bp->link_params.eee_mode = 0;
}
} }
void bnx2x_get_iscsi_info(struct bnx2x *bp) void bnx2x_get_iscsi_info(struct bnx2x *bp)
......
...@@ -785,6 +785,10 @@ static int bnx2x_hw_stats_update(struct bnx2x *bp) ...@@ -785,6 +785,10 @@ static int bnx2x_hw_stats_update(struct bnx2x *bp)
pstats->host_port_stats_counter++; pstats->host_port_stats_counter++;
if (CHIP_IS_E3(bp))
estats->eee_tx_lpi += REG_RD(bp,
MISC_REG_CPMU_LP_SM_ENT_CNT_P0);
if (!BP_NOMCP(bp)) { if (!BP_NOMCP(bp)) {
u32 nig_timer_max = u32 nig_timer_max =
SHMEM_RD(bp, port_mb[BP_PORT(bp)].stat_nig_timer); SHMEM_RD(bp, port_mb[BP_PORT(bp)].stat_nig_timer);
......
...@@ -203,6 +203,8 @@ struct bnx2x_eth_stats { ...@@ -203,6 +203,8 @@ struct bnx2x_eth_stats {
/* Recovery */ /* Recovery */
u32 recoverable_error; u32 recoverable_error;
u32 unrecoverable_error; u32 unrecoverable_error;
/* src: Clear-on-Read register; Will not survive PMF Migration */
u32 eee_tx_lpi;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment