Commit 0db711bb authored by Mintz, Yuval's avatar Mintz, Yuval Committed by David S. Miller

qed: Create L2 queue database

First step in allowing a single PF/VF to open multiple queues on
the same queue zone is to add per-hwfn database of queue-cids
as a two-dimensional array where entry would be according to
[queue zone][internal index].
Signed-off-by: default avatarYuval Mintz <Yuval.Mintz@cavium.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6bea61da
...@@ -533,6 +533,9 @@ struct qed_hwfn { ...@@ -533,6 +533,9 @@ struct qed_hwfn {
u8 dcbx_no_edpm; u8 dcbx_no_edpm;
u8 db_bar_no_edpm; u8 db_bar_no_edpm;
/* L2-related */
struct qed_l2_info *p_l2_info;
struct qed_ptt *p_arfs_ptt; struct qed_ptt *p_arfs_ptt;
struct qed_simd_fp_handler simd_proto_handler[64]; struct qed_simd_fp_handler simd_proto_handler[64];
......
...@@ -154,8 +154,11 @@ void qed_resc_free(struct qed_dev *cdev) ...@@ -154,8 +154,11 @@ void qed_resc_free(struct qed_dev *cdev)
{ {
int i; int i;
if (IS_VF(cdev)) if (IS_VF(cdev)) {
for_each_hwfn(cdev, i)
qed_l2_free(&cdev->hwfns[i]);
return; return;
}
kfree(cdev->fw_data); kfree(cdev->fw_data);
cdev->fw_data = NULL; cdev->fw_data = NULL;
...@@ -183,6 +186,7 @@ void qed_resc_free(struct qed_dev *cdev) ...@@ -183,6 +186,7 @@ void qed_resc_free(struct qed_dev *cdev)
qed_ooo_free(p_hwfn); qed_ooo_free(p_hwfn);
} }
qed_iov_free(p_hwfn); qed_iov_free(p_hwfn);
qed_l2_free(p_hwfn);
qed_dmae_info_free(p_hwfn); qed_dmae_info_free(p_hwfn);
qed_dcbx_info_free(p_hwfn); qed_dcbx_info_free(p_hwfn);
} }
...@@ -848,8 +852,14 @@ int qed_resc_alloc(struct qed_dev *cdev) ...@@ -848,8 +852,14 @@ int qed_resc_alloc(struct qed_dev *cdev)
u32 line_count; u32 line_count;
int i, rc = 0; int i, rc = 0;
if (IS_VF(cdev)) if (IS_VF(cdev)) {
for_each_hwfn(cdev, i) {
rc = qed_l2_alloc(&cdev->hwfns[i]);
if (rc)
return rc;
}
return rc; return rc;
}
cdev->fw_data = kzalloc(sizeof(*cdev->fw_data), GFP_KERNEL); cdev->fw_data = kzalloc(sizeof(*cdev->fw_data), GFP_KERNEL);
if (!cdev->fw_data) if (!cdev->fw_data)
...@@ -960,6 +970,10 @@ int qed_resc_alloc(struct qed_dev *cdev) ...@@ -960,6 +970,10 @@ int qed_resc_alloc(struct qed_dev *cdev)
if (rc) if (rc)
goto alloc_err; goto alloc_err;
rc = qed_l2_alloc(p_hwfn);
if (rc)
goto alloc_err;
#ifdef CONFIG_QED_LL2 #ifdef CONFIG_QED_LL2
if (p_hwfn->using_ll2) { if (p_hwfn->using_ll2) {
rc = qed_ll2_alloc(p_hwfn); rc = qed_ll2_alloc(p_hwfn);
...@@ -1011,8 +1025,11 @@ void qed_resc_setup(struct qed_dev *cdev) ...@@ -1011,8 +1025,11 @@ void qed_resc_setup(struct qed_dev *cdev)
{ {
int i; int i;
if (IS_VF(cdev)) if (IS_VF(cdev)) {
for_each_hwfn(cdev, i)
qed_l2_setup(&cdev->hwfns[i]);
return; return;
}
for_each_hwfn(cdev, i) { for_each_hwfn(cdev, i) {
struct qed_hwfn *p_hwfn = &cdev->hwfns[i]; struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
...@@ -1030,6 +1047,7 @@ void qed_resc_setup(struct qed_dev *cdev) ...@@ -1030,6 +1047,7 @@ void qed_resc_setup(struct qed_dev *cdev)
qed_int_setup(p_hwfn, p_hwfn->p_main_ptt); qed_int_setup(p_hwfn, p_hwfn->p_main_ptt);
qed_l2_setup(p_hwfn);
qed_iov_setup(p_hwfn); qed_iov_setup(p_hwfn);
#ifdef CONFIG_QED_LL2 #ifdef CONFIG_QED_LL2
if (p_hwfn->using_ll2) if (p_hwfn->using_ll2)
......
...@@ -65,6 +65,92 @@ ...@@ -65,6 +65,92 @@
#define QED_MAX_SGES_NUM 16 #define QED_MAX_SGES_NUM 16
#define CRC32_POLY 0x1edc6f41 #define CRC32_POLY 0x1edc6f41
struct qed_l2_info {
u32 queues;
unsigned long **pp_qid_usage;
/* The lock is meant to synchronize access to the qid usage */
struct mutex lock;
};
int qed_l2_alloc(struct qed_hwfn *p_hwfn)
{
struct qed_l2_info *p_l2_info;
unsigned long **pp_qids;
u32 i;
if (p_hwfn->hw_info.personality != QED_PCI_ETH &&
p_hwfn->hw_info.personality != QED_PCI_ETH_ROCE)
return 0;
p_l2_info = kzalloc(sizeof(*p_l2_info), GFP_KERNEL);
if (!p_l2_info)
return -ENOMEM;
p_hwfn->p_l2_info = p_l2_info;
if (IS_PF(p_hwfn->cdev)) {
p_l2_info->queues = RESC_NUM(p_hwfn, QED_L2_QUEUE);
} else {
u8 rx = 0, tx = 0;
qed_vf_get_num_rxqs(p_hwfn, &rx);
qed_vf_get_num_txqs(p_hwfn, &tx);
p_l2_info->queues = max_t(u8, rx, tx);
}
pp_qids = kzalloc(sizeof(unsigned long *) * p_l2_info->queues,
GFP_KERNEL);
if (!pp_qids)
return -ENOMEM;
p_l2_info->pp_qid_usage = pp_qids;
for (i = 0; i < p_l2_info->queues; i++) {
pp_qids[i] = kzalloc(MAX_QUEUES_PER_QZONE / 8, GFP_KERNEL);
if (!pp_qids[i])
return -ENOMEM;
}
return 0;
}
void qed_l2_setup(struct qed_hwfn *p_hwfn)
{
if (p_hwfn->hw_info.personality != QED_PCI_ETH &&
p_hwfn->hw_info.personality != QED_PCI_ETH_ROCE)
return;
mutex_init(&p_hwfn->p_l2_info->lock);
}
void qed_l2_free(struct qed_hwfn *p_hwfn)
{
u32 i;
if (p_hwfn->hw_info.personality != QED_PCI_ETH &&
p_hwfn->hw_info.personality != QED_PCI_ETH_ROCE)
return;
if (!p_hwfn->p_l2_info)
return;
if (!p_hwfn->p_l2_info->pp_qid_usage)
goto out_l2_info;
/* Free until hit first uninitialized entry */
for (i = 0; i < p_hwfn->p_l2_info->queues; i++) {
if (!p_hwfn->p_l2_info->pp_qid_usage[i])
break;
kfree(p_hwfn->p_l2_info->pp_qid_usage[i]);
}
kfree(p_hwfn->p_l2_info->pp_qid_usage);
out_l2_info:
kfree(p_hwfn->p_l2_info);
p_hwfn->p_l2_info = NULL;
}
void qed_eth_queue_cid_release(struct qed_hwfn *p_hwfn, void qed_eth_queue_cid_release(struct qed_hwfn *p_hwfn,
struct qed_queue_cid *p_cid) struct qed_queue_cid *p_cid)
{ {
......
...@@ -277,6 +277,8 @@ void qed_get_vport_stats(struct qed_dev *cdev, struct qed_eth_stats *stats); ...@@ -277,6 +277,8 @@ void qed_get_vport_stats(struct qed_dev *cdev, struct qed_eth_stats *stats);
void qed_reset_vport_stats(struct qed_dev *cdev); void qed_reset_vport_stats(struct qed_dev *cdev);
#define MAX_QUEUES_PER_QZONE (sizeof(unsigned long) * 8)
struct qed_queue_cid { struct qed_queue_cid {
/* 'Relative' is a relative term ;-). Usually the indices [not counting /* 'Relative' is a relative term ;-). Usually the indices [not counting
* SBs] would be PF-relative, but there are some cases where that isn't * SBs] would be PF-relative, but there are some cases where that isn't
...@@ -302,6 +304,10 @@ struct qed_queue_cid { ...@@ -302,6 +304,10 @@ struct qed_queue_cid {
struct qed_hwfn *p_owner; struct qed_hwfn *p_owner;
}; };
int qed_l2_alloc(struct qed_hwfn *p_hwfn);
void qed_l2_setup(struct qed_hwfn *p_hwfn);
void qed_l2_free(struct qed_hwfn *p_hwfn);
void qed_eth_queue_cid_release(struct qed_hwfn *p_hwfn, void qed_eth_queue_cid_release(struct qed_hwfn *p_hwfn,
struct qed_queue_cid *p_cid); struct qed_queue_cid *p_cid);
......
...@@ -1363,6 +1363,11 @@ void qed_vf_get_num_rxqs(struct qed_hwfn *p_hwfn, u8 *num_rxqs) ...@@ -1363,6 +1363,11 @@ void qed_vf_get_num_rxqs(struct qed_hwfn *p_hwfn, u8 *num_rxqs)
*num_rxqs = p_hwfn->vf_iov_info->acquire_resp.resc.num_rxqs; *num_rxqs = p_hwfn->vf_iov_info->acquire_resp.resc.num_rxqs;
} }
void qed_vf_get_num_txqs(struct qed_hwfn *p_hwfn, u8 *num_txqs)
{
*num_txqs = p_hwfn->vf_iov_info->acquire_resp.resc.num_txqs;
}
void qed_vf_get_port_mac(struct qed_hwfn *p_hwfn, u8 *port_mac) void qed_vf_get_port_mac(struct qed_hwfn *p_hwfn, u8 *port_mac)
{ {
memcpy(port_mac, memcpy(port_mac,
......
...@@ -683,6 +683,14 @@ void qed_vf_get_link_caps(struct qed_hwfn *p_hwfn, ...@@ -683,6 +683,14 @@ void qed_vf_get_link_caps(struct qed_hwfn *p_hwfn,
*/ */
void qed_vf_get_num_rxqs(struct qed_hwfn *p_hwfn, u8 *num_rxqs); void qed_vf_get_num_rxqs(struct qed_hwfn *p_hwfn, u8 *num_rxqs);
/**
* @brief Get number of Rx queues allocated for VF by qed
*
* @param p_hwfn
* @param num_txqs - allocated RX queues
*/
void qed_vf_get_num_txqs(struct qed_hwfn *p_hwfn, u8 *num_txqs);
/** /**
* @brief Get port mac address for VF * @brief Get port mac address for VF
* *
...@@ -956,6 +964,10 @@ static inline void qed_vf_get_num_rxqs(struct qed_hwfn *p_hwfn, u8 *num_rxqs) ...@@ -956,6 +964,10 @@ static inline void qed_vf_get_num_rxqs(struct qed_hwfn *p_hwfn, u8 *num_rxqs)
{ {
} }
static inline void qed_vf_get_num_txqs(struct qed_hwfn *p_hwfn, u8 *num_txqs)
{
}
static inline void qed_vf_get_port_mac(struct qed_hwfn *p_hwfn, u8 *port_mac) static inline void qed_vf_get_port_mac(struct qed_hwfn *p_hwfn, u8 *port_mac)
{ {
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment