aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x
diff options
context:
space:
mode:
authorDmitry Kravkov <dmitry@broadcom.com>2010-12-01 15:39:28 -0500
committerDavid S. Miller <davem@davemloft.net>2010-12-01 15:39:28 -0500
commit0793f83f0ec2142d06abe53570417c8d95e0310a (patch)
tree6716837e759bb83722d07084f57bcd327167ee56 /drivers/net/bnx2x
parent3f419d2d487821093ee46e898b5f8747f9edc9cd (diff)
bnx2x: Add Nic partitioning mode (57712 devices)
NIC partitioning is another flavor of multi function - having few PCI functions share the same physical port. Unlike the currently supported mode of multi-function which depends on the switch configuration and uses outer-VLAN, the NPAR mode is switch independent and uses the MAC addresses to distribute incoming packets to the different functions. This patch adds the specific HW setting of the NPAR mode and some distinctions between switch dependent (SD) and switch independent (SI) multi-function (MF) modes where the configuration is not the same. Advance driver version to 1.60.00-6 Signed-off-by: Dmitry Kravkov <dmitry@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')
-rw-r--r--drivers/net/bnx2x/bnx2x.h11
-rw-r--r--drivers/net/bnx2x/bnx2x_cmn.c34
-rw-r--r--drivers/net/bnx2x/bnx2x_cmn.h10
-rw-r--r--drivers/net/bnx2x/bnx2x_ethtool.c58
-rw-r--r--drivers/net/bnx2x/bnx2x_hsi.h42
-rw-r--r--drivers/net/bnx2x/bnx2x_main.c336
-rw-r--r--drivers/net/bnx2x/bnx2x_reg.h5
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 */
702u16 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
701void bnx2x_link_report(struct bnx2x *bp) 724void 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);
73void bnx2x_link_report(struct bnx2x *bp); 73void 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 */
83u16 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 */
1001struct 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
991struct mf_cfg { 1030struct 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
2027static void bnx2x_read_mf_cfg(struct bnx2x *bp) 2027static 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 */
2612static 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
2621static 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
2576static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event) 2627static 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 */
6244enum {
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
6250static 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
6173void bnx2x_set_eth_mac(struct bnx2x *bp, int set) 6298void 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)
8076static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) 8205static 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); 8268static 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
8152static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) 8317static 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