Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+66 −18
Original line number Original line Diff line number Diff line
@@ -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)
	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,14 +4318,44 @@ 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;
@@ -4317,6 +4363,8 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev)
				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)
+3 −0
Original line number Original line Diff line number Diff line
@@ -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 :\