aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cnic.c
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2010-12-23 02:43:01 -0500
committerDavid S. Miller <davem@davemloft.net>2010-12-23 14:44:31 -0500
commit4aacb7afb6afd78efe26427e74fa56a5fc72fad3 (patch)
treed7c73eb50096f589921696699950e7e9e7176ac8 /drivers/net/cnic.c
parent5159fdc1e6cb4000f482faebeeba0be91611276d (diff)
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: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/cnic.c')
-rw-r--r--drivers/net/cnic.c84
1 files changed, 66 insertions, 18 deletions
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index 9bd133d3a5aa..bf4a804e4787 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -4247,10 +4247,36 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev,
4247 cp->rx_cons = *cp->rx_cons_ptr; 4247 cp->rx_cons = *cp->rx_cons_ptr;
4248} 4248}
4249 4249
4250static int cnic_read_bnx2x_iscsi_mac(struct cnic_dev *dev, u32 upper_addr,
4251 u32 lower_addr)
4252{
4253 u32 val;
4254 u8 mac[6];
4255
4256 val = CNIC_RD(dev, upper_addr);
4257
4258 mac[0] = (u8) (val >> 8);
4259 mac[1] = (u8) val;
4260
4261 val = CNIC_RD(dev, lower_addr);
4262
4263 mac[2] = (u8) (val >> 24);
4264 mac[3] = (u8) (val >> 16);
4265 mac[4] = (u8) (val >> 8);
4266 mac[5] = (u8) val;
4267
4268 if (is_valid_ether_addr(mac)) {
4269 memcpy(dev->mac_addr, mac, 6);
4270 return 0;
4271 } else {
4272 return -EINVAL;
4273 }
4274}
4275
4250static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) 4276static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev)
4251{ 4277{
4252 struct cnic_local *cp = dev->cnic_priv; 4278 struct cnic_local *cp = dev->cnic_priv;
4253 u32 base, base2, addr, val; 4279 u32 base, base2, addr, addr1, val;
4254 int port = CNIC_PORT(cp); 4280 int port = CNIC_PORT(cp);
4255 4281
4256 dev->max_iscsi_conn = 0; 4282 dev->max_iscsi_conn = 0;
@@ -4263,20 +4289,10 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev)
4263 addr = BNX2X_SHMEM_ADDR(base, 4289 addr = BNX2X_SHMEM_ADDR(base,
4264 dev_info.port_hw_config[port].iscsi_mac_upper); 4290 dev_info.port_hw_config[port].iscsi_mac_upper);
4265 4291
4266 val = CNIC_RD(dev, addr); 4292 addr1 = BNX2X_SHMEM_ADDR(base,
4267
4268 dev->mac_addr[0] = (u8) (val >> 8);
4269 dev->mac_addr[1] = (u8) val;
4270
4271 addr = BNX2X_SHMEM_ADDR(base,
4272 dev_info.port_hw_config[port].iscsi_mac_lower); 4293 dev_info.port_hw_config[port].iscsi_mac_lower);
4273 4294
4274 val = CNIC_RD(dev, addr); 4295 cnic_read_bnx2x_iscsi_mac(dev, addr, addr1);
4275
4276 dev->mac_addr[2] = (u8) (val >> 24);
4277 dev->mac_addr[3] = (u8) (val >> 16);
4278 dev->mac_addr[4] = (u8) (val >> 8);
4279 dev->mac_addr[5] = (u8) val;
4280 4296
4281 addr = BNX2X_SHMEM_ADDR(base, validity_map[port]); 4297 addr = BNX2X_SHMEM_ADDR(base, validity_map[port]);
4282 val = CNIC_RD(dev, addr); 4298 val = CNIC_RD(dev, addr);
@@ -4302,21 +4318,53 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev)
4302 else 4318 else
4303 mf_cfg_addr = base + BNX2X_SHMEM_MF_BLK_OFFSET; 4319 mf_cfg_addr = base + BNX2X_SHMEM_MF_BLK_OFFSET;
4304 4320
4305 addr = mf_cfg_addr + 4321 if (BNX2X_CHIP_IS_E2(cp->chip_id)) {
4306 offsetof(struct mf_cfg, func_mf_config[func].e1hov_tag); 4322 /* Must determine if the MF is SD vs SI mode */
4323 addr = BNX2X_SHMEM_ADDR(base,
4324 dev_info.shared_feature_config.config);
4325 val = CNIC_RD(dev, addr);
4326 if ((val & SHARED_FEAT_CFG_FORCE_SF_MODE_MASK) ==
4327 SHARED_FEAT_CFG_FORCE_SF_MODE_SWITCH_INDEPT) {
4328 int rc;
4329
4330 /* MULTI_FUNCTION_SI mode */
4331 addr = BNX2X_MF_CFG_ADDR(mf_cfg_addr,
4332 func_ext_config[func].func_cfg);
4333 val = CNIC_RD(dev, addr);
4334 if (!(val & MACP_FUNC_CFG_FLAGS_ISCSI_OFFLOAD))
4335 dev->max_iscsi_conn = 0;
4336
4337 addr = BNX2X_MF_CFG_ADDR(mf_cfg_addr,
4338 func_ext_config[func].
4339 iscsi_mac_addr_upper);
4340 addr1 = BNX2X_MF_CFG_ADDR(mf_cfg_addr,
4341 func_ext_config[func].
4342 iscsi_mac_addr_lower);
4343 rc = cnic_read_bnx2x_iscsi_mac(dev, addr,
4344 addr1);
4345 if (rc && func > 1)
4346 dev->max_iscsi_conn = 0;
4347
4348 return;
4349 }
4350 }
4351
4352 addr = BNX2X_MF_CFG_ADDR(mf_cfg_addr,
4353 func_mf_config[func].e1hov_tag);
4307 4354
4308 val = CNIC_RD(dev, addr); 4355 val = CNIC_RD(dev, addr);
4309 val &= FUNC_MF_CFG_E1HOV_TAG_MASK; 4356 val &= FUNC_MF_CFG_E1HOV_TAG_MASK;
4310 if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { 4357 if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) {
4311 addr = mf_cfg_addr + 4358 addr = BNX2X_MF_CFG_ADDR(mf_cfg_addr,
4312 offsetof(struct mf_cfg, 4359 func_mf_config[func].config);
4313 func_mf_config[func].config);
4314 val = CNIC_RD(dev, addr); 4360 val = CNIC_RD(dev, addr);
4315 val &= FUNC_MF_CFG_PROTOCOL_MASK; 4361 val &= FUNC_MF_CFG_PROTOCOL_MASK;
4316 if (val != FUNC_MF_CFG_PROTOCOL_ISCSI) 4362 if (val != FUNC_MF_CFG_PROTOCOL_ISCSI)
4317 dev->max_iscsi_conn = 0; 4363 dev->max_iscsi_conn = 0;
4318 } 4364 }
4319 } 4365 }
4366 if (!is_valid_ether_addr(dev->mac_addr))
4367 dev->max_iscsi_conn = 0;
4320} 4368}
4321 4369
4322static int cnic_start_bnx2x_hw(struct cnic_dev *dev) 4370static int cnic_start_bnx2x_hw(struct cnic_dev *dev)