Merge branch 'qed-Improve-performance-on-100G-link-for-offload-protocols'

Michal Kalderon says:

====================
qed*: Improve performance on 100G link for offload protocols

This patch series modifies the current implementation of PF selection.
The refactoring of the llh code enables setting additional filters
(mac / protocol) per PF, and improves performance for offload protocols
(RoCE, iWARP, iSCSI, fcoe) on 100G link (was capped at 90G per single
PF).

Improved performance on 100G link is achieved by configuring engine
affinty to each PF.
The engine affinity is read from the Management FW and hw is configured accordingly.
A new hw resource called PPFID is exposed and an API is introduced to utilize
it. This additional resource enables setting the affinity of a PF and providing
more classification rules per PF.
qedr,qedi,qedf are also modified as part of the series. Without the
changes functionality is broken.

v1 --> v2
---------
- Remove iWARP module parameter. Instead use devlink param infrastructure
  for setting the iwarp_cmt mode. Additional patch added to the series for
  adding the devlink support.

- Fix kbuild test robot warning on qed_llh_filter initialization.

- Remove comments inside function calls
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2019-05-26 13:04:12 -07:00
commit 9b3c520e96
28 changed files with 1812 additions and 624 deletions

View file

@ -312,7 +312,8 @@ static void qedr_free_mem_sb(struct qedr_dev *dev,
struct qed_sb_info *sb_info, int sb_id)
{
if (sb_info->sb_virt) {
dev->ops->common->sb_release(dev->cdev, sb_info, sb_id);
dev->ops->common->sb_release(dev->cdev, sb_info, sb_id,
QED_SB_TYPE_CNQ);
dma_free_coherent(&dev->pdev->dev, sizeof(*sb_info->sb_virt),
(void *)sb_info->sb_virt, sb_info->sb_phys);
}
@ -504,11 +505,13 @@ static irqreturn_t qedr_irq_handler(int irq, void *handle)
static void qedr_sync_free_irqs(struct qedr_dev *dev)
{
u32 vector;
u16 idx;
int i;
for (i = 0; i < dev->int_info.used_cnt; i++) {
if (dev->int_info.msix_cnt) {
vector = dev->int_info.msix[i * dev->num_hwfns].vector;
idx = i * dev->num_hwfns + dev->affin_hwfn_idx;
vector = dev->int_info.msix[idx].vector;
synchronize_irq(vector);
free_irq(vector, &dev->cnq_array[i]);
}
@ -520,6 +523,7 @@ static void qedr_sync_free_irqs(struct qedr_dev *dev)
static int qedr_req_msix_irqs(struct qedr_dev *dev)
{
int i, rc = 0;
u16 idx;
if (dev->num_cnq > dev->int_info.msix_cnt) {
DP_ERR(dev,
@ -529,7 +533,8 @@ static int qedr_req_msix_irqs(struct qedr_dev *dev)
}
for (i = 0; i < dev->num_cnq; i++) {
rc = request_irq(dev->int_info.msix[i * dev->num_hwfns].vector,
idx = i * dev->num_hwfns + dev->affin_hwfn_idx;
rc = request_irq(dev->int_info.msix[idx].vector,
qedr_irq_handler, 0, dev->cnq_array[i].name,
&dev->cnq_array[i]);
if (rc) {
@ -866,6 +871,16 @@ static struct qedr_dev *qedr_add(struct qed_dev *cdev, struct pci_dev *pdev,
dev->user_dpm_enabled = dev_info.user_dpm_enabled;
dev->rdma_type = dev_info.rdma_type;
dev->num_hwfns = dev_info.common.num_hwfns;
if (IS_IWARP(dev) && QEDR_IS_CMT(dev)) {
rc = dev->ops->iwarp_set_engine_affin(cdev, false);
if (rc) {
DP_ERR(dev, "iWARP is disabled over a 100g device Enabling it may impact L2 performance. To enable it run devlink dev param set <dev> name iwarp_cmt value true cmode runtime\n");
goto init_err;
}
}
dev->affin_hwfn_idx = dev->ops->common->get_affin_hwfn_idx(cdev);
dev->rdma_ctx = dev->ops->rdma_get_rdma_ctx(cdev);
dev->num_cnq = dev->ops->rdma_get_min_cnq_msix(cdev);
@ -926,6 +941,10 @@ static void qedr_remove(struct qedr_dev *dev)
qedr_stop_hw(dev);
qedr_sync_free_irqs(dev);
qedr_free_resources(dev);
if (IS_IWARP(dev) && QEDR_IS_CMT(dev))
dev->ops->iwarp_set_engine_affin(dev->cdev, true);
ib_dealloc_device(&dev->ibdev);
}

View file

@ -157,6 +157,8 @@ struct qedr_dev {
u32 dp_module;
u8 dp_level;
u8 num_hwfns;
#define QEDR_IS_CMT(dev) ((dev)->num_hwfns > 1)
u8 affin_hwfn_idx;
u8 gsi_ll2_handle;
uint wq_multiplier;

View file

@ -140,6 +140,7 @@ struct qed_cxt_mngr;
struct qed_sb_sp_info;
struct qed_ll2_info;
struct qed_mcp_info;
struct qed_llh_info;
struct qed_rt_data {
u32 *init_val;
@ -741,6 +742,7 @@ struct qed_dev {
#define QED_DEV_ID_MASK 0xff00
#define QED_DEV_ID_MASK_BB 0x1600
#define QED_DEV_ID_MASK_AH 0x8000
#define QED_IS_E4(dev) (QED_IS_BB(dev) || QED_IS_AH(dev))
u16 chip_num;
#define CHIP_NUM_MASK 0xffff
@ -801,6 +803,11 @@ struct qed_dev {
u8 num_hwfns;
struct qed_hwfn hwfns[MAX_HWFNS_PER_DEVICE];
/* Engine affinity */
u8 l2_affin_hint;
u8 fir_affin;
u8 iwarp_affin;
/* SRIOV */
struct qed_hw_sriov_info *p_iov_info;
#define IS_QED_SRIOV(cdev) (!!(cdev)->p_iov_info)
@ -815,6 +822,10 @@ struct qed_dev {
/* Recovery */
bool recov_in_prog;
/* LLH info */
u8 ppfid_bitmap;
struct qed_llh_info *p_llh_info;
/* Linux specific here */
struct qede_dev *edev;
struct pci_dev *pdev;
@ -852,6 +863,9 @@ struct qed_dev {
u32 rdma_max_inline;
u32 rdma_max_srq_sge;
u16 tunn_feature_mask;
struct devlink *dl;
bool iwarp_cmt;
};
#define NUM_OF_VFS(dev) (QED_IS_BB(dev) ? MAX_NUM_VFS_BB \
@ -904,6 +918,14 @@ void qed_set_fw_mac_addr(__le16 *fw_msb,
__le16 *fw_mid, __le16 *fw_lsb, u8 *mac);
#define QED_LEADING_HWFN(dev) (&dev->hwfns[0])
#define QED_IS_CMT(dev) ((dev)->num_hwfns > 1)
/* Macros for getting the engine-affinitized hwfn (FIR: fcoe,iscsi,roce) */
#define QED_FIR_AFFIN_HWFN(dev) (&(dev)->hwfns[dev->fir_affin])
#define QED_IWARP_AFFIN_HWFN(dev) (&(dev)->hwfns[dev->iwarp_affin])
#define QED_AFFIN_HWFN(dev) \
(QED_IS_IWARP_PERSONALITY(QED_LEADING_HWFN(dev)) ? \
QED_IWARP_AFFIN_HWFN(dev) : QED_FIR_AFFIN_HWFN(dev))
#define QED_AFFIN_HWFN_IDX(dev) (IS_LEAD_HWFN(QED_AFFIN_HWFN(dev)) ? 0 : 1)
/* Flags for indication of required queues */
#define PQ_FLAGS_RLS (BIT(0))
@ -923,8 +945,6 @@ u16 qed_get_cm_pq_idx_vf(struct qed_hwfn *p_hwfn, u16 vf);
u16 qed_get_cm_pq_idx_ofld_mtc(struct qed_hwfn *p_hwfn, u8 tc);
u16 qed_get_cm_pq_idx_llt_mtc(struct qed_hwfn *p_hwfn, u8 tc);
#define QED_LEADING_HWFN(dev) (&dev->hwfns[0])
/* doorbell recovery mechanism */
void qed_db_recovery_dp(struct qed_hwfn *p_hwfn);
void qed_db_recovery_execute(struct qed_hwfn *p_hwfn);

View file

@ -2351,7 +2351,8 @@ qed_cxt_dynamic_ilt_alloc(struct qed_hwfn *p_hwfn,
/* Write via DMAE since the PSWRQ2_REG_ILT_MEMORY line is a wide-bus */
qed_dmae_host2grc(p_hwfn, p_ptt, (u64) (uintptr_t)&ilt_hw_entry,
reg_offset, sizeof(ilt_hw_entry) / sizeof(u32), 0);
reg_offset, sizeof(ilt_hw_entry) / sizeof(u32),
NULL);
if (elem_type == QED_ELEM_CXT) {
u32 last_cid_allocated = (1 + (iid / elems_per_p)) *
@ -2457,7 +2458,7 @@ qed_cxt_free_ilt_range(struct qed_hwfn *p_hwfn,
(u64) (uintptr_t) &ilt_hw_entry,
reg_offset,
sizeof(ilt_hw_entry) / sizeof(u32),
0);
NULL);
}
qed_ptt_release(p_hwfn, p_ptt);

View file

@ -2537,7 +2537,7 @@ static u32 qed_grc_dump_addr_range(struct qed_hwfn *p_hwfn,
(len >= s_platform_defs[dev_data->platform_id].dmae_thresh ||
wide_bus)) {
if (!qed_dmae_grc2host(p_hwfn, p_ptt, DWORDS_TO_BYTES(addr),
(u64)(uintptr_t)(dump_buf), len, 0))
(u64)(uintptr_t)(dump_buf), len, NULL))
return len;
dev_data->use_dmae = 0;
DP_VERBOSE(p_hwfn,

File diff suppressed because it is too large Load diff

View file

@ -241,11 +241,17 @@ enum qed_dmae_address_type_t {
#define QED_DMAE_FLAG_VF_SRC 0x00000002
#define QED_DMAE_FLAG_VF_DST 0x00000004
#define QED_DMAE_FLAG_COMPLETION_DST 0x00000008
#define QED_DMAE_FLAG_PORT 0x00000010
#define QED_DMAE_FLAG_PF_SRC 0x00000020
#define QED_DMAE_FLAG_PF_DST 0x00000040
struct qed_dmae_params {
u32 flags; /* consists of QED_DMAE_FLAG_* values */
u8 src_vfid;
u8 dst_vfid;
u8 port_id;
u8 src_pfid;
u8 dst_pfid;
};
/**
@ -257,7 +263,7 @@ struct qed_dmae_params {
* @param source_addr
* @param grc_addr (dmae_data_offset)
* @param size_in_dwords
* @param flags (one of the flags defined above)
* @param p_params (default parameters will be used in case of NULL)
*/
int
qed_dmae_host2grc(struct qed_hwfn *p_hwfn,
@ -265,7 +271,7 @@ qed_dmae_host2grc(struct qed_hwfn *p_hwfn,
u64 source_addr,
u32 grc_addr,
u32 size_in_dwords,
u32 flags);
struct qed_dmae_params *p_params);
/**
* @brief qed_dmae_grc2host - Read data from dmae data offset
@ -275,11 +281,11 @@ qed_dmae_host2grc(struct qed_hwfn *p_hwfn,
* @param grc_addr (dmae_data_offset)
* @param dest_addr
* @param size_in_dwords
* @param flags - one of the flags defined above
* @param p_params (default parameters will be used in case of NULL)
*/
int qed_dmae_grc2host(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
u32 grc_addr, dma_addr_t dest_addr, u32 size_in_dwords,
u32 flags);
struct qed_dmae_params *p_params);
/**
* @brief qed_dmae_host2host - copy data from to source address
@ -290,7 +296,7 @@ int qed_dmae_grc2host(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
* @param source_addr
* @param dest_addr
* @param size_in_dwords
* @param params
* @param p_params (default parameters will be used in case of NULL)
*/
int qed_dmae_host2host(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
@ -368,26 +374,66 @@ int qed_fw_rss_eng(struct qed_hwfn *p_hwfn,
u8 *dst_id);
/**
* @brief qed_llh_add_mac_filter - configures a MAC filter in llh
* @brief qed_llh_get_num_ppfid - Return the allocated number of LLH filter
* banks that are allocated to the PF.
*
* @param p_hwfn
* @param p_ptt
* @param p_filter - MAC to add
* @param cdev
*
* @return u8 - Number of LLH filter banks
*/
int qed_llh_add_mac_filter(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, u8 *p_filter);
u8 qed_llh_get_num_ppfid(struct qed_dev *cdev);
enum qed_eng {
QED_ENG0,
QED_ENG1,
QED_BOTH_ENG,
};
/**
* @brief qed_llh_remove_mac_filter - removes a MAC filter from llh
* @brief qed_llh_set_ppfid_affinity - Set the engine affinity for the given
* LLH filter bank.
*
* @param cdev
* @param ppfid - relative within the allocated ppfids ('0' is the default one).
* @param eng
*
* @return int
*/
int qed_llh_set_ppfid_affinity(struct qed_dev *cdev,
u8 ppfid, enum qed_eng eng);
/**
* @brief qed_llh_set_roce_affinity - Set the RoCE engine affinity
*
* @param cdev
* @param eng
*
* @return int
*/
int qed_llh_set_roce_affinity(struct qed_dev *cdev, enum qed_eng eng);
/**
* @brief qed_llh_add_mac_filter - Add a LLH MAC filter into the given filter
* bank.
*
* @param cdev
* @param ppfid - relative within the allocated ppfids ('0' is the default one).
* @param mac_addr - MAC to add
*/
int qed_llh_add_mac_filter(struct qed_dev *cdev,
u8 ppfid, u8 mac_addr[ETH_ALEN]);
/**
* @brief qed_llh_remove_mac_filter - Remove a LLH MAC filter from the given
* filter bank.
*
* @param p_hwfn
* @param p_ptt
* @param p_filter - MAC to remove
*/
void qed_llh_remove_mac_filter(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, u8 *p_filter);
void qed_llh_remove_mac_filter(struct qed_dev *cdev,
u8 ppfid, u8 mac_addr[ETH_ALEN]);
enum qed_llh_port_filter_type_t {
enum qed_llh_prot_filter_type_t {
QED_LLH_FILTER_ETHERTYPE,
QED_LLH_FILTER_TCP_SRC_PORT,
QED_LLH_FILTER_TCP_DEST_PORT,
@ -398,36 +444,37 @@ enum qed_llh_port_filter_type_t {
};
/**
* @brief qed_llh_add_protocol_filter - configures a protocol filter in llh
* @brief qed_llh_add_protocol_filter - Add a LLH protocol filter into the
* given filter bank.
*
* @param p_hwfn
* @param p_ptt
* @param cdev
* @param ppfid - relative within the allocated ppfids ('0' is the default one).
* @param type - type of filters and comparing
* @param source_port_or_eth_type - source port or ethertype to add
* @param dest_port - destination port to add
* @param type - type of filters and comparing
*/
int
qed_llh_add_protocol_filter(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
u16 source_port_or_eth_type,
u16 dest_port,
enum qed_llh_port_filter_type_t type);
qed_llh_add_protocol_filter(struct qed_dev *cdev,
u8 ppfid,
enum qed_llh_prot_filter_type_t type,
u16 source_port_or_eth_type, u16 dest_port);
/**
* @brief qed_llh_remove_protocol_filter - remove a protocol filter in llh
* @brief qed_llh_remove_protocol_filter - Remove a LLH protocol filter from
* the given filter bank.
*
* @param p_hwfn
* @param p_ptt
* @param cdev
* @param ppfid - relative within the allocated ppfids ('0' is the default one).
* @param type - type of filters and comparing
* @param source_port_or_eth_type - source port or ethertype to add
* @param dest_port - destination port to add
* @param type - type of filters and comparing
*/
void
qed_llh_remove_protocol_filter(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
u16 source_port_or_eth_type,
u16 dest_port,
enum qed_llh_port_filter_type_t type);
qed_llh_remove_protocol_filter(struct qed_dev *cdev,
u8 ppfid,
enum qed_llh_prot_filter_type_t type,
u16 source_port_or_eth_type, u16 dest_port);
/**
* *@brief Cleanup of previous driver remains prior to load

View file

@ -745,7 +745,7 @@ struct qed_hash_fcoe_con {
static int qed_fill_fcoe_dev_info(struct qed_dev *cdev,
struct qed_dev_fcoe_info *info)
{
struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
struct qed_hwfn *hwfn = QED_AFFIN_HWFN(cdev);
int rc;
memset(info, 0, sizeof(*info));
@ -806,15 +806,15 @@ static int qed_fcoe_stop(struct qed_dev *cdev)
return -EINVAL;
}
p_ptt = qed_ptt_acquire(QED_LEADING_HWFN(cdev));
p_ptt = qed_ptt_acquire(QED_AFFIN_HWFN(cdev));
if (!p_ptt)
return -EAGAIN;
/* Stop the fcoe */
rc = qed_sp_fcoe_func_stop(QED_LEADING_HWFN(cdev), p_ptt,
rc = qed_sp_fcoe_func_stop(QED_AFFIN_HWFN(cdev), p_ptt,
QED_SPQ_MODE_EBLOCK, NULL);
cdev->flags &= ~QED_FLAG_STORAGE_STARTED;
qed_ptt_release(QED_LEADING_HWFN(cdev), p_ptt);
qed_ptt_release(QED_AFFIN_HWFN(cdev), p_ptt);
return rc;
}
@ -828,8 +828,8 @@ static int qed_fcoe_start(struct qed_dev *cdev, struct qed_fcoe_tid *tasks)
return 0;
}
rc = qed_sp_fcoe_func_start(QED_LEADING_HWFN(cdev),
QED_SPQ_MODE_EBLOCK, NULL);
rc = qed_sp_fcoe_func_start(QED_AFFIN_HWFN(cdev), QED_SPQ_MODE_EBLOCK,
NULL);
if (rc) {
DP_NOTICE(cdev, "Failed to start fcoe\n");
return rc;
@ -849,7 +849,7 @@ static int qed_fcoe_start(struct qed_dev *cdev, struct qed_fcoe_tid *tasks)
return -ENOMEM;
}
rc = qed_cxt_get_tid_mem_info(QED_LEADING_HWFN(cdev), tid_info);
rc = qed_cxt_get_tid_mem_info(QED_AFFIN_HWFN(cdev), tid_info);
if (rc) {
DP_NOTICE(cdev, "Failed to gather task information\n");
qed_fcoe_stop(cdev);
@ -884,7 +884,7 @@ static int qed_fcoe_acquire_conn(struct qed_dev *cdev,
}
/* Acquire the connection */
rc = qed_fcoe_acquire_connection(QED_LEADING_HWFN(cdev), NULL,
rc = qed_fcoe_acquire_connection(QED_AFFIN_HWFN(cdev), NULL,
&hash_con->con);
if (rc) {
DP_NOTICE(cdev, "Failed to acquire Connection\n");
@ -898,7 +898,7 @@ static int qed_fcoe_acquire_conn(struct qed_dev *cdev,
hash_add(cdev->connections, &hash_con->node, *handle);
if (p_doorbell)
*p_doorbell = qed_fcoe_get_db_addr(QED_LEADING_HWFN(cdev),
*p_doorbell = qed_fcoe_get_db_addr(QED_AFFIN_HWFN(cdev),
*handle);
return 0;
@ -916,7 +916,7 @@ static int qed_fcoe_release_conn(struct qed_dev *cdev, u32 handle)
}
hlist_del(&hash_con->node);
qed_fcoe_release_connection(QED_LEADING_HWFN(cdev), hash_con->con);
qed_fcoe_release_connection(QED_AFFIN_HWFN(cdev), hash_con->con);
kfree(hash_con);
return 0;
@ -971,7 +971,7 @@ static int qed_fcoe_offload_conn(struct qed_dev *cdev,
con->d_id.addr_mid = conn_info->d_id.addr_mid;
con->d_id.addr_lo = conn_info->d_id.addr_lo;
return qed_sp_fcoe_conn_offload(QED_LEADING_HWFN(cdev), con,
return qed_sp_fcoe_conn_offload(QED_AFFIN_HWFN(cdev), con,
QED_SPQ_MODE_EBLOCK, NULL);
}
@ -992,13 +992,13 @@ static int qed_fcoe_destroy_conn(struct qed_dev *cdev,
con = hash_con->con;
con->terminate_params = terminate_params;
return qed_sp_fcoe_conn_destroy(QED_LEADING_HWFN(cdev), con,
return qed_sp_fcoe_conn_destroy(QED_AFFIN_HWFN(cdev), con,
QED_SPQ_MODE_EBLOCK, NULL);
}
static int qed_fcoe_stats(struct qed_dev *cdev, struct qed_fcoe_stats *stats)
{
return qed_fcoe_get_stats(QED_LEADING_HWFN(cdev), stats);
return qed_fcoe_get_stats(QED_AFFIN_HWFN(cdev), stats);
}
void qed_get_protocol_stats_fcoe(struct qed_dev *cdev,

View file

@ -12614,6 +12614,8 @@ struct public_drv_mb {
#define DRV_MSG_CODE_SET_LED_MODE 0x00200000
#define DRV_MSG_CODE_RESOURCE_CMD 0x00230000
#define DRV_MSG_CODE_GET_TLV_DONE 0x002f0000
#define DRV_MSG_CODE_GET_ENGINE_CONFIG 0x00370000
#define DRV_MSG_CODE_GET_PPFID_BITMAP 0x43000000
#define RESOURCE_CMD_REQ_RESC_MASK 0x0000001F
#define RESOURCE_CMD_REQ_RESC_SHIFT 0
@ -12802,6 +12804,18 @@ struct public_drv_mb {
#define FW_MB_PARAM_LOAD_DONE_DID_EFUSE_ERROR (1 << 0)
#define FW_MB_PARAM_ENG_CFG_FIR_AFFIN_VALID_MASK 0x00000001
#define FW_MB_PARAM_ENG_CFG_FIR_AFFIN_VALID_SHIFT 0
#define FW_MB_PARAM_ENG_CFG_FIR_AFFIN_VALUE_MASK 0x00000002
#define FW_MB_PARAM_ENG_CFG_FIR_AFFIN_VALUE_SHIFT 1
#define FW_MB_PARAM_ENG_CFG_L2_AFFIN_VALID_MASK 0x00000004
#define FW_MB_PARAM_ENG_CFG_L2_AFFIN_VALID_SHIFT 2
#define FW_MB_PARAM_ENG_CFG_L2_AFFIN_VALUE_MASK 0x00000008
#define FW_MB_PARAM_ENG_CFG_L2_AFFIN_VALUE_SHIFT 3
#define FW_MB_PARAM_PPFID_BITMAP_MASK 0xFF
#define FW_MB_PARAM_PPFID_BITMAP_SHIFT 0
u32 drv_pulse_mb;
#define DRV_PULSE_SEQ_MASK 0x00007fff
#define DRV_PULSE_SYSTEM_TIME_MASK 0xffff0000

View file

@ -392,11 +392,15 @@ u32 qed_vfid_to_concrete(struct qed_hwfn *p_hwfn, u8 vfid)
}
/* DMAE */
#define QED_DMAE_FLAGS_IS_SET(params, flag) \
((params) != NULL && ((params)->flags & QED_DMAE_FLAG_##flag))
static void qed_dmae_opcode(struct qed_hwfn *p_hwfn,
const u8 is_src_type_grc,
const u8 is_dst_type_grc,
struct qed_dmae_params *p_params)
{
u8 src_pfid, dst_pfid, port_id;
u16 opcode_b = 0;
u32 opcode = 0;
@ -407,14 +411,18 @@ static void qed_dmae_opcode(struct qed_hwfn *p_hwfn,
opcode |= (is_src_type_grc ? DMAE_CMD_SRC_MASK_GRC
: DMAE_CMD_SRC_MASK_PCIE) <<
DMAE_CMD_SRC_SHIFT;
opcode |= ((p_hwfn->rel_pf_id & DMAE_CMD_SRC_PF_ID_MASK) <<
src_pfid = QED_DMAE_FLAGS_IS_SET(p_params, PF_SRC) ?
p_params->src_pfid : p_hwfn->rel_pf_id;
opcode |= ((src_pfid & DMAE_CMD_SRC_PF_ID_MASK) <<
DMAE_CMD_SRC_PF_ID_SHIFT);
/* The destination of the DMA can be: 0-None 1-PCIe 2-GRC 3-None */
opcode |= (is_dst_type_grc ? DMAE_CMD_DST_MASK_GRC
: DMAE_CMD_DST_MASK_PCIE) <<
DMAE_CMD_DST_SHIFT;
opcode |= ((p_hwfn->rel_pf_id & DMAE_CMD_DST_PF_ID_MASK) <<
dst_pfid = QED_DMAE_FLAGS_IS_SET(p_params, PF_DST) ?
p_params->dst_pfid : p_hwfn->rel_pf_id;
opcode |= ((dst_pfid & DMAE_CMD_DST_PF_ID_MASK) <<
DMAE_CMD_DST_PF_ID_SHIFT);
/* Whether to write a completion word to the completion destination:
@ -425,12 +433,14 @@ static void qed_dmae_opcode(struct qed_hwfn *p_hwfn,
opcode |= (DMAE_CMD_SRC_ADDR_RESET_MASK <<
DMAE_CMD_SRC_ADDR_RESET_SHIFT);
if (p_params->flags & QED_DMAE_FLAG_COMPLETION_DST)
if (QED_DMAE_FLAGS_IS_SET(p_params, COMPLETION_DST))
opcode |= (1 << DMAE_CMD_COMP_FUNC_SHIFT);
opcode |= (DMAE_CMD_ENDIANITY << DMAE_CMD_ENDIANITY_MODE_SHIFT);
opcode |= ((p_hwfn->port_id) << DMAE_CMD_PORT_ID_SHIFT);
port_id = (QED_DMAE_FLAGS_IS_SET(p_params, PORT)) ?
p_params->port_id : p_hwfn->port_id;
opcode |= (port_id << DMAE_CMD_PORT_ID_SHIFT);
/* reset source address in next go */
opcode |= (DMAE_CMD_SRC_ADDR_RESET_MASK <<
@ -441,7 +451,7 @@ static void qed_dmae_opcode(struct qed_hwfn *p_hwfn,
DMAE_CMD_DST_ADDR_RESET_SHIFT);
/* SRC/DST VFID: all 1's - pf, otherwise VF id */
if (p_params->flags & QED_DMAE_FLAG_VF_SRC) {
if (QED_DMAE_FLAGS_IS_SET(p_params, VF_SRC)) {
opcode |= 1 << DMAE_CMD_SRC_VF_ID_VALID_SHIFT;
opcode_b |= p_params->src_vfid << DMAE_CMD_SRC_VF_ID_SHIFT;
} else {
@ -449,7 +459,7 @@ static void qed_dmae_opcode(struct qed_hwfn *p_hwfn,
DMAE_CMD_SRC_VF_ID_SHIFT;
}
if (p_params->flags & QED_DMAE_FLAG_VF_DST) {
if (QED_DMAE_FLAGS_IS_SET(p_params, VF_DST)) {
opcode |= 1 << DMAE_CMD_DST_VF_ID_VALID_SHIFT;
opcode_b |= p_params->dst_vfid << DMAE_CMD_DST_VF_ID_SHIFT;
} else {
@ -733,7 +743,7 @@ static int qed_dmae_execute_command(struct qed_hwfn *p_hwfn,
for (i = 0; i <= cnt_split; i++) {
offset = length_limit * i;
if (!(p_params->flags & QED_DMAE_FLAG_RW_REPL_SRC)) {
if (!QED_DMAE_FLAGS_IS_SET(p_params, RW_REPL_SRC)) {
if (src_type == QED_DMAE_ADDRESS_GRC)
src_addr_split = src_addr + offset;
else
@ -771,14 +781,12 @@ static int qed_dmae_execute_command(struct qed_hwfn *p_hwfn,
int qed_dmae_host2grc(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
u64 source_addr, u32 grc_addr, u32 size_in_dwords, u32 flags)
u64 source_addr, u32 grc_addr, u32 size_in_dwords,
struct qed_dmae_params *p_params)
{
u32 grc_addr_in_dw = grc_addr / sizeof(u32);
struct qed_dmae_params params;
int rc;
memset(&params, 0, sizeof(struct qed_dmae_params));
params.flags = flags;
mutex_lock(&p_hwfn->dmae_info.mutex);
@ -786,7 +794,7 @@ int qed_dmae_host2grc(struct qed_hwfn *p_hwfn,
grc_addr_in_dw,
QED_DMAE_ADDRESS_HOST_VIRT,
QED_DMAE_ADDRESS_GRC,
size_in_dwords, &params);
size_in_dwords, p_params);
mutex_unlock(&p_hwfn->dmae_info.mutex);
@ -796,21 +804,19 @@ int qed_dmae_host2grc(struct qed_hwfn *p_hwfn,
int qed_dmae_grc2host(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
u32 grc_addr,
dma_addr_t dest_addr, u32 size_in_dwords, u32 flags)
dma_addr_t dest_addr, u32 size_in_dwords,
struct qed_dmae_params *p_params)
{
u32 grc_addr_in_dw = grc_addr / sizeof(u32);
struct qed_dmae_params params;
int rc;
memset(&params, 0, sizeof(struct qed_dmae_params));
params.flags = flags;
mutex_lock(&p_hwfn->dmae_info.mutex);
rc = qed_dmae_execute_command(p_hwfn, p_ptt, grc_addr_in_dw,
dest_addr, QED_DMAE_ADDRESS_GRC,
QED_DMAE_ADDRESS_HOST_VIRT,
size_in_dwords, &params);
size_in_dwords, p_params);
mutex_unlock(&p_hwfn->dmae_info.mutex);
@ -842,7 +848,6 @@ int qed_dmae_sanity(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, const char *phase)
{
u32 size = PAGE_SIZE / 2, val;
struct qed_dmae_params params;
int rc = 0;
dma_addr_t p_phys;
void *p_virt;
@ -875,9 +880,8 @@ int qed_dmae_sanity(struct qed_hwfn *p_hwfn,
(u64)p_phys,
p_virt, (u64)(p_phys + size), (u8 *)p_virt + size, size);
memset(&params, 0, sizeof(params));
rc = qed_dmae_host2host(p_hwfn, p_ptt, p_phys, p_phys + size,
size / 4 /* size_in_dwords */, &params);
size / 4, NULL);
if (rc) {
DP_NOTICE(p_hwfn,
"DMAE sanity [%s]: qed_dmae_host2host() failed. rc = %d.\n",

View file

@ -131,7 +131,7 @@ static int qed_init_rt(struct qed_hwfn *p_hwfn,
rc = qed_dmae_host2grc(p_hwfn, p_ptt,
(uintptr_t)(p_init_val + i),
addr + (i << 2), segment, 0);
addr + (i << 2), segment, NULL);
if (rc)
return rc;
@ -194,7 +194,7 @@ static int qed_init_array_dmae(struct qed_hwfn *p_hwfn,
} else {
rc = qed_dmae_host2grc(p_hwfn, p_ptt,
(uintptr_t)(buf + dmae_data_offset),
addr, size, 0);
addr, size, NULL);
}
return rc;
@ -205,6 +205,7 @@ static int qed_init_fill_dmae(struct qed_hwfn *p_hwfn,
u32 addr, u32 fill, u32 fill_count)
{
static u32 zero_buffer[DMAE_MAX_RW_SIZE];
struct qed_dmae_params params = {};
memset(zero_buffer, 0, sizeof(u32) * DMAE_MAX_RW_SIZE);
@ -214,10 +215,10 @@ static int qed_init_fill_dmae(struct qed_hwfn *p_hwfn,
* 3. p_hwfb->temp_data,
* 4. fill_count
*/
params.flags = QED_DMAE_FLAG_RW_REPL_SRC;
return qed_dmae_host2grc(p_hwfn, p_ptt,
(uintptr_t)(&zero_buffer[0]),
addr, fill_count, QED_DMAE_FLAG_RW_REPL_SRC);
addr, fill_count, &params);
}
static void qed_init_fill(struct qed_hwfn *p_hwfn,

View file

@ -1508,10 +1508,10 @@ void qed_int_cau_conf_sb(struct qed_hwfn *p_hwfn,
qed_dmae_host2grc(p_hwfn, p_ptt, (u64)(uintptr_t)&phys_addr,
CAU_REG_SB_ADDR_MEMORY +
igu_sb_id * sizeof(u64), 2, 0);
igu_sb_id * sizeof(u64), 2, NULL);
qed_dmae_host2grc(p_hwfn, p_ptt, (u64)(uintptr_t)&sb_entry,
CAU_REG_SB_VAR_MEMORY +
igu_sb_id * sizeof(u64), 2, 0);
igu_sb_id * sizeof(u64), 2, NULL);
} else {
/* Initialize Status Block Address */
STORE_RT_REG_AGG(p_hwfn,
@ -2362,7 +2362,7 @@ int qed_int_set_timer_res(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
rc = qed_dmae_grc2host(p_hwfn, p_ptt, CAU_REG_SB_VAR_MEMORY +
sb_id * sizeof(u64),
(u64)(uintptr_t)&sb_entry, 2, 0);
(u64)(uintptr_t)&sb_entry, 2, NULL);
if (rc) {
DP_ERR(p_hwfn, "dmae_grc2host failed %d\n", rc);
return rc;
@ -2376,7 +2376,7 @@ int qed_int_set_timer_res(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
rc = qed_dmae_host2grc(p_hwfn, p_ptt,
(u64)(uintptr_t)&sb_entry,
CAU_REG_SB_VAR_MEMORY +
sb_id * sizeof(u64), 2, 0);
sb_id * sizeof(u64), 2, NULL);
if (rc) {
DP_ERR(p_hwfn, "dmae_host2grc failed %d\n", rc);
return rc;

View file

@ -1082,7 +1082,7 @@ struct qed_hash_iscsi_con {
static int qed_fill_iscsi_dev_info(struct qed_dev *cdev,
struct qed_dev_iscsi_info *info)
{
struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
struct qed_hwfn *hwfn = QED_AFFIN_HWFN(cdev);
int rc;
@ -1141,8 +1141,8 @@ static int qed_iscsi_stop(struct qed_dev *cdev)
}
/* Stop the iscsi */
rc = qed_sp_iscsi_func_stop(QED_LEADING_HWFN(cdev),
QED_SPQ_MODE_EBLOCK, NULL);
rc = qed_sp_iscsi_func_stop(QED_AFFIN_HWFN(cdev), QED_SPQ_MODE_EBLOCK,
NULL);
cdev->flags &= ~QED_FLAG_STORAGE_STARTED;
return rc;
@ -1161,9 +1161,8 @@ static int qed_iscsi_start(struct qed_dev *cdev,
return 0;
}
rc = qed_sp_iscsi_func_start(QED_LEADING_HWFN(cdev),
QED_SPQ_MODE_EBLOCK, NULL, event_context,
async_event_cb);
rc = qed_sp_iscsi_func_start(QED_AFFIN_HWFN(cdev), QED_SPQ_MODE_EBLOCK,
NULL, event_context, async_event_cb);
if (rc) {
DP_NOTICE(cdev, "Failed to start iscsi\n");
return rc;
@ -1182,8 +1181,7 @@ static int qed_iscsi_start(struct qed_dev *cdev,
return -ENOMEM;
}
rc = qed_cxt_get_tid_mem_info(QED_LEADING_HWFN(cdev),
tid_info);
rc = qed_cxt_get_tid_mem_info(QED_AFFIN_HWFN(cdev), tid_info);
if (rc) {
DP_NOTICE(cdev, "Failed to gather task information\n");
qed_iscsi_stop(cdev);
@ -1215,7 +1213,7 @@ static int qed_iscsi_acquire_conn(struct qed_dev *cdev,
return -ENOMEM;
/* Acquire the connection */
rc = qed_iscsi_acquire_connection(QED_LEADING_HWFN(cdev), NULL,
rc = qed_iscsi_acquire_connection(QED_AFFIN_HWFN(cdev), NULL,
&hash_con->con);
if (rc) {
DP_NOTICE(cdev, "Failed to acquire Connection\n");
@ -1229,7 +1227,7 @@ static int qed_iscsi_acquire_conn(struct qed_dev *cdev,
hash_add(cdev->connections, &hash_con->node, *handle);
if (p_doorbell)
*p_doorbell = qed_iscsi_get_db_addr(QED_LEADING_HWFN(cdev),
*p_doorbell = qed_iscsi_get_db_addr(QED_AFFIN_HWFN(cdev),
*handle);
return 0;
@ -1247,7 +1245,7 @@ static int qed_iscsi_release_conn(struct qed_dev *cdev, u32 handle)
}
hlist_del(&hash_con->node);
qed_iscsi_release_connection(QED_LEADING_HWFN(cdev), hash_con->con);
qed_iscsi_release_connection(QED_AFFIN_HWFN(cdev), hash_con->con);
kfree(hash_con);
return 0;
@ -1324,7 +1322,7 @@ static int qed_iscsi_offload_conn(struct qed_dev *cdev,
/* Set default values on other connection fields */
con->offl_flags = 0x1;
return qed_sp_iscsi_conn_offload(QED_LEADING_HWFN(cdev), con,
return qed_sp_iscsi_conn_offload(QED_AFFIN_HWFN(cdev), con,
QED_SPQ_MODE_EBLOCK, NULL);
}
@ -1351,7 +1349,7 @@ static int qed_iscsi_update_conn(struct qed_dev *cdev,
con->first_seq_length = conn_info->first_seq_length;
con->exp_stat_sn = conn_info->exp_stat_sn;
return qed_sp_iscsi_conn_update(QED_LEADING_HWFN(cdev), con,
return qed_sp_iscsi_conn_update(QED_AFFIN_HWFN(cdev), con,
QED_SPQ_MODE_EBLOCK, NULL);
}
@ -1366,8 +1364,7 @@ static int qed_iscsi_clear_conn_sq(struct qed_dev *cdev, u32 handle)
return -EINVAL;
}
return qed_sp_iscsi_conn_clear_sq(QED_LEADING_HWFN(cdev),
hash_con->con,
return qed_sp_iscsi_conn_clear_sq(QED_AFFIN_HWFN(cdev), hash_con->con,
QED_SPQ_MODE_EBLOCK, NULL);
}
@ -1385,14 +1382,13 @@ static int qed_iscsi_destroy_conn(struct qed_dev *cdev,
hash_con->con->abortive_dsconnect = abrt_conn;
return qed_sp_iscsi_conn_terminate(QED_LEADING_HWFN(cdev),
hash_con->con,
return qed_sp_iscsi_conn_terminate(QED_AFFIN_HWFN(cdev), hash_con->con,
QED_SPQ_MODE_EBLOCK, NULL);
}
static int qed_iscsi_stats(struct qed_dev *cdev, struct qed_iscsi_stats *stats)
{
return qed_iscsi_get_stats(QED_LEADING_HWFN(cdev), stats);
return qed_iscsi_get_stats(QED_AFFIN_HWFN(cdev), stats);
}
static int qed_iscsi_change_mac(struct qed_dev *cdev,
@ -1407,8 +1403,7 @@ static int qed_iscsi_change_mac(struct qed_dev *cdev,
return -EINVAL;
}
return qed_sp_iscsi_mac_update(QED_LEADING_HWFN(cdev),
hash_con->con,
return qed_sp_iscsi_mac_update(QED_AFFIN_HWFN(cdev), hash_con->con,
QED_SPQ_MODE_EBLOCK, NULL);
}

View file

@ -2528,7 +2528,7 @@ qed_iwarp_ll2_slowpath(void *cxt,
memset(fpdu, 0, sizeof(*fpdu));
}
static int qed_iwarp_ll2_stop(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
static int qed_iwarp_ll2_stop(struct qed_hwfn *p_hwfn)
{
struct qed_iwarp_info *iwarp_info = &p_hwfn->p_rdma_info->iwarp;
int rc = 0;
@ -2563,8 +2563,9 @@ static int qed_iwarp_ll2_stop(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
iwarp_info->ll2_mpa_handle = QED_IWARP_HANDLE_INVAL;
}
qed_llh_remove_mac_filter(p_hwfn,
p_ptt, p_hwfn->p_rdma_info->iwarp.mac_addr);
qed_llh_remove_mac_filter(p_hwfn->cdev, 0,
p_hwfn->p_rdma_info->iwarp.mac_addr);
return rc;
}
@ -2608,8 +2609,7 @@ qed_iwarp_ll2_alloc_buffers(struct qed_hwfn *p_hwfn,
static int
qed_iwarp_ll2_start(struct qed_hwfn *p_hwfn,
struct qed_rdma_start_in_params *params,
struct qed_ptt *p_ptt)
struct qed_rdma_start_in_params *params)
{
struct qed_iwarp_info *iwarp_info;
struct qed_ll2_acquire_data data;
@ -2628,7 +2628,7 @@ qed_iwarp_ll2_start(struct qed_hwfn *p_hwfn,
ether_addr_copy(p_hwfn->p_rdma_info->iwarp.mac_addr, params->mac_addr);
rc = qed_llh_add_mac_filter(p_hwfn, p_ptt, params->mac_addr);
rc = qed_llh_add_mac_filter(p_hwfn->cdev, 0, params->mac_addr);
if (rc)
return rc;
@ -2653,7 +2653,7 @@ qed_iwarp_ll2_start(struct qed_hwfn *p_hwfn,
rc = qed_ll2_acquire_connection(p_hwfn, &data);
if (rc) {
DP_NOTICE(p_hwfn, "Failed to acquire LL2 connection\n");
qed_llh_remove_mac_filter(p_hwfn, p_ptt, params->mac_addr);
qed_llh_remove_mac_filter(p_hwfn->cdev, 0, params->mac_addr);
return rc;
}
@ -2757,12 +2757,12 @@ qed_iwarp_ll2_start(struct qed_hwfn *p_hwfn,
&iwarp_info->mpa_buf_list);
return rc;
err:
qed_iwarp_ll2_stop(p_hwfn, p_ptt);
qed_iwarp_ll2_stop(p_hwfn);
return rc;
}
int qed_iwarp_setup(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
int qed_iwarp_setup(struct qed_hwfn *p_hwfn,
struct qed_rdma_start_in_params *params)
{
struct qed_iwarp_info *iwarp_info;
@ -2794,10 +2794,10 @@ int qed_iwarp_setup(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
qed_iwarp_async_event);
qed_ooo_setup(p_hwfn);
return qed_iwarp_ll2_start(p_hwfn, params, p_ptt);
return qed_iwarp_ll2_start(p_hwfn, params);
}
int qed_iwarp_stop(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
int qed_iwarp_stop(struct qed_hwfn *p_hwfn)
{
int rc;
@ -2808,7 +2808,7 @@ int qed_iwarp_stop(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
qed_spq_unregister_async_cb(p_hwfn, PROTOCOLID_IWARP);
return qed_iwarp_ll2_stop(p_hwfn, p_ptt);
return qed_iwarp_ll2_stop(p_hwfn);
}
static void qed_iwarp_qp_in_error(struct qed_hwfn *p_hwfn,

View file

@ -183,13 +183,13 @@ struct qed_iwarp_listener {
int qed_iwarp_alloc(struct qed_hwfn *p_hwfn);
int qed_iwarp_setup(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
int qed_iwarp_setup(struct qed_hwfn *p_hwfn,
struct qed_rdma_start_in_params *params);
void qed_iwarp_init_fw_ramrod(struct qed_hwfn *p_hwfn,
struct iwarp_init_func_ramrod_data *p_ramrod);
int qed_iwarp_stop(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
int qed_iwarp_stop(struct qed_hwfn *p_hwfn);
void qed_iwarp_resc_free(struct qed_hwfn *p_hwfn);

View file

@ -2111,7 +2111,7 @@ int qed_get_rxq_coalesce(struct qed_hwfn *p_hwfn,
rc = qed_dmae_grc2host(p_hwfn, p_ptt, CAU_REG_SB_VAR_MEMORY +
p_cid->sb_igu_id * sizeof(u64),
(u64)(uintptr_t)&sb_entry, 2, 0);
(u64)(uintptr_t)&sb_entry, 2, NULL);
if (rc) {
DP_ERR(p_hwfn, "dmae_grc2host failed %d\n", rc);
return rc;
@ -2144,7 +2144,7 @@ int qed_get_txq_coalesce(struct qed_hwfn *p_hwfn,
rc = qed_dmae_grc2host(p_hwfn, p_ptt, CAU_REG_SB_VAR_MEMORY +
p_cid->sb_igu_id * sizeof(u64),
(u64)(uintptr_t)&sb_entry, 2, 0);
(u64)(uintptr_t)&sb_entry, 2, NULL);
if (rc) {
DP_ERR(p_hwfn, "dmae_grc2host failed %d\n", rc);
return rc;

View file

@ -239,9 +239,8 @@ static void qed_ll2b_complete_rx_packet(void *cxt,
buffer->phys_addr = new_phys_addr;
out_post:
rc = qed_ll2_post_rx_buffer(QED_LEADING_HWFN(cdev), cdev->ll2->handle,
rc = qed_ll2_post_rx_buffer(p_hwfn, cdev->ll2->handle,
buffer->phys_addr, 0, buffer, 1);
if (rc)
qed_ll2_dealloc_buffer(cdev, buffer);
}
@ -926,16 +925,15 @@ static int qed_ll2_lb_txq_completion(struct qed_hwfn *p_hwfn, void *p_cookie)
return 0;
}
static void qed_ll2_stop_ooo(struct qed_dev *cdev)
static void qed_ll2_stop_ooo(struct qed_hwfn *p_hwfn)
{
struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
u8 *handle = &hwfn->pf_params.iscsi_pf_params.ll2_ooo_queue_id;
u8 *handle = &p_hwfn->pf_params.iscsi_pf_params.ll2_ooo_queue_id;
DP_VERBOSE(cdev, QED_MSG_STORAGE, "Stopping LL2 OOO queue [%02x]\n",
*handle);
DP_VERBOSE(p_hwfn, (QED_MSG_STORAGE | QED_MSG_LL2),
"Stopping LL2 OOO queue [%02x]\n", *handle);
qed_ll2_terminate_connection(hwfn, *handle);
qed_ll2_release_connection(hwfn, *handle);
qed_ll2_terminate_connection(p_hwfn, *handle);
qed_ll2_release_connection(p_hwfn, *handle);
*handle = QED_LL2_UNUSED_HANDLE;
}
@ -1574,12 +1572,12 @@ int qed_ll2_establish_connection(void *cxt, u8 connection_handle)
if (p_ll2_conn->input.conn_type == QED_LL2_TYPE_FCOE) {
if (!test_bit(QED_MF_UFP_SPECIFIC, &p_hwfn->cdev->mf_bits))
qed_llh_add_protocol_filter(p_hwfn, p_ptt,
ETH_P_FCOE, 0,
QED_LLH_FILTER_ETHERTYPE);
qed_llh_add_protocol_filter(p_hwfn, p_ptt,
ETH_P_FIP, 0,
QED_LLH_FILTER_ETHERTYPE);
qed_llh_add_protocol_filter(p_hwfn->cdev, 0,
QED_LLH_FILTER_ETHERTYPE,
ETH_P_FCOE, 0);
qed_llh_add_protocol_filter(p_hwfn->cdev, 0,
QED_LLH_FILTER_ETHERTYPE,
ETH_P_FIP, 0);
}
out:
@ -1980,12 +1978,12 @@ int qed_ll2_terminate_connection(void *cxt, u8 connection_handle)
if (p_ll2_conn->input.conn_type == QED_LL2_TYPE_FCOE) {
if (!test_bit(QED_MF_UFP_SPECIFIC, &p_hwfn->cdev->mf_bits))
qed_llh_remove_protocol_filter(p_hwfn, p_ptt,
ETH_P_FCOE, 0,
QED_LLH_FILTER_ETHERTYPE);
qed_llh_remove_protocol_filter(p_hwfn, p_ptt,
ETH_P_FIP, 0,
QED_LLH_FILTER_ETHERTYPE);
qed_llh_remove_protocol_filter(p_hwfn->cdev, 0,
QED_LLH_FILTER_ETHERTYPE,
ETH_P_FCOE, 0);
qed_llh_remove_protocol_filter(p_hwfn->cdev, 0,
QED_LLH_FILTER_ETHERTYPE,
ETH_P_FIP, 0);
}
out:
@ -2086,12 +2084,12 @@ static void _qed_ll2_get_port_stats(struct qed_hwfn *p_hwfn,
TSTORM_LL2_PORT_STAT_OFFSET(MFW_PORT(p_hwfn)),
sizeof(port_stats));
p_stats->gsi_invalid_hdr = HILO_64_REGPAIR(port_stats.gsi_invalid_hdr);
p_stats->gsi_invalid_pkt_length =
p_stats->gsi_invalid_hdr += HILO_64_REGPAIR(port_stats.gsi_invalid_hdr);
p_stats->gsi_invalid_pkt_length +=
HILO_64_REGPAIR(port_stats.gsi_invalid_pkt_length);
p_stats->gsi_unsupported_pkt_typ =
p_stats->gsi_unsupported_pkt_typ +=
HILO_64_REGPAIR(port_stats.gsi_unsupported_pkt_typ);
p_stats->gsi_crcchksm_error =
p_stats->gsi_crcchksm_error +=
HILO_64_REGPAIR(port_stats.gsi_crcchksm_error);
}
@ -2109,9 +2107,9 @@ static void _qed_ll2_get_tstats(struct qed_hwfn *p_hwfn,
CORE_LL2_TSTORM_PER_QUEUE_STAT_OFFSET(qid);
qed_memcpy_from(p_hwfn, p_ptt, &tstats, tstats_addr, sizeof(tstats));
p_stats->packet_too_big_discard =
p_stats->packet_too_big_discard +=
HILO_64_REGPAIR(tstats.packet_too_big_discard);
p_stats->no_buff_discard = HILO_64_REGPAIR(tstats.no_buff_discard);
p_stats->no_buff_discard += HILO_64_REGPAIR(tstats.no_buff_discard);
}
static void _qed_ll2_get_ustats(struct qed_hwfn *p_hwfn,
@ -2128,12 +2126,12 @@ static void _qed_ll2_get_ustats(struct qed_hwfn *p_hwfn,
CORE_LL2_USTORM_PER_QUEUE_STAT_OFFSET(qid);
qed_memcpy_from(p_hwfn, p_ptt, &ustats, ustats_addr, sizeof(ustats));
p_stats->rcv_ucast_bytes = HILO_64_REGPAIR(ustats.rcv_ucast_bytes);
p_stats->rcv_mcast_bytes = HILO_64_REGPAIR(ustats.rcv_mcast_bytes);
p_stats->rcv_bcast_bytes = HILO_64_REGPAIR(ustats.rcv_bcast_bytes);
p_stats->rcv_ucast_pkts = HILO_64_REGPAIR(ustats.rcv_ucast_pkts);
p_stats->rcv_mcast_pkts = HILO_64_REGPAIR(ustats.rcv_mcast_pkts);
p_stats->rcv_bcast_pkts = HILO_64_REGPAIR(ustats.rcv_bcast_pkts);
p_stats->rcv_ucast_bytes += HILO_64_REGPAIR(ustats.rcv_ucast_bytes);
p_stats->rcv_mcast_bytes += HILO_64_REGPAIR(ustats.rcv_mcast_bytes);
p_stats->rcv_bcast_bytes += HILO_64_REGPAIR(ustats.rcv_bcast_bytes);
p_stats->rcv_ucast_pkts += HILO_64_REGPAIR(ustats.rcv_ucast_pkts);
p_stats->rcv_mcast_pkts += HILO_64_REGPAIR(ustats.rcv_mcast_pkts);
p_stats->rcv_bcast_pkts += HILO_64_REGPAIR(ustats.rcv_bcast_pkts);
}
static void _qed_ll2_get_pstats(struct qed_hwfn *p_hwfn,
@ -2150,23 +2148,21 @@ static void _qed_ll2_get_pstats(struct qed_hwfn *p_hwfn,
CORE_LL2_PSTORM_PER_QUEUE_STAT_OFFSET(stats_id);
qed_memcpy_from(p_hwfn, p_ptt, &pstats, pstats_addr, sizeof(pstats));
p_stats->sent_ucast_bytes = HILO_64_REGPAIR(pstats.sent_ucast_bytes);
p_stats->sent_mcast_bytes = HILO_64_REGPAIR(pstats.sent_mcast_bytes);
p_stats->sent_bcast_bytes = HILO_64_REGPAIR(pstats.sent_bcast_bytes);
p_stats->sent_ucast_pkts = HILO_64_REGPAIR(pstats.sent_ucast_pkts);
p_stats->sent_mcast_pkts = HILO_64_REGPAIR(pstats.sent_mcast_pkts);
p_stats->sent_bcast_pkts = HILO_64_REGPAIR(pstats.sent_bcast_pkts);
p_stats->sent_ucast_bytes += HILO_64_REGPAIR(pstats.sent_ucast_bytes);
p_stats->sent_mcast_bytes += HILO_64_REGPAIR(pstats.sent_mcast_bytes);
p_stats->sent_bcast_bytes += HILO_64_REGPAIR(pstats.sent_bcast_bytes);
p_stats->sent_ucast_pkts += HILO_64_REGPAIR(pstats.sent_ucast_pkts);
p_stats->sent_mcast_pkts += HILO_64_REGPAIR(pstats.sent_mcast_pkts);
p_stats->sent_bcast_pkts += HILO_64_REGPAIR(pstats.sent_bcast_pkts);
}
int qed_ll2_get_stats(void *cxt,
u8 connection_handle, struct qed_ll2_stats *p_stats)
static int __qed_ll2_get_stats(void *cxt, u8 connection_handle,
struct qed_ll2_stats *p_stats)
{
struct qed_hwfn *p_hwfn = cxt;
struct qed_ll2_info *p_ll2_conn = NULL;
struct qed_ptt *p_ptt;
memset(p_stats, 0, sizeof(*p_stats));
if ((connection_handle >= QED_MAX_NUM_OF_LL2_CONNECTIONS) ||
!p_hwfn->p_ll2_info)
return -EINVAL;
@ -2181,15 +2177,26 @@ int qed_ll2_get_stats(void *cxt,
if (p_ll2_conn->input.gsi_enable)
_qed_ll2_get_port_stats(p_hwfn, p_ptt, p_stats);
_qed_ll2_get_tstats(p_hwfn, p_ptt, p_ll2_conn, p_stats);
_qed_ll2_get_ustats(p_hwfn, p_ptt, p_ll2_conn, p_stats);
if (p_ll2_conn->tx_stats_en)
_qed_ll2_get_pstats(p_hwfn, p_ptt, p_ll2_conn, p_stats);
qed_ptt_release(p_hwfn, p_ptt);
return 0;
}
int qed_ll2_get_stats(void *cxt,
u8 connection_handle, struct qed_ll2_stats *p_stats)
{
memset(p_stats, 0, sizeof(*p_stats));
return __qed_ll2_get_stats(cxt, connection_handle, p_stats);
}
static void qed_ll2b_release_rx_packet(void *cxt,
u8 connection_handle,
void *cookie,
@ -2216,7 +2223,7 @@ struct qed_ll2_cbs ll2_cbs = {
.tx_release_cb = &qed_ll2b_complete_tx_packet,
};
static void qed_ll2_set_conn_data(struct qed_dev *cdev,
static void qed_ll2_set_conn_data(struct qed_hwfn *p_hwfn,
struct qed_ll2_acquire_data *data,
struct qed_ll2_params *params,
enum qed_ll2_conn_type conn_type,
@ -2232,7 +2239,7 @@ static void qed_ll2_set_conn_data(struct qed_dev *cdev,
data->input.tx_num_desc = QED_LL2_TX_SIZE;
data->p_connection_handle = handle;
data->cbs = &ll2_cbs;
ll2_cbs.cookie = QED_LEADING_HWFN(cdev);
ll2_cbs.cookie = p_hwfn;
if (lb) {
data->input.tx_tc = PKT_LB_TC;
@ -2243,74 +2250,102 @@ static void qed_ll2_set_conn_data(struct qed_dev *cdev,
}
}
static int qed_ll2_start_ooo(struct qed_dev *cdev,
static int qed_ll2_start_ooo(struct qed_hwfn *p_hwfn,
struct qed_ll2_params *params)
{
struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
u8 *handle = &hwfn->pf_params.iscsi_pf_params.ll2_ooo_queue_id;
u8 *handle = &p_hwfn->pf_params.iscsi_pf_params.ll2_ooo_queue_id;
struct qed_ll2_acquire_data data;
int rc;
qed_ll2_set_conn_data(cdev, &data, params,
qed_ll2_set_conn_data(p_hwfn, &data, params,
QED_LL2_TYPE_OOO, handle, true);
rc = qed_ll2_acquire_connection(hwfn, &data);
rc = qed_ll2_acquire_connection(p_hwfn, &data);
if (rc) {
DP_INFO(cdev, "Failed to acquire LL2 OOO connection\n");
DP_INFO(p_hwfn, "Failed to acquire LL2 OOO connection\n");
goto out;
}
rc = qed_ll2_establish_connection(hwfn, *handle);
rc = qed_ll2_establish_connection(p_hwfn, *handle);
if (rc) {
DP_INFO(cdev, "Failed to establist LL2 OOO connection\n");
DP_INFO(p_hwfn, "Failed to establish LL2 OOO connection\n");
goto fail;
}
return 0;
fail:
qed_ll2_release_connection(hwfn, *handle);
qed_ll2_release_connection(p_hwfn, *handle);
out:
*handle = QED_LL2_UNUSED_HANDLE;
return rc;
}
static int qed_ll2_start(struct qed_dev *cdev, struct qed_ll2_params *params)
static bool qed_ll2_is_storage_eng1(struct qed_dev *cdev)
{
return (QED_IS_FCOE_PERSONALITY(QED_LEADING_HWFN(cdev)) ||
QED_IS_ISCSI_PERSONALITY(QED_LEADING_HWFN(cdev))) &&
(QED_AFFIN_HWFN(cdev) != QED_LEADING_HWFN(cdev));
}
static int __qed_ll2_stop(struct qed_hwfn *p_hwfn)
{
struct qed_dev *cdev = p_hwfn->cdev;
int rc;
rc = qed_ll2_terminate_connection(p_hwfn, cdev->ll2->handle);
if (rc)
DP_INFO(cdev, "Failed to terminate LL2 connection\n");
qed_ll2_release_connection(p_hwfn, cdev->ll2->handle);
return rc;
}
static int qed_ll2_stop(struct qed_dev *cdev)
{
bool b_is_storage_eng1 = qed_ll2_is_storage_eng1(cdev);
struct qed_hwfn *p_hwfn = QED_AFFIN_HWFN(cdev);
int rc = 0, rc2 = 0;
if (cdev->ll2->handle == QED_LL2_UNUSED_HANDLE)
return 0;
qed_llh_remove_mac_filter(cdev, 0, cdev->ll2_mac_address);
eth_zero_addr(cdev->ll2_mac_address);
if (QED_IS_ISCSI_PERSONALITY(p_hwfn))
qed_ll2_stop_ooo(p_hwfn);
/* In CMT mode, LL2 is always started on engine 0 for a storage PF */
if (b_is_storage_eng1) {
rc2 = __qed_ll2_stop(QED_LEADING_HWFN(cdev));
if (rc2)
DP_NOTICE(QED_LEADING_HWFN(cdev),
"Failed to stop LL2 on engine 0\n");
}
rc = __qed_ll2_stop(p_hwfn);
if (rc)
DP_NOTICE(p_hwfn, "Failed to stop LL2\n");
qed_ll2_kill_buffers(cdev);
cdev->ll2->handle = QED_LL2_UNUSED_HANDLE;
return rc | rc2;
}
static int __qed_ll2_start(struct qed_hwfn *p_hwfn,
struct qed_ll2_params *params)
{
struct qed_ll2_buffer *buffer, *tmp_buffer;
struct qed_dev *cdev = p_hwfn->cdev;
enum qed_ll2_conn_type conn_type;
struct qed_ll2_acquire_data data;
struct qed_ptt *p_ptt;
int rc, i;
int rc, rx_cnt;
/* Initialize LL2 locks & lists */
INIT_LIST_HEAD(&cdev->ll2->list);
spin_lock_init(&cdev->ll2->lock);
cdev->ll2->rx_size = NET_SKB_PAD + ETH_HLEN +
L1_CACHE_BYTES + params->mtu;
/*Allocate memory for LL2 */
DP_INFO(cdev, "Allocating LL2 buffers of size %08x bytes\n",
cdev->ll2->rx_size);
for (i = 0; i < QED_LL2_RX_SIZE; i++) {
buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
if (!buffer) {
DP_INFO(cdev, "Failed to allocate LL2 buffers\n");
goto fail;
}
rc = qed_ll2_alloc_buffer(cdev, (u8 **)&buffer->data,
&buffer->phys_addr);
if (rc) {
kfree(buffer);
goto fail;
}
list_add_tail(&buffer->list, &cdev->ll2->list);
}
switch (QED_LEADING_HWFN(cdev)->hw_info.personality) {
switch (p_hwfn->hw_info.personality) {
case QED_PCI_FCOE:
conn_type = QED_LL2_TYPE_FCOE;
break;
@ -2321,33 +2356,34 @@ static int qed_ll2_start(struct qed_dev *cdev, struct qed_ll2_params *params)
conn_type = QED_LL2_TYPE_ROCE;
break;
default:
conn_type = QED_LL2_TYPE_TEST;
}
qed_ll2_set_conn_data(cdev, &data, params, conn_type,
qed_ll2_set_conn_data(p_hwfn, &data, params, conn_type,
&cdev->ll2->handle, false);
rc = qed_ll2_acquire_connection(QED_LEADING_HWFN(cdev), &data);
rc = qed_ll2_acquire_connection(p_hwfn, &data);
if (rc) {
DP_INFO(cdev, "Failed to acquire LL2 connection\n");
goto fail;
DP_INFO(p_hwfn, "Failed to acquire LL2 connection\n");
return rc;
}
rc = qed_ll2_establish_connection(QED_LEADING_HWFN(cdev),
cdev->ll2->handle);
rc = qed_ll2_establish_connection(p_hwfn, cdev->ll2->handle);
if (rc) {
DP_INFO(cdev, "Failed to establish LL2 connection\n");
goto release_fail;
DP_INFO(p_hwfn, "Failed to establish LL2 connection\n");
goto release_conn;
}
/* Post all Rx buffers to FW */
spin_lock_bh(&cdev->ll2->lock);
rx_cnt = cdev->ll2->rx_cnt;
list_for_each_entry_safe(buffer, tmp_buffer, &cdev->ll2->list, list) {
rc = qed_ll2_post_rx_buffer(QED_LEADING_HWFN(cdev),
rc = qed_ll2_post_rx_buffer(p_hwfn,
cdev->ll2->handle,
buffer->phys_addr, 0, buffer, 1);
if (rc) {
DP_INFO(cdev,
DP_INFO(p_hwfn,
"Failed to post an Rx buffer; Deleting it\n");
dma_unmap_single(&cdev->pdev->dev, buffer->phys_addr,
cdev->ll2->rx_size, DMA_FROM_DEVICE);
@ -2355,100 +2391,127 @@ static int qed_ll2_start(struct qed_dev *cdev, struct qed_ll2_params *params)
list_del(&buffer->list);
kfree(buffer);
} else {
cdev->ll2->rx_cnt++;
rx_cnt++;
}
}
spin_unlock_bh(&cdev->ll2->lock);
if (!cdev->ll2->rx_cnt) {
DP_INFO(cdev, "Failed passing even a single Rx buffer\n");
goto release_terminate;
if (rx_cnt == cdev->ll2->rx_cnt) {
DP_NOTICE(p_hwfn, "Failed passing even a single Rx buffer\n");
goto terminate_conn;
}
cdev->ll2->rx_cnt = rx_cnt;
return 0;
terminate_conn:
qed_ll2_terminate_connection(p_hwfn, cdev->ll2->handle);
release_conn:
qed_ll2_release_connection(p_hwfn, cdev->ll2->handle);
return rc;
}
static int qed_ll2_start(struct qed_dev *cdev, struct qed_ll2_params *params)
{
bool b_is_storage_eng1 = qed_ll2_is_storage_eng1(cdev);
struct qed_hwfn *p_hwfn = QED_AFFIN_HWFN(cdev);
struct qed_ll2_buffer *buffer;
int rx_num_desc, i, rc;
if (!is_valid_ether_addr(params->ll2_mac_address)) {
DP_INFO(cdev, "Invalid Ethernet address\n");
goto release_terminate;
DP_NOTICE(cdev, "Invalid Ethernet address\n");
return -EINVAL;
}
if (QED_LEADING_HWFN(cdev)->hw_info.personality == QED_PCI_ISCSI) {
WARN_ON(!cdev->ll2->cbs);
/* Initialize LL2 locks & lists */
INIT_LIST_HEAD(&cdev->ll2->list);
spin_lock_init(&cdev->ll2->lock);
cdev->ll2->rx_size = NET_SKB_PAD + ETH_HLEN +
L1_CACHE_BYTES + params->mtu;
/* Allocate memory for LL2.
* In CMT mode, in case of a storage PF which is affintized to engine 1,
* LL2 is started also on engine 0 and thus we need twofold buffers.
*/
rx_num_desc = QED_LL2_RX_SIZE * (b_is_storage_eng1 ? 2 : 1);
DP_INFO(cdev, "Allocating %d LL2 buffers of size %08x bytes\n",
rx_num_desc, cdev->ll2->rx_size);
for (i = 0; i < rx_num_desc; i++) {
buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
if (!buffer) {
DP_INFO(cdev, "Failed to allocate LL2 buffers\n");
rc = -ENOMEM;
goto err0;
}
rc = qed_ll2_alloc_buffer(cdev, (u8 **)&buffer->data,
&buffer->phys_addr);
if (rc) {
kfree(buffer);
goto err0;
}
list_add_tail(&buffer->list, &cdev->ll2->list);
}
rc = __qed_ll2_start(p_hwfn, params);
if (rc) {
DP_NOTICE(cdev, "Failed to start LL2\n");
goto err0;
}
/* In CMT mode, always need to start LL2 on engine 0 for a storage PF,
* since broadcast/mutlicast packets are routed to engine 0.
*/
if (b_is_storage_eng1) {
rc = __qed_ll2_start(QED_LEADING_HWFN(cdev), params);
if (rc) {
DP_NOTICE(QED_LEADING_HWFN(cdev),
"Failed to start LL2 on engine 0\n");
goto err1;
}
}
if (QED_IS_ISCSI_PERSONALITY(p_hwfn)) {
DP_VERBOSE(cdev, QED_MSG_STORAGE, "Starting OOO LL2 queue\n");
rc = qed_ll2_start_ooo(cdev, params);
rc = qed_ll2_start_ooo(p_hwfn, params);
if (rc) {
DP_INFO(cdev,
"Failed to initialize the OOO LL2 queue\n");
goto release_terminate;
DP_NOTICE(cdev, "Failed to start OOO LL2\n");
goto err2;
}
}
p_ptt = qed_ptt_acquire(QED_LEADING_HWFN(cdev));
if (!p_ptt) {
DP_INFO(cdev, "Failed to acquire PTT\n");
goto release_terminate;
}
rc = qed_llh_add_mac_filter(QED_LEADING_HWFN(cdev), p_ptt,
params->ll2_mac_address);
qed_ptt_release(QED_LEADING_HWFN(cdev), p_ptt);
rc = qed_llh_add_mac_filter(cdev, 0, params->ll2_mac_address);
if (rc) {
DP_ERR(cdev, "Failed to allocate LLH filter\n");
goto release_terminate_all;
DP_NOTICE(cdev, "Failed to add an LLH filter\n");
goto err3;
}
ether_addr_copy(cdev->ll2_mac_address, params->ll2_mac_address);
return 0;
release_terminate_all:
release_terminate:
qed_ll2_terminate_connection(QED_LEADING_HWFN(cdev), cdev->ll2->handle);
release_fail:
qed_ll2_release_connection(QED_LEADING_HWFN(cdev), cdev->ll2->handle);
fail:
err3:
if (QED_IS_ISCSI_PERSONALITY(p_hwfn))
qed_ll2_stop_ooo(p_hwfn);
err2:
if (b_is_storage_eng1)
__qed_ll2_stop(QED_LEADING_HWFN(cdev));
err1:
__qed_ll2_stop(p_hwfn);
err0:
qed_ll2_kill_buffers(cdev);
cdev->ll2->handle = QED_LL2_UNUSED_HANDLE;
return -EINVAL;
}
static int qed_ll2_stop(struct qed_dev *cdev)
{
struct qed_ptt *p_ptt;
int rc;
if (cdev->ll2->handle == QED_LL2_UNUSED_HANDLE)
return 0;
p_ptt = qed_ptt_acquire(QED_LEADING_HWFN(cdev));
if (!p_ptt) {
DP_INFO(cdev, "Failed to acquire PTT\n");
goto fail;
}
qed_llh_remove_mac_filter(QED_LEADING_HWFN(cdev), p_ptt,
cdev->ll2_mac_address);
qed_ptt_release(QED_LEADING_HWFN(cdev), p_ptt);
eth_zero_addr(cdev->ll2_mac_address);
if (QED_LEADING_HWFN(cdev)->hw_info.personality == QED_PCI_ISCSI)
qed_ll2_stop_ooo(cdev);
rc = qed_ll2_terminate_connection(QED_LEADING_HWFN(cdev),
cdev->ll2->handle);
if (rc)
DP_INFO(cdev, "Failed to terminate LL2 connection\n");
qed_ll2_kill_buffers(cdev);
qed_ll2_release_connection(QED_LEADING_HWFN(cdev), cdev->ll2->handle);
cdev->ll2->handle = QED_LL2_UNUSED_HANDLE;
return rc;
fail:
return -EINVAL;
}
static int qed_ll2_start_xmit(struct qed_dev *cdev, struct sk_buff *skb,
unsigned long xmit_flags)
{
struct qed_hwfn *p_hwfn = QED_AFFIN_HWFN(cdev);
struct qed_ll2_tx_pkt_info pkt;
const skb_frag_t *frag;
u8 flags = 0, nr_frags;
@ -2506,7 +2569,7 @@ static int qed_ll2_start_xmit(struct qed_dev *cdev, struct sk_buff *skb,
* routine may run and free the SKB, so no dereferencing the SKB
* beyond this point unless skb has any fragments.
*/
rc = qed_ll2_prepare_tx_packet(&cdev->hwfns[0], cdev->ll2->handle,
rc = qed_ll2_prepare_tx_packet(p_hwfn, cdev->ll2->handle,
&pkt, 1);
if (rc)
goto err;
@ -2524,13 +2587,13 @@ static int qed_ll2_start_xmit(struct qed_dev *cdev, struct sk_buff *skb,
goto err;
}
rc = qed_ll2_set_fragment_of_tx_packet(QED_LEADING_HWFN(cdev),
rc = qed_ll2_set_fragment_of_tx_packet(p_hwfn,
cdev->ll2->handle,
mapping,
skb_frag_size(frag));
/* if failed not much to do here, partial packet has been posted
* we can't free memory, will need to wait for completion.
* we can't free memory, will need to wait for completion
*/
if (rc)
goto err2;
@ -2540,18 +2603,37 @@ static int qed_ll2_start_xmit(struct qed_dev *cdev, struct sk_buff *skb,
err:
dma_unmap_single(&cdev->pdev->dev, mapping, skb->len, DMA_TO_DEVICE);
err2:
return rc;
}
static int qed_ll2_stats(struct qed_dev *cdev, struct qed_ll2_stats *stats)
{
bool b_is_storage_eng1 = qed_ll2_is_storage_eng1(cdev);
struct qed_hwfn *p_hwfn = QED_AFFIN_HWFN(cdev);
int rc;
if (!cdev->ll2)
return -EINVAL;
return qed_ll2_get_stats(QED_LEADING_HWFN(cdev),
rc = qed_ll2_get_stats(p_hwfn, cdev->ll2->handle, stats);
if (rc) {
DP_NOTICE(p_hwfn, "Failed to get LL2 stats\n");
return rc;
}
/* In CMT mode, LL2 is always started on engine 0 for a storage PF */
if (b_is_storage_eng1) {
rc = __qed_ll2_get_stats(QED_LEADING_HWFN(cdev),
cdev->ll2->handle, stats);
if (rc) {
DP_NOTICE(QED_LEADING_HWFN(cdev),
"Failed to get LL2 stats on engine 0\n");
return rc;
}
}
return 0;
}
const struct qed_ll2_ops qed_ll2_ops_pass = {

View file

@ -48,6 +48,7 @@
#include <linux/crc32.h>
#include <linux/qed/qed_if.h>
#include <linux/qed/qed_ll2_if.h>
#include <net/devlink.h>
#include "qed.h"
#include "qed_sriov.h"
@ -342,6 +343,107 @@ static int qed_set_power_state(struct qed_dev *cdev, pci_power_t state)
return 0;
}
struct qed_devlink {
struct qed_dev *cdev;
};
enum qed_devlink_param_id {
QED_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
QED_DEVLINK_PARAM_ID_IWARP_CMT,
};
static int qed_dl_param_get(struct devlink *dl, u32 id,
struct devlink_param_gset_ctx *ctx)
{
struct qed_devlink *qed_dl;
struct qed_dev *cdev;
qed_dl = devlink_priv(dl);
cdev = qed_dl->cdev;
ctx->val.vbool = cdev->iwarp_cmt;
return 0;
}
static int qed_dl_param_set(struct devlink *dl, u32 id,
struct devlink_param_gset_ctx *ctx)
{
struct qed_devlink *qed_dl;
struct qed_dev *cdev;
qed_dl = devlink_priv(dl);
cdev = qed_dl->cdev;
cdev->iwarp_cmt = ctx->val.vbool;
return 0;
}
static const struct devlink_param qed_devlink_params[] = {
DEVLINK_PARAM_DRIVER(QED_DEVLINK_PARAM_ID_IWARP_CMT,
"iwarp_cmt", DEVLINK_PARAM_TYPE_BOOL,
BIT(DEVLINK_PARAM_CMODE_RUNTIME),
qed_dl_param_get, qed_dl_param_set, NULL),
};
static const struct devlink_ops qed_dl_ops;
static int qed_devlink_register(struct qed_dev *cdev)
{
union devlink_param_value value;
struct qed_devlink *qed_dl;
struct devlink *dl;
int rc;
dl = devlink_alloc(&qed_dl_ops, sizeof(*qed_dl));
if (!dl)
return -ENOMEM;
qed_dl = devlink_priv(dl);
cdev->dl = dl;
qed_dl->cdev = cdev;
rc = devlink_register(dl, &cdev->pdev->dev);
if (rc)
goto err_free;
rc = devlink_params_register(dl, qed_devlink_params,
ARRAY_SIZE(qed_devlink_params));
if (rc)
goto err_unregister;
value.vbool = false;
devlink_param_driverinit_value_set(dl,
QED_DEVLINK_PARAM_ID_IWARP_CMT,
value);
devlink_params_publish(dl);
cdev->iwarp_cmt = false;
return 0;
err_unregister:
devlink_unregister(dl);
err_free:
cdev->dl = NULL;
devlink_free(dl);
return rc;
}
static void qed_devlink_unregister(struct qed_dev *cdev)
{
if (!cdev->dl)
return;
devlink_params_unregister(cdev->dl, qed_devlink_params,
ARRAY_SIZE(qed_devlink_params));
devlink_unregister(cdev->dl);
devlink_free(cdev->dl);
}
/* probing */
static struct qed_dev *qed_probe(struct pci_dev *pdev,
struct qed_probe_params *params)
@ -370,6 +472,12 @@ static struct qed_dev *qed_probe(struct pci_dev *pdev,
}
DP_INFO(cdev, "PCI init completed successfully\n");
rc = qed_devlink_register(cdev);
if (rc) {
DP_INFO(cdev, "Failed to register devlink.\n");
goto err2;
}
rc = qed_hw_prepare(cdev, QED_PCI_DEFAULT);
if (rc) {
DP_ERR(cdev, "hw prepare failed\n");
@ -399,6 +507,8 @@ static void qed_remove(struct qed_dev *cdev)
qed_set_power_state(cdev, PCI_D3hot);
qed_devlink_unregister(cdev);
qed_free_cdev(cdev);
}
@ -1301,26 +1411,21 @@ static u32 qed_sb_init(struct qed_dev *cdev,
{
struct qed_hwfn *p_hwfn;
struct qed_ptt *p_ptt;
int hwfn_index;
u16 rel_sb_id;
u8 n_hwfns;
u32 rc;
/* RoCE uses single engine and CMT uses two engines. When using both
* we force only a single engine. Storage uses only engine 0 too.
*/
if (type == QED_SB_TYPE_L2_QUEUE)
n_hwfns = cdev->num_hwfns;
else
n_hwfns = 1;
hwfn_index = sb_id % n_hwfns;
p_hwfn = &cdev->hwfns[hwfn_index];
rel_sb_id = sb_id / n_hwfns;
/* RoCE/Storage use a single engine in CMT mode while L2 uses both */
if (type == QED_SB_TYPE_L2_QUEUE) {
p_hwfn = &cdev->hwfns[sb_id % cdev->num_hwfns];
rel_sb_id = sb_id / cdev->num_hwfns;
} else {
p_hwfn = QED_AFFIN_HWFN(cdev);
rel_sb_id = sb_id;
}
DP_VERBOSE(cdev, NETIF_MSG_INTR,
"hwfn [%d] <--[init]-- SB %04x [0x%04x upper]\n",
hwfn_index, rel_sb_id, sb_id);
IS_LEAD_HWFN(p_hwfn) ? 0 : 1, rel_sb_id, sb_id);
if (IS_PF(p_hwfn->cdev)) {
p_ptt = qed_ptt_acquire(p_hwfn);
@ -1339,20 +1444,26 @@ static u32 qed_sb_init(struct qed_dev *cdev,
}
static u32 qed_sb_release(struct qed_dev *cdev,
struct qed_sb_info *sb_info, u16 sb_id)
struct qed_sb_info *sb_info,
u16 sb_id,
enum qed_sb_type type)
{
struct qed_hwfn *p_hwfn;
int hwfn_index;
u16 rel_sb_id;
u32 rc;
hwfn_index = sb_id % cdev->num_hwfns;
p_hwfn = &cdev->hwfns[hwfn_index];
/* RoCE/Storage use a single engine in CMT mode while L2 uses both */
if (type == QED_SB_TYPE_L2_QUEUE) {
p_hwfn = &cdev->hwfns[sb_id % cdev->num_hwfns];
rel_sb_id = sb_id / cdev->num_hwfns;
} else {
p_hwfn = QED_AFFIN_HWFN(cdev);
rel_sb_id = sb_id;
}
DP_VERBOSE(cdev, NETIF_MSG_INTR,
"hwfn [%d] <--[init]-- SB %04x [0x%04x upper]\n",
hwfn_index, rel_sb_id, sb_id);
IS_LEAD_HWFN(p_hwfn) ? 0 : 1, rel_sb_id, sb_id);
rc = qed_int_sb_release(p_hwfn, sb_info, rel_sb_id);
@ -2372,6 +2483,11 @@ static int qed_read_module_eeprom(struct qed_dev *cdev, char *buf,
return rc;
}
static u8 qed_get_affin_hwfn_idx(struct qed_dev *cdev)
{
return QED_AFFIN_HWFN_IDX(cdev);
}
static struct qed_selftest_ops qed_selftest_ops_pass = {
.selftest_memory = &qed_selftest_memory,
.selftest_interrupt = &qed_selftest_interrupt,
@ -2419,6 +2535,7 @@ const struct qed_common_ops qed_common_ops_pass = {
.db_recovery_add = &qed_db_recovery_add,
.db_recovery_del = &qed_db_recovery_del,
.read_module_eeprom = &qed_read_module_eeprom,
.get_affin_hwfn_idx = &qed_get_affin_hwfn_idx,
};
void qed_get_protocol_stats(struct qed_dev *cdev,

View file

@ -3685,3 +3685,68 @@ int qed_mcp_set_capabilities(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
return qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_FEATURE_SUPPORT,
features, &mcp_resp, &mcp_param);
}
int qed_mcp_get_engine_config(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
{
struct qed_mcp_mb_params mb_params = {0};
struct qed_dev *cdev = p_hwfn->cdev;
u8 fir_valid, l2_valid;
int rc;
mb_params.cmd = DRV_MSG_CODE_GET_ENGINE_CONFIG;
rc = qed_mcp_cmd_and_union(p_hwfn, p_ptt, &mb_params);
if (rc)
return rc;
if (mb_params.mcp_resp == FW_MSG_CODE_UNSUPPORTED) {
DP_INFO(p_hwfn,
"The get_engine_config command is unsupported by the MFW\n");
return -EOPNOTSUPP;
}
fir_valid = QED_MFW_GET_FIELD(mb_params.mcp_param,
FW_MB_PARAM_ENG_CFG_FIR_AFFIN_VALID);
if (fir_valid)
cdev->fir_affin =
QED_MFW_GET_FIELD(mb_params.mcp_param,
FW_MB_PARAM_ENG_CFG_FIR_AFFIN_VALUE);
l2_valid = QED_MFW_GET_FIELD(mb_params.mcp_param,
FW_MB_PARAM_ENG_CFG_L2_AFFIN_VALID);
if (l2_valid)
cdev->l2_affin_hint =
QED_MFW_GET_FIELD(mb_params.mcp_param,
FW_MB_PARAM_ENG_CFG_L2_AFFIN_VALUE);
DP_INFO(p_hwfn,
"Engine affinity config: FIR={valid %hhd, value %hhd}, L2_hint={valid %hhd, value %hhd}\n",
fir_valid, cdev->fir_affin, l2_valid, cdev->l2_affin_hint);
return 0;
}
int qed_mcp_get_ppfid_bitmap(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
{
struct qed_mcp_mb_params mb_params = {0};
struct qed_dev *cdev = p_hwfn->cdev;
int rc;
mb_params.cmd = DRV_MSG_CODE_GET_PPFID_BITMAP;
rc = qed_mcp_cmd_and_union(p_hwfn, p_ptt, &mb_params);
if (rc)
return rc;
if (mb_params.mcp_resp == FW_MSG_CODE_UNSUPPORTED) {
DP_INFO(p_hwfn,
"The get_ppfid_bitmap command is unsupported by the MFW\n");
return -EOPNOTSUPP;
}
cdev->ppfid_bitmap = QED_MFW_GET_FIELD(mb_params.mcp_param,
FW_MB_PARAM_PPFID_BITMAP);
DP_VERBOSE(p_hwfn, QED_MSG_SP, "PPFID bitmap 0x%hhx\n",
cdev->ppfid_bitmap);
return 0;
}

View file

@ -1186,4 +1186,20 @@ void qed_mcp_read_ufp_config(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
*/
int qed_mcp_nvm_info_populate(struct qed_hwfn *p_hwfn);
/**
* @brief Get the engine affinity configuration.
*
* @param p_hwfn
* @param p_ptt
*/
int qed_mcp_get_engine_config(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
/**
* @brief Get the PPFID bitmap.
*
* @param p_hwfn
* @param p_ptt
*/
int qed_mcp_get_ppfid_bitmap(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
#endif

View file

@ -700,7 +700,7 @@ static int qed_rdma_setup(struct qed_hwfn *p_hwfn,
return rc;
if (QED_IS_IWARP_PERSONALITY(p_hwfn)) {
rc = qed_iwarp_setup(p_hwfn, p_ptt, params);
rc = qed_iwarp_setup(p_hwfn, params);
if (rc)
return rc;
} else {
@ -742,7 +742,7 @@ static int qed_rdma_stop(void *rdma_cxt)
(ll2_ethertype_en & 0xFFFE));
if (QED_IS_IWARP_PERSONALITY(p_hwfn)) {
rc = qed_iwarp_stop(p_hwfn, p_ptt);
rc = qed_iwarp_stop(p_hwfn);
if (rc) {
qed_ptt_release(p_hwfn, p_ptt);
return rc;
@ -803,7 +803,7 @@ static int qed_rdma_add_user(void *rdma_cxt,
dpi_start_offset +
((out_params->dpi) * p_hwfn->dpi_size));
out_params->dpi_phys_addr = p_hwfn->cdev->db_phys_addr +
out_params->dpi_phys_addr = p_hwfn->db_phys_addr +
dpi_start_offset +
((out_params->dpi) * p_hwfn->dpi_size);
@ -818,14 +818,17 @@ static struct qed_rdma_port *qed_rdma_query_port(void *rdma_cxt)
{
struct qed_hwfn *p_hwfn = (struct qed_hwfn *)rdma_cxt;
struct qed_rdma_port *p_port = p_hwfn->p_rdma_info->port;
struct qed_mcp_link_state *p_link_output;
DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "RDMA Query port\n");
/* Link may have changed */
p_port->port_state = p_hwfn->mcp_info->link_output.link_up ?
QED_RDMA_PORT_UP : QED_RDMA_PORT_DOWN;
/* The link state is saved only for the leading hwfn */
p_link_output = &QED_LEADING_HWFN(p_hwfn->cdev)->mcp_info->link_output;
p_port->link_speed = p_hwfn->mcp_info->link_output.speed;
p_port->port_state = p_link_output->link_up ? QED_RDMA_PORT_UP
: QED_RDMA_PORT_DOWN;
p_port->link_speed = p_link_output->speed;
p_port->max_msg_size = RDMA_MAX_DATA_SIZE_IN_WQE;
@ -870,7 +873,7 @@ static void qed_rdma_cnq_prod_update(void *rdma_cxt, u8 qz_offset, u16 prod)
static int qed_fill_rdma_dev_info(struct qed_dev *cdev,
struct qed_dev_rdma_info *info)
{
struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
struct qed_hwfn *p_hwfn = QED_AFFIN_HWFN(cdev);
memset(info, 0, sizeof(*info));
@ -889,9 +892,9 @@ static int qed_rdma_get_sb_start(struct qed_dev *cdev)
int feat_num;
if (cdev->num_hwfns > 1)
feat_num = FEAT_NUM(QED_LEADING_HWFN(cdev), QED_PF_L2_QUE);
feat_num = FEAT_NUM(QED_AFFIN_HWFN(cdev), QED_PF_L2_QUE);
else
feat_num = FEAT_NUM(QED_LEADING_HWFN(cdev), QED_PF_L2_QUE) *
feat_num = FEAT_NUM(QED_AFFIN_HWFN(cdev), QED_PF_L2_QUE) *
cdev->num_hwfns;
return feat_num;
@ -899,7 +902,7 @@ static int qed_rdma_get_sb_start(struct qed_dev *cdev)
static int qed_rdma_get_min_cnq_msix(struct qed_dev *cdev)
{
int n_cnq = FEAT_NUM(QED_LEADING_HWFN(cdev), QED_RDMA_CNQ);
int n_cnq = FEAT_NUM(QED_AFFIN_HWFN(cdev), QED_RDMA_CNQ);
int n_msix = cdev->int_params.rdma_msix_cnt;
return min_t(int, n_cnq, n_msix);
@ -1653,7 +1656,7 @@ static int qed_rdma_deregister_tid(void *rdma_cxt, u32 itid)
static void *qed_rdma_get_rdma_ctx(struct qed_dev *cdev)
{
return QED_LEADING_HWFN(cdev);
return QED_AFFIN_HWFN(cdev);
}
static int qed_rdma_modify_srq(void *rdma_cxt,
@ -1881,7 +1884,7 @@ static int qed_rdma_start(void *rdma_cxt,
static int qed_rdma_init(struct qed_dev *cdev,
struct qed_rdma_start_in_params *params)
{
return qed_rdma_start(QED_LEADING_HWFN(cdev), params);
return qed_rdma_start(QED_AFFIN_HWFN(cdev), params);
}
static void qed_rdma_remove_user(void *rdma_cxt, u16 dpi)
@ -1899,23 +1902,12 @@ static int qed_roce_ll2_set_mac_filter(struct qed_dev *cdev,
u8 *old_mac_address,
u8 *new_mac_address)
{
struct qed_hwfn *p_hwfn = QED_LEADING_HWFN(cdev);
struct qed_ptt *p_ptt;
int rc = 0;
p_ptt = qed_ptt_acquire(p_hwfn);
if (!p_ptt) {
DP_ERR(cdev,
"qed roce ll2 mac filter set: failed to acquire PTT\n");
return -EINVAL;
}
if (old_mac_address)
qed_llh_remove_mac_filter(p_hwfn, p_ptt, old_mac_address);
qed_llh_remove_mac_filter(cdev, 0, old_mac_address);
if (new_mac_address)
rc = qed_llh_add_mac_filter(p_hwfn, p_ptt, new_mac_address);
qed_ptt_release(p_hwfn, p_ptt);
rc = qed_llh_add_mac_filter(cdev, 0, new_mac_address);
if (rc)
DP_ERR(cdev,
@ -1924,6 +1916,36 @@ static int qed_roce_ll2_set_mac_filter(struct qed_dev *cdev,
return rc;
}
static int qed_iwarp_set_engine_affin(struct qed_dev *cdev, bool b_reset)
{
enum qed_eng eng;
u8 ppfid = 0;
int rc;
/* Make sure iwarp cmt mode is enabled before setting affinity */
if (!cdev->iwarp_cmt)
return -EINVAL;
if (b_reset)
eng = QED_BOTH_ENG;
else
eng = cdev->l2_affin_hint ? QED_ENG1 : QED_ENG0;
rc = qed_llh_set_ppfid_affinity(cdev, ppfid, eng);
if (rc) {
DP_NOTICE(cdev,
"Failed to set the engine affinity of ppfid %d\n",
ppfid);
return rc;
}
DP_VERBOSE(cdev, (QED_MSG_RDMA | QED_MSG_SP),
"LLH: Set the engine affinity of non-RoCE packets as %d\n",
eng);
return 0;
}
static const struct qed_rdma_ops qed_rdma_ops_pass = {
.common = &qed_common_ops_pass,
.fill_dev_info = &qed_fill_rdma_dev_info,
@ -1963,6 +1985,7 @@ static const struct qed_rdma_ops qed_rdma_ops_pass = {
.ll2_set_fragment_of_tx_packet = &qed_ll2_set_fragment_of_tx_packet,
.ll2_set_mac_filter = &qed_roce_ll2_set_mac_filter,
.ll2_get_stats = &qed_ll2_get_stats,
.iwarp_set_engine_affin = &qed_iwarp_set_engine_affin,
.iwarp_connect = &qed_iwarp_connect,
.iwarp_create_listen = &qed_iwarp_create_listen,
.iwarp_destroy_listen = &qed_iwarp_destroy_listen,

View file

@ -254,6 +254,10 @@
0x500840UL
#define NIG_REG_LLH_TAGMAC_DEF_PF_VECTOR \
0x50196cUL
#define NIG_REG_LLH_PPFID2PFID_TBL_0 \
0x501970UL
#define NIG_REG_LLH_ENG_CLS_ROCE_QP_SEL \
0x50
#define NIG_REG_LLH_CLS_TYPE_DUALMODE \
0x501964UL
#define NIG_REG_LLH_FUNC_TAG_EN 0x5019b0UL
@ -1626,6 +1630,8 @@
#define PHY_PCIE_REG_PHY1_K2_E5 \
0x624000UL
#define NIG_REG_ROCE_DUPLICATE_TO_HOST 0x5088f0UL
#define NIG_REG_PPF_TO_ENGINE_SEL 0x508900UL
#define NIG_REG_PPF_TO_ENGINE_SEL_SIZE 8
#define PRS_REG_LIGHT_L2_ETHERTYPE_EN 0x1f0968UL
#define NIG_REG_LLH_ENG_CLS_ENG_ID_TBL 0x501b90UL
#define DORQ_REG_PF_DPM_ENABLE 0x100510UL

View file

@ -917,10 +917,11 @@ static u8 qed_iov_alloc_vf_igu_sbs(struct qed_hwfn *p_hwfn,
/* Configure igu sb in CAU which were marked valid */
qed_init_cau_sb_entry(p_hwfn, &sb_entry,
p_hwfn->rel_pf_id, vf->abs_vf_id, 1);
qed_dmae_host2grc(p_hwfn, p_ptt,
(u64)(uintptr_t)&sb_entry,
CAU_REG_SB_VAR_MEMORY +
p_block->igu_sb_id * sizeof(u64), 2, 0);
p_block->igu_sb_id * sizeof(u64), 2, NULL);
}
vf->num_sbs = (u8) num_rx_queues;

View file

@ -1306,7 +1306,8 @@ static void qede_free_mem_sb(struct qede_dev *edev, struct qed_sb_info *sb_info,
u16 sb_id)
{
if (sb_info->sb_virt) {
edev->ops->common->sb_release(edev->cdev, sb_info, sb_id);
edev->ops->common->sb_release(edev->cdev, sb_info, sb_id,
QED_SB_TYPE_L2_QUEUE);
dma_free_coherent(&edev->pdev->dev, sizeof(*sb_info->sb_virt),
(void *)sb_info->sb_virt, sb_info->sb_phys);
memset(sb_info, 0, sizeof(*sb_info));

View file

@ -2218,16 +2218,21 @@ static void qedf_simd_int_handler(void *cookie)
static void qedf_sync_free_irqs(struct qedf_ctx *qedf)
{
int i;
u16 vector_idx = 0;
u32 vector;
if (qedf->int_info.msix_cnt) {
for (i = 0; i < qedf->int_info.used_cnt; i++) {
synchronize_irq(qedf->int_info.msix[i].vector);
irq_set_affinity_hint(qedf->int_info.msix[i].vector,
NULL);
irq_set_affinity_notifier(qedf->int_info.msix[i].vector,
NULL);
free_irq(qedf->int_info.msix[i].vector,
&qedf->fp_array[i]);
vector_idx = i * qedf->dev_info.common.num_hwfns +
qed_ops->common->get_affin_hwfn_idx(qedf->cdev);
QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC,
"Freeing IRQ #%d vector_idx=%d.\n",
i, vector_idx);
vector = qedf->int_info.msix[vector_idx].vector;
synchronize_irq(vector);
irq_set_affinity_hint(vector, NULL);
irq_set_affinity_notifier(vector, NULL);
free_irq(vector, &qedf->fp_array[i]);
}
} else
qed_ops->common->simd_handler_clean(qedf->cdev,
@ -2240,11 +2245,19 @@ static void qedf_sync_free_irqs(struct qedf_ctx *qedf)
static int qedf_request_msix_irq(struct qedf_ctx *qedf)
{
int i, rc, cpu;
u16 vector_idx = 0;
u32 vector;
cpu = cpumask_first(cpu_online_mask);
for (i = 0; i < qedf->num_queues; i++) {
rc = request_irq(qedf->int_info.msix[i].vector,
qedf_msix_handler, 0, "qedf", &qedf->fp_array[i]);
vector_idx = i * qedf->dev_info.common.num_hwfns +
qed_ops->common->get_affin_hwfn_idx(qedf->cdev);
QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC,
"Requesting IRQ #%d vector_idx=%d.\n",
i, vector_idx);
vector = qedf->int_info.msix[vector_idx].vector;
rc = request_irq(vector, qedf_msix_handler, 0, "qedf",
&qedf->fp_array[i]);
if (rc) {
QEDF_WARN(&(qedf->dbg_ctx), "request_irq failed.\n");
@ -2253,8 +2266,7 @@ static int qedf_request_msix_irq(struct qedf_ctx *qedf)
}
qedf->int_info.used_cnt++;
rc = irq_set_affinity_hint(qedf->int_info.msix[i].vector,
get_cpu_mask(cpu));
rc = irq_set_affinity_hint(vector, get_cpu_mask(cpu));
cpu = cpumask_next(cpu, cpu_online_mask);
}
@ -3211,6 +3223,11 @@ static int __qedf_probe(struct pci_dev *pdev, int mode)
goto err1;
}
QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC,
"dev_info: num_hwfns=%d affin_hwfn_idx=%d.\n",
qedf->dev_info.common.num_hwfns,
qed_ops->common->get_affin_hwfn_idx(qedf->cdev));
/* queue allocation code should come here
* order should be
* slowpath_start

View file

@ -1313,13 +1313,20 @@ static void qedi_simd_int_handler(void *cookie)
static void qedi_sync_free_irqs(struct qedi_ctx *qedi)
{
int i;
u16 idx;
if (qedi->int_info.msix_cnt) {
for (i = 0; i < qedi->int_info.used_cnt; i++) {
synchronize_irq(qedi->int_info.msix[i].vector);
irq_set_affinity_hint(qedi->int_info.msix[i].vector,
idx = i * qedi->dev_info.common.num_hwfns +
qedi_ops->common->get_affin_hwfn_idx(qedi->cdev);
QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
"Freeing IRQ #%d vector_idx=%d.\n", i, idx);
synchronize_irq(qedi->int_info.msix[idx].vector);
irq_set_affinity_hint(qedi->int_info.msix[idx].vector,
NULL);
free_irq(qedi->int_info.msix[i].vector,
free_irq(qedi->int_info.msix[idx].vector,
&qedi->fp_array[i]);
}
} else {
@ -1334,20 +1341,28 @@ static void qedi_sync_free_irqs(struct qedi_ctx *qedi)
static int qedi_request_msix_irq(struct qedi_ctx *qedi)
{
int i, rc, cpu;
u16 idx;
cpu = cpumask_first(cpu_online_mask);
for (i = 0; i < qedi->int_info.msix_cnt; i++) {
rc = request_irq(qedi->int_info.msix[i].vector,
for (i = 0; i < MIN_NUM_CPUS_MSIX(qedi); i++) {
idx = i * qedi->dev_info.common.num_hwfns +
qedi_ops->common->get_affin_hwfn_idx(qedi->cdev);
QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
"dev_info: num_hwfns=%d affin_hwfn_idx=%d.\n",
qedi->dev_info.common.num_hwfns,
qedi_ops->common->get_affin_hwfn_idx(qedi->cdev));
rc = request_irq(qedi->int_info.msix[idx].vector,
qedi_msix_handler, 0, "qedi",
&qedi->fp_array[i]);
if (rc) {
QEDI_WARN(&qedi->dbg_ctx, "request_irq failed.\n");
qedi_sync_free_irqs(qedi);
return rc;
}
qedi->int_info.used_cnt++;
rc = irq_set_affinity_hint(qedi->int_info.msix[i].vector,
rc = irq_set_affinity_hint(qedi->int_info.msix[idx].vector,
get_cpu_mask(cpu));
cpu = cpumask_next(cpu, cpu_online_mask);
}
@ -2415,6 +2430,11 @@ static int __qedi_probe(struct pci_dev *pdev, int mode)
if (rc)
goto free_host;
QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
"dev_info: num_hwfns=%d affin_hwfn_idx=%d.\n",
qedi->dev_info.common.num_hwfns,
qedi_ops->common->get_affin_hwfn_idx(qedi->cdev));
if (mode != QEDI_MODE_RECOVERY) {
rc = qedi_set_iscsi_pf_param(qedi);
if (rc) {

View file

@ -907,7 +907,8 @@ struct qed_common_ops {
u32 (*sb_release)(struct qed_dev *cdev,
struct qed_sb_info *sb_info,
u16 sb_id);
u16 sb_id,
enum qed_sb_type type);
void (*simd_handler_config)(struct qed_dev *cdev,
void *token,
@ -1123,6 +1124,13 @@ struct qed_common_ops {
*/
int (*read_module_eeprom)(struct qed_dev *cdev,
char *buf, u8 dev_addr, u32 offset, u32 len);
/**
* @brief get_affin_hwfn_idx
*
* @param cdev
*/
u8 (*get_affin_hwfn_idx)(struct qed_dev *cdev);
};
#define MASK_FIELD(_name, _value) \

View file

@ -670,6 +670,8 @@ struct qed_rdma_ops {
int (*ll2_set_mac_filter)(struct qed_dev *cdev,
u8 *old_mac_address, u8 *new_mac_address);
int (*iwarp_set_engine_affin)(struct qed_dev *cdev, bool b_reset);
int (*iwarp_connect)(void *rdma_cxt,
struct qed_iwarp_connect_in *iparams,
struct qed_iwarp_connect_out *oparams);