Skip to content

Commit

Permalink
qed: Add support for hardware offloaded FCoE.
Browse files Browse the repository at this point in the history
This adds the backbone required for the various HW initalizations
which are necessary for the FCoE driver (qedf) for QLogic FastLinQ
4xxxx line of adapters - FW notification, resource initializations, etc.

Signed-off-by: Arun Easi <arun.easi@cavium.com>
Signed-off-by: Yuval Mintz <yuval.mintz@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Arun Easi authored and David S. Miller committed Feb 19, 2017
1 parent f787d1d commit 1e128c8
Show file tree
Hide file tree
Showing 25 changed files with 3,211 additions and 19 deletions.
3 changes: 3 additions & 0 deletions drivers/net/ethernet/qlogic/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,7 @@ config QED_RDMA
config QED_ISCSI
bool

config QED_FCOE
bool

endif # NET_VENDOR_QLOGIC
1 change: 1 addition & 0 deletions drivers/net/ethernet/qlogic/qed/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ qed-$(CONFIG_QED_SRIOV) += qed_sriov.o qed_vf.o
qed-$(CONFIG_QED_LL2) += qed_ll2.o
qed-$(CONFIG_QED_RDMA) += qed_roce.o
qed-$(CONFIG_QED_ISCSI) += qed_iscsi.o qed_ooo.o
qed-$(CONFIG_QED_FCOE) += qed_fcoe.o
11 changes: 11 additions & 0 deletions drivers/net/ethernet/qlogic/qed/qed.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ extern const struct qed_common_ops qed_common_ops_pass;
#define QED_WFQ_UNIT 100

#define ISCSI_BDQ_ID(_port_id) (_port_id)
#define FCOE_BDQ_ID(_port_id) ((_port_id) + 2)
#define QED_WID_SIZE (1024)
#define QED_PF_DEMS_SIZE (4)

Expand Down Expand Up @@ -167,6 +168,7 @@ struct qed_tunn_update_params {
*/
enum qed_pci_personality {
QED_PCI_ETH,
QED_PCI_FCOE,
QED_PCI_ISCSI,
QED_PCI_ETH_ROCE,
QED_PCI_DEFAULT /* default in shmem */
Expand Down Expand Up @@ -204,6 +206,7 @@ enum QED_FEATURE {
QED_VF,
QED_RDMA_CNQ,
QED_VF_L2_QUE,
QED_FCOE_CQ,
QED_MAX_FEATURES,
};

Expand All @@ -221,6 +224,7 @@ enum QED_PORT_MODE {

enum qed_dev_cap {
QED_DEV_CAP_ETH,
QED_DEV_CAP_FCOE,
QED_DEV_CAP_ISCSI,
QED_DEV_CAP_ROCE,
};
Expand Down Expand Up @@ -255,6 +259,10 @@ struct qed_hw_info {
u32 part_num[4];

unsigned char hw_mac_addr[ETH_ALEN];
u64 node_wwn;
u64 port_wwn;

u16 num_fcoe_conns;

struct qed_igu_info *p_igu_info;

Expand Down Expand Up @@ -410,6 +418,7 @@ struct qed_hwfn {
struct qed_ooo_info *p_ooo_info;
struct qed_rdma_info *p_rdma_info;
struct qed_iscsi_info *p_iscsi_info;
struct qed_fcoe_info *p_fcoe_info;
struct qed_pf_params pf_params;

bool b_rdma_enabled_in_prs;
Expand Down Expand Up @@ -620,11 +629,13 @@ struct qed_dev {

u8 protocol;
#define IS_QED_ETH_IF(cdev) ((cdev)->protocol == QED_PROTOCOL_ETH)
#define IS_QED_FCOE_IF(cdev) ((cdev)->protocol == QED_PROTOCOL_FCOE)

/* Callbacks to protocol driver */
union {
struct qed_common_cb_ops *common;
struct qed_eth_cb_ops *eth;
struct qed_fcoe_cb_ops *fcoe;
struct qed_iscsi_cb_ops *iscsi;
} protocol_ops;
void *ops_cookie;
Expand Down
98 changes: 93 additions & 5 deletions drivers/net/ethernet/qlogic/qed/qed_cxt.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,14 @@ union conn_context {
struct core_conn_context core_ctx;
struct eth_conn_context eth_ctx;
struct iscsi_conn_context iscsi_ctx;
struct fcoe_conn_context fcoe_ctx;
struct roce_conn_context roce_ctx;
};

/* TYPE-0 task context - iSCSI */
/* TYPE-0 task context - iSCSI, FCOE */
union type0_task_context {
struct iscsi_task_context iscsi_ctx;
struct fcoe_task_context fcoe_ctx;
};

/* TYPE-1 task context - ROCE */
Expand Down Expand Up @@ -240,15 +242,22 @@ struct qed_cxt_mngr {
static bool src_proto(enum protocol_type type)
{
return type == PROTOCOLID_ISCSI ||
type == PROTOCOLID_FCOE ||
type == PROTOCOLID_ROCE;
}

static bool tm_cid_proto(enum protocol_type type)
{
return type == PROTOCOLID_ISCSI ||
type == PROTOCOLID_FCOE ||
type == PROTOCOLID_ROCE;
}

static bool tm_tid_proto(enum protocol_type type)
{
return type == PROTOCOLID_FCOE;
}

/* counts the iids for the CDU/CDUC ILT client configuration */
struct qed_cdu_iids {
u32 pf_cids;
Expand Down Expand Up @@ -307,6 +316,22 @@ static void qed_cxt_tm_iids(struct qed_cxt_mngr *p_mngr,
iids->pf_cids += p_cfg->cid_count;
iids->per_vf_cids += p_cfg->cids_per_vf;
}

if (tm_tid_proto(i)) {
struct qed_tid_seg *segs = p_cfg->tid_seg;

/* for each segment there is at most one
* protocol for which count is not 0.
*/
for (j = 0; j < NUM_TASK_PF_SEGMENTS; j++)
iids->pf_tids[j] += segs[j].count;

/* The last array elelment is for the VFs. As for PF
* segments there can be only one protocol for
* which this value is not 0.
*/
iids->per_vf_tids += segs[NUM_TASK_PF_SEGMENTS].count;
}
}

iids->pf_cids = roundup(iids->pf_cids, TM_ALIGN);
Expand Down Expand Up @@ -1694,9 +1719,42 @@ static void qed_tm_init_pf(struct qed_hwfn *p_hwfn)
/* @@@TBD how to enable the scan for the VFs */
}

static void qed_prs_init_common(struct qed_hwfn *p_hwfn)
{
if ((p_hwfn->hw_info.personality == QED_PCI_FCOE) &&
p_hwfn->pf_params.fcoe_pf_params.is_target)
STORE_RT_REG(p_hwfn,
PRS_REG_SEARCH_RESP_INITIATOR_TYPE_RT_OFFSET, 0);
}

static void qed_prs_init_pf(struct qed_hwfn *p_hwfn)
{
struct qed_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
struct qed_conn_type_cfg *p_fcoe;
struct qed_tid_seg *p_tid;

p_fcoe = &p_mngr->conn_cfg[PROTOCOLID_FCOE];

/* If FCoE is active set the MAX OX_ID (tid) in the Parser */
if (!p_fcoe->cid_count)
return;

p_tid = &p_fcoe->tid_seg[QED_CXT_FCOE_TID_SEG];
if (p_hwfn->pf_params.fcoe_pf_params.is_target) {
STORE_RT_REG_AGG(p_hwfn,
PRS_REG_TASK_ID_MAX_TARGET_PF_RT_OFFSET,
p_tid->count);
} else {
STORE_RT_REG_AGG(p_hwfn,
PRS_REG_TASK_ID_MAX_INITIATOR_PF_RT_OFFSET,
p_tid->count);
}
}

void qed_cxt_hw_init_common(struct qed_hwfn *p_hwfn)
{
qed_cdu_init_common(p_hwfn);
qed_prs_init_common(p_hwfn);
}

void qed_cxt_hw_init_pf(struct qed_hwfn *p_hwfn)
Expand All @@ -1708,6 +1766,7 @@ void qed_cxt_hw_init_pf(struct qed_hwfn *p_hwfn)
qed_ilt_init_pf(p_hwfn);
qed_src_init_pf(p_hwfn);
qed_tm_init_pf(p_hwfn);
qed_prs_init_pf(p_hwfn);
}

int qed_cxt_acquire_cid(struct qed_hwfn *p_hwfn,
Expand Down Expand Up @@ -1885,6 +1944,27 @@ int qed_cxt_set_pf_params(struct qed_hwfn *p_hwfn)
p_params->num_cons, 1);
break;
}
case QED_PCI_FCOE:
{
struct qed_fcoe_pf_params *p_params;

p_params = &p_hwfn->pf_params.fcoe_pf_params;

if (p_params->num_cons && p_params->num_tasks) {
qed_cxt_set_proto_cid_count(p_hwfn,
PROTOCOLID_FCOE,
p_params->num_cons,
0);

qed_cxt_set_proto_tid_count(p_hwfn, PROTOCOLID_FCOE,
QED_CXT_FCOE_TID_SEG, 0,
p_params->num_tasks, true);
} else {
DP_INFO(p_hwfn->cdev,
"Fcoe personality used without setting params!\n");
}
break;
}
case QED_PCI_ISCSI:
{
struct qed_iscsi_pf_params *p_params;
Expand Down Expand Up @@ -1927,6 +2007,10 @@ int qed_cxt_get_tid_mem_info(struct qed_hwfn *p_hwfn,

/* Verify the personality */
switch (p_hwfn->hw_info.personality) {
case QED_PCI_FCOE:
proto = PROTOCOLID_FCOE;
seg = QED_CXT_FCOE_TID_SEG;
break;
case QED_PCI_ISCSI:
proto = PROTOCOLID_ISCSI;
seg = QED_CXT_ISCSI_TID_SEG;
Expand Down Expand Up @@ -2215,15 +2299,19 @@ int qed_cxt_get_task_ctx(struct qed_hwfn *p_hwfn,
{
struct qed_cxt_mngr *p_mngr = p_hwfn->p_cxt_mngr;
struct qed_ilt_client_cfg *p_cli;
struct qed_ilt_cli_blk *p_seg;
struct qed_tid_seg *p_seg_info;
u32 proto, seg;
u32 total_lines;
u32 tid_size, ilt_idx;
struct qed_ilt_cli_blk *p_seg;
u32 num_tids_per_block;
u32 tid_size, ilt_idx;
u32 total_lines;
u32 proto, seg;

/* Verify the personality */
switch (p_hwfn->hw_info.personality) {
case QED_PCI_FCOE:
proto = PROTOCOLID_FCOE;
seg = QED_CXT_FCOE_TID_SEG;
break;
case QED_PCI_ISCSI:
proto = PROTOCOLID_ISCSI;
seg = QED_CXT_ISCSI_TID_SEG;
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/qlogic/qed/qed_cxt.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ int qed_cxt_get_tid_mem_info(struct qed_hwfn *p_hwfn,

#define QED_CXT_ISCSI_TID_SEG PROTOCOLID_ISCSI
#define QED_CXT_ROCE_TID_SEG PROTOCOLID_ROCE
#define QED_CXT_FCOE_TID_SEG PROTOCOLID_FCOE
enum qed_cxt_elem_type {
QED_ELEM_CXT,
QED_ELEM_SRQ,
Expand Down Expand Up @@ -204,4 +205,6 @@ int qed_cxt_free_proto_ilt(struct qed_hwfn *p_hwfn, enum protocol_type proto);

#define QED_CTX_WORKING_MEM 0
#define QED_CTX_FL_MEM 1
int qed_cxt_get_task_ctx(struct qed_hwfn *p_hwfn,
u32 tid, u8 ctx_type, void **task_ctx);
#endif
13 changes: 11 additions & 2 deletions drivers/net/ethernet/qlogic/qed/qed_dcbx.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,6 @@ qed_dcbx_copy_mib(struct qed_hwfn *p_hwfn,
return rc;
}

#ifdef CONFIG_DCB
static void
qed_dcbx_get_priority_info(struct qed_hwfn *p_hwfn,
struct qed_dcbx_app_prio *p_prio,
Expand Down Expand Up @@ -749,7 +748,6 @@ qed_dcbx_get_params(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,

return 0;
}
#endif

static int
qed_dcbx_read_local_lldp_mib(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
Expand Down Expand Up @@ -864,6 +862,15 @@ static int qed_dcbx_read_mib(struct qed_hwfn *p_hwfn,
return rc;
}

void qed_dcbx_aen(struct qed_hwfn *hwfn, u32 mib_type)
{
struct qed_common_cb_ops *op = hwfn->cdev->protocol_ops.common;
void *cookie = hwfn->cdev->ops_cookie;

if (cookie && op->dcbx_aen)
op->dcbx_aen(cookie, &hwfn->p_dcbx_info->get, mib_type);
}

/* Read updated MIB.
* Reconfigure QM and invoke PF update ramrod command if operational MIB
* change is detected.
Expand All @@ -890,6 +897,8 @@ qed_dcbx_mib_update_event(struct qed_hwfn *p_hwfn,
qed_sp_pf_update(p_hwfn);
}
}
qed_dcbx_get_params(p_hwfn, p_ptt, &p_hwfn->p_dcbx_info->get, type);
qed_dcbx_aen(p_hwfn, type);

return rc;
}
Expand Down
5 changes: 1 addition & 4 deletions drivers/net/ethernet/qlogic/qed/qed_dcbx.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ struct qed_dcbx_app_data {
u8 tc; /* Traffic Class */
};

#ifdef CONFIG_DCB
#define QED_DCBX_VERSION_DISABLED 0
#define QED_DCBX_VERSION_IEEE 1
#define QED_DCBX_VERSION_CEE 2
Expand All @@ -73,7 +72,6 @@ struct qed_dcbx_set {
struct qed_dcbx_admin_params config;
u32 ver_num;
};
#endif

struct qed_dcbx_results {
bool dcbx_enabled;
Expand All @@ -97,9 +95,8 @@ struct qed_dcbx_info {
struct qed_dcbx_results results;
struct dcbx_mib operational;
struct dcbx_mib remote;
#ifdef CONFIG_DCB
struct qed_dcbx_set set;
#endif
struct qed_dcbx_get get;
u8 dcbx_cap;
};

Expand Down
Loading

0 comments on commit 1e128c8

Please sign in to comment.