diff options
-rw-r--r-- | drivers/net/bnx2x/bnx2x.h | 11 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_cmn.c | 34 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_cmn.h | 10 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_ethtool.c | 58 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_hsi.h | 42 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_main.c | 336 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_reg.h | 5 |
7 files changed, 400 insertions, 96 deletions
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 342ab58b14b..cfc25cf064d 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h | |||
@@ -20,8 +20,8 @@ | |||
20 | * (you will need to reboot afterwards) */ | 20 | * (you will need to reboot afterwards) */ |
21 | /* #define BNX2X_STOP_ON_ERROR */ | 21 | /* #define BNX2X_STOP_ON_ERROR */ |
22 | 22 | ||
23 | #define DRV_MODULE_VERSION "1.60.00-5" | 23 | #define DRV_MODULE_VERSION "1.60.00-6" |
24 | #define DRV_MODULE_RELDATE "2010/11/24" | 24 | #define DRV_MODULE_RELDATE "2010/11/29" |
25 | #define BNX2X_BC_VER 0x040200 | 25 | #define BNX2X_BC_VER 0x040200 |
26 | 26 | ||
27 | #define BNX2X_MULTI_QUEUE | 27 | #define BNX2X_MULTI_QUEUE |
@@ -671,6 +671,10 @@ enum { | |||
671 | CAM_ISCSI_ETH_LINE, | 671 | CAM_ISCSI_ETH_LINE, |
672 | CAM_MAX_PF_LINE = CAM_ISCSI_ETH_LINE | 672 | CAM_MAX_PF_LINE = CAM_ISCSI_ETH_LINE |
673 | }; | 673 | }; |
674 | /* number of MACs per function in NIG memory - used for SI mode */ | ||
675 | #define NIG_LLH_FUNC_MEM_SIZE 16 | ||
676 | /* number of entries in NIG_REG_LLHX_FUNC_MEM */ | ||
677 | #define NIG_LLH_FUNC_MEM_MAX_OFFSET 8 | ||
674 | 678 | ||
675 | #define BNX2X_VF_ID_INVALID 0xFF | 679 | #define BNX2X_VF_ID_INVALID 0xFF |
676 | 680 | ||
@@ -967,6 +971,8 @@ struct bnx2x { | |||
967 | u16 mf_ov; | 971 | u16 mf_ov; |
968 | u8 mf_mode; | 972 | u8 mf_mode; |
969 | #define IS_MF(bp) (bp->mf_mode != 0) | 973 | #define IS_MF(bp) (bp->mf_mode != 0) |
974 | #define IS_MF_SI(bp) (bp->mf_mode == MULTI_FUNCTION_SI) | ||
975 | #define IS_MF_SD(bp) (bp->mf_mode == MULTI_FUNCTION_SD) | ||
970 | 976 | ||
971 | u8 wol; | 977 | u8 wol; |
972 | 978 | ||
@@ -1010,6 +1016,7 @@ struct bnx2x { | |||
1010 | #define BNX2X_ACCEPT_ALL_UNICAST 0x0004 | 1016 | #define BNX2X_ACCEPT_ALL_UNICAST 0x0004 |
1011 | #define BNX2X_ACCEPT_ALL_MULTICAST 0x0008 | 1017 | #define BNX2X_ACCEPT_ALL_MULTICAST 0x0008 |
1012 | #define BNX2X_ACCEPT_BROADCAST 0x0010 | 1018 | #define BNX2X_ACCEPT_BROADCAST 0x0010 |
1019 | #define BNX2X_ACCEPT_UNMATCHED_UCAST 0x0020 | ||
1013 | #define BNX2X_PROMISCUOUS_MODE 0x10000 | 1020 | #define BNX2X_PROMISCUOUS_MODE 0x10000 |
1014 | 1021 | ||
1015 | u32 rx_mode; | 1022 | u32 rx_mode; |
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index e20b2d37892..a4555edbe9c 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c | |||
@@ -698,6 +698,29 @@ void bnx2x_release_phy_lock(struct bnx2x *bp) | |||
698 | mutex_unlock(&bp->port.phy_mutex); | 698 | mutex_unlock(&bp->port.phy_mutex); |
699 | } | 699 | } |
700 | 700 | ||
701 | /* calculates MF speed according to current linespeed and MF configuration */ | ||
702 | u16 bnx2x_get_mf_speed(struct bnx2x *bp) | ||
703 | { | ||
704 | u16 line_speed = bp->link_vars.line_speed; | ||
705 | if (IS_MF(bp)) { | ||
706 | u16 maxCfg = (bp->mf_config[BP_VN(bp)] & | ||
707 | FUNC_MF_CFG_MAX_BW_MASK) >> | ||
708 | FUNC_MF_CFG_MAX_BW_SHIFT; | ||
709 | /* Calculate the current MAX line speed limit for the DCC | ||
710 | * capable devices | ||
711 | */ | ||
712 | if (IS_MF_SD(bp)) { | ||
713 | u16 vn_max_rate = maxCfg * 100; | ||
714 | |||
715 | if (vn_max_rate < line_speed) | ||
716 | line_speed = vn_max_rate; | ||
717 | } else /* IS_MF_SI(bp)) */ | ||
718 | line_speed = (line_speed * maxCfg) / 100; | ||
719 | } | ||
720 | |||
721 | return line_speed; | ||
722 | } | ||
723 | |||
701 | void bnx2x_link_report(struct bnx2x *bp) | 724 | void bnx2x_link_report(struct bnx2x *bp) |
702 | { | 725 | { |
703 | if (bp->flags & MF_FUNC_DIS) { | 726 | if (bp->flags & MF_FUNC_DIS) { |
@@ -713,17 +736,8 @@ void bnx2x_link_report(struct bnx2x *bp) | |||
713 | netif_carrier_on(bp->dev); | 736 | netif_carrier_on(bp->dev); |
714 | netdev_info(bp->dev, "NIC Link is Up, "); | 737 | netdev_info(bp->dev, "NIC Link is Up, "); |
715 | 738 | ||
716 | line_speed = bp->link_vars.line_speed; | 739 | line_speed = bnx2x_get_mf_speed(bp); |
717 | if (IS_MF(bp)) { | ||
718 | u16 vn_max_rate; | ||
719 | 740 | ||
720 | vn_max_rate = | ||
721 | ((bp->mf_config[BP_VN(bp)] & | ||
722 | FUNC_MF_CFG_MAX_BW_MASK) >> | ||
723 | FUNC_MF_CFG_MAX_BW_SHIFT) * 100; | ||
724 | if (vn_max_rate < line_speed) | ||
725 | line_speed = vn_max_rate; | ||
726 | } | ||
727 | pr_cont("%d Mbps ", line_speed); | 741 | pr_cont("%d Mbps ", line_speed); |
728 | 742 | ||
729 | if (bp->link_vars.duplex == DUPLEX_FULL) | 743 | if (bp->link_vars.duplex == DUPLEX_FULL) |
diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index 6b28739c530..cb8f2a040a1 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h | |||
@@ -73,6 +73,16 @@ void bnx2x__link_status_update(struct bnx2x *bp); | |||
73 | void bnx2x_link_report(struct bnx2x *bp); | 73 | void bnx2x_link_report(struct bnx2x *bp); |
74 | 74 | ||
75 | /** | 75 | /** |
76 | * calculates MF speed according to current linespeed and MF | ||
77 | * configuration | ||
78 | * | ||
79 | * @param bp | ||
80 | * | ||
81 | * @return u16 | ||
82 | */ | ||
83 | u16 bnx2x_get_mf_speed(struct bnx2x *bp); | ||
84 | |||
85 | /** | ||
76 | * MSI-X slowpath interrupt handler | 86 | * MSI-X slowpath interrupt handler |
77 | * | 87 | * |
78 | * @param irq | 88 | * @param irq |
diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 03012787de2..bd94827e5e5 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c | |||
@@ -45,14 +45,9 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
45 | cmd->speed = bp->link_params.req_line_speed[cfg_idx]; | 45 | cmd->speed = bp->link_params.req_line_speed[cfg_idx]; |
46 | cmd->duplex = bp->link_params.req_duplex[cfg_idx]; | 46 | cmd->duplex = bp->link_params.req_duplex[cfg_idx]; |
47 | } | 47 | } |
48 | if (IS_MF(bp)) { | ||
49 | u16 vn_max_rate = ((bp->mf_config[BP_VN(bp)] & | ||
50 | FUNC_MF_CFG_MAX_BW_MASK) >> FUNC_MF_CFG_MAX_BW_SHIFT) * | ||
51 | 100; | ||
52 | 48 | ||
53 | if (vn_max_rate < cmd->speed) | 49 | if (IS_MF(bp)) |
54 | cmd->speed = vn_max_rate; | 50 | cmd->speed = bnx2x_get_mf_speed(bp); |
55 | } | ||
56 | 51 | ||
57 | if (bp->port.supported[cfg_idx] & SUPPORTED_TP) | 52 | if (bp->port.supported[cfg_idx] & SUPPORTED_TP) |
58 | cmd->port = PORT_TP; | 53 | cmd->port = PORT_TP; |
@@ -87,18 +82,57 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
87 | { | 82 | { |
88 | struct bnx2x *bp = netdev_priv(dev); | 83 | struct bnx2x *bp = netdev_priv(dev); |
89 | u32 advertising, cfg_idx, old_multi_phy_config, new_multi_phy_config; | 84 | u32 advertising, cfg_idx, old_multi_phy_config, new_multi_phy_config; |
85 | u32 speed; | ||
90 | 86 | ||
91 | if (IS_MF(bp)) | 87 | if (IS_MF_SD(bp)) |
92 | return 0; | 88 | return 0; |
93 | 89 | ||
94 | DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n" | 90 | DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n" |
95 | DP_LEVEL " supported 0x%x advertising 0x%x speed %d\n" | 91 | " supported 0x%x advertising 0x%x speed %d speed_hi %d\n" |
96 | DP_LEVEL " duplex %d port %d phy_address %d transceiver %d\n" | 92 | " duplex %d port %d phy_address %d transceiver %d\n" |
97 | DP_LEVEL " autoneg %d maxtxpkt %d maxrxpkt %d\n", | 93 | " autoneg %d maxtxpkt %d maxrxpkt %d\n", |
98 | cmd->cmd, cmd->supported, cmd->advertising, cmd->speed, | 94 | cmd->cmd, cmd->supported, cmd->advertising, cmd->speed, |
95 | cmd->speed_hi, | ||
99 | cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver, | 96 | cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver, |
100 | cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt); | 97 | cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt); |
101 | 98 | ||
99 | speed = cmd->speed; | ||
100 | speed |= (cmd->speed_hi << 16); | ||
101 | |||
102 | if (IS_MF_SI(bp)) { | ||
103 | u32 param = 0; | ||
104 | u32 line_speed = bp->link_vars.line_speed; | ||
105 | |||
106 | /* use 10G if no link detected */ | ||
107 | if (!line_speed) | ||
108 | line_speed = 10000; | ||
109 | |||
110 | if (bp->common.bc_ver < REQ_BC_VER_4_SET_MF_BW) { | ||
111 | BNX2X_DEV_INFO("To set speed BC %X or higher " | ||
112 | "is required, please upgrade BC\n", | ||
113 | REQ_BC_VER_4_SET_MF_BW); | ||
114 | return -EINVAL; | ||
115 | } | ||
116 | if (line_speed < speed) { | ||
117 | BNX2X_DEV_INFO("New speed should be less or equal " | ||
118 | "to actual line speed\n"); | ||
119 | return -EINVAL; | ||
120 | } | ||
121 | /* load old values */ | ||
122 | param = bp->mf_config[BP_VN(bp)]; | ||
123 | |||
124 | /* leave only MIN value */ | ||
125 | param &= FUNC_MF_CFG_MIN_BW_MASK; | ||
126 | |||
127 | /* set new MAX value */ | ||
128 | param |= (((speed * 100) / line_speed) | ||
129 | << FUNC_MF_CFG_MAX_BW_SHIFT) | ||
130 | & FUNC_MF_CFG_MAX_BW_MASK; | ||
131 | |||
132 | bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW, param); | ||
133 | return 0; | ||
134 | } | ||
135 | |||
102 | cfg_idx = bnx2x_get_link_cfg_idx(bp); | 136 | cfg_idx = bnx2x_get_link_cfg_idx(bp); |
103 | old_multi_phy_config = bp->link_params.multi_phy_config; | 137 | old_multi_phy_config = bp->link_params.multi_phy_config; |
104 | switch (cmd->port) { | 138 | switch (cmd->port) { |
@@ -168,8 +202,6 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
168 | 202 | ||
169 | } else { /* forced speed */ | 203 | } else { /* forced speed */ |
170 | /* advertise the requested speed and duplex if supported */ | 204 | /* advertise the requested speed and duplex if supported */ |
171 | u32 speed = cmd->speed; | ||
172 | speed |= (cmd->speed_hi << 16); | ||
173 | switch (speed) { | 205 | switch (speed) { |
174 | case SPEED_10: | 206 | case SPEED_10: |
175 | if (cmd->duplex == DUPLEX_FULL) { | 207 | if (cmd->duplex == DUPLEX_FULL) { |
diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index 4cfd4e9b558..6555c477f89 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h | |||
@@ -434,7 +434,12 @@ struct shared_feat_cfg { /* NVRAM Offset */ | |||
434 | #define SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_DISABLED 0x00000000 | 434 | #define SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_DISABLED 0x00000000 |
435 | #define SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_ENABLED 0x00000002 | 435 | #define SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_ENABLED 0x00000002 |
436 | 436 | ||
437 | #define SHARED_FEATURE_MF_MODE_DISABLED 0x00000100 | 437 | #define SHARED_FEAT_CFG_FORCE_SF_MODE_MASK 0x00000700 |
438 | #define SHARED_FEAT_CFG_FORCE_SF_MODE_SHIFT 8 | ||
439 | #define SHARED_FEAT_CFG_FORCE_SF_MODE_MF_ALLOWED 0x00000000 | ||
440 | #define SHARED_FEAT_CFG_FORCE_SF_MODE_FORCED_SF 0x00000100 | ||
441 | #define SHARED_FEAT_CFG_FORCE_SF_MODE_SPIO4 0x00000200 | ||
442 | #define SHARED_FEAT_CFG_FORCE_SF_MODE_SWITCH_INDEPT 0x00000300 | ||
438 | 443 | ||
439 | }; | 444 | }; |
440 | 445 | ||
@@ -815,6 +820,9 @@ struct drv_func_mb { | |||
815 | #define DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL 0xa1000000 | 820 | #define DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL 0xa1000000 |
816 | #define REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL 0x00050234 | 821 | #define REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL 0x00050234 |
817 | 822 | ||
823 | #define DRV_MSG_CODE_SET_MF_BW 0xe0000000 | ||
824 | #define REQ_BC_VER_4_SET_MF_BW 0x00060202 | ||
825 | #define DRV_MSG_CODE_SET_MF_BW_ACK 0xe1000000 | ||
818 | #define BIOS_MSG_CODE_LIC_CHALLENGE 0xff010000 | 826 | #define BIOS_MSG_CODE_LIC_CHALLENGE 0xff010000 |
819 | #define BIOS_MSG_CODE_LIC_RESPONSE 0xff020000 | 827 | #define BIOS_MSG_CODE_LIC_RESPONSE 0xff020000 |
820 | #define BIOS_MSG_CODE_VIRT_MAC_PRIM 0xff030000 | 828 | #define BIOS_MSG_CODE_VIRT_MAC_PRIM 0xff030000 |
@@ -888,6 +896,7 @@ struct drv_func_mb { | |||
888 | 896 | ||
889 | u32 drv_status; | 897 | u32 drv_status; |
890 | #define DRV_STATUS_PMF 0x00000001 | 898 | #define DRV_STATUS_PMF 0x00000001 |
899 | #define DRV_STATUS_SET_MF_BW 0x00000004 | ||
891 | 900 | ||
892 | #define DRV_STATUS_DCC_EVENT_MASK 0x0000ff00 | 901 | #define DRV_STATUS_DCC_EVENT_MASK 0x0000ff00 |
893 | #define DRV_STATUS_DCC_DISABLE_ENABLE_PF 0x00000100 | 902 | #define DRV_STATUS_DCC_DISABLE_ENABLE_PF 0x00000100 |
@@ -988,12 +997,43 @@ struct func_mf_cfg { | |||
988 | 997 | ||
989 | }; | 998 | }; |
990 | 999 | ||
1000 | /* This structure is not applicable and should not be accessed on 57711 */ | ||
1001 | struct func_ext_cfg { | ||
1002 | u32 func_cfg; | ||
1003 | #define MACP_FUNC_CFG_FLAGS_MASK 0x000000FF | ||
1004 | #define MACP_FUNC_CFG_FLAGS_SHIFT 0 | ||
1005 | #define MACP_FUNC_CFG_FLAGS_ENABLED 0x00000001 | ||
1006 | #define MACP_FUNC_CFG_FLAGS_ETHERNET 0x00000002 | ||
1007 | #define MACP_FUNC_CFG_FLAGS_ISCSI_OFFLOAD 0x00000004 | ||
1008 | #define MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD 0x00000008 | ||
1009 | |||
1010 | u32 iscsi_mac_addr_upper; | ||
1011 | u32 iscsi_mac_addr_lower; | ||
1012 | |||
1013 | u32 fcoe_mac_addr_upper; | ||
1014 | u32 fcoe_mac_addr_lower; | ||
1015 | |||
1016 | u32 fcoe_wwn_port_name_upper; | ||
1017 | u32 fcoe_wwn_port_name_lower; | ||
1018 | |||
1019 | u32 fcoe_wwn_node_name_upper; | ||
1020 | u32 fcoe_wwn_node_name_lower; | ||
1021 | |||
1022 | u32 preserve_data; | ||
1023 | #define MF_FUNC_CFG_PRESERVE_L2_MAC (1<<0) | ||
1024 | #define MF_FUNC_CFG_PRESERVE_ISCSI_MAC (1<<1) | ||
1025 | #define MF_FUNC_CFG_PRESERVE_FCOE_MAC (1<<2) | ||
1026 | #define MF_FUNC_CFG_PRESERVE_FCOE_WWN_P (1<<3) | ||
1027 | #define MF_FUNC_CFG_PRESERVE_FCOE_WWN_N (1<<4) | ||
1028 | }; | ||
1029 | |||
991 | struct mf_cfg { | 1030 | struct mf_cfg { |
992 | 1031 | ||
993 | struct shared_mf_cfg shared_mf_config; | 1032 | struct shared_mf_cfg shared_mf_config; |
994 | struct port_mf_cfg port_mf_config[PORT_MAX]; | 1033 | struct port_mf_cfg port_mf_config[PORT_MAX]; |
995 | struct func_mf_cfg func_mf_config[E1H_FUNC_MAX]; | 1034 | struct func_mf_cfg func_mf_config[E1H_FUNC_MAX]; |
996 | 1035 | ||
1036 | struct func_ext_cfg func_ext_config[E1H_FUNC_MAX]; | ||
997 | }; | 1037 | }; |
998 | 1038 | ||
999 | 1039 | ||
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index f53edfd011b..1552fc3c135 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c | |||
@@ -2026,13 +2026,28 @@ static int bnx2x_get_cmng_fns_mode(struct bnx2x *bp) | |||
2026 | 2026 | ||
2027 | static void bnx2x_read_mf_cfg(struct bnx2x *bp) | 2027 | static void bnx2x_read_mf_cfg(struct bnx2x *bp) |
2028 | { | 2028 | { |
2029 | int vn; | 2029 | int vn, n = (CHIP_MODE_IS_4_PORT(bp) ? 2 : 1); |
2030 | 2030 | ||
2031 | if (BP_NOMCP(bp)) | 2031 | if (BP_NOMCP(bp)) |
2032 | return; /* what should be the default bvalue in this case */ | 2032 | return; /* what should be the default bvalue in this case */ |
2033 | 2033 | ||
2034 | /* For 2 port configuration the absolute function number formula | ||
2035 | * is: | ||
2036 | * abs_func = 2 * vn + BP_PORT + BP_PATH | ||
2037 | * | ||
2038 | * and there are 4 functions per port | ||
2039 | * | ||
2040 | * For 4 port configuration it is | ||
2041 | * abs_func = 4 * vn + 2 * BP_PORT + BP_PATH | ||
2042 | * | ||
2043 | * and there are 2 functions per port | ||
2044 | */ | ||
2034 | for (vn = VN_0; vn < E1HVN_MAX; vn++) { | 2045 | for (vn = VN_0; vn < E1HVN_MAX; vn++) { |
2035 | int /*abs*/func = 2*vn + BP_PORT(bp); | 2046 | int /*abs*/func = n * (2 * vn + BP_PORT(bp)) + BP_PATH(bp); |
2047 | |||
2048 | if (func >= E1H_FUNC_MAX) | ||
2049 | break; | ||
2050 | |||
2036 | bp->mf_config[vn] = | 2051 | bp->mf_config[vn] = |
2037 | MF_CFG_RD(bp, func_mf_config[func].config); | 2052 | MF_CFG_RD(bp, func_mf_config[func].config); |
2038 | } | 2053 | } |
@@ -2248,10 +2263,21 @@ static void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters) | |||
2248 | u8 accp_all_ucast = 0, accp_all_bcast = 0, accp_all_mcast = 0; | 2263 | u8 accp_all_ucast = 0, accp_all_bcast = 0, accp_all_mcast = 0; |
2249 | u8 unmatched_unicast = 0; | 2264 | u8 unmatched_unicast = 0; |
2250 | 2265 | ||
2266 | if (filters & BNX2X_ACCEPT_UNMATCHED_UCAST) | ||
2267 | unmatched_unicast = 1; | ||
2268 | |||
2251 | if (filters & BNX2X_PROMISCUOUS_MODE) { | 2269 | if (filters & BNX2X_PROMISCUOUS_MODE) { |
2252 | /* promiscious - accept all, drop none */ | 2270 | /* promiscious - accept all, drop none */ |
2253 | drop_all_ucast = drop_all_bcast = drop_all_mcast = 0; | 2271 | drop_all_ucast = drop_all_bcast = drop_all_mcast = 0; |
2254 | accp_all_ucast = accp_all_bcast = accp_all_mcast = 1; | 2272 | accp_all_ucast = accp_all_bcast = accp_all_mcast = 1; |
2273 | if (IS_MF_SI(bp)) { | ||
2274 | /* | ||
2275 | * SI mode defines to accept in promiscuos mode | ||
2276 | * only unmatched packets | ||
2277 | */ | ||
2278 | unmatched_unicast = 1; | ||
2279 | accp_all_ucast = 0; | ||
2280 | } | ||
2255 | } | 2281 | } |
2256 | if (filters & BNX2X_ACCEPT_UNICAST) { | 2282 | if (filters & BNX2X_ACCEPT_UNICAST) { |
2257 | /* accept matched ucast */ | 2283 | /* accept matched ucast */ |
@@ -2260,6 +2286,11 @@ static void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters) | |||
2260 | if (filters & BNX2X_ACCEPT_MULTICAST) { | 2286 | if (filters & BNX2X_ACCEPT_MULTICAST) { |
2261 | /* accept matched mcast */ | 2287 | /* accept matched mcast */ |
2262 | drop_all_mcast = 0; | 2288 | drop_all_mcast = 0; |
2289 | if (IS_MF_SI(bp)) | ||
2290 | /* since mcast addresses won't arrive with ovlan, | ||
2291 | * fw needs to accept all of them in | ||
2292 | * switch-independent mode */ | ||
2293 | accp_all_mcast = 1; | ||
2263 | } | 2294 | } |
2264 | if (filters & BNX2X_ACCEPT_ALL_UNICAST) { | 2295 | if (filters & BNX2X_ACCEPT_ALL_UNICAST) { |
2265 | /* accept all mcast */ | 2296 | /* accept all mcast */ |
@@ -2372,7 +2403,7 @@ static inline u16 bnx2x_get_cl_flags(struct bnx2x *bp, | |||
2372 | /* calculate queue flags */ | 2403 | /* calculate queue flags */ |
2373 | flags |= QUEUE_FLG_CACHE_ALIGN; | 2404 | flags |= QUEUE_FLG_CACHE_ALIGN; |
2374 | flags |= QUEUE_FLG_HC; | 2405 | flags |= QUEUE_FLG_HC; |
2375 | flags |= IS_MF(bp) ? QUEUE_FLG_OV : 0; | 2406 | flags |= IS_MF_SD(bp) ? QUEUE_FLG_OV : 0; |
2376 | 2407 | ||
2377 | flags |= QUEUE_FLG_VLAN; | 2408 | flags |= QUEUE_FLG_VLAN; |
2378 | DP(NETIF_MSG_IFUP, "vlan removal enabled\n"); | 2409 | DP(NETIF_MSG_IFUP, "vlan removal enabled\n"); |
@@ -2573,6 +2604,26 @@ static void bnx2x_e1h_enable(struct bnx2x *bp) | |||
2573 | */ | 2604 | */ |
2574 | } | 2605 | } |
2575 | 2606 | ||
2607 | /* called due to MCP event (on pmf): | ||
2608 | * reread new bandwidth configuration | ||
2609 | * configure FW | ||
2610 | * notify others function about the change | ||
2611 | */ | ||
2612 | static inline void bnx2x_config_mf_bw(struct bnx2x *bp) | ||
2613 | { | ||
2614 | if (bp->link_vars.link_up) { | ||
2615 | bnx2x_cmng_fns_init(bp, true, CMNG_FNS_MINMAX); | ||
2616 | bnx2x_link_sync_notify(bp); | ||
2617 | } | ||
2618 | storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp)); | ||
2619 | } | ||
2620 | |||
2621 | static inline void bnx2x_set_mf_bw(struct bnx2x *bp) | ||
2622 | { | ||
2623 | bnx2x_config_mf_bw(bp); | ||
2624 | bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW_ACK, 0); | ||
2625 | } | ||
2626 | |||
2576 | static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event) | 2627 | static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event) |
2577 | { | 2628 | { |
2578 | DP(BNX2X_MSG_MCP, "dcc_event 0x%x\n", dcc_event); | 2629 | DP(BNX2X_MSG_MCP, "dcc_event 0x%x\n", dcc_event); |
@@ -2598,10 +2649,7 @@ static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event) | |||
2598 | dcc_event &= ~DRV_STATUS_DCC_DISABLE_ENABLE_PF; | 2649 | dcc_event &= ~DRV_STATUS_DCC_DISABLE_ENABLE_PF; |
2599 | } | 2650 | } |
2600 | if (dcc_event & DRV_STATUS_DCC_BANDWIDTH_ALLOCATION) { | 2651 | if (dcc_event & DRV_STATUS_DCC_BANDWIDTH_ALLOCATION) { |
2601 | 2652 | bnx2x_config_mf_bw(bp); | |
2602 | bnx2x_cmng_fns_init(bp, true, CMNG_FNS_MINMAX); | ||
2603 | bnx2x_link_sync_notify(bp); | ||
2604 | storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp)); | ||
2605 | dcc_event &= ~DRV_STATUS_DCC_BANDWIDTH_ALLOCATION; | 2653 | dcc_event &= ~DRV_STATUS_DCC_BANDWIDTH_ALLOCATION; |
2606 | } | 2654 | } |
2607 | 2655 | ||
@@ -3022,6 +3070,10 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) | |||
3022 | if (val & DRV_STATUS_DCC_EVENT_MASK) | 3070 | if (val & DRV_STATUS_DCC_EVENT_MASK) |
3023 | bnx2x_dcc_event(bp, | 3071 | bnx2x_dcc_event(bp, |
3024 | (val & DRV_STATUS_DCC_EVENT_MASK)); | 3072 | (val & DRV_STATUS_DCC_EVENT_MASK)); |
3073 | |||
3074 | if (val & DRV_STATUS_SET_MF_BW) | ||
3075 | bnx2x_set_mf_bw(bp); | ||
3076 | |||
3025 | bnx2x__link_status_update(bp); | 3077 | bnx2x__link_status_update(bp); |
3026 | if ((bp->port.pmf == 0) && (val & DRV_STATUS_PMF)) | 3078 | if ((bp->port.pmf == 0) && (val & DRV_STATUS_PMF)) |
3027 | bnx2x_pmf_update(bp); | 3079 | bnx2x_pmf_update(bp); |
@@ -4232,6 +4284,15 @@ static void bnx2x_init_internal_common(struct bnx2x *bp) | |||
4232 | bp->mf_mode); | 4284 | bp->mf_mode); |
4233 | } | 4285 | } |
4234 | 4286 | ||
4287 | if (IS_MF_SI(bp)) | ||
4288 | /* | ||
4289 | * In switch independent mode, the TSTORM needs to accept | ||
4290 | * packets that failed classification, since approximate match | ||
4291 | * mac addresses aren't written to NIG LLH | ||
4292 | */ | ||
4293 | REG_WR8(bp, BAR_TSTRORM_INTMEM + | ||
4294 | TSTORM_ACCEPT_CLASSIFY_FAILED_OFFSET, 2); | ||
4295 | |||
4235 | /* Zero this manually as its initialization is | 4296 | /* Zero this manually as its initialization is |
4236 | currently missing in the initTool */ | 4297 | currently missing in the initTool */ |
4237 | for (i = 0; i < (USTORM_AGG_DATA_SIZE >> 2); i++) | 4298 | for (i = 0; i < (USTORM_AGG_DATA_SIZE >> 2); i++) |
@@ -5048,12 +5109,12 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) | |||
5048 | REG_WR(bp, PRS_REG_NIC_MODE, 1); | 5109 | REG_WR(bp, PRS_REG_NIC_MODE, 1); |
5049 | #endif | 5110 | #endif |
5050 | if (!CHIP_IS_E1(bp)) | 5111 | if (!CHIP_IS_E1(bp)) |
5051 | REG_WR(bp, PRS_REG_E1HOV_MODE, IS_MF(bp)); | 5112 | REG_WR(bp, PRS_REG_E1HOV_MODE, IS_MF_SD(bp)); |
5052 | 5113 | ||
5053 | if (CHIP_IS_E2(bp)) { | 5114 | if (CHIP_IS_E2(bp)) { |
5054 | /* Bit-map indicating which L2 hdrs may appear after the | 5115 | /* Bit-map indicating which L2 hdrs may appear after the |
5055 | basic Ethernet header */ | 5116 | basic Ethernet header */ |
5056 | int has_ovlan = IS_MF(bp); | 5117 | int has_ovlan = IS_MF_SD(bp); |
5057 | REG_WR(bp, PRS_REG_HDRS_AFTER_BASIC, (has_ovlan ? 7 : 6)); | 5118 | REG_WR(bp, PRS_REG_HDRS_AFTER_BASIC, (has_ovlan ? 7 : 6)); |
5058 | REG_WR(bp, PRS_REG_MUST_HAVE_HDRS, (has_ovlan ? 1 : 0)); | 5119 | REG_WR(bp, PRS_REG_MUST_HAVE_HDRS, (has_ovlan ? 1 : 0)); |
5059 | } | 5120 | } |
@@ -5087,7 +5148,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) | |||
5087 | bnx2x_init_block(bp, PBF_BLOCK, COMMON_STAGE); | 5148 | bnx2x_init_block(bp, PBF_BLOCK, COMMON_STAGE); |
5088 | 5149 | ||
5089 | if (CHIP_IS_E2(bp)) { | 5150 | if (CHIP_IS_E2(bp)) { |
5090 | int has_ovlan = IS_MF(bp); | 5151 | int has_ovlan = IS_MF_SD(bp); |
5091 | REG_WR(bp, PBF_REG_HDRS_AFTER_BASIC, (has_ovlan ? 7 : 6)); | 5152 | REG_WR(bp, PBF_REG_HDRS_AFTER_BASIC, (has_ovlan ? 7 : 6)); |
5092 | REG_WR(bp, PBF_REG_MUST_HAVE_HDRS, (has_ovlan ? 1 : 0)); | 5153 | REG_WR(bp, PBF_REG_MUST_HAVE_HDRS, (has_ovlan ? 1 : 0)); |
5093 | } | 5154 | } |
@@ -5164,12 +5225,12 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) | |||
5164 | bnx2x_init_block(bp, NIG_BLOCK, COMMON_STAGE); | 5225 | bnx2x_init_block(bp, NIG_BLOCK, COMMON_STAGE); |
5165 | if (!CHIP_IS_E1(bp)) { | 5226 | if (!CHIP_IS_E1(bp)) { |
5166 | REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_MF(bp)); | 5227 | REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_MF(bp)); |
5167 | REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_MF(bp)); | 5228 | REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_MF_SD(bp)); |
5168 | } | 5229 | } |
5169 | if (CHIP_IS_E2(bp)) { | 5230 | if (CHIP_IS_E2(bp)) { |
5170 | /* Bit-map indicating which L2 hdrs may appear after the | 5231 | /* Bit-map indicating which L2 hdrs may appear after the |
5171 | basic Ethernet header */ | 5232 | basic Ethernet header */ |
5172 | REG_WR(bp, NIG_REG_P0_HDRS_AFTER_BASIC, (IS_MF(bp) ? 7 : 6)); | 5233 | REG_WR(bp, NIG_REG_P0_HDRS_AFTER_BASIC, (IS_MF_SD(bp) ? 7 : 6)); |
5173 | } | 5234 | } |
5174 | 5235 | ||
5175 | if (CHIP_REV_IS_SLOW(bp)) | 5236 | if (CHIP_REV_IS_SLOW(bp)) |
@@ -5386,7 +5447,7 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) | |||
5386 | if (!CHIP_IS_E1(bp)) { | 5447 | if (!CHIP_IS_E1(bp)) { |
5387 | /* 0x2 disable mf_ov, 0x1 enable */ | 5448 | /* 0x2 disable mf_ov, 0x1 enable */ |
5388 | REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + port*4, | 5449 | REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + port*4, |
5389 | (IS_MF(bp) ? 0x1 : 0x2)); | 5450 | (IS_MF_SD(bp) ? 0x1 : 0x2)); |
5390 | 5451 | ||
5391 | if (CHIP_IS_E2(bp)) { | 5452 | if (CHIP_IS_E2(bp)) { |
5392 | val = 0; | 5453 | val = 0; |
@@ -6170,6 +6231,70 @@ static u8 bnx2x_e1h_cam_offset(struct bnx2x *bp, u8 rel_offset) | |||
6170 | return BP_VN(bp) * 32 + rel_offset; | 6231 | return BP_VN(bp) * 32 + rel_offset; |
6171 | } | 6232 | } |
6172 | 6233 | ||
6234 | /** | ||
6235 | * LLH CAM line allocations: currently only iSCSI and ETH macs are | ||
6236 | * relevant. In addition, current implementation is tuned for a | ||
6237 | * single ETH MAC. | ||
6238 | * | ||
6239 | * When multiple unicast ETH MACs PF configuration in switch | ||
6240 | * independent mode is required (NetQ, multiple netdev MACs, | ||
6241 | * etc.), consider better utilisation of 16 per function MAC | ||
6242 | * entries in the LLH memory. | ||
6243 | */ | ||
6244 | enum { | ||
6245 | LLH_CAM_ISCSI_ETH_LINE = 0, | ||
6246 | LLH_CAM_ETH_LINE, | ||
6247 | LLH_CAM_MAX_PF_LINE = NIG_REG_LLH1_FUNC_MEM_SIZE | ||
6248 | }; | ||
6249 | |||
6250 | static void bnx2x_set_mac_in_nig(struct bnx2x *bp, | ||
6251 | int set, | ||
6252 | unsigned char *dev_addr, | ||
6253 | int index) | ||
6254 | { | ||
6255 | u32 wb_data[2]; | ||
6256 | u32 mem_offset, ena_offset, mem_index; | ||
6257 | /** | ||
6258 | * indexes mapping: | ||
6259 | * 0..7 - goes to MEM | ||
6260 | * 8..15 - goes to MEM2 | ||
6261 | */ | ||
6262 | |||
6263 | if (!IS_MF_SI(bp) || index > LLH_CAM_MAX_PF_LINE) | ||
6264 | return; | ||
6265 | |||
6266 | /* calculate memory start offset according to the mapping | ||
6267 | * and index in the memory */ | ||
6268 | if (index < NIG_LLH_FUNC_MEM_MAX_OFFSET) { | ||
6269 | mem_offset = BP_PORT(bp) ? NIG_REG_LLH1_FUNC_MEM : | ||
6270 | NIG_REG_LLH0_FUNC_MEM; | ||
6271 | ena_offset = BP_PORT(bp) ? NIG_REG_LLH1_FUNC_MEM_ENABLE : | ||
6272 | NIG_REG_LLH0_FUNC_MEM_ENABLE; | ||
6273 | mem_index = index; | ||
6274 | } else { | ||
6275 | mem_offset = BP_PORT(bp) ? NIG_REG_P1_LLH_FUNC_MEM2 : | ||
6276 | NIG_REG_P0_LLH_FUNC_MEM2; | ||
6277 | ena_offset = BP_PORT(bp) ? NIG_REG_P1_LLH_FUNC_MEM2_ENABLE : | ||
6278 | NIG_REG_P0_LLH_FUNC_MEM2_ENABLE; | ||
6279 | mem_index = index - NIG_LLH_FUNC_MEM_MAX_OFFSET; | ||
6280 | } | ||
6281 | |||
6282 | if (set) { | ||
6283 | /* LLH_FUNC_MEM is a u64 WB register */ | ||
6284 | mem_offset += 8*mem_index; | ||
6285 | |||
6286 | wb_data[0] = ((dev_addr[2] << 24) | (dev_addr[3] << 16) | | ||
6287 | (dev_addr[4] << 8) | dev_addr[5]); | ||
6288 | wb_data[1] = ((dev_addr[0] << 8) | dev_addr[1]); | ||
6289 | |||
6290 | REG_WR_DMAE(bp, mem_offset, wb_data, 2); | ||
6291 | } | ||
6292 | |||
6293 | /* enable/disable the entry */ | ||
6294 | REG_WR(bp, ena_offset + 4*mem_index, set); | ||
6295 | |||
6296 | } | ||
6297 | |||
6173 | void bnx2x_set_eth_mac(struct bnx2x *bp, int set) | 6298 | void bnx2x_set_eth_mac(struct bnx2x *bp, int set) |
6174 | { | 6299 | { |
6175 | u8 cam_offset = (CHIP_IS_E1(bp) ? (BP_PORT(bp) ? 32 : 0) : | 6300 | u8 cam_offset = (CHIP_IS_E1(bp) ? (BP_PORT(bp) ? 32 : 0) : |
@@ -6179,6 +6304,8 @@ void bnx2x_set_eth_mac(struct bnx2x *bp, int set) | |||
6179 | bnx2x_set_mac_addr_gen(bp, set, bp->dev->dev_addr, | 6304 | bnx2x_set_mac_addr_gen(bp, set, bp->dev->dev_addr, |
6180 | (1 << bp->fp->cl_id), cam_offset , 0); | 6305 | (1 << bp->fp->cl_id), cam_offset , 0); |
6181 | 6306 | ||
6307 | bnx2x_set_mac_in_nig(bp, set, bp->dev->dev_addr, LLH_CAM_ETH_LINE); | ||
6308 | |||
6182 | if (CHIP_IS_E1(bp)) { | 6309 | if (CHIP_IS_E1(bp)) { |
6183 | /* broadcast MAC */ | 6310 | /* broadcast MAC */ |
6184 | u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | 6311 | u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
@@ -6289,6 +6416,8 @@ static int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set) | |||
6289 | /* Send a SET_MAC ramrod */ | 6416 | /* Send a SET_MAC ramrod */ |
6290 | bnx2x_set_mac_addr_gen(bp, set, bp->iscsi_mac, cl_bit_vec, | 6417 | bnx2x_set_mac_addr_gen(bp, set, bp->iscsi_mac, cl_bit_vec, |
6291 | cam_offset, 0); | 6418 | cam_offset, 0); |
6419 | |||
6420 | bnx2x_set_mac_in_nig(bp, set, bp->iscsi_mac, LLH_CAM_ISCSI_ETH_LINE); | ||
6292 | return 0; | 6421 | return 0; |
6293 | } | 6422 | } |
6294 | #endif | 6423 | #endif |
@@ -8076,7 +8205,6 @@ static void __devinit bnx2x_set_mac_buf(u8 *mac_buf, u32 mac_lo, u16 mac_hi) | |||
8076 | static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) | 8205 | static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) |
8077 | { | 8206 | { |
8078 | int port = BP_PORT(bp); | 8207 | int port = BP_PORT(bp); |
8079 | u32 val, val2; | ||
8080 | u32 config; | 8208 | u32 config; |
8081 | u32 ext_phy_type, ext_phy_config; | 8209 | u32 ext_phy_type, ext_phy_config; |
8082 | 8210 | ||
@@ -8135,25 +8263,62 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) | |||
8135 | (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) | 8263 | (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) |
8136 | bp->mdio.prtad = | 8264 | bp->mdio.prtad = |
8137 | XGXS_EXT_PHY_ADDR(ext_phy_config); | 8265 | XGXS_EXT_PHY_ADDR(ext_phy_config); |
8266 | } | ||
8138 | 8267 | ||
8139 | val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper); | 8268 | static void __devinit bnx2x_get_mac_hwinfo(struct bnx2x *bp) |
8140 | val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower); | 8269 | { |
8141 | bnx2x_set_mac_buf(bp->dev->dev_addr, val, val2); | 8270 | u32 val, val2; |
8142 | memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, ETH_ALEN); | 8271 | int func = BP_ABS_FUNC(bp); |
8143 | memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN); | 8272 | int port = BP_PORT(bp); |
8273 | |||
8274 | if (BP_NOMCP(bp)) { | ||
8275 | BNX2X_ERROR("warning: random MAC workaround active\n"); | ||
8276 | random_ether_addr(bp->dev->dev_addr); | ||
8277 | } else if (IS_MF(bp)) { | ||
8278 | val2 = MF_CFG_RD(bp, func_mf_config[func].mac_upper); | ||
8279 | val = MF_CFG_RD(bp, func_mf_config[func].mac_lower); | ||
8280 | if ((val2 != FUNC_MF_CFG_UPPERMAC_DEFAULT) && | ||
8281 | (val != FUNC_MF_CFG_LOWERMAC_DEFAULT)) | ||
8282 | bnx2x_set_mac_buf(bp->dev->dev_addr, val, val2); | ||
8144 | 8283 | ||
8145 | #ifdef BCM_CNIC | 8284 | #ifdef BCM_CNIC |
8146 | val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].iscsi_mac_upper); | 8285 | /* iSCSI NPAR MAC */ |
8147 | val = SHMEM_RD(bp, dev_info.port_hw_config[port].iscsi_mac_lower); | 8286 | if (IS_MF_SI(bp)) { |
8148 | bnx2x_set_mac_buf(bp->iscsi_mac, val, val2); | 8287 | u32 cfg = MF_CFG_RD(bp, func_ext_config[func].func_cfg); |
8288 | if (cfg & MACP_FUNC_CFG_FLAGS_ISCSI_OFFLOAD) { | ||
8289 | val2 = MF_CFG_RD(bp, func_ext_config[func]. | ||
8290 | iscsi_mac_addr_upper); | ||
8291 | val = MF_CFG_RD(bp, func_ext_config[func]. | ||
8292 | iscsi_mac_addr_lower); | ||
8293 | bnx2x_set_mac_buf(bp->iscsi_mac, val, val2); | ||
8294 | } | ||
8295 | } | ||
8149 | #endif | 8296 | #endif |
8297 | } else { | ||
8298 | /* in SF read MACs from port configuration */ | ||
8299 | val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper); | ||
8300 | val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower); | ||
8301 | bnx2x_set_mac_buf(bp->dev->dev_addr, val, val2); | ||
8302 | |||
8303 | #ifdef BCM_CNIC | ||
8304 | val2 = SHMEM_RD(bp, dev_info.port_hw_config[port]. | ||
8305 | iscsi_mac_upper); | ||
8306 | val = SHMEM_RD(bp, dev_info.port_hw_config[port]. | ||
8307 | iscsi_mac_lower); | ||
8308 | bnx2x_set_mac_buf(bp->iscsi_mac, val, val2); | ||
8309 | #endif | ||
8310 | } | ||
8311 | |||
8312 | memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, ETH_ALEN); | ||
8313 | memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN); | ||
8314 | |||
8150 | } | 8315 | } |
8151 | 8316 | ||
8152 | static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) | 8317 | static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) |
8153 | { | 8318 | { |
8154 | int func = BP_ABS_FUNC(bp); | 8319 | int /*abs*/func = BP_ABS_FUNC(bp); |
8155 | int vn; | 8320 | int vn, port; |
8156 | u32 val, val2; | 8321 | u32 val = 0; |
8157 | int rc = 0; | 8322 | int rc = 0; |
8158 | 8323 | ||
8159 | bnx2x_get_common_hwinfo(bp); | 8324 | bnx2x_get_common_hwinfo(bp); |
@@ -8186,44 +8351,99 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) | |||
8186 | bp->mf_ov = 0; | 8351 | bp->mf_ov = 0; |
8187 | bp->mf_mode = 0; | 8352 | bp->mf_mode = 0; |
8188 | vn = BP_E1HVN(bp); | 8353 | vn = BP_E1HVN(bp); |
8354 | port = BP_PORT(bp); | ||
8355 | |||
8189 | if (!CHIP_IS_E1(bp) && !BP_NOMCP(bp)) { | 8356 | if (!CHIP_IS_E1(bp) && !BP_NOMCP(bp)) { |
8357 | DP(NETIF_MSG_PROBE, | ||
8358 | "shmem2base 0x%x, size %d, mfcfg offset %d\n", | ||
8359 | bp->common.shmem2_base, SHMEM2_RD(bp, size), | ||
8360 | (u32)offsetof(struct shmem2_region, mf_cfg_addr)); | ||
8190 | if (SHMEM2_HAS(bp, mf_cfg_addr)) | 8361 | if (SHMEM2_HAS(bp, mf_cfg_addr)) |
8191 | bp->common.mf_cfg_base = SHMEM2_RD(bp, mf_cfg_addr); | 8362 | bp->common.mf_cfg_base = SHMEM2_RD(bp, mf_cfg_addr); |
8192 | else | 8363 | else |
8193 | bp->common.mf_cfg_base = bp->common.shmem_base + | 8364 | bp->common.mf_cfg_base = bp->common.shmem_base + |
8194 | offsetof(struct shmem_region, func_mb) + | 8365 | offsetof(struct shmem_region, func_mb) + |
8195 | E1H_FUNC_MAX * sizeof(struct drv_func_mb); | 8366 | E1H_FUNC_MAX * sizeof(struct drv_func_mb); |
8196 | bp->mf_config[vn] = | 8367 | /* |
8197 | MF_CFG_RD(bp, func_mf_config[func].config); | 8368 | * get mf configuration: |
8369 | * 1. existance of MF configuration | ||
8370 | * 2. MAC address must be legal (check only upper bytes) | ||
8371 | * for Switch-Independent mode; | ||
8372 | * OVLAN must be legal for Switch-Dependent mode | ||
8373 | * 3. SF_MODE configures specific MF mode | ||
8374 | */ | ||
8375 | if (bp->common.mf_cfg_base != SHMEM_MF_CFG_ADDR_NONE) { | ||
8376 | /* get mf configuration */ | ||
8377 | val = SHMEM_RD(bp, | ||
8378 | dev_info.shared_feature_config.config); | ||
8379 | val &= SHARED_FEAT_CFG_FORCE_SF_MODE_MASK; | ||
8380 | |||
8381 | switch (val) { | ||
8382 | case SHARED_FEAT_CFG_FORCE_SF_MODE_SWITCH_INDEPT: | ||
8383 | val = MF_CFG_RD(bp, func_mf_config[func]. | ||
8384 | mac_upper); | ||
8385 | /* check for legal mac (upper bytes)*/ | ||
8386 | if (val != 0xffff) { | ||
8387 | bp->mf_mode = MULTI_FUNCTION_SI; | ||
8388 | bp->mf_config[vn] = MF_CFG_RD(bp, | ||
8389 | func_mf_config[func].config); | ||
8390 | } else | ||
8391 | DP(NETIF_MSG_PROBE, "illegal MAC " | ||
8392 | "address for SI\n"); | ||
8393 | break; | ||
8394 | case SHARED_FEAT_CFG_FORCE_SF_MODE_MF_ALLOWED: | ||
8395 | /* get OV configuration */ | ||
8396 | val = MF_CFG_RD(bp, | ||
8397 | func_mf_config[FUNC_0].e1hov_tag); | ||
8398 | val &= FUNC_MF_CFG_E1HOV_TAG_MASK; | ||
8399 | |||
8400 | if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { | ||
8401 | bp->mf_mode = MULTI_FUNCTION_SD; | ||
8402 | bp->mf_config[vn] = MF_CFG_RD(bp, | ||
8403 | func_mf_config[func].config); | ||
8404 | } else | ||
8405 | DP(NETIF_MSG_PROBE, "illegal OV for " | ||
8406 | "SD\n"); | ||
8407 | break; | ||
8408 | default: | ||
8409 | /* Unknown configuration: reset mf_config */ | ||
8410 | bp->mf_config[vn] = 0; | ||
8411 | DP(NETIF_MSG_PROBE, "Unkown MF mode 0x%x\n", | ||
8412 | val); | ||
8413 | } | ||
8414 | } | ||
8198 | 8415 | ||
8199 | val = (MF_CFG_RD(bp, func_mf_config[FUNC_0].e1hov_tag) & | ||
8200 | FUNC_MF_CFG_E1HOV_TAG_MASK); | ||
8201 | if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) | ||
8202 | bp->mf_mode = 1; | ||
8203 | BNX2X_DEV_INFO("%s function mode\n", | 8416 | BNX2X_DEV_INFO("%s function mode\n", |
8204 | IS_MF(bp) ? "multi" : "single"); | 8417 | IS_MF(bp) ? "multi" : "single"); |
8205 | 8418 | ||
8206 | if (IS_MF(bp)) { | 8419 | switch (bp->mf_mode) { |
8207 | val = (MF_CFG_RD(bp, func_mf_config[func]. | 8420 | case MULTI_FUNCTION_SD: |
8208 | e1hov_tag) & | 8421 | val = MF_CFG_RD(bp, func_mf_config[func].e1hov_tag) & |
8209 | FUNC_MF_CFG_E1HOV_TAG_MASK); | 8422 | FUNC_MF_CFG_E1HOV_TAG_MASK; |
8210 | if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { | 8423 | if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { |
8211 | bp->mf_ov = val; | 8424 | bp->mf_ov = val; |
8212 | BNX2X_DEV_INFO("MF OV for func %d is %d " | 8425 | BNX2X_DEV_INFO("MF OV for func %d is %d" |
8213 | "(0x%04x)\n", | 8426 | " (0x%04x)\n", func, |
8214 | func, bp->mf_ov, bp->mf_ov); | 8427 | bp->mf_ov, bp->mf_ov); |
8215 | } else { | 8428 | } else { |
8216 | BNX2X_ERROR("No valid MF OV for func %d," | 8429 | BNX2X_ERR("No valid MF OV for func %d," |
8217 | " aborting\n", func); | 8430 | " aborting\n", func); |
8218 | rc = -EPERM; | 8431 | rc = -EPERM; |
8219 | } | 8432 | } |
8220 | } else { | 8433 | break; |
8221 | if (BP_VN(bp)) { | 8434 | case MULTI_FUNCTION_SI: |
8222 | BNX2X_ERROR("VN %d in single function mode," | 8435 | BNX2X_DEV_INFO("func %d is in MF " |
8223 | " aborting\n", BP_E1HVN(bp)); | 8436 | "switch-independent mode\n", func); |
8437 | break; | ||
8438 | default: | ||
8439 | if (vn) { | ||
8440 | BNX2X_ERR("VN %d in single function mode," | ||
8441 | " aborting\n", vn); | ||
8224 | rc = -EPERM; | 8442 | rc = -EPERM; |
8225 | } | 8443 | } |
8444 | break; | ||
8226 | } | 8445 | } |
8446 | |||
8227 | } | 8447 | } |
8228 | 8448 | ||
8229 | /* adjust igu_sb_cnt to MF for E1x */ | 8449 | /* adjust igu_sb_cnt to MF for E1x */ |
@@ -8248,32 +8468,8 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) | |||
8248 | BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq); | 8468 | BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq); |
8249 | } | 8469 | } |
8250 | 8470 | ||
8251 | if (IS_MF(bp)) { | 8471 | /* Get MAC addresses */ |
8252 | val2 = MF_CFG_RD(bp, func_mf_config[func].mac_upper); | 8472 | bnx2x_get_mac_hwinfo(bp); |
8253 | val = MF_CFG_RD(bp, func_mf_config[func].mac_lower); | ||
8254 | if ((val2 != FUNC_MF_CFG_UPPERMAC_DEFAULT) && | ||
8255 | (val != FUNC_MF_CFG_LOWERMAC_DEFAULT)) { | ||
8256 | bp->dev->dev_addr[0] = (u8)(val2 >> 8 & 0xff); | ||
8257 | bp->dev->dev_addr[1] = (u8)(val2 & 0xff); | ||
8258 | bp->dev->dev_addr[2] = (u8)(val >> 24 & 0xff); | ||
8259 | bp->dev->dev_addr[3] = (u8)(val >> 16 & 0xff); | ||
8260 | bp->dev->dev_addr[4] = (u8)(val >> 8 & 0xff); | ||
8261 | bp->dev->dev_addr[5] = (u8)(val & 0xff); | ||
8262 | memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, | ||
8263 | ETH_ALEN); | ||
8264 | memcpy(bp->dev->perm_addr, bp->dev->dev_addr, | ||
8265 | ETH_ALEN); | ||
8266 | } | ||
8267 | |||
8268 | return rc; | ||
8269 | } | ||
8270 | |||
8271 | if (BP_NOMCP(bp)) { | ||
8272 | /* only supposed to happen on emulation/FPGA */ | ||
8273 | BNX2X_ERROR("warning: random MAC workaround active\n"); | ||
8274 | random_ether_addr(bp->dev->dev_addr); | ||
8275 | memcpy(bp->dev->perm_addr, bp->dev->dev_addr, ETH_ALEN); | ||
8276 | } | ||
8277 | 8473 | ||
8278 | return rc; | 8474 | return rc; |
8279 | } | 8475 | } |
diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 1cefe489a95..64bdda189e5 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h | |||
@@ -1774,6 +1774,8 @@ | |||
1774 | /* [RW 8] event id for llh0 */ | 1774 | /* [RW 8] event id for llh0 */ |
1775 | #define NIG_REG_LLH0_EVENT_ID 0x10084 | 1775 | #define NIG_REG_LLH0_EVENT_ID 0x10084 |
1776 | #define NIG_REG_LLH0_FUNC_EN 0x160fc | 1776 | #define NIG_REG_LLH0_FUNC_EN 0x160fc |
1777 | #define NIG_REG_LLH0_FUNC_MEM 0x16180 | ||
1778 | #define NIG_REG_LLH0_FUNC_MEM_ENABLE 0x16140 | ||
1777 | #define NIG_REG_LLH0_FUNC_VLAN_ID 0x16100 | 1779 | #define NIG_REG_LLH0_FUNC_VLAN_ID 0x16100 |
1778 | /* [RW 1] Determine the IP version to look for in | 1780 | /* [RW 1] Determine the IP version to look for in |
1779 | ~nig_registers_llh0_dest_ip_0.llh0_dest_ip_0. 0 - IPv6; 1-IPv4 */ | 1781 | ~nig_registers_llh0_dest_ip_0.llh0_dest_ip_0. 0 - IPv6; 1-IPv4 */ |
@@ -1797,6 +1799,9 @@ | |||
1797 | #define NIG_REG_LLH1_ERROR_MASK 0x10090 | 1799 | #define NIG_REG_LLH1_ERROR_MASK 0x10090 |
1798 | /* [RW 8] event id for llh1 */ | 1800 | /* [RW 8] event id for llh1 */ |
1799 | #define NIG_REG_LLH1_EVENT_ID 0x10088 | 1801 | #define NIG_REG_LLH1_EVENT_ID 0x10088 |
1802 | #define NIG_REG_LLH1_FUNC_MEM 0x161c0 | ||
1803 | #define NIG_REG_LLH1_FUNC_MEM_ENABLE 0x16160 | ||
1804 | #define NIG_REG_LLH1_FUNC_MEM_SIZE 16 | ||
1800 | /* [RW 8] init credit counter for port1 in LLH */ | 1805 | /* [RW 8] init credit counter for port1 in LLH */ |
1801 | #define NIG_REG_LLH1_XCM_INIT_CREDIT 0x10564 | 1806 | #define NIG_REG_LLH1_XCM_INIT_CREDIT 0x10564 |
1802 | #define NIG_REG_LLH1_XCM_MASK 0x10134 | 1807 | #define NIG_REG_LLH1_XCM_MASK 0x10134 |