Commit 0793f83f authored by Dmitry Kravkov's avatar Dmitry Kravkov Committed by David S. Miller

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: default avatarDmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: default avatarEilon Greenstein <eilong@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3f419d2d
......@@ -20,8 +20,8 @@
* (you will need to reboot afterwards) */
/* #define BNX2X_STOP_ON_ERROR */
#define DRV_MODULE_VERSION "1.60.00-5"
#define DRV_MODULE_RELDATE "2010/11/24"
#define DRV_MODULE_VERSION "1.60.00-6"
#define DRV_MODULE_RELDATE "2010/11/29"
#define BNX2X_BC_VER 0x040200
#define BNX2X_MULTI_QUEUE
......@@ -671,6 +671,10 @@ enum {
CAM_ISCSI_ETH_LINE,
CAM_MAX_PF_LINE = CAM_ISCSI_ETH_LINE
};
/* number of MACs per function in NIG memory - used for SI mode */
#define NIG_LLH_FUNC_MEM_SIZE 16
/* number of entries in NIG_REG_LLHX_FUNC_MEM */
#define NIG_LLH_FUNC_MEM_MAX_OFFSET 8
#define BNX2X_VF_ID_INVALID 0xFF
......@@ -967,6 +971,8 @@ struct bnx2x {
u16 mf_ov;
u8 mf_mode;
#define IS_MF(bp) (bp->mf_mode != 0)
#define IS_MF_SI(bp) (bp->mf_mode == MULTI_FUNCTION_SI)
#define IS_MF_SD(bp) (bp->mf_mode == MULTI_FUNCTION_SD)
u8 wol;
......@@ -1010,6 +1016,7 @@ struct bnx2x {
#define BNX2X_ACCEPT_ALL_UNICAST 0x0004
#define BNX2X_ACCEPT_ALL_MULTICAST 0x0008
#define BNX2X_ACCEPT_BROADCAST 0x0010
#define BNX2X_ACCEPT_UNMATCHED_UCAST 0x0020
#define BNX2X_PROMISCUOUS_MODE 0x10000
u32 rx_mode;
......
......@@ -698,6 +698,29 @@ void bnx2x_release_phy_lock(struct bnx2x *bp)
mutex_unlock(&bp->port.phy_mutex);
}
/* calculates MF speed according to current linespeed and MF configuration */
u16 bnx2x_get_mf_speed(struct bnx2x *bp)
{
u16 line_speed = bp->link_vars.line_speed;
if (IS_MF(bp)) {
u16 maxCfg = (bp->mf_config[BP_VN(bp)] &
FUNC_MF_CFG_MAX_BW_MASK) >>
FUNC_MF_CFG_MAX_BW_SHIFT;
/* Calculate the current MAX line speed limit for the DCC
* capable devices
*/
if (IS_MF_SD(bp)) {
u16 vn_max_rate = maxCfg * 100;
if (vn_max_rate < line_speed)
line_speed = vn_max_rate;
} else /* IS_MF_SI(bp)) */
line_speed = (line_speed * maxCfg) / 100;
}
return line_speed;
}
void bnx2x_link_report(struct bnx2x *bp)
{
if (bp->flags & MF_FUNC_DIS) {
......@@ -713,17 +736,8 @@ void bnx2x_link_report(struct bnx2x *bp)
netif_carrier_on(bp->dev);
netdev_info(bp->dev, "NIC Link is Up, ");
line_speed = bp->link_vars.line_speed;
if (IS_MF(bp)) {
u16 vn_max_rate;
line_speed = bnx2x_get_mf_speed(bp);
vn_max_rate =
((bp->mf_config[BP_VN(bp)] &
FUNC_MF_CFG_MAX_BW_MASK) >>
FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
if (vn_max_rate < line_speed)
line_speed = vn_max_rate;
}
pr_cont("%d Mbps ", line_speed);
if (bp->link_vars.duplex == DUPLEX_FULL)
......
......@@ -72,6 +72,16 @@ void bnx2x__link_status_update(struct bnx2x *bp);
*/
void bnx2x_link_report(struct bnx2x *bp);
/**
* calculates MF speed according to current linespeed and MF
* configuration
*
* @param bp
*
* @return u16
*/
u16 bnx2x_get_mf_speed(struct bnx2x *bp);
/**
* MSI-X slowpath interrupt handler
*
......
......@@ -45,14 +45,9 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
cmd->speed = bp->link_params.req_line_speed[cfg_idx];
cmd->duplex = bp->link_params.req_duplex[cfg_idx];
}
if (IS_MF(bp)) {
u16 vn_max_rate = ((bp->mf_config[BP_VN(bp)] &
FUNC_MF_CFG_MAX_BW_MASK) >> FUNC_MF_CFG_MAX_BW_SHIFT) *
100;
if (vn_max_rate < cmd->speed)
cmd->speed = vn_max_rate;
}
if (IS_MF(bp))
cmd->speed = bnx2x_get_mf_speed(bp);
if (bp->port.supported[cfg_idx] & SUPPORTED_TP)
cmd->port = PORT_TP;
......@@ -87,18 +82,57 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct bnx2x *bp = netdev_priv(dev);
u32 advertising, cfg_idx, old_multi_phy_config, new_multi_phy_config;
u32 speed;
if (IS_MF(bp))
if (IS_MF_SD(bp))
return 0;
DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n"
DP_LEVEL " supported 0x%x advertising 0x%x speed %d\n"
DP_LEVEL " duplex %d port %d phy_address %d transceiver %d\n"
DP_LEVEL " autoneg %d maxtxpkt %d maxrxpkt %d\n",
" supported 0x%x advertising 0x%x speed %d speed_hi %d\n"
" duplex %d port %d phy_address %d transceiver %d\n"
" autoneg %d maxtxpkt %d maxrxpkt %d\n",
cmd->cmd, cmd->supported, cmd->advertising, cmd->speed,
cmd->speed_hi,
cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
speed = cmd->speed;
speed |= (cmd->speed_hi << 16);
if (IS_MF_SI(bp)) {
u32 param = 0;
u32 line_speed = bp->link_vars.line_speed;
/* use 10G if no link detected */
if (!line_speed)
line_speed = 10000;
if (bp->common.bc_ver < REQ_BC_VER_4_SET_MF_BW) {
BNX2X_DEV_INFO("To set speed BC %X or higher "
"is required, please upgrade BC\n",
REQ_BC_VER_4_SET_MF_BW);
return -EINVAL;
}
if (line_speed < speed) {
BNX2X_DEV_INFO("New speed should be less or equal "
"to actual line speed\n");
return -EINVAL;
}
/* load old values */
param = bp->mf_config[BP_VN(bp)];
/* leave only MIN value */
param &= FUNC_MF_CFG_MIN_BW_MASK;
/* set new MAX value */
param |= (((speed * 100) / line_speed)
<< FUNC_MF_CFG_MAX_BW_SHIFT)
& FUNC_MF_CFG_MAX_BW_MASK;
bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW, param);
return 0;
}
cfg_idx = bnx2x_get_link_cfg_idx(bp);
old_multi_phy_config = bp->link_params.multi_phy_config;
switch (cmd->port) {
......@@ -168,8 +202,6 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
} else { /* forced speed */
/* advertise the requested speed and duplex if supported */
u32 speed = cmd->speed;
speed |= (cmd->speed_hi << 16);
switch (speed) {
case SPEED_10:
if (cmd->duplex == DUPLEX_FULL) {
......
......@@ -434,7 +434,12 @@ struct shared_feat_cfg { /* NVRAM Offset */
#define SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_DISABLED 0x00000000
#define SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_ENABLED 0x00000002
#define SHARED_FEATURE_MF_MODE_DISABLED 0x00000100
#define SHARED_FEAT_CFG_FORCE_SF_MODE_MASK 0x00000700
#define SHARED_FEAT_CFG_FORCE_SF_MODE_SHIFT 8
#define SHARED_FEAT_CFG_FORCE_SF_MODE_MF_ALLOWED 0x00000000
#define SHARED_FEAT_CFG_FORCE_SF_MODE_FORCED_SF 0x00000100
#define SHARED_FEAT_CFG_FORCE_SF_MODE_SPIO4 0x00000200
#define SHARED_FEAT_CFG_FORCE_SF_MODE_SWITCH_INDEPT 0x00000300
};
......@@ -815,6 +820,9 @@ struct drv_func_mb {
#define DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL 0xa1000000
#define REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL 0x00050234
#define DRV_MSG_CODE_SET_MF_BW 0xe0000000
#define REQ_BC_VER_4_SET_MF_BW 0x00060202
#define DRV_MSG_CODE_SET_MF_BW_ACK 0xe1000000
#define BIOS_MSG_CODE_LIC_CHALLENGE 0xff010000
#define BIOS_MSG_CODE_LIC_RESPONSE 0xff020000
#define BIOS_MSG_CODE_VIRT_MAC_PRIM 0xff030000
......@@ -888,6 +896,7 @@ struct drv_func_mb {
u32 drv_status;
#define DRV_STATUS_PMF 0x00000001
#define DRV_STATUS_SET_MF_BW 0x00000004
#define DRV_STATUS_DCC_EVENT_MASK 0x0000ff00
#define DRV_STATUS_DCC_DISABLE_ENABLE_PF 0x00000100
......@@ -988,12 +997,43 @@ struct func_mf_cfg {
};
/* This structure is not applicable and should not be accessed on 57711 */
struct func_ext_cfg {
u32 func_cfg;
#define MACP_FUNC_CFG_FLAGS_MASK 0x000000FF
#define MACP_FUNC_CFG_FLAGS_SHIFT 0
#define MACP_FUNC_CFG_FLAGS_ENABLED 0x00000001
#define MACP_FUNC_CFG_FLAGS_ETHERNET 0x00000002
#define MACP_FUNC_CFG_FLAGS_ISCSI_OFFLOAD 0x00000004
#define MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD 0x00000008
u32 iscsi_mac_addr_upper;
u32 iscsi_mac_addr_lower;
u32 fcoe_mac_addr_upper;
u32 fcoe_mac_addr_lower;
u32 fcoe_wwn_port_name_upper;
u32 fcoe_wwn_port_name_lower;
u32 fcoe_wwn_node_name_upper;
u32 fcoe_wwn_node_name_lower;
u32 preserve_data;
#define MF_FUNC_CFG_PRESERVE_L2_MAC (1<<0)
#define MF_FUNC_CFG_PRESERVE_ISCSI_MAC (1<<1)
#define MF_FUNC_CFG_PRESERVE_FCOE_MAC (1<<2)
#define MF_FUNC_CFG_PRESERVE_FCOE_WWN_P (1<<3)
#define MF_FUNC_CFG_PRESERVE_FCOE_WWN_N (1<<4)
};
struct mf_cfg {
struct shared_mf_cfg shared_mf_config;
struct port_mf_cfg port_mf_config[PORT_MAX];
struct func_mf_cfg func_mf_config[E1H_FUNC_MAX];
struct func_ext_cfg func_ext_config[E1H_FUNC_MAX];
};
......
This diff is collapsed.
......@@ -1774,6 +1774,8 @@
/* [RW 8] event id for llh0 */
#define NIG_REG_LLH0_EVENT_ID 0x10084
#define NIG_REG_LLH0_FUNC_EN 0x160fc
#define NIG_REG_LLH0_FUNC_MEM 0x16180
#define NIG_REG_LLH0_FUNC_MEM_ENABLE 0x16140
#define NIG_REG_LLH0_FUNC_VLAN_ID 0x16100
/* [RW 1] Determine the IP version to look for in
~nig_registers_llh0_dest_ip_0.llh0_dest_ip_0. 0 - IPv6; 1-IPv4 */
......@@ -1797,6 +1799,9 @@
#define NIG_REG_LLH1_ERROR_MASK 0x10090
/* [RW 8] event id for llh1 */
#define NIG_REG_LLH1_EVENT_ID 0x10088
#define NIG_REG_LLH1_FUNC_MEM 0x161c0
#define NIG_REG_LLH1_FUNC_MEM_ENABLE 0x16160
#define NIG_REG_LLH1_FUNC_MEM_SIZE 16
/* [RW 8] init credit counter for port1 in LLH */
#define NIG_REG_LLH1_XCM_INIT_CREDIT 0x10564
#define NIG_REG_LLH1_XCM_MASK 0x10134
......
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