Skip to content

Commit 02b5242

Browse files
committed
Merge branch 'bnx2x-cnic-bnx2fc-bd-support'
Yuval Mintz says: ==================== bnx2x, cnic, bnx2fc: add support for BD Commit 230d00e ("bnx2x: new Multi-function mode - BD") added support for a new multi-function mode, but it added only the support required by bnx2x for L2 interfaces. This adds the required changes to support the new multi-function mode in the offloaded storage protocols. Dave, Please consider applying this series to `net-next'. Do notice that this involves non-networking driver changes - but sending this as a single series seemed like the best approach as we had to have bnx2x changes to support the new functionality. If this is problematic, please tell us what's the preferred solution here. Changes from previous versions ------------------------------ - From v1 - no actual changes; v1 failed to reach netdev so in order to keep things in line I've termed this one v2. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents ff14702 + 2971ff6 commit 02b5242

File tree

7 files changed

+236
-7
lines changed

7 files changed

+236
-7
lines changed

drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,4 +1386,16 @@ void bnx2x_schedule_sp_rtnl(struct bnx2x*, enum sp_rtnl_flag,
13861386
* @state: OS_DRIVER_STATE_* value reflecting current driver state
13871387
*/
13881388
void bnx2x_set_os_driver_state(struct bnx2x *bp, u32 state);
1389+
1390+
/**
1391+
* bnx2x_nvram_read - reads data from nvram [might sleep]
1392+
*
1393+
* @bp: driver handle
1394+
* @offset: byte offset in nvram
1395+
* @ret_buf: pointer to buffer where data is to be stored
1396+
* @buf_size: Length of 'ret_buf' in bytes
1397+
*/
1398+
int bnx2x_nvram_read(struct bnx2x *bp, u32 offset, u8 *ret_buf,
1399+
int buf_size);
1400+
13891401
#endif /* BNX2X_CMN_H */

drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,8 +1348,8 @@ static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, __be32 *ret_val,
13481348
return rc;
13491349
}
13501350

1351-
static int bnx2x_nvram_read(struct bnx2x *bp, u32 offset, u8 *ret_buf,
1352-
int buf_size)
1351+
int bnx2x_nvram_read(struct bnx2x *bp, u32 offset, u8 *ret_buf,
1352+
int buf_size)
13531353
{
13541354
int rc;
13551355
u32 cmd_flags;

drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2075,6 +2075,25 @@ enum curr_cfg_method_e {
20752075
CURR_CFG_MET_VENDOR_SPEC = 2,/* e.g. Option ROM, NPAR, O/S Cfg Utils */
20762076
};
20772077

2078+
#define FC_NPIV_WWPN_SIZE 8
2079+
#define FC_NPIV_WWNN_SIZE 8
2080+
struct bdn_npiv_settings {
2081+
u8 npiv_wwpn[FC_NPIV_WWPN_SIZE];
2082+
u8 npiv_wwnn[FC_NPIV_WWNN_SIZE];
2083+
};
2084+
2085+
struct bdn_fc_npiv_cfg {
2086+
/* hdr used internally by the MFW */
2087+
u32 hdr;
2088+
u32 num_of_npiv;
2089+
};
2090+
2091+
#define MAX_NUMBER_NPIV 64
2092+
struct bdn_fc_npiv_tbl {
2093+
struct bdn_fc_npiv_cfg fc_npiv_cfg;
2094+
struct bdn_npiv_settings settings[MAX_NUMBER_NPIV];
2095+
};
2096+
20782097
struct mdump_driver_info {
20792098
u32 epoc;
20802099
u32 drv_ver;

drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14653,6 +14653,90 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl)
1465314653
rc = -EINVAL;
1465414654
}
1465514655

14656+
/* For storage-only interfaces, change driver state */
14657+
if (IS_MF_SD_STORAGE_PERSONALITY_ONLY(bp)) {
14658+
switch (ctl->drv_state) {
14659+
case DRV_NOP:
14660+
break;
14661+
case DRV_ACTIVE:
14662+
bnx2x_set_os_driver_state(bp,
14663+
OS_DRIVER_STATE_ACTIVE);
14664+
break;
14665+
case DRV_INACTIVE:
14666+
bnx2x_set_os_driver_state(bp,
14667+
OS_DRIVER_STATE_DISABLED);
14668+
break;
14669+
case DRV_UNLOADED:
14670+
bnx2x_set_os_driver_state(bp,
14671+
OS_DRIVER_STATE_NOT_LOADED);
14672+
break;
14673+
default:
14674+
BNX2X_ERR("Unknown cnic driver state: %d\n", ctl->drv_state);
14675+
}
14676+
}
14677+
14678+
return rc;
14679+
}
14680+
14681+
static int bnx2x_get_fc_npiv(struct net_device *dev,
14682+
struct cnic_fc_npiv_tbl *cnic_tbl)
14683+
{
14684+
struct bnx2x *bp = netdev_priv(dev);
14685+
struct bdn_fc_npiv_tbl *tbl = NULL;
14686+
u32 offset, entries;
14687+
int rc = -EINVAL;
14688+
int i;
14689+
14690+
if (!SHMEM2_HAS(bp, fc_npiv_nvram_tbl_addr[0]))
14691+
goto out;
14692+
14693+
DP(BNX2X_MSG_MCP, "About to read the FC-NPIV table\n");
14694+
14695+
tbl = kmalloc(sizeof(*tbl), GFP_KERNEL);
14696+
if (!tbl) {
14697+
BNX2X_ERR("Failed to allocate fc_npiv table\n");
14698+
goto out;
14699+
}
14700+
14701+
offset = SHMEM2_RD(bp, fc_npiv_nvram_tbl_addr[BP_PORT(bp)]);
14702+
DP(BNX2X_MSG_MCP, "Offset of FC-NPIV in NVRAM: %08x\n", offset);
14703+
14704+
/* Read the table contents from nvram */
14705+
if (bnx2x_nvram_read(bp, offset, (u8 *)tbl, sizeof(*tbl))) {
14706+
BNX2X_ERR("Failed to read FC-NPIV table\n");
14707+
goto out;
14708+
}
14709+
14710+
/* Since bnx2x_nvram_read() returns data in be32, we need to convert
14711+
* the number of entries back to cpu endianness.
14712+
*/
14713+
entries = tbl->fc_npiv_cfg.num_of_npiv;
14714+
entries = (__force u32)be32_to_cpu((__force __be32)entries);
14715+
tbl->fc_npiv_cfg.num_of_npiv = entries;
14716+
14717+
if (!tbl->fc_npiv_cfg.num_of_npiv) {
14718+
DP(BNX2X_MSG_MCP,
14719+
"No FC-NPIV table [valid, simply not present]\n");
14720+
goto out;
14721+
} else if (tbl->fc_npiv_cfg.num_of_npiv > MAX_NUMBER_NPIV) {
14722+
BNX2X_ERR("FC-NPIV table with bad length 0x%08x\n",
14723+
tbl->fc_npiv_cfg.num_of_npiv);
14724+
goto out;
14725+
} else {
14726+
DP(BNX2X_MSG_MCP, "Read 0x%08x entries from NVRAM\n",
14727+
tbl->fc_npiv_cfg.num_of_npiv);
14728+
}
14729+
14730+
/* Copy the data into cnic-provided struct */
14731+
cnic_tbl->count = tbl->fc_npiv_cfg.num_of_npiv;
14732+
for (i = 0; i < cnic_tbl->count; i++) {
14733+
memcpy(cnic_tbl->wwpn[i], tbl->settings[i].npiv_wwpn, 8);
14734+
memcpy(cnic_tbl->wwnn[i], tbl->settings[i].npiv_wwnn, 8);
14735+
}
14736+
14737+
rc = 0;
14738+
out:
14739+
kfree(tbl);
1465614740
return rc;
1465714741
}
1465814742

@@ -14798,6 +14882,7 @@ static struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev)
1479814882
cp->starting_cid = bnx2x_cid_ilt_lines(bp) * ILT_PAGE_CIDS;
1479914883
cp->drv_submit_kwqes_16 = bnx2x_cnic_sp_queue;
1480014884
cp->drv_ctl = bnx2x_drv_ctl;
14885+
cp->drv_get_fc_npiv_tbl = bnx2x_get_fc_npiv;
1480114886
cp->drv_register_cnic = bnx2x_register_cnic;
1480214887
cp->drv_unregister_cnic = bnx2x_unregister_cnic;
1480314888
cp->fcoe_init_cid = BNX2X_FCOE_ETH_CID(bp);

drivers/net/ethernet/broadcom/cnic.c

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ static void cnic_ctx_wr(struct cnic_dev *dev, u32 cid_addr, u32 off, u32 val)
192192
struct drv_ctl_info info;
193193
struct drv_ctl_io *io = &info.data.io;
194194

195+
memset(&info, 0, sizeof(struct drv_ctl_info));
195196
info.cmd = DRV_CTL_CTX_WR_CMD;
196197
io->cid_addr = cid_addr;
197198
io->offset = off;
@@ -206,6 +207,7 @@ static void cnic_ctx_tbl_wr(struct cnic_dev *dev, u32 off, dma_addr_t addr)
206207
struct drv_ctl_info info;
207208
struct drv_ctl_io *io = &info.data.io;
208209

210+
memset(&info, 0, sizeof(struct drv_ctl_info));
209211
info.cmd = DRV_CTL_CTXTBL_WR_CMD;
210212
io->offset = off;
211213
io->dma_addr = addr;
@@ -219,6 +221,7 @@ static void cnic_ring_ctl(struct cnic_dev *dev, u32 cid, u32 cl_id, int start)
219221
struct drv_ctl_info info;
220222
struct drv_ctl_l2_ring *ring = &info.data.ring;
221223

224+
memset(&info, 0, sizeof(struct drv_ctl_info));
222225
if (start)
223226
info.cmd = DRV_CTL_START_L2_CMD;
224227
else
@@ -236,6 +239,7 @@ static void cnic_reg_wr_ind(struct cnic_dev *dev, u32 off, u32 val)
236239
struct drv_ctl_info info;
237240
struct drv_ctl_io *io = &info.data.io;
238241

242+
memset(&info, 0, sizeof(struct drv_ctl_info));
239243
info.cmd = DRV_CTL_IO_WR_CMD;
240244
io->offset = off;
241245
io->data = val;
@@ -249,20 +253,22 @@ static u32 cnic_reg_rd_ind(struct cnic_dev *dev, u32 off)
249253
struct drv_ctl_info info;
250254
struct drv_ctl_io *io = &info.data.io;
251255

256+
memset(&info, 0, sizeof(struct drv_ctl_info));
252257
info.cmd = DRV_CTL_IO_RD_CMD;
253258
io->offset = off;
254259
ethdev->drv_ctl(dev->netdev, &info);
255260
return io->data;
256261
}
257262

258-
static void cnic_ulp_ctl(struct cnic_dev *dev, int ulp_type, bool reg)
263+
static void cnic_ulp_ctl(struct cnic_dev *dev, int ulp_type, bool reg, int state)
259264
{
260265
struct cnic_local *cp = dev->cnic_priv;
261266
struct cnic_eth_dev *ethdev = cp->ethdev;
262267
struct drv_ctl_info info;
263268
struct fcoe_capabilities *fcoe_cap =
264269
&info.data.register_data.fcoe_features;
265270

271+
memset(&info, 0, sizeof(struct drv_ctl_info));
266272
if (reg) {
267273
info.cmd = DRV_CTL_ULP_REGISTER_CMD;
268274
if (ulp_type == CNIC_ULP_FCOE && dev->fcoe_cap)
@@ -272,6 +278,7 @@ static void cnic_ulp_ctl(struct cnic_dev *dev, int ulp_type, bool reg)
272278
}
273279

274280
info.data.ulp_type = ulp_type;
281+
info.drv_state = state;
275282
ethdev->drv_ctl(dev->netdev, &info);
276283
}
277284

@@ -286,6 +293,7 @@ static void cnic_spq_completion(struct cnic_dev *dev, int cmd, u32 count)
286293
struct cnic_eth_dev *ethdev = cp->ethdev;
287294
struct drv_ctl_info info;
288295

296+
memset(&info, 0, sizeof(struct drv_ctl_info));
289297
info.cmd = cmd;
290298
info.data.credit.credit_count = count;
291299
ethdev->drv_ctl(dev->netdev, &info);
@@ -591,7 +599,7 @@ static int cnic_register_device(struct cnic_dev *dev, int ulp_type,
591599

592600
mutex_unlock(&cnic_lock);
593601

594-
cnic_ulp_ctl(dev, ulp_type, true);
602+
cnic_ulp_ctl(dev, ulp_type, true, DRV_ACTIVE);
595603

596604
return 0;
597605

@@ -636,7 +644,10 @@ static int cnic_unregister_device(struct cnic_dev *dev, int ulp_type)
636644
if (test_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[ulp_type]))
637645
netdev_warn(dev->netdev, "Failed waiting for ULP up call to complete\n");
638646

639-
cnic_ulp_ctl(dev, ulp_type, false);
647+
if (test_bit(ULP_F_INIT, &cp->ulp_flags[ulp_type]))
648+
cnic_ulp_ctl(dev, ulp_type, false, DRV_UNLOADED);
649+
else
650+
cnic_ulp_ctl(dev, ulp_type, false, DRV_INACTIVE);
640651

641652
return 0;
642653
}
@@ -4267,6 +4278,7 @@ static void cnic_delete_task(struct work_struct *work)
42674278

42684279
cnic_ulp_stop_one(cp, CNIC_ULP_ISCSI);
42694280

4281+
memset(&info, 0, sizeof(struct drv_ctl_info));
42704282
info.cmd = DRV_CTL_ISCSI_STOPPED_CMD;
42714283
cp->ethdev->drv_ctl(dev->netdev, &info);
42724284
}
@@ -5433,6 +5445,23 @@ static void cnic_free_dev(struct cnic_dev *dev)
54335445
kfree(dev);
54345446
}
54355447

5448+
static int cnic_get_fc_npiv_tbl(struct cnic_dev *dev,
5449+
struct cnic_fc_npiv_tbl *npiv_tbl)
5450+
{
5451+
struct cnic_local *cp = dev->cnic_priv;
5452+
struct bnx2x *bp = netdev_priv(dev->netdev);
5453+
int ret;
5454+
5455+
if (!test_bit(CNIC_F_CNIC_UP, &dev->flags))
5456+
return -EAGAIN; /* bnx2x is down */
5457+
5458+
if (!BNX2X_CHIP_IS_E2_PLUS(bp))
5459+
return -EINVAL;
5460+
5461+
ret = cp->ethdev->drv_get_fc_npiv_tbl(dev->netdev, npiv_tbl);
5462+
return ret;
5463+
}
5464+
54365465
static struct cnic_dev *cnic_alloc_dev(struct net_device *dev,
54375466
struct pci_dev *pdev)
54385467
{
@@ -5451,6 +5480,7 @@ static struct cnic_dev *cnic_alloc_dev(struct net_device *dev,
54515480
cdev->register_device = cnic_register_device;
54525481
cdev->unregister_device = cnic_unregister_device;
54535482
cdev->iscsi_nl_msg_recv = cnic_iscsi_nl_msg_recv;
5483+
cdev->get_fc_npiv_tbl = cnic_get_fc_npiv_tbl;
54545484

54555485
cp = cdev->cnic_priv;
54565486
cp->dev = cdev;

drivers/net/ethernet/broadcom/cnic_if.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515

1616
#include "bnx2x/bnx2x_mfw_req.h"
1717

18-
#define CNIC_MODULE_VERSION "2.5.21"
19-
#define CNIC_MODULE_RELDATE "January 29, 2015"
18+
#define CNIC_MODULE_VERSION "2.5.22"
19+
#define CNIC_MODULE_RELDATE "July 20, 2015"
2020

2121
#define CNIC_ULP_RDMA 0
2222
#define CNIC_ULP_ISCSI 1
@@ -151,6 +151,11 @@ struct drv_ctl_register_data {
151151

152152
struct drv_ctl_info {
153153
int cmd;
154+
int drv_state;
155+
#define DRV_NOP 0
156+
#define DRV_ACTIVE 1
157+
#define DRV_INACTIVE 2
158+
#define DRV_UNLOADED 3
154159
union {
155160
struct drv_ctl_spq_credit credit;
156161
struct drv_ctl_io io;
@@ -161,6 +166,15 @@ struct drv_ctl_info {
161166
} data;
162167
};
163168

169+
#define MAX_NPIV_ENTRIES 64
170+
#define FC_NPIV_WWN_SIZE 8
171+
172+
struct cnic_fc_npiv_tbl {
173+
u8 wwpn[MAX_NPIV_ENTRIES][FC_NPIV_WWN_SIZE];
174+
u8 wwnn[MAX_NPIV_ENTRIES][FC_NPIV_WWN_SIZE];
175+
u32 count;
176+
};
177+
164178
struct cnic_ops {
165179
struct module *cnic_owner;
166180
/* Calls to these functions are protected by RCU. When
@@ -226,6 +240,8 @@ struct cnic_eth_dev {
226240
int (*drv_submit_kwqes_16)(struct net_device *,
227241
struct kwqe_16 *[], u32);
228242
int (*drv_ctl)(struct net_device *, struct drv_ctl_info *);
243+
int (*drv_get_fc_npiv_tbl)(struct net_device *,
244+
struct cnic_fc_npiv_tbl *);
229245
unsigned long reserved1[2];
230246
union drv_info_to_mcp *addr_drv_info_to_mcp;
231247
};
@@ -314,6 +330,7 @@ struct cnic_dev {
314330
struct cnic_dev *(*cm_select_dev)(struct sockaddr_in *, int ulp_type);
315331
int (*iscsi_nl_msg_recv)(struct cnic_dev *dev, u32 msg_type,
316332
char *data, u16 data_size);
333+
int (*get_fc_npiv_tbl)(struct cnic_dev *, struct cnic_fc_npiv_tbl *);
317334
unsigned long flags;
318335
#define CNIC_F_CNIC_UP 1
319336
#define CNIC_F_BNX2_CLASS 3

0 commit comments

Comments
 (0)