diff options
Diffstat (limited to 'drivers/bus/dpaa/base/qbman')
-rw-r--r-- | drivers/bus/dpaa/base/qbman/bman.c | 37 | ||||
-rw-r--r-- | drivers/bus/dpaa/base/qbman/bman.h | 69 | ||||
-rw-r--r-- | drivers/bus/dpaa/base/qbman/bman_driver.c | 37 | ||||
-rw-r--r-- | drivers/bus/dpaa/base/qbman/bman_priv.h | 37 | ||||
-rw-r--r-- | drivers/bus/dpaa/base/qbman/dpaa_alloc.c | 37 | ||||
-rw-r--r-- | drivers/bus/dpaa/base/qbman/dpaa_sys.c | 37 | ||||
-rw-r--r-- | drivers/bus/dpaa/base/qbman/dpaa_sys.h | 37 | ||||
-rw-r--r-- | drivers/bus/dpaa/base/qbman/process.c | 37 | ||||
-rw-r--r-- | drivers/bus/dpaa/base/qbman/qman.c | 362 | ||||
-rw-r--r-- | drivers/bus/dpaa/base/qbman/qman.h | 105 | ||||
-rw-r--r-- | drivers/bus/dpaa/base/qbman/qman_driver.c | 190 | ||||
-rw-r--r-- | drivers/bus/dpaa/base/qbman/qman_priv.h | 43 |
12 files changed, 556 insertions, 472 deletions
diff --git a/drivers/bus/dpaa/base/qbman/bman.c b/drivers/bus/dpaa/base/qbman/bman.c index 0480caa9..8a629073 100644 --- a/drivers/bus/dpaa/base/qbman/bman.c +++ b/drivers/bus/dpaa/base/qbman/bman.c @@ -1,41 +1,8 @@ -/*- - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * BSD LICENSE +/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) * * Copyright 2008-2016 Freescale Semiconductor Inc. - * Copyright 2017 NXP. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * GPL LICENSE SUMMARY - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. + * Copyright 2017 NXP * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #include "bman.h" diff --git a/drivers/bus/dpaa/base/qbman/bman.h b/drivers/bus/dpaa/base/qbman/bman.h index 4b088da9..21a6bee7 100644 --- a/drivers/bus/dpaa/base/qbman/bman.h +++ b/drivers/bus/dpaa/base/qbman/bman.h @@ -1,41 +1,8 @@ -/*- - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * BSD LICENSE +/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) * * Copyright 2010-2016 Freescale Semiconductor Inc. - * Copyright 2017 NXP. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * GPL LICENSE SUMMARY + * Copyright 2017 NXP * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __BMAN_H @@ -228,7 +195,9 @@ static inline void bm_rcr_finish(struct bm_portal *portal) u8 pi = bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1); u8 ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1); +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(!rcr->busy); +#endif if (pi != RCR_PTR2IDX(rcr->cursor)) pr_crit("losing uncommitted RCR entries\n"); if (ci != rcr->ci) @@ -241,7 +210,9 @@ static inline struct bm_rcr_entry *bm_rcr_start(struct bm_portal *portal) { register struct bm_rcr *rcr = &portal->rcr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(!rcr->busy); +#endif if (!rcr->available) return NULL; #ifdef RTE_LIBRTE_DPAA_HWDEBUG @@ -255,8 +226,8 @@ static inline void bm_rcr_abort(struct bm_portal *portal) { __maybe_unused register struct bm_rcr *rcr = &portal->rcr; - DPAA_ASSERT(rcr->busy); #ifdef RTE_LIBRTE_DPAA_HWDEBUG + DPAA_ASSERT(rcr->busy); rcr->busy = 0; #endif } @@ -266,8 +237,10 @@ static inline struct bm_rcr_entry *bm_rcr_pend_and_next( { register struct bm_rcr *rcr = &portal->rcr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(rcr->busy); DPAA_ASSERT(rcr->pmode != bm_rcr_pvb); +#endif if (rcr->available == 1) return NULL; rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit; @@ -282,8 +255,10 @@ static inline void bm_rcr_pci_commit(struct bm_portal *portal, u8 myverb) { register struct bm_rcr *rcr = &portal->rcr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(rcr->busy); DPAA_ASSERT(rcr->pmode == bm_rcr_pci); +#endif rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit; RCR_INC(rcr); rcr->available--; @@ -298,7 +273,9 @@ static inline void bm_rcr_pce_prefetch(struct bm_portal *portal) { __maybe_unused register struct bm_rcr *rcr = &portal->rcr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(rcr->pmode == bm_rcr_pce); +#endif bm_cl_invalidate(RCR_PI); bm_cl_touch_rw(RCR_PI); } @@ -307,8 +284,10 @@ static inline void bm_rcr_pce_commit(struct bm_portal *portal, u8 myverb) { register struct bm_rcr *rcr = &portal->rcr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(rcr->busy); DPAA_ASSERT(rcr->pmode == bm_rcr_pce); +#endif rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit; RCR_INC(rcr); rcr->available--; @@ -324,8 +303,10 @@ static inline void bm_rcr_pvb_commit(struct bm_portal *portal, u8 myverb) register struct bm_rcr *rcr = &portal->rcr; struct bm_rcr_entry *rcursor; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(rcr->busy); DPAA_ASSERT(rcr->pmode == bm_rcr_pvb); +#endif lwsync(); rcursor = rcr->cursor; rcursor->__dont_write_directly__verb = myverb | rcr->vbit; @@ -342,7 +323,9 @@ static inline u8 bm_rcr_cci_update(struct bm_portal *portal) register struct bm_rcr *rcr = &portal->rcr; u8 diff, old_ci = rcr->ci; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(rcr->cmode == bm_rcr_cci); +#endif rcr->ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1); diff = bm_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci); rcr->available += diff; @@ -353,7 +336,9 @@ static inline void bm_rcr_cce_prefetch(struct bm_portal *portal) { __maybe_unused register struct bm_rcr *rcr = &portal->rcr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(rcr->cmode == bm_rcr_cce); +#endif bm_cl_touch_ro(RCR_CI); } @@ -362,7 +347,9 @@ static inline u8 bm_rcr_cce_update(struct bm_portal *portal) register struct bm_rcr *rcr = &portal->rcr; u8 diff, old_ci = rcr->ci; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(rcr->cmode == bm_rcr_cce); +#endif rcr->ci = bm_cl_in(RCR_CI) & (BM_RCR_SIZE - 1); bm_cl_invalidate(RCR_CI); diff = bm_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci); @@ -420,8 +407,8 @@ static inline void bm_mc_finish(struct bm_portal *portal) { __maybe_unused register struct bm_mc *mc = &portal->mc; - DPAA_ASSERT(mc->state == mc_idle); #ifdef RTE_LIBRTE_DPAA_HWDEBUG + DPAA_ASSERT(mc->state == mc_idle); if (mc->state != mc_idle) pr_crit("Losing incomplete MC command\n"); #endif @@ -431,8 +418,8 @@ static inline struct bm_mc_command *bm_mc_start(struct bm_portal *portal) { register struct bm_mc *mc = &portal->mc; - DPAA_ASSERT(mc->state == mc_idle); #ifdef RTE_LIBRTE_DPAA_HWDEBUG + DPAA_ASSERT(mc->state == mc_idle); mc->state = mc_user; #endif dcbz_64(mc->cr); @@ -443,8 +430,8 @@ static inline void bm_mc_abort(struct bm_portal *portal) { __maybe_unused register struct bm_mc *mc = &portal->mc; - DPAA_ASSERT(mc->state == mc_user); #ifdef RTE_LIBRTE_DPAA_HWDEBUG + DPAA_ASSERT(mc->state == mc_user); mc->state = mc_idle; #endif } @@ -454,7 +441,9 @@ static inline void bm_mc_commit(struct bm_portal *portal, u8 myverb) register struct bm_mc *mc = &portal->mc; struct bm_mc_result *rr = mc->rr + mc->rridx; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(mc->state == mc_user); +#endif lwsync(); mc->cr->__dont_write_directly__verb = myverb | mc->vbit; dcbf(mc->cr); @@ -469,7 +458,9 @@ static inline struct bm_mc_result *bm_mc_result(struct bm_portal *portal) register struct bm_mc *mc = &portal->mc; struct bm_mc_result *rr = mc->rr + mc->rridx; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(mc->state == mc_hw); +#endif /* The inactive response register's verb byte always returns zero until * its command is submitted and completed. This includes the valid-bit, * in case you were wondering. diff --git a/drivers/bus/dpaa/base/qbman/bman_driver.c b/drivers/bus/dpaa/base/qbman/bman_driver.c index 5c13a803..a1ef3921 100644 --- a/drivers/bus/dpaa/base/qbman/bman_driver.c +++ b/drivers/bus/dpaa/base/qbman/bman_driver.c @@ -1,41 +1,8 @@ -/*- - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * BSD LICENSE +/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) * * Copyright 2008-2016 Freescale Semiconductor Inc. - * Copyright 2017 NXP. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * GPL LICENSE SUMMARY - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. + * Copyright 2017 NXP * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #include <rte_branch_prediction.h> diff --git a/drivers/bus/dpaa/base/qbman/bman_priv.h b/drivers/bus/dpaa/base/qbman/bman_priv.h index 07d9cec6..5a3e330d 100644 --- a/drivers/bus/dpaa/base/qbman/bman_priv.h +++ b/drivers/bus/dpaa/base/qbman/bman_priv.h @@ -1,41 +1,8 @@ -/*- - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * BSD LICENSE +/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) * * Copyright 2008-2016 Freescale Semiconductor Inc. - * Copyright 2017 NXP. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * GPL LICENSE SUMMARY - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. + * Copyright 2017 NXP * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __BMAN_PRIV_H diff --git a/drivers/bus/dpaa/base/qbman/dpaa_alloc.c b/drivers/bus/dpaa/base/qbman/dpaa_alloc.c index 35dba7f7..a05803c2 100644 --- a/drivers/bus/dpaa/base/qbman/dpaa_alloc.c +++ b/drivers/bus/dpaa/base/qbman/dpaa_alloc.c @@ -1,41 +1,8 @@ -/*- - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * BSD LICENSE +/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) * * Copyright 2009-2016 Freescale Semiconductor Inc. - * Copyright 2017 NXP. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * GPL LICENSE SUMMARY - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. + * Copyright 2017 NXP * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #include "dpaa_sys.h" diff --git a/drivers/bus/dpaa/base/qbman/dpaa_sys.c b/drivers/bus/dpaa/base/qbman/dpaa_sys.c index 0017da52..9d6bfd40 100644 --- a/drivers/bus/dpaa/base/qbman/dpaa_sys.c +++ b/drivers/bus/dpaa/base/qbman/dpaa_sys.c @@ -1,41 +1,8 @@ -/*- - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * BSD LICENSE +/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) * * Copyright 2013-2016 Freescale Semiconductor Inc. - * Copyright 2017 NXP. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * GPL LICENSE SUMMARY - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. + * Copyright 2017 NXP * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #include <process.h> diff --git a/drivers/bus/dpaa/base/qbman/dpaa_sys.h b/drivers/bus/dpaa/base/qbman/dpaa_sys.h index bee9fe57..034991ba 100644 --- a/drivers/bus/dpaa/base/qbman/dpaa_sys.h +++ b/drivers/bus/dpaa/base/qbman/dpaa_sys.h @@ -1,41 +1,8 @@ -/*- - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * BSD LICENSE +/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) * * Copyright 2008-2016 Freescale Semiconductor Inc. - * Copyright 2017 NXP. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * GPL LICENSE SUMMARY - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. + * Copyright 2017 NXP * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __DPAA_SYS_H diff --git a/drivers/bus/dpaa/base/qbman/process.c b/drivers/bus/dpaa/base/qbman/process.c index b8ec5398..2c23c98d 100644 --- a/drivers/bus/dpaa/base/qbman/process.c +++ b/drivers/bus/dpaa/base/qbman/process.c @@ -1,41 +1,8 @@ -/*- - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * BSD LICENSE +/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) * * Copyright 2011-2016 Freescale Semiconductor Inc. - * Copyright 2017 NXP. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * GPL LICENSE SUMMARY - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. + * Copyright 2017 NXP * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #include <assert.h> #include <fcntl.h> diff --git a/drivers/bus/dpaa/base/qbman/qman.c b/drivers/bus/dpaa/base/qbman/qman.c index 87fec60d..2b97671b 100644 --- a/drivers/bus/dpaa/base/qbman/qman.c +++ b/drivers/bus/dpaa/base/qbman/qman.c @@ -1,45 +1,15 @@ -/*- - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * BSD LICENSE +/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) * * Copyright 2008-2016 Freescale Semiconductor Inc. - * Copyright 2017 NXP. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * GPL LICENSE SUMMARY - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. + * Copyright 2017 NXP * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #include "qman.h" #include <rte_branch_prediction.h> +#include <rte_dpaa_bus.h> +#include <rte_eventdev.h> +#include <rte_byteorder.h> /* Compilation constants */ #define DQRR_MAXFILL 15 @@ -416,7 +386,9 @@ static inline void qm_eqcr_finish(struct qm_portal *portal) qm_cl_invalidate(EQCR_CI); eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1); +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(!eqcr->busy); +#endif if (pi != EQCR_PTR2IDX(eqcr->cursor)) pr_crit("losing uncommitted EQCR entries\n"); if (ci != eqcr->ci) @@ -505,7 +477,9 @@ static inline void qm_mr_pvb_update(struct qm_portal *portal) register struct qm_mr *mr = &portal->mr; const struct qm_mr_entry *res = qm_cl(mr->ring, mr->pi); +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(mr->pmode == qm_mr_pvb); +#endif /* when accessing 'verb', use __raw_readb() to ensure that compiler * inlining doesn't try to optimise out "excess reads". */ @@ -532,7 +506,12 @@ struct qman_portal *qman_create_portal( p = &portal->p; - portal->use_eqcr_ci_stashing = ((qman_ip_rev >= QMAN_REV30) ? 1 : 0); + if (dpaa_svr_family == SVR_LS1043A_FAMILY) + portal->use_eqcr_ci_stashing = 3; + else + portal->use_eqcr_ci_stashing = + ((qman_ip_rev >= QMAN_REV30) ? 1 : 0); + /* * prep the low-level portal struct with the mapped addresses from the * config, everything that follows depends on it and "config" is more @@ -545,7 +524,7 @@ struct qman_portal *qman_create_portal( * and stash with high-than-DQRR priority. */ if (qm_eqcr_init(p, qm_eqcr_pvb, - portal->use_eqcr_ci_stashing ? 3 : 0, 1)) { + portal->use_eqcr_ci_stashing, 1)) { pr_err("Qman EQCR initialisation failed\n"); goto fail_eqcr; } @@ -644,11 +623,50 @@ fail_eqcr: return NULL; } +#define MAX_GLOBAL_PORTALS 8 +static struct qman_portal global_portals[MAX_GLOBAL_PORTALS]; +rte_atomic16_t global_portals_used[MAX_GLOBAL_PORTALS]; + +static struct qman_portal * +qman_alloc_global_portal(void) +{ + unsigned int i; + + for (i = 0; i < MAX_GLOBAL_PORTALS; i++) { + if (rte_atomic16_test_and_set(&global_portals_used[i])) + return &global_portals[i]; + } + pr_err("No portal available (%x)\n", MAX_GLOBAL_PORTALS); + + return NULL; +} + +static int +qman_free_global_portal(struct qman_portal *portal) +{ + unsigned int i; + + for (i = 0; i < MAX_GLOBAL_PORTALS; i++) { + if (&global_portals[i] == portal) { + rte_atomic16_clear(&global_portals_used[i]); + return 0; + } + } + return -1; +} + struct qman_portal *qman_create_affine_portal(const struct qm_portal_config *c, - const struct qman_cgrs *cgrs) + const struct qman_cgrs *cgrs, + int alloc) { struct qman_portal *res; - struct qman_portal *portal = get_affine_portal(); + struct qman_portal *portal; + + if (alloc) + portal = qman_alloc_global_portal(); + else + portal = get_affine_portal(); + /* A criteria for calling this function (from qman_driver.c) is that * we're already affine to the cpu and won't schedule onto another cpu. */ @@ -698,13 +716,18 @@ void qman_destroy_portal(struct qman_portal *qm) spin_lock_destroy(&qm->cgr_lock); } -const struct qm_portal_config *qman_destroy_affine_portal(void) +const struct qm_portal_config * +qman_destroy_affine_portal(struct qman_portal *qp) { /* We don't want to redirect if we're a slave, use "raw" */ - struct qman_portal *qm = get_affine_portal(); + struct qman_portal *qm; const struct qm_portal_config *pcfg; int cpu; + if (qp == NULL) + qm = get_affine_portal(); + else + qm = qp; pcfg = qm->config; cpu = pcfg->cpu; @@ -713,6 +736,9 @@ const struct qm_portal_config *qman_destroy_affine_portal(void) spin_lock(&affine_mask_lock); CPU_CLR(cpu, &affine_mask); spin_unlock(&affine_mask_lock); + + qman_free_global_portal(qm); + return pcfg; } @@ -929,7 +955,7 @@ static inline unsigned int __poll_portal_fast(struct qman_portal *p, do { qm_dqrr_pvb_update(&p->p); dq = qm_dqrr_current(&p->p); - if (!dq) + if (unlikely(!dq)) break; #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ /* If running on an LE system the fields of the @@ -1025,6 +1051,137 @@ u16 qman_affine_channel(int cpu) return affine_channels[cpu]; } +unsigned int qman_portal_poll_rx(unsigned int poll_limit, + void **bufs, + struct qman_portal *p) +{ + struct qm_portal *portal = &p->p; + register struct qm_dqrr *dqrr = &portal->dqrr; + struct qm_dqrr_entry *dq[QM_DQRR_SIZE], *shadow[QM_DQRR_SIZE]; + struct qman_fq *fq[QM_DQRR_SIZE]; + unsigned int limit = 0, rx_number = 0; + uint32_t consume = 0; + + do { + qm_dqrr_pvb_update(&p->p); + if (!dqrr->fill) + break; + + dq[rx_number] = dqrr->cursor; + dqrr->cursor = DQRR_CARRYCLEAR(dqrr->cursor + 1); + /* Prefetch the next DQRR entry */ + rte_prefetch0(dqrr->cursor); + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + /* If running on an LE system the fields of the + * dequeue entry must be swapper. Because the + * QMan HW will ignore writes the DQRR entry is + * copied and the index stored within the copy + */ + shadow[rx_number] = + &p->shadow_dqrr[DQRR_PTR2IDX(dq[rx_number])]; + shadow[rx_number]->fd.opaque_addr = + dq[rx_number]->fd.opaque_addr; + shadow[rx_number]->fd.addr = + be40_to_cpu(dq[rx_number]->fd.addr); + shadow[rx_number]->fd.opaque = + be32_to_cpu(dq[rx_number]->fd.opaque); +#else + shadow = dq; +#endif + + /* SDQCR: context_b points to the FQ */ +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP + fq[rx_number] = qman_fq_lookup_table[be32_to_cpu( + dq[rx_number]->contextB)]; +#else + fq[rx_number] = (void *)(uintptr_t)be32_to_cpu(dq->contextB); +#endif + fq[rx_number]->cb.dqrr_prepare(shadow[rx_number], + &bufs[rx_number]); + + consume |= (1 << (31 - DQRR_PTR2IDX(shadow[rx_number]))); + rx_number++; + --dqrr->fill; + } while (++limit < poll_limit); + + if (rx_number) + fq[0]->cb.dqrr_dpdk_pull_cb(fq, shadow, bufs, rx_number); + + /* Consume all the DQRR enries together */ + qm_out(DQRR_DCAP, (1 << 8) | consume); + + return rx_number; +} + +u32 qman_portal_dequeue(struct rte_event ev[], unsigned int poll_limit, + void **bufs) +{ + const struct qm_dqrr_entry *dq; + struct qman_fq *fq; + enum qman_cb_dqrr_result res; + unsigned int limit = 0; + struct qman_portal *p = get_affine_portal(); +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN + struct qm_dqrr_entry *shadow; +#endif + unsigned int rx_number = 0; + + do { + qm_dqrr_pvb_update(&p->p); + dq = qm_dqrr_current(&p->p); + if (!dq) + break; +#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN + /* + * If running on an LE system the fields of the + * dequeue entry must be swapper. Because the + * QMan HW will ignore writes the DQRR entry is + * copied and the index stored within the copy + */ + shadow = &p->shadow_dqrr[DQRR_PTR2IDX(dq)]; + *shadow = *dq; + dq = shadow; + shadow->fqid = be32_to_cpu(shadow->fqid); + shadow->contextB = be32_to_cpu(shadow->contextB); + shadow->seqnum = be16_to_cpu(shadow->seqnum); + hw_fd_to_cpu(&shadow->fd); +#endif + + /* SDQCR: context_b points to the FQ */ +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP + fq = get_fq_table_entry(dq->contextB); +#else + fq = (void *)(uintptr_t)dq->contextB; +#endif + /* Now let the callback do its stuff */ + res = fq->cb.dqrr_dpdk_cb(&ev[rx_number], p, fq, + dq, &bufs[rx_number]); + rx_number++; + /* Interpret 'dq' from a driver perspective. */ + /* + * Parking isn't possible unless HELDACTIVE was set. NB, + * FORCEELIGIBLE implies HELDACTIVE, so we only need to + * check for HELDACTIVE to cover both. + */ + DPAA_ASSERT((dq->stat & QM_DQRR_STAT_FQ_HELDACTIVE) || + (res != qman_cb_dqrr_park)); + if (res != qman_cb_dqrr_defer) + qm_dqrr_cdc_consume_1ptr(&p->p, dq, + res == qman_cb_dqrr_park); + /* Move forward */ + qm_dqrr_next(&p->p); + /* + * Entry processed and consumed, increment our counter. The + * callback can request that we exit after consuming the + * entry, and we also exit if we reach our processing limit, + * so loop back only if neither of these conditions is met. + */ + } while (++limit < poll_limit); + + return limit; +} + struct qm_dqrr_entry *qman_dequeue(struct qman_fq *fq) { struct qman_portal *p = get_affine_portal(); @@ -1119,37 +1276,44 @@ void qman_start_dequeues(void) qm_dqrr_set_maxfill(&p->p, DQRR_MAXFILL); } -void qman_static_dequeue_add(u32 pools) +void qman_static_dequeue_add(u32 pools, struct qman_portal *qp) { - struct qman_portal *p = get_affine_portal(); + struct qman_portal *p = qp ? qp : get_affine_portal(); pools &= p->config->pools; p->sdqcr |= pools; qm_dqrr_sdqcr_set(&p->p, p->sdqcr); } -void qman_static_dequeue_del(u32 pools) +void qman_static_dequeue_del(u32 pools, struct qman_portal *qp) { - struct qman_portal *p = get_affine_portal(); + struct qman_portal *p = qp ? qp : get_affine_portal(); pools &= p->config->pools; p->sdqcr &= ~pools; qm_dqrr_sdqcr_set(&p->p, p->sdqcr); } -u32 qman_static_dequeue_get(void) +u32 qman_static_dequeue_get(struct qman_portal *qp) { - struct qman_portal *p = get_affine_portal(); + struct qman_portal *p = qp ? qp : get_affine_portal(); return p->sdqcr; } -void qman_dca(struct qm_dqrr_entry *dq, int park_request) +void qman_dca(const struct qm_dqrr_entry *dq, int park_request) { struct qman_portal *p = get_affine_portal(); qm_dqrr_cdc_consume_1ptr(&p->p, dq, park_request); } +void qman_dca_index(u8 index, int park_request) +{ + struct qman_portal *p = get_affine_portal(); + + qm_dqrr_cdc_consume_1(&p->p, index, park_request); +} + /* Frame queue API */ static const char *mcr_result_str(u8 result) { @@ -1188,6 +1352,7 @@ int qman_create_fq(u32 fqid, u32 flags, struct qman_fq *fq) } spin_lock_init(&fq->fqlock); fq->fqid = fqid; + fq->fqid_le = cpu_to_be32(fqid); fq->flags = flags; fq->state = qman_fq_state_oos; fq->cgr_groupid = 0; @@ -1267,6 +1432,7 @@ void qman_destroy_fq(struct qman_fq *fq, u32 flags __maybe_unused) switch (fq->state) { case qman_fq_state_parked: DPAA_ASSERT(flags & QMAN_FQ_DESTROY_PARKED); + /* Fallthrough */ case qman_fq_state_oos: if (fq_isset(fq, QMAN_FQ_FLAG_DYNAMIC_FQID)) qman_release_fqid(fq->fqid); @@ -1694,6 +1860,28 @@ int qman_query_fq_np(struct qman_fq *fq, struct qm_mcr_queryfq_np *np) return 0; } +int qman_query_fq_frm_cnt(struct qman_fq *fq, u32 *frm_cnt) +{ + struct qm_mc_command *mcc; + struct qm_mc_result *mcr; + struct qman_portal *p = get_affine_portal(); + + mcc = qm_mc_start(&p->p); + mcc->queryfq.fqid = cpu_to_be32(fq->fqid); + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ_NP); + while (!(mcr = qm_mc_result(&p->p))) + cpu_relax(); + DPAA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ_NP); + + if (mcr->result == QM_MCR_RESULT_OK) + *frm_cnt = be24_to_cpu(mcr->queryfq_np.frm_cnt); + else if (mcr->result == QM_MCR_RESULT_ERR_FQID) + return -ERANGE; + else if (mcr->result != QM_MCR_RESULT_OK) + return -EIO; + return 0; +} + int qman_query_wq(u8 query_dedicated, struct qm_mcr_querywq *wq) { struct qm_mc_command *mcc; @@ -1974,7 +2162,7 @@ int qman_enqueue(struct qman_fq *fq, const struct qm_fd *fd, u32 flags) } int qman_enqueue_multi(struct qman_fq *fq, - const struct qm_fd *fd, + const struct qm_fd *fd, u32 *flags, int frames_to_send) { struct qman_portal *p = get_affine_portal(); @@ -1983,7 +2171,7 @@ int qman_enqueue_multi(struct qman_fq *fq, register struct qm_eqcr *eqcr = &portal->eqcr; struct qm_eqcr_entry *eq = eqcr->cursor, *prev_eq; - u8 i, diff, old_ci, sent = 0; + u8 i = 0, diff, old_ci, sent = 0; /* Update the available entries if no entry is free */ if (!eqcr->available) { @@ -1997,7 +2185,7 @@ int qman_enqueue_multi(struct qman_fq *fq, /* try to send as many frames as possible */ while (eqcr->available && frames_to_send--) { - eq->fqid = cpu_to_be32(fq->fqid); + eq->fqid = fq->fqid_le; #ifdef CONFIG_FSL_QMAN_FQ_LOOKUP eq->tag = cpu_to_be32(fq->key); #else @@ -2007,6 +2195,76 @@ int qman_enqueue_multi(struct qman_fq *fq, eq->fd.addr = cpu_to_be40(fd->addr); eq->fd.status = cpu_to_be32(fd->status); eq->fd.opaque = cpu_to_be32(fd->opaque); + if (flags && (flags[i] & QMAN_ENQUEUE_FLAG_DCA)) { + eq->dca = QM_EQCR_DCA_ENABLE | + ((flags[i] >> 8) & QM_EQCR_DCA_IDXMASK); + } + i++; + eq = (void *)((unsigned long)(eq + 1) & + (~(unsigned long)(QM_EQCR_SIZE << 6))); + eqcr->available--; + sent++; + fd++; + } + lwsync(); + + /* In order for flushes to complete faster, all lines are recorded in + * 32 bit word. + */ + eq = eqcr->cursor; + for (i = 0; i < sent; i++) { + eq->__dont_write_directly__verb = + QM_EQCR_VERB_CMD_ENQUEUE | eqcr->vbit; + prev_eq = eq; + eq = (void *)((unsigned long)(eq + 1) & + (~(unsigned long)(QM_EQCR_SIZE << 6))); + if (unlikely((prev_eq + 1) != eq)) + eqcr->vbit ^= QM_EQCR_VERB_VBIT; + } + + /* We need to flush all the lines but without load/store operations + * between them + */ + eq = eqcr->cursor; + for (i = 0; i < sent; i++) { + dcbf(eq); + eq = (void *)((unsigned long)(eq + 1) & + (~(unsigned long)(QM_EQCR_SIZE << 6))); + } + /* Update cursor for the next call */ + eqcr->cursor = eq; + return sent; +} + +int +qman_enqueue_multi_fq(struct qman_fq *fq[], const struct qm_fd *fd, + int frames_to_send) +{ + struct qman_portal *p = get_affine_portal(); + struct qm_portal *portal = &p->p; + + register struct qm_eqcr *eqcr = &portal->eqcr; + struct qm_eqcr_entry *eq = eqcr->cursor, *prev_eq; + + u8 i, diff, old_ci, sent = 0; + + /* Update the available entries if no entry is free */ + if (!eqcr->available) { + old_ci = eqcr->ci; + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1); + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci); + eqcr->available += diff; + if (!diff) + return 0; + } + + /* try to send as many frames as possible */ + while (eqcr->available && frames_to_send--) { + eq->fqid = fq[sent]->fqid_le; + eq->fd.opaque_addr = fd->opaque_addr; + eq->fd.addr = cpu_to_be40(fd->addr); + eq->fd.status = cpu_to_be32(fd->status); + eq->fd.opaque = cpu_to_be32(fd->opaque); eq = (void *)((unsigned long)(eq + 1) & (~(unsigned long)(QM_EQCR_SIZE << 6))); diff --git a/drivers/bus/dpaa/base/qbman/qman.h b/drivers/bus/dpaa/base/qbman/qman.h index 2c0f694c..4346d865 100644 --- a/drivers/bus/dpaa/base/qbman/qman.h +++ b/drivers/bus/dpaa/base/qbman/qman.h @@ -1,41 +1,8 @@ -/*- - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * BSD LICENSE +/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) * * Copyright 2008-2016 Freescale Semiconductor Inc. - * Copyright 2017 NXP. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * GPL LICENSE SUMMARY + * Copyright 2017 NXP * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #include "qman_priv.h" @@ -187,7 +154,7 @@ struct qm_eqcr { }; struct qm_dqrr { - const struct qm_dqrr_entry *ring, *cursor; + struct qm_dqrr_entry *ring, *cursor; u8 pi, ci, fill, ithresh, vbit; #ifdef RTE_LIBRTE_DPAA_HWDEBUG enum qm_dqrr_dmode dmode; @@ -267,7 +234,9 @@ static inline struct qm_eqcr_entry *qm_eqcr_start_no_stash(struct qm_portal { register struct qm_eqcr *eqcr = &portal->eqcr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(!eqcr->busy); +#endif if (!eqcr->available) return NULL; @@ -284,7 +253,9 @@ static inline struct qm_eqcr_entry *qm_eqcr_start_stash(struct qm_portal register struct qm_eqcr *eqcr = &portal->eqcr; u8 diff, old_ci; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(!eqcr->busy); +#endif if (!eqcr->available) { old_ci = eqcr->ci; eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1); @@ -303,8 +274,8 @@ static inline void qm_eqcr_abort(struct qm_portal *portal) { __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr; - DPAA_ASSERT(eqcr->busy); #ifdef RTE_LIBRTE_DPAA_HWDEBUG + DPAA_ASSERT(eqcr->busy); eqcr->busy = 0; #endif } @@ -314,8 +285,10 @@ static inline struct qm_eqcr_entry *qm_eqcr_pend_and_next( { register struct qm_eqcr *eqcr = &portal->eqcr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(eqcr->busy); DPAA_ASSERT(eqcr->pmode != qm_eqcr_pvb); +#endif if (eqcr->available == 1) return NULL; eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit; @@ -336,8 +309,10 @@ static inline void qm_eqcr_pci_commit(struct qm_portal *portal, u8 myverb) { register struct qm_eqcr *eqcr = &portal->eqcr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG EQCR_COMMIT_CHECKS(eqcr); DPAA_ASSERT(eqcr->pmode == qm_eqcr_pci); +#endif eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit; EQCR_INC(eqcr); eqcr->available--; @@ -353,7 +328,9 @@ static inline void qm_eqcr_pce_prefetch(struct qm_portal *portal) { __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(eqcr->pmode == qm_eqcr_pce); +#endif qm_cl_invalidate(EQCR_PI); qm_cl_touch_rw(EQCR_PI); } @@ -362,8 +339,10 @@ static inline void qm_eqcr_pce_commit(struct qm_portal *portal, u8 myverb) { register struct qm_eqcr *eqcr = &portal->eqcr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG EQCR_COMMIT_CHECKS(eqcr); DPAA_ASSERT(eqcr->pmode == qm_eqcr_pce); +#endif eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit; EQCR_INC(eqcr); eqcr->available--; @@ -380,8 +359,10 @@ static inline void qm_eqcr_pvb_commit(struct qm_portal *portal, u8 myverb) register struct qm_eqcr *eqcr = &portal->eqcr; struct qm_eqcr_entry *eqcursor; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG EQCR_COMMIT_CHECKS(eqcr); DPAA_ASSERT(eqcr->pmode == qm_eqcr_pvb); +#endif lwsync(); eqcursor = eqcr->cursor; eqcursor->__dont_write_directly__verb = myverb | eqcr->vbit; @@ -460,7 +441,7 @@ static inline u8 DQRR_PTR2IDX(const struct qm_dqrr_entry *e) return ((uintptr_t)e >> 6) & (QM_DQRR_SIZE - 1); } -static inline const struct qm_dqrr_entry *DQRR_INC( +static inline struct qm_dqrr_entry *DQRR_INC( const struct qm_dqrr_entry *e) { return DQRR_CARRYCLEAR(e + 1); @@ -503,7 +484,9 @@ static inline u8 qm_dqrr_pci_update(struct qm_portal *portal) register struct qm_dqrr *dqrr = &portal->dqrr; u8 diff, old_pi = dqrr->pi; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(dqrr->pmode == qm_dqrr_pci); +#endif dqrr->pi = qm_in(DQRR_PI_CINH) & (QM_DQRR_SIZE - 1); diff = qm_cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi); dqrr->fill += diff; @@ -514,7 +497,9 @@ static inline void qm_dqrr_pce_prefetch(struct qm_portal *portal) { __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(dqrr->pmode == qm_dqrr_pce); +#endif qm_cl_invalidate(DQRR_PI); qm_cl_touch_ro(DQRR_PI); } @@ -524,7 +509,9 @@ static inline u8 qm_dqrr_pce_update(struct qm_portal *portal) register struct qm_dqrr *dqrr = &portal->dqrr; u8 diff, old_pi = dqrr->pi; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(dqrr->pmode == qm_dqrr_pce); +#endif dqrr->pi = qm_cl_in(DQRR_PI) & (QM_DQRR_SIZE - 1); diff = qm_cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi); dqrr->fill += diff; @@ -536,7 +523,9 @@ static inline void qm_dqrr_pvb_update(struct qm_portal *portal) register struct qm_dqrr *dqrr = &portal->dqrr; const struct qm_dqrr_entry *res = qm_cl(dqrr->ring, dqrr->pi); +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(dqrr->pmode == qm_dqrr_pvb); +#endif /* when accessing 'verb', use __raw_readb() to ensure that compiler * inlining doesn't try to optimise out "excess reads". */ @@ -552,7 +541,9 @@ static inline void qm_dqrr_cci_consume(struct qm_portal *portal, u8 num) { register struct qm_dqrr *dqrr = &portal->dqrr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(dqrr->cmode == qm_dqrr_cci); +#endif dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1); qm_out(DQRR_CI_CINH, dqrr->ci); } @@ -561,7 +552,9 @@ static inline void qm_dqrr_cci_consume_to_current(struct qm_portal *portal) { register struct qm_dqrr *dqrr = &portal->dqrr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(dqrr->cmode == qm_dqrr_cci); +#endif dqrr->ci = DQRR_PTR2IDX(dqrr->cursor); qm_out(DQRR_CI_CINH, dqrr->ci); } @@ -570,7 +563,9 @@ static inline void qm_dqrr_cce_prefetch(struct qm_portal *portal) { __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(dqrr->cmode == qm_dqrr_cce); +#endif qm_cl_invalidate(DQRR_CI); qm_cl_touch_rw(DQRR_CI); } @@ -579,7 +574,9 @@ static inline void qm_dqrr_cce_consume(struct qm_portal *portal, u8 num) { register struct qm_dqrr *dqrr = &portal->dqrr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(dqrr->cmode == qm_dqrr_cce); +#endif dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1); qm_cl_out(DQRR_CI, dqrr->ci); } @@ -588,7 +585,9 @@ static inline void qm_dqrr_cce_consume_to_current(struct qm_portal *portal) { register struct qm_dqrr *dqrr = &portal->dqrr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(dqrr->cmode == qm_dqrr_cce); +#endif dqrr->ci = DQRR_PTR2IDX(dqrr->cursor); qm_cl_out(DQRR_CI, dqrr->ci); } @@ -598,7 +597,9 @@ static inline void qm_dqrr_cdc_consume_1(struct qm_portal *portal, u8 idx, { __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(dqrr->cmode == qm_dqrr_cdc); +#endif DPAA_ASSERT(idx < QM_DQRR_SIZE); qm_out(DQRR_DCAP, (0 << 8) | /* S */ ((park ? 1 : 0) << 6) | /* PK */ @@ -612,7 +613,9 @@ static inline void qm_dqrr_cdc_consume_1ptr(struct qm_portal *portal, __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr; u8 idx = DQRR_PTR2IDX(dq); +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(dqrr->cmode == qm_dqrr_cdc); +#endif DPAA_ASSERT(idx < QM_DQRR_SIZE); qm_out(DQRR_DCAP, (0 << 8) | /* DQRR_DCAP::S */ ((park ? 1 : 0) << 6) | /* DQRR_DCAP::PK */ @@ -623,7 +626,9 @@ static inline void qm_dqrr_cdc_consume_n(struct qm_portal *portal, u16 bitmask) { __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(dqrr->cmode == qm_dqrr_cdc); +#endif qm_out(DQRR_DCAP, (1 << 8) | /* DQRR_DCAP::S */ ((u32)bitmask << 16)); /* DQRR_DCAP::DCAP_CI */ dqrr->ci = qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1); @@ -634,7 +639,9 @@ static inline u8 qm_dqrr_cdc_cci(struct qm_portal *portal) { __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(dqrr->cmode == qm_dqrr_cdc); +#endif return qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1); } @@ -642,7 +649,9 @@ static inline void qm_dqrr_cdc_cce_prefetch(struct qm_portal *portal) { __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(dqrr->cmode == qm_dqrr_cdc); +#endif qm_cl_invalidate(DQRR_CI); qm_cl_touch_ro(DQRR_CI); } @@ -651,7 +660,9 @@ static inline u8 qm_dqrr_cdc_cce(struct qm_portal *portal) { __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(dqrr->cmode == qm_dqrr_cdc); +#endif return qm_cl_in(DQRR_CI) & (QM_DQRR_SIZE - 1); } @@ -659,7 +670,9 @@ static inline u8 qm_dqrr_get_ci(struct qm_portal *portal) { register struct qm_dqrr *dqrr = &portal->dqrr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(dqrr->cmode != qm_dqrr_cdc); +#endif return dqrr->ci; } @@ -667,7 +680,9 @@ static inline void qm_dqrr_park(struct qm_portal *portal, u8 idx) { __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(dqrr->cmode != qm_dqrr_cdc); +#endif qm_out(DQRR_DCAP, (0 << 8) | /* S */ (1 << 6) | /* PK */ (idx & (QM_DQRR_SIZE - 1))); /* DCAP_CI */ @@ -677,7 +692,9 @@ static inline void qm_dqrr_park_current(struct qm_portal *portal) { register struct qm_dqrr *dqrr = &portal->dqrr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(dqrr->cmode != qm_dqrr_cdc); +#endif qm_out(DQRR_DCAP, (0 << 8) | /* S */ (1 << 6) | /* PK */ DQRR_PTR2IDX(dqrr->cursor)); /* DCAP_CI */ @@ -766,7 +783,9 @@ static inline void qm_mr_cci_consume(struct qm_portal *portal, u8 num) { register struct qm_mr *mr = &portal->mr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(mr->cmode == qm_mr_cci); +#endif mr->ci = (mr->ci + num) & (QM_MR_SIZE - 1); qm_out(MR_CI_CINH, mr->ci); } @@ -775,7 +794,9 @@ static inline void qm_mr_cci_consume_to_current(struct qm_portal *portal) { register struct qm_mr *mr = &portal->mr; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(mr->cmode == qm_mr_cci); +#endif mr->ci = MR_PTR2IDX(mr->cursor); qm_out(MR_CI_CINH, mr->ci); } @@ -806,8 +827,8 @@ static inline void qm_mc_finish(struct qm_portal *portal) { __maybe_unused register struct qm_mc *mc = &portal->mc; - DPAA_ASSERT(mc->state == qman_mc_idle); #ifdef RTE_LIBRTE_DPAA_HWDEBUG + DPAA_ASSERT(mc->state == qman_mc_idle); if (mc->state != qman_mc_idle) pr_crit("Losing incomplete MC command\n"); #endif @@ -817,8 +838,8 @@ static inline struct qm_mc_command *qm_mc_start(struct qm_portal *portal) { register struct qm_mc *mc = &portal->mc; - DPAA_ASSERT(mc->state == qman_mc_idle); #ifdef RTE_LIBRTE_DPAA_HWDEBUG + DPAA_ASSERT(mc->state == qman_mc_idle); mc->state = qman_mc_user; #endif dcbz_64(mc->cr); @@ -830,7 +851,9 @@ static inline void qm_mc_commit(struct qm_portal *portal, u8 myverb) register struct qm_mc *mc = &portal->mc; struct qm_mc_result *rr = mc->rr + mc->rridx; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(mc->state == qman_mc_user); +#endif lwsync(); mc->cr->__dont_write_directly__verb = myverb | mc->vbit; dcbf(mc->cr); @@ -845,7 +868,9 @@ static inline struct qm_mc_result *qm_mc_result(struct qm_portal *portal) register struct qm_mc *mc = &portal->mc; struct qm_mc_result *rr = mc->rr + mc->rridx; +#ifdef RTE_LIBRTE_DPAA_HWDEBUG DPAA_ASSERT(mc->state == qman_mc_hw); +#endif /* The inactive response register's verb byte always returns zero until * its command is submitted and completed. This includes the valid-bit, * in case you were wondering. diff --git a/drivers/bus/dpaa/base/qbman/qman_driver.c b/drivers/bus/dpaa/base/qbman/qman_driver.c index 7a688967..7cfa8ee4 100644 --- a/drivers/bus/dpaa/base/qbman/qman_driver.c +++ b/drivers/bus/dpaa/base/qbman/qman_driver.c @@ -1,41 +1,8 @@ -/*- - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * BSD LICENSE +/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) * * Copyright 2008-2016 Freescale Semiconductor Inc. - * Copyright 2017 NXP. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * GPL LICENSE SUMMARY - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. + * Copyright 2017 NXP * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #include <fsl_usd.h> @@ -57,8 +24,8 @@ void *qman_ccsr_map; /* The qman clock frequency */ u32 qman_clk; -static __thread int fd = -1; -static __thread struct qm_portal_config pcfg; +static __thread int qmfd = -1; +static __thread struct qm_portal_config qpcfg; static __thread struct dpaa_ioctl_portal_map map = { .type = dpaa_portal_qman }; @@ -77,16 +44,16 @@ static int fsl_qman_portal_init(uint32_t index, int is_shared) error(0, ret, "pthread_getaffinity_np()"); return ret; } - pcfg.cpu = -1; + qpcfg.cpu = -1; for (loop = 0; loop < CPU_SETSIZE; loop++) if (CPU_ISSET(loop, &cpuset)) { - if (pcfg.cpu != -1) { + if (qpcfg.cpu != -1) { pr_err("Thread is not affine to 1 cpu\n"); return -EINVAL; } - pcfg.cpu = loop; + qpcfg.cpu = loop; } - if (pcfg.cpu == -1) { + if (qpcfg.cpu == -1) { pr_err("Bug in getaffinity handling!\n"); return -EINVAL; } @@ -98,36 +65,36 @@ static int fsl_qman_portal_init(uint32_t index, int is_shared) error(0, ret, "process_portal_map()"); return ret; } - pcfg.channel = map.channel; - pcfg.pools = map.pools; - pcfg.index = map.index; + qpcfg.channel = map.channel; + qpcfg.pools = map.pools; + qpcfg.index = map.index; /* Make the portal's cache-[enabled|inhibited] regions */ - pcfg.addr_virt[DPAA_PORTAL_CE] = map.addr.cena; - pcfg.addr_virt[DPAA_PORTAL_CI] = map.addr.cinh; + qpcfg.addr_virt[DPAA_PORTAL_CE] = map.addr.cena; + qpcfg.addr_virt[DPAA_PORTAL_CI] = map.addr.cinh; - fd = open(QMAN_PORTAL_IRQ_PATH, O_RDONLY); - if (fd == -1) { + qmfd = open(QMAN_PORTAL_IRQ_PATH, O_RDONLY); + if (qmfd == -1) { pr_err("QMan irq init failed\n"); process_portal_unmap(&map.addr); return -EBUSY; } - pcfg.is_shared = is_shared; - pcfg.node = NULL; - pcfg.irq = fd; + qpcfg.is_shared = is_shared; + qpcfg.node = NULL; + qpcfg.irq = qmfd; - portal = qman_create_affine_portal(&pcfg, NULL); + portal = qman_create_affine_portal(&qpcfg, NULL, 0); if (!portal) { pr_err("Qman portal initialisation failed (%d)\n", - pcfg.cpu); + qpcfg.cpu); process_portal_unmap(&map.addr); return -EBUSY; } irq_map.type = dpaa_portal_qman; irq_map.portal_cinh = map.addr.cinh; - process_portal_irq_map(fd, &irq_map); + process_portal_irq_map(qmfd, &irq_map); return 0; } @@ -136,10 +103,10 @@ static int fsl_qman_portal_finish(void) __maybe_unused const struct qm_portal_config *cfg; int ret; - process_portal_irq_unmap(fd); + process_portal_irq_unmap(qmfd); - cfg = qman_destroy_affine_portal(); - DPAA_BUG_ON(cfg != &pcfg); + cfg = qman_destroy_affine_portal(NULL); + DPAA_BUG_ON(cfg != &qpcfg); ret = process_portal_unmap(&map.addr); if (ret) error(0, ret, "process_portal_unmap()"); @@ -161,14 +128,119 @@ int qman_thread_finish(void) void qman_thread_irq(void) { - qbman_invoke_irq(pcfg.irq); + qbman_invoke_irq(qpcfg.irq); /* Now we need to uninhibit interrupts. This is the only code outside * the regular portal driver that manipulates any portal register, so * rather than breaking that encapsulation I am simply hard-coding the * offset to the inhibit register here. */ - out_be32(pcfg.addr_virt[DPAA_PORTAL_CI] + 0xe0c, 0); + out_be32(qpcfg.addr_virt[DPAA_PORTAL_CI] + 0xe0c, 0); +} + +struct qman_portal *fsl_qman_portal_create(void) +{ + cpu_set_t cpuset; + struct qman_portal *res; + + struct qm_portal_config *q_pcfg; + int loop, ret; + struct dpaa_ioctl_irq_map irq_map; + struct dpaa_ioctl_portal_map q_map = {0}; + int q_fd; + + q_pcfg = kzalloc((sizeof(struct qm_portal_config)), 0); + if (!q_pcfg) { + error(0, -1, "q_pcfg kzalloc failed"); + return NULL; + } + + /* Verify the thread's cpu-affinity */ + ret = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), + &cpuset); + if (ret) { + error(0, ret, "pthread_getaffinity_np()"); + return NULL; + } + + q_pcfg->cpu = -1; + for (loop = 0; loop < CPU_SETSIZE; loop++) + if (CPU_ISSET(loop, &cpuset)) { + if (q_pcfg->cpu != -1) { + pr_err("Thread is not affine to 1 cpu\n"); + return NULL; + } + q_pcfg->cpu = loop; + } + if (q_pcfg->cpu == -1) { + pr_err("Bug in getaffinity handling!\n"); + return NULL; + } + + /* Allocate and map a qman portal */ + q_map.type = dpaa_portal_qman; + q_map.index = QBMAN_ANY_PORTAL_IDX; + ret = process_portal_map(&q_map); + if (ret) { + error(0, ret, "process_portal_map()"); + return NULL; + } + q_pcfg->channel = q_map.channel; + q_pcfg->pools = q_map.pools; + q_pcfg->index = q_map.index; + + /* Make the portal's cache-[enabled|inhibited] regions */ + q_pcfg->addr_virt[DPAA_PORTAL_CE] = q_map.addr.cena; + q_pcfg->addr_virt[DPAA_PORTAL_CI] = q_map.addr.cinh; + + q_fd = open(QMAN_PORTAL_IRQ_PATH, O_RDONLY); + if (q_fd == -1) { + pr_err("QMan irq init failed\n"); + goto err1; + } + + q_pcfg->irq = q_fd; + + res = qman_create_affine_portal(q_pcfg, NULL, true); + if (!res) { + pr_err("Qman portal initialisation failed (%d)\n", + q_pcfg->cpu); + goto err2; + } + + irq_map.type = dpaa_portal_qman; + irq_map.portal_cinh = q_map.addr.cinh; + process_portal_irq_map(q_fd, &irq_map); + + return res; +err2: + close(q_fd); +err1: + process_portal_unmap(&q_map.addr); + return NULL; +} + +int fsl_qman_portal_destroy(struct qman_portal *qp) +{ + const struct qm_portal_config *cfg; + struct dpaa_portal_map addr; + int ret; + + cfg = qman_destroy_affine_portal(qp); + kfree(qp); + + process_portal_irq_unmap(cfg->irq); + + addr.cena = cfg->addr_virt[DPAA_PORTAL_CE]; + addr.cinh = cfg->addr_virt[DPAA_PORTAL_CI]; + + ret = process_portal_unmap(&addr); + if (ret) + pr_err("process_portal_unmap() (%d)\n", ret); + + kfree((void *)cfg); + + return ret; } int qman_global_init(void) diff --git a/drivers/bus/dpaa/base/qbman/qman_priv.h b/drivers/bus/dpaa/base/qbman/qman_priv.h index 3e1d7f92..9e4471e6 100644 --- a/drivers/bus/dpaa/base/qbman/qman_priv.h +++ b/drivers/bus/dpaa/base/qbman/qman_priv.h @@ -1,41 +1,8 @@ -/*- - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * BSD LICENSE +/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) * * Copyright 2008-2016 Freescale Semiconductor Inc. - * Copyright 2017 NXP. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * GPL LICENSE SUMMARY - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. + * Copyright 2017 NXP * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __QMAN_PRIV_H @@ -179,8 +146,10 @@ int qm_get_wpm(int *wpm); struct qman_portal *qman_create_affine_portal( const struct qm_portal_config *config, - const struct qman_cgrs *cgrs); -const struct qm_portal_config *qman_destroy_affine_portal(void); + const struct qman_cgrs *cgrs, + int alloc); +const struct qm_portal_config * +qman_destroy_affine_portal(struct qman_portal *q); struct qm_portal_config *qm_get_unused_portal(void); struct qm_portal_config *qm_get_unused_portal_idx(uint32_t idx); |