Commit 4aacb7af authored by Michael Chan's avatar Michael Chan Committed by David S. Miller

cnic: Support NIC Partition mode

Add a common function cnic_read_bnx2x_iscsi_mac() to read the iSCSI
MAC address at any specified shared memory location.  In NIC Partition
mode, we need to get the MAC address from the MF_CFG area of shared
memory.
Signed-off-by: default avatarMichael Chan <mchan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5159fdc1
...@@ -4247,10 +4247,36 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev, ...@@ -4247,10 +4247,36 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev,
cp->rx_cons = *cp->rx_cons_ptr; cp->rx_cons = *cp->rx_cons_ptr;
} }
static int cnic_read_bnx2x_iscsi_mac(struct cnic_dev *dev, u32 upper_addr,
u32 lower_addr)
{
u32 val;
u8 mac[6];
val = CNIC_RD(dev, upper_addr);
mac[0] = (u8) (val >> 8);
mac[1] = (u8) val;
val = CNIC_RD(dev, lower_addr);
mac[2] = (u8) (val >> 24);
mac[3] = (u8) (val >> 16);
mac[4] = (u8) (val >> 8);
mac[5] = (u8) val;
if (is_valid_ether_addr(mac)) {
memcpy(dev->mac_addr, mac, 6);
return 0;
} else {
return -EINVAL;
}
}
static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev)
{ {
struct cnic_local *cp = dev->cnic_priv; struct cnic_local *cp = dev->cnic_priv;
u32 base, base2, addr, val; u32 base, base2, addr, addr1, val;
int port = CNIC_PORT(cp); int port = CNIC_PORT(cp);
dev->max_iscsi_conn = 0; dev->max_iscsi_conn = 0;
...@@ -4263,20 +4289,10 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) ...@@ -4263,20 +4289,10 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev)
addr = BNX2X_SHMEM_ADDR(base, addr = BNX2X_SHMEM_ADDR(base,
dev_info.port_hw_config[port].iscsi_mac_upper); dev_info.port_hw_config[port].iscsi_mac_upper);
val = CNIC_RD(dev, addr); addr1 = BNX2X_SHMEM_ADDR(base,
dev->mac_addr[0] = (u8) (val >> 8);
dev->mac_addr[1] = (u8) val;
addr = BNX2X_SHMEM_ADDR(base,
dev_info.port_hw_config[port].iscsi_mac_lower); dev_info.port_hw_config[port].iscsi_mac_lower);
val = CNIC_RD(dev, addr); cnic_read_bnx2x_iscsi_mac(dev, addr, addr1);
dev->mac_addr[2] = (u8) (val >> 24);
dev->mac_addr[3] = (u8) (val >> 16);
dev->mac_addr[4] = (u8) (val >> 8);
dev->mac_addr[5] = (u8) val;
addr = BNX2X_SHMEM_ADDR(base, validity_map[port]); addr = BNX2X_SHMEM_ADDR(base, validity_map[port]);
val = CNIC_RD(dev, addr); val = CNIC_RD(dev, addr);
...@@ -4302,21 +4318,53 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) ...@@ -4302,21 +4318,53 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev)
else else
mf_cfg_addr = base + BNX2X_SHMEM_MF_BLK_OFFSET; mf_cfg_addr = base + BNX2X_SHMEM_MF_BLK_OFFSET;
addr = mf_cfg_addr + if (BNX2X_CHIP_IS_E2(cp->chip_id)) {
offsetof(struct mf_cfg, func_mf_config[func].e1hov_tag); /* Must determine if the MF is SD vs SI mode */
addr = BNX2X_SHMEM_ADDR(base,
dev_info.shared_feature_config.config);
val = CNIC_RD(dev, addr);
if ((val & SHARED_FEAT_CFG_FORCE_SF_MODE_MASK) ==
SHARED_FEAT_CFG_FORCE_SF_MODE_SWITCH_INDEPT) {
int rc;
/* MULTI_FUNCTION_SI mode */
addr = BNX2X_MF_CFG_ADDR(mf_cfg_addr,
func_ext_config[func].func_cfg);
val = CNIC_RD(dev, addr);
if (!(val & MACP_FUNC_CFG_FLAGS_ISCSI_OFFLOAD))
dev->max_iscsi_conn = 0;
addr = BNX2X_MF_CFG_ADDR(mf_cfg_addr,
func_ext_config[func].
iscsi_mac_addr_upper);
addr1 = BNX2X_MF_CFG_ADDR(mf_cfg_addr,
func_ext_config[func].
iscsi_mac_addr_lower);
rc = cnic_read_bnx2x_iscsi_mac(dev, addr,
addr1);
if (rc && func > 1)
dev->max_iscsi_conn = 0;
return;
}
}
addr = BNX2X_MF_CFG_ADDR(mf_cfg_addr,
func_mf_config[func].e1hov_tag);
val = CNIC_RD(dev, addr); val = CNIC_RD(dev, addr);
val &= FUNC_MF_CFG_E1HOV_TAG_MASK; val &= FUNC_MF_CFG_E1HOV_TAG_MASK;
if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) {
addr = mf_cfg_addr + addr = BNX2X_MF_CFG_ADDR(mf_cfg_addr,
offsetof(struct mf_cfg, func_mf_config[func].config);
func_mf_config[func].config);
val = CNIC_RD(dev, addr); val = CNIC_RD(dev, addr);
val &= FUNC_MF_CFG_PROTOCOL_MASK; val &= FUNC_MF_CFG_PROTOCOL_MASK;
if (val != FUNC_MF_CFG_PROTOCOL_ISCSI) if (val != FUNC_MF_CFG_PROTOCOL_ISCSI)
dev->max_iscsi_conn = 0; dev->max_iscsi_conn = 0;
} }
} }
if (!is_valid_ether_addr(dev->mac_addr))
dev->max_iscsi_conn = 0;
} }
static int cnic_start_bnx2x_hw(struct cnic_dev *dev) static int cnic_start_bnx2x_hw(struct cnic_dev *dev)
......
...@@ -422,6 +422,9 @@ struct bnx2x_bd_chain_next { ...@@ -422,6 +422,9 @@ struct bnx2x_bd_chain_next {
(CNIC_RD(dev, BNX2X_SHMEM2_ADDR(base, size)) > \ (CNIC_RD(dev, BNX2X_SHMEM2_ADDR(base, size)) > \
offsetof(struct shmem2_region, field))) offsetof(struct shmem2_region, field)))
#define BNX2X_MF_CFG_ADDR(base, field) \
((base) + offsetof(struct mf_cfg, field))
#define CNIC_PORT(cp) ((cp)->pfid & 1) #define CNIC_PORT(cp) ((cp)->pfid & 1)
#define CNIC_FUNC(cp) ((cp)->func) #define CNIC_FUNC(cp) ((cp)->func)
#define CNIC_PATH(cp) (!BNX2X_CHIP_IS_E2(cp->chip_id) ? 0 :\ #define CNIC_PATH(cp) (!BNX2X_CHIP_IS_E2(cp->chip_id) ? 0 :\
......
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