Skip to content

Commit

Permalink
Merge branch 'bnx2x-cnic-bnx2fc-bd-support'
Browse files Browse the repository at this point in the history
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 <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Aug 7, 2015
2 parents ff14702 + 2971ff6 commit 02b5242
Show file tree
Hide file tree
Showing 7 changed files with 236 additions and 7 deletions.
12 changes: 12 additions & 0 deletions drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
Original file line number Diff line number Diff line change
Expand Up @@ -1386,4 +1386,16 @@ void bnx2x_schedule_sp_rtnl(struct bnx2x*, enum sp_rtnl_flag,
* @state: OS_DRIVER_STATE_* value reflecting current driver state
*/
void bnx2x_set_os_driver_state(struct bnx2x *bp, u32 state);

/**
* bnx2x_nvram_read - reads data from nvram [might sleep]
*
* @bp: driver handle
* @offset: byte offset in nvram
* @ret_buf: pointer to buffer where data is to be stored
* @buf_size: Length of 'ret_buf' in bytes
*/
int bnx2x_nvram_read(struct bnx2x *bp, u32 offset, u8 *ret_buf,
int buf_size);

#endif /* BNX2X_CMN_H */
4 changes: 2 additions & 2 deletions drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -1348,8 +1348,8 @@ static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, __be32 *ret_val,
return rc;
}

static int bnx2x_nvram_read(struct bnx2x *bp, u32 offset, u8 *ret_buf,
int buf_size)
int bnx2x_nvram_read(struct bnx2x *bp, u32 offset, u8 *ret_buf,
int buf_size)
{
int rc;
u32 cmd_flags;
Expand Down
19 changes: 19 additions & 0 deletions drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -2075,6 +2075,25 @@ enum curr_cfg_method_e {
CURR_CFG_MET_VENDOR_SPEC = 2,/* e.g. Option ROM, NPAR, O/S Cfg Utils */
};

#define FC_NPIV_WWPN_SIZE 8
#define FC_NPIV_WWNN_SIZE 8
struct bdn_npiv_settings {
u8 npiv_wwpn[FC_NPIV_WWPN_SIZE];
u8 npiv_wwnn[FC_NPIV_WWNN_SIZE];
};

struct bdn_fc_npiv_cfg {
/* hdr used internally by the MFW */
u32 hdr;
u32 num_of_npiv;
};

#define MAX_NUMBER_NPIV 64
struct bdn_fc_npiv_tbl {
struct bdn_fc_npiv_cfg fc_npiv_cfg;
struct bdn_npiv_settings settings[MAX_NUMBER_NPIV];
};

struct mdump_driver_info {
u32 epoc;
u32 drv_ver;
Expand Down
85 changes: 85 additions & 0 deletions drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -14653,6 +14653,90 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl)
rc = -EINVAL;
}

/* For storage-only interfaces, change driver state */
if (IS_MF_SD_STORAGE_PERSONALITY_ONLY(bp)) {
switch (ctl->drv_state) {
case DRV_NOP:
break;
case DRV_ACTIVE:
bnx2x_set_os_driver_state(bp,
OS_DRIVER_STATE_ACTIVE);
break;
case DRV_INACTIVE:
bnx2x_set_os_driver_state(bp,
OS_DRIVER_STATE_DISABLED);
break;
case DRV_UNLOADED:
bnx2x_set_os_driver_state(bp,
OS_DRIVER_STATE_NOT_LOADED);
break;
default:
BNX2X_ERR("Unknown cnic driver state: %d\n", ctl->drv_state);
}
}

return rc;
}

static int bnx2x_get_fc_npiv(struct net_device *dev,
struct cnic_fc_npiv_tbl *cnic_tbl)
{
struct bnx2x *bp = netdev_priv(dev);
struct bdn_fc_npiv_tbl *tbl = NULL;
u32 offset, entries;
int rc = -EINVAL;
int i;

if (!SHMEM2_HAS(bp, fc_npiv_nvram_tbl_addr[0]))
goto out;

DP(BNX2X_MSG_MCP, "About to read the FC-NPIV table\n");

tbl = kmalloc(sizeof(*tbl), GFP_KERNEL);
if (!tbl) {
BNX2X_ERR("Failed to allocate fc_npiv table\n");
goto out;
}

offset = SHMEM2_RD(bp, fc_npiv_nvram_tbl_addr[BP_PORT(bp)]);
DP(BNX2X_MSG_MCP, "Offset of FC-NPIV in NVRAM: %08x\n", offset);

/* Read the table contents from nvram */
if (bnx2x_nvram_read(bp, offset, (u8 *)tbl, sizeof(*tbl))) {
BNX2X_ERR("Failed to read FC-NPIV table\n");
goto out;
}

/* Since bnx2x_nvram_read() returns data in be32, we need to convert
* the number of entries back to cpu endianness.
*/
entries = tbl->fc_npiv_cfg.num_of_npiv;
entries = (__force u32)be32_to_cpu((__force __be32)entries);
tbl->fc_npiv_cfg.num_of_npiv = entries;

if (!tbl->fc_npiv_cfg.num_of_npiv) {
DP(BNX2X_MSG_MCP,
"No FC-NPIV table [valid, simply not present]\n");
goto out;
} else if (tbl->fc_npiv_cfg.num_of_npiv > MAX_NUMBER_NPIV) {
BNX2X_ERR("FC-NPIV table with bad length 0x%08x\n",
tbl->fc_npiv_cfg.num_of_npiv);
goto out;
} else {
DP(BNX2X_MSG_MCP, "Read 0x%08x entries from NVRAM\n",
tbl->fc_npiv_cfg.num_of_npiv);
}

/* Copy the data into cnic-provided struct */
cnic_tbl->count = tbl->fc_npiv_cfg.num_of_npiv;
for (i = 0; i < cnic_tbl->count; i++) {
memcpy(cnic_tbl->wwpn[i], tbl->settings[i].npiv_wwpn, 8);
memcpy(cnic_tbl->wwnn[i], tbl->settings[i].npiv_wwnn, 8);
}

rc = 0;
out:
kfree(tbl);
return rc;
}

Expand Down Expand Up @@ -14798,6 +14882,7 @@ static struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev)
cp->starting_cid = bnx2x_cid_ilt_lines(bp) * ILT_PAGE_CIDS;
cp->drv_submit_kwqes_16 = bnx2x_cnic_sp_queue;
cp->drv_ctl = bnx2x_drv_ctl;
cp->drv_get_fc_npiv_tbl = bnx2x_get_fc_npiv;
cp->drv_register_cnic = bnx2x_register_cnic;
cp->drv_unregister_cnic = bnx2x_unregister_cnic;
cp->fcoe_init_cid = BNX2X_FCOE_ETH_CID(bp);
Expand Down
36 changes: 33 additions & 3 deletions drivers/net/ethernet/broadcom/cnic.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ static void cnic_ctx_wr(struct cnic_dev *dev, u32 cid_addr, u32 off, u32 val)
struct drv_ctl_info info;
struct drv_ctl_io *io = &info.data.io;

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

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

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

memset(&info, 0, sizeof(struct drv_ctl_info));
info.cmd = DRV_CTL_IO_WR_CMD;
io->offset = off;
io->data = val;
Expand All @@ -249,20 +253,22 @@ static u32 cnic_reg_rd_ind(struct cnic_dev *dev, u32 off)
struct drv_ctl_info info;
struct drv_ctl_io *io = &info.data.io;

memset(&info, 0, sizeof(struct drv_ctl_info));
info.cmd = DRV_CTL_IO_RD_CMD;
io->offset = off;
ethdev->drv_ctl(dev->netdev, &info);
return io->data;
}

static void cnic_ulp_ctl(struct cnic_dev *dev, int ulp_type, bool reg)
static void cnic_ulp_ctl(struct cnic_dev *dev, int ulp_type, bool reg, int state)
{
struct cnic_local *cp = dev->cnic_priv;
struct cnic_eth_dev *ethdev = cp->ethdev;
struct drv_ctl_info info;
struct fcoe_capabilities *fcoe_cap =
&info.data.register_data.fcoe_features;

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

info.data.ulp_type = ulp_type;
info.drv_state = state;
ethdev->drv_ctl(dev->netdev, &info);
}

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

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

mutex_unlock(&cnic_lock);

cnic_ulp_ctl(dev, ulp_type, true);
cnic_ulp_ctl(dev, ulp_type, true, DRV_ACTIVE);

return 0;

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

cnic_ulp_ctl(dev, ulp_type, false);
if (test_bit(ULP_F_INIT, &cp->ulp_flags[ulp_type]))
cnic_ulp_ctl(dev, ulp_type, false, DRV_UNLOADED);
else
cnic_ulp_ctl(dev, ulp_type, false, DRV_INACTIVE);

return 0;
}
Expand Down Expand Up @@ -4267,6 +4278,7 @@ static void cnic_delete_task(struct work_struct *work)

cnic_ulp_stop_one(cp, CNIC_ULP_ISCSI);

memset(&info, 0, sizeof(struct drv_ctl_info));
info.cmd = DRV_CTL_ISCSI_STOPPED_CMD;
cp->ethdev->drv_ctl(dev->netdev, &info);
}
Expand Down Expand Up @@ -5433,6 +5445,23 @@ static void cnic_free_dev(struct cnic_dev *dev)
kfree(dev);
}

static int cnic_get_fc_npiv_tbl(struct cnic_dev *dev,
struct cnic_fc_npiv_tbl *npiv_tbl)
{
struct cnic_local *cp = dev->cnic_priv;
struct bnx2x *bp = netdev_priv(dev->netdev);
int ret;

if (!test_bit(CNIC_F_CNIC_UP, &dev->flags))
return -EAGAIN; /* bnx2x is down */

if (!BNX2X_CHIP_IS_E2_PLUS(bp))
return -EINVAL;

ret = cp->ethdev->drv_get_fc_npiv_tbl(dev->netdev, npiv_tbl);
return ret;
}

static struct cnic_dev *cnic_alloc_dev(struct net_device *dev,
struct pci_dev *pdev)
{
Expand All @@ -5451,6 +5480,7 @@ static struct cnic_dev *cnic_alloc_dev(struct net_device *dev,
cdev->register_device = cnic_register_device;
cdev->unregister_device = cnic_unregister_device;
cdev->iscsi_nl_msg_recv = cnic_iscsi_nl_msg_recv;
cdev->get_fc_npiv_tbl = cnic_get_fc_npiv_tbl;

cp = cdev->cnic_priv;
cp->dev = cdev;
Expand Down
21 changes: 19 additions & 2 deletions drivers/net/ethernet/broadcom/cnic_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@

#include "bnx2x/bnx2x_mfw_req.h"

#define CNIC_MODULE_VERSION "2.5.21"
#define CNIC_MODULE_RELDATE "January 29, 2015"
#define CNIC_MODULE_VERSION "2.5.22"
#define CNIC_MODULE_RELDATE "July 20, 2015"

#define CNIC_ULP_RDMA 0
#define CNIC_ULP_ISCSI 1
Expand Down Expand Up @@ -151,6 +151,11 @@ struct drv_ctl_register_data {

struct drv_ctl_info {
int cmd;
int drv_state;
#define DRV_NOP 0
#define DRV_ACTIVE 1
#define DRV_INACTIVE 2
#define DRV_UNLOADED 3
union {
struct drv_ctl_spq_credit credit;
struct drv_ctl_io io;
Expand All @@ -161,6 +166,15 @@ struct drv_ctl_info {
} data;
};

#define MAX_NPIV_ENTRIES 64
#define FC_NPIV_WWN_SIZE 8

struct cnic_fc_npiv_tbl {
u8 wwpn[MAX_NPIV_ENTRIES][FC_NPIV_WWN_SIZE];
u8 wwnn[MAX_NPIV_ENTRIES][FC_NPIV_WWN_SIZE];
u32 count;
};

struct cnic_ops {
struct module *cnic_owner;
/* Calls to these functions are protected by RCU. When
Expand Down Expand Up @@ -226,6 +240,8 @@ struct cnic_eth_dev {
int (*drv_submit_kwqes_16)(struct net_device *,
struct kwqe_16 *[], u32);
int (*drv_ctl)(struct net_device *, struct drv_ctl_info *);
int (*drv_get_fc_npiv_tbl)(struct net_device *,
struct cnic_fc_npiv_tbl *);
unsigned long reserved1[2];
union drv_info_to_mcp *addr_drv_info_to_mcp;
};
Expand Down Expand Up @@ -314,6 +330,7 @@ struct cnic_dev {
struct cnic_dev *(*cm_select_dev)(struct sockaddr_in *, int ulp_type);
int (*iscsi_nl_msg_recv)(struct cnic_dev *dev, u32 msg_type,
char *data, u16 data_size);
int (*get_fc_npiv_tbl)(struct cnic_dev *, struct cnic_fc_npiv_tbl *);
unsigned long flags;
#define CNIC_F_CNIC_UP 1
#define CNIC_F_BNX2_CLASS 3
Expand Down
Loading

0 comments on commit 02b5242

Please sign in to comment.