summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorHaiying Wang <Haiying.Wang@freescale.com>2013-10-18 19:27:13 (GMT)
committerJ. German Rivera <German.Rivera@freescale.com>2013-10-22 20:14:50 (GMT)
commit79bd27e905da1b17a17ea807c04dc7fddd0dcb14 (patch)
tree6ece4e072fe0590331e1692289caf5fc9744ea1e /drivers
parentc0e2e95af2c30aaf2161633623d3f32f91403071 (diff)
downloadlinux-fsl-qoriq-79bd27e905da1b17a17ea807c04dc7fddd0dcb14.tar.xz
fsl_qman: add APIs to set CQ CR/ER eligibility within the channel
Signed-off-by: Haiying Wang <Haiying.Wang@freescale.com> Change-Id: I1ba0d8eb5f0a5c4b1b7156e2556253b916d351e9 Reviewed-on: http://git.am.freescale.net:8181/5871 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com> Reviewed-by: Thorpe Geoff-R01361 <Geoff.Thorpe@freescale.com> Reviewed-by: Rivera Jose-B46482 <German.Rivera@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/fsl_qbman/qman_high.c221
1 files changed, 142 insertions, 79 deletions
diff --git a/drivers/staging/fsl_qbman/qman_high.c b/drivers/staging/fsl_qbman/qman_high.c
index 00ecab8..af190cd 100644
--- a/drivers/staging/fsl_qbman/qman_high.c
+++ b/drivers/staging/fsl_qbman/qman_high.c
@@ -4001,18 +4001,154 @@ int qman_ceetm_channel_get_group(struct qm_ceetm_channel *channel, int *group_b,
}
EXPORT_SYMBOL(qman_ceetm_channel_get_group);
-#define CQ_ELIGIBILITY_MASK(n) (1 << (7 - n))
-#define CQ_A_ELIGIBILITY_MASK (1 << 8)
-#define CQ_B_ELIGIBILITY_MASK (1 << 9)
+#define GROUP_A_ELIGIBILITY_SET (1 << 8)
+#define GROUP_B_ELIGIBILITY_SET (1 << 9)
+#define CQ_ELIGIBILITY_SET(n) (1 << (7 - n))
+int qman_ceetm_channel_set_group_cr_eligibility(struct qm_ceetm_channel
+ *channel, int group_b, int cre)
+{
+ struct qm_mcc_ceetm_class_scheduler_config csch_config;
+ struct qm_mcr_ceetm_class_scheduler_query csch_query;
+ int i;
+
+ if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
+ pr_err("Cannot get the channel %d scheduler setting.\n",
+ channel->idx);
+ return -EINVAL;
+ }
+ csch_config.cqcid = channel->idx;
+ csch_config.dcpid = channel->dcp_idx;
+ csch_config.gpc = csch_query.gpc;
+ for (i = 0; i < 8; i++)
+ csch_config.w[i] = csch_query.w[i];
+ csch_config.erem = csch_query.erem;
+ if (group_b)
+ csch_config.crem = (csch_query.crem & ~GROUP_B_ELIGIBILITY_SET)
+ | (cre ? GROUP_B_ELIGIBILITY_SET : 0);
+ else
+ csch_config.crem = (csch_query.crem & ~GROUP_A_ELIGIBILITY_SET)
+ | (cre ? GROUP_A_ELIGIBILITY_SET : 0);
+
+ if (qman_ceetm_configure_class_scheduler(&csch_config)) {
+ pr_err("Cannot config channel %d's scheduler with "
+ "group_%c's cr eligibility\n", channel->idx,
+ group_b ? 'b' : 'a');
+ return -EINVAL;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(qman_ceetm_channel_set_group_cr_eligibility);
+
+int qman_ceetm_channel_set_group_er_eligibility(struct qm_ceetm_channel
+ *channel, int group_b, int ere)
+{
+ struct qm_mcc_ceetm_class_scheduler_config csch_config;
+ struct qm_mcr_ceetm_class_scheduler_query csch_query;
+ int i;
+
+ if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
+ pr_err("Cannot get the channel %d scheduler setting.\n",
+ channel->idx);
+ return -EINVAL;
+ }
+ csch_config.cqcid = channel->idx;
+ csch_config.dcpid = channel->dcp_idx;
+ csch_config.gpc = csch_query.gpc;
+ for (i = 0; i < 8; i++)
+ csch_config.w[i] = csch_query.w[i];
+ csch_config.crem = csch_query.crem;
+ if (group_b)
+ csch_config.erem = (csch_query.erem & ~GROUP_B_ELIGIBILITY_SET)
+ | (ere ? GROUP_B_ELIGIBILITY_SET : 0);
+ else
+ csch_config.erem = (csch_query.erem & ~GROUP_A_ELIGIBILITY_SET)
+ | (ere ? GROUP_A_ELIGIBILITY_SET : 0);
+
+ if (qman_ceetm_configure_class_scheduler(&csch_config)) {
+ pr_err("Cannot config channel %d's scheduler with "
+ "group_%c's er eligibility\n", channel->idx,
+ group_b ? 'b' : 'a');
+ return -EINVAL;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(qman_ceetm_channel_set_group_er_eligibility);
+
+int qman_ceetm_channel_set_cq_cr_eligibility(struct qm_ceetm_channel *channel,
+ unsigned int idx, u16 cre)
+{
+ struct qm_mcc_ceetm_class_scheduler_config csch_config;
+ struct qm_mcr_ceetm_class_scheduler_query csch_query;
+ int i;
+
+ if (idx > 7) {
+ pr_err("CQ index is out of range\n");
+ return -EINVAL;
+ }
+ if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
+ pr_err("Cannot get the channel %d scheduler setting.\n",
+ channel->idx);
+ return -EINVAL;
+ }
+ csch_config.cqcid = channel->idx;
+ csch_config.dcpid = channel->dcp_idx;
+ csch_config.gpc = csch_query.gpc;
+ for (i = 0; i < 8; i++)
+ csch_config.w[i] = csch_query.w[i];
+ csch_config.erem = csch_query.erem;
+ csch_config.crem = (csch_query.crem & ~CQ_ELIGIBILITY_SET(idx)) |
+ (cre ? CQ_ELIGIBILITY_SET(idx) : 0);
+ if (qman_ceetm_configure_class_scheduler(&csch_config)) {
+ pr_err("Cannot config channel scheduler to set "
+ "cr eligibility mask for CQ#%d\n", idx);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(qman_ceetm_channel_set_cq_cr_eligibility);
+
+int qman_ceetm_channel_set_cq_er_eligibility(struct qm_ceetm_channel *channel,
+ unsigned int idx, u16 ere)
+{
+ struct qm_mcc_ceetm_class_scheduler_config csch_config;
+ struct qm_mcr_ceetm_class_scheduler_query csch_query;
+ int i;
+
+ if (idx > 7) {
+ pr_err("CQ index is out of range\n");
+ return -EINVAL;
+ }
+ if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
+ pr_err("Cannot get the channel %d scheduler setting.\n",
+ channel->idx);
+ return -EINVAL;
+ }
+ csch_config.cqcid = channel->idx;
+ csch_config.dcpid = channel->dcp_idx;
+ csch_config.gpc = csch_query.gpc;
+ for (i = 0; i < 8; i++)
+ csch_config.w[i] = csch_query.w[i];
+ csch_config.crem = csch_query.crem;
+ csch_config.erem = (csch_query.erem & ~CQ_ELIGIBILITY_SET(idx)) |
+ (ere ? CQ_ELIGIBILITY_SET(idx) : 0);
+ if (qman_ceetm_configure_class_scheduler(&csch_config)) {
+ pr_err("Cannot config channel scheduler to set "
+ "er eligibility mask for CQ#%d\n", idx);
+ return -EINVAL;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(qman_ceetm_channel_set_cq_er_eligibility);
+
int qman_ceetm_cq_claim(struct qm_ceetm_cq **cq,
struct qm_ceetm_channel *channel, unsigned int idx,
struct qm_ceetm_ccg *ccg)
{
struct qm_ceetm_cq *p;
struct qm_mcc_ceetm_cq_config cq_config;
- struct qm_mcc_ceetm_class_scheduler_config csch_config;
- struct qm_mcr_ceetm_class_scheduler_query csch_query_result;
- int i;
if (idx > 7) {
pr_err("The independent class queue id is out of range\n");
@@ -4049,29 +4185,6 @@ int qman_ceetm_cq_claim(struct qm_ceetm_cq **cq,
}
}
- if (channel->shaper_enable) {
- if (qman_ceetm_query_class_scheduler(channel,
- &csch_query_result)) {
- pr_err("Can't query channel#%d!\n", channel->idx);
- return -EINVAL;
- }
- csch_config.cqcid = channel->idx;
- csch_config.dcpid = channel->dcp_idx;
- csch_config.crem = csch_query_result.crem |
- CQ_ELIGIBILITY_MASK(idx);
- csch_config.erem = csch_query_result.erem |
- CQ_ELIGIBILITY_MASK(idx);
- csch_config.gpc = csch_query_result.gpc;
- for (i = 0; i < 8; i++)
- csch_config.w[i] = csch_query_result.w[i];
-
- if (qman_ceetm_configure_class_scheduler(&csch_config)) {
- pr_err("Can't config channel scheduler to set"
- " eligibility mask for CQ#%d\n", idx);
- return -EINVAL;
- }
- }
-
*cq = p;
return 0;
}
@@ -4083,9 +4196,6 @@ int qman_ceetm_cq_claim_A(struct qm_ceetm_cq **cq,
{
struct qm_ceetm_cq *p;
struct qm_mcc_ceetm_cq_config cq_config;
- struct qm_mcc_ceetm_class_scheduler_config csch_config;
- struct qm_mcr_ceetm_class_scheduler_query csch_query_result;
- int i;
if ((idx < 7) || (idx > 15)) {
pr_err("This grouped class queue id is out of range\n");
@@ -4121,28 +4231,6 @@ int qman_ceetm_cq_claim_A(struct qm_ceetm_cq **cq,
return -EINVAL;
}
}
-
- if (channel->shaper_enable) {
- if (qman_ceetm_query_class_scheduler(channel,
- &csch_query_result)) {
- pr_err("Can't query channel#%d!\n", channel->idx);
- return -EINVAL;
- }
- csch_config.cqcid = channel->idx;
- csch_config.dcpid = channel->dcp_idx;
- csch_config.crem = csch_query_result.crem |
- CQ_A_ELIGIBILITY_MASK;
- csch_config.erem = csch_query_result.erem |
- CQ_A_ELIGIBILITY_MASK;
- csch_config.gpc = csch_query_result.gpc;
- for (i = 0; i < 8; i++)
- csch_config.w[i] = csch_query_result.w[i];
- if (qman_ceetm_configure_class_scheduler(&csch_config)) {
- pr_err("Can't config channel scheduler to set"
- " eligibility mask for CQ#%d\n", idx);
- return -EINVAL;
- }
- }
*cq = p;
return 0;
}
@@ -4154,9 +4242,6 @@ int qman_ceetm_cq_claim_B(struct qm_ceetm_cq **cq,
{
struct qm_ceetm_cq *p;
struct qm_mcc_ceetm_cq_config cq_config;
- struct qm_mcc_ceetm_class_scheduler_config csch_config;
- struct qm_mcr_ceetm_class_scheduler_query csch_query_result;
- int i;
if ((idx < 11) || (idx > 15)) {
pr_err("This grouped class queue id is out of range\n");
@@ -4192,28 +4277,6 @@ int qman_ceetm_cq_claim_B(struct qm_ceetm_cq **cq,
return -EINVAL;
}
}
-
- if (channel->shaper_enable) {
- if (qman_ceetm_query_class_scheduler(channel,
- &csch_query_result)) {
- pr_err("Can't query channel#%d!\n", channel->idx);
- return -EINVAL;
- }
- csch_config.cqcid = channel->idx;
- csch_config.dcpid = channel->dcp_idx;
- csch_config.crem = csch_query_result.crem |
- CQ_B_ELIGIBILITY_MASK;
- csch_config.erem = csch_query_result.erem |
- CQ_B_ELIGIBILITY_MASK;
- csch_config.gpc = csch_query_result.gpc;
- for (i = 0; i < 8; i++)
- csch_config.w[i] = csch_query_result.w[i];
- if (qman_ceetm_configure_class_scheduler(&csch_config)) {
- pr_err("Can't config channel scheduler to set"
- " eligibility mask for CQ#%d\n", idx);
- return -EINVAL;
- }
- }
*cq = p;
return 0;
}