Back to home page

OSCL-LXR

 
 

    


0001 /***********************license start***************
0002  * Author: Cavium Networks
0003  *
0004  * Contact: support@caviumnetworks.com
0005  * This file is part of the OCTEON SDK
0006  *
0007  * Copyright (c) 2003-2008 Cavium Networks
0008  *
0009  * This file is free software; you can redistribute it and/or modify
0010  * it under the terms of the GNU General Public License, Version 2, as
0011  * published by the Free Software Foundation.
0012  *
0013  * This file is distributed in the hope that it will be useful, but
0014  * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
0015  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
0016  * NONINFRINGEMENT.  See the GNU General Public License for more
0017  * details.
0018  *
0019  * You should have received a copy of the GNU General Public License
0020  * along with this file; if not, write to the Free Software
0021  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
0022  * or visit http://www.gnu.org/licenses/.
0023  *
0024  * This file may also be available under a different license from Cavium.
0025  * Contact Cavium Networks for more information
0026  ***********************license end**************************************/
0027 
0028 /**
0029  *
0030  * Interface to the hardware Input Packet Data unit.
0031  */
0032 
0033 #ifndef __CVMX_IPD_H__
0034 #define __CVMX_IPD_H__
0035 
0036 #include <asm/octeon/octeon-feature.h>
0037 
0038 #include <asm/octeon/cvmx-ipd-defs.h>
0039 #include <asm/octeon/cvmx-pip-defs.h>
0040 
0041 enum cvmx_ipd_mode {
0042    CVMX_IPD_OPC_MODE_STT = 0LL,   /* All blocks DRAM, not cached in L2 */
0043    CVMX_IPD_OPC_MODE_STF = 1LL,   /* All blocks into  L2 */
0044    CVMX_IPD_OPC_MODE_STF1_STT = 2LL,   /* 1st block L2, rest DRAM */
0045    CVMX_IPD_OPC_MODE_STF2_STT = 3LL    /* 1st, 2nd blocks L2, rest DRAM */
0046 };
0047 
0048 #ifndef CVMX_ENABLE_LEN_M8_FIX
0049 #define CVMX_ENABLE_LEN_M8_FIX 0
0050 #endif
0051 
0052 /* CSR typedefs have been moved to cvmx-csr-*.h */
0053 typedef union cvmx_ipd_1st_mbuff_skip cvmx_ipd_mbuff_first_skip_t;
0054 typedef union cvmx_ipd_1st_next_ptr_back cvmx_ipd_first_next_ptr_back_t;
0055 
0056 typedef cvmx_ipd_mbuff_first_skip_t cvmx_ipd_mbuff_not_first_skip_t;
0057 typedef cvmx_ipd_first_next_ptr_back_t cvmx_ipd_second_next_ptr_back_t;
0058 
0059 /**
0060  * Configure IPD
0061  *
0062  * @mbuff_size: Packets buffer size in 8 byte words
0063  * @first_mbuff_skip:
0064  *           Number of 8 byte words to skip in the first buffer
0065  * @not_first_mbuff_skip:
0066  *           Number of 8 byte words to skip in each following buffer
0067  * @first_back: Must be same as first_mbuff_skip / 128
0068  * @second_back:
0069  *           Must be same as not_first_mbuff_skip / 128
0070  * @wqe_fpa_pool:
0071  *           FPA pool to get work entries from
0072  * @cache_mode:
0073  * @back_pres_enable_flag:
0074  *           Enable or disable port back pressure
0075  */
0076 static inline void cvmx_ipd_config(uint64_t mbuff_size,
0077                    uint64_t first_mbuff_skip,
0078                    uint64_t not_first_mbuff_skip,
0079                    uint64_t first_back,
0080                    uint64_t second_back,
0081                    uint64_t wqe_fpa_pool,
0082                    enum cvmx_ipd_mode cache_mode,
0083                    uint64_t back_pres_enable_flag)
0084 {
0085     cvmx_ipd_mbuff_first_skip_t first_skip;
0086     cvmx_ipd_mbuff_not_first_skip_t not_first_skip;
0087     union cvmx_ipd_packet_mbuff_size size;
0088     cvmx_ipd_first_next_ptr_back_t first_back_struct;
0089     cvmx_ipd_second_next_ptr_back_t second_back_struct;
0090     union cvmx_ipd_wqe_fpa_queue wqe_pool;
0091     union cvmx_ipd_ctl_status ipd_ctl_reg;
0092 
0093     first_skip.u64 = 0;
0094     first_skip.s.skip_sz = first_mbuff_skip;
0095     cvmx_write_csr(CVMX_IPD_1ST_MBUFF_SKIP, first_skip.u64);
0096 
0097     not_first_skip.u64 = 0;
0098     not_first_skip.s.skip_sz = not_first_mbuff_skip;
0099     cvmx_write_csr(CVMX_IPD_NOT_1ST_MBUFF_SKIP, not_first_skip.u64);
0100 
0101     size.u64 = 0;
0102     size.s.mb_size = mbuff_size;
0103     cvmx_write_csr(CVMX_IPD_PACKET_MBUFF_SIZE, size.u64);
0104 
0105     first_back_struct.u64 = 0;
0106     first_back_struct.s.back = first_back;
0107     cvmx_write_csr(CVMX_IPD_1st_NEXT_PTR_BACK, first_back_struct.u64);
0108 
0109     second_back_struct.u64 = 0;
0110     second_back_struct.s.back = second_back;
0111     cvmx_write_csr(CVMX_IPD_2nd_NEXT_PTR_BACK, second_back_struct.u64);
0112 
0113     wqe_pool.u64 = 0;
0114     wqe_pool.s.wqe_pool = wqe_fpa_pool;
0115     cvmx_write_csr(CVMX_IPD_WQE_FPA_QUEUE, wqe_pool.u64);
0116 
0117     ipd_ctl_reg.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
0118     ipd_ctl_reg.s.opc_mode = cache_mode;
0119     ipd_ctl_reg.s.pbp_en = back_pres_enable_flag;
0120     cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_ctl_reg.u64);
0121 
0122     /* Note: the example RED code that used to be here has been moved to
0123        cvmx_helper_setup_red */
0124 }
0125 
0126 /**
0127  * Enable IPD
0128  */
0129 static inline void cvmx_ipd_enable(void)
0130 {
0131     union cvmx_ipd_ctl_status ipd_reg;
0132     ipd_reg.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
0133     if (ipd_reg.s.ipd_en) {
0134         cvmx_dprintf
0135             ("Warning: Enabling IPD when IPD already enabled.\n");
0136     }
0137     ipd_reg.s.ipd_en = 1;
0138 #if  CVMX_ENABLE_LEN_M8_FIX
0139     if (!OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2))
0140         ipd_reg.s.len_m8 = TRUE;
0141 #endif
0142     cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_reg.u64);
0143 }
0144 
0145 /**
0146  * Disable IPD
0147  */
0148 static inline void cvmx_ipd_disable(void)
0149 {
0150     union cvmx_ipd_ctl_status ipd_reg;
0151     ipd_reg.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
0152     ipd_reg.s.ipd_en = 0;
0153     cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_reg.u64);
0154 }
0155 
0156 /**
0157  * Supportive function for cvmx_fpa_shutdown_pool.
0158  */
0159 static inline void cvmx_ipd_free_ptr(void)
0160 {
0161     /* Only CN38XXp{1,2} cannot read pointer out of the IPD */
0162     if (!OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1)
0163         && !OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2)) {
0164         int no_wptr = 0;
0165         union cvmx_ipd_ptr_count ipd_ptr_count;
0166         ipd_ptr_count.u64 = cvmx_read_csr(CVMX_IPD_PTR_COUNT);
0167 
0168         /* Handle Work Queue Entry in cn56xx and cn52xx */
0169         if (octeon_has_feature(OCTEON_FEATURE_NO_WPTR)) {
0170             union cvmx_ipd_ctl_status ipd_ctl_status;
0171             ipd_ctl_status.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
0172             if (ipd_ctl_status.s.no_wptr)
0173                 no_wptr = 1;
0174         }
0175 
0176         /* Free the prefetched WQE */
0177         if (ipd_ptr_count.s.wqev_cnt) {
0178             union cvmx_ipd_wqe_ptr_valid ipd_wqe_ptr_valid;
0179             ipd_wqe_ptr_valid.u64 =
0180                 cvmx_read_csr(CVMX_IPD_WQE_PTR_VALID);
0181             if (no_wptr)
0182                 cvmx_fpa_free(cvmx_phys_to_ptr
0183                           ((uint64_t) ipd_wqe_ptr_valid.s.
0184                            ptr << 7), CVMX_FPA_PACKET_POOL,
0185                           0);
0186             else
0187                 cvmx_fpa_free(cvmx_phys_to_ptr
0188                           ((uint64_t) ipd_wqe_ptr_valid.s.
0189                            ptr << 7), CVMX_FPA_WQE_POOL, 0);
0190         }
0191 
0192         /* Free all WQE in the fifo */
0193         if (ipd_ptr_count.s.wqe_pcnt) {
0194             int i;
0195             union cvmx_ipd_pwp_ptr_fifo_ctl ipd_pwp_ptr_fifo_ctl;
0196             ipd_pwp_ptr_fifo_ctl.u64 =
0197                 cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
0198             for (i = 0; i < ipd_ptr_count.s.wqe_pcnt; i++) {
0199                 ipd_pwp_ptr_fifo_ctl.s.cena = 0;
0200                 ipd_pwp_ptr_fifo_ctl.s.raddr =
0201                     ipd_pwp_ptr_fifo_ctl.s.max_cnts +
0202                     (ipd_pwp_ptr_fifo_ctl.s.wraddr +
0203                      i) % ipd_pwp_ptr_fifo_ctl.s.max_cnts;
0204                 cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL,
0205                            ipd_pwp_ptr_fifo_ctl.u64);
0206                 ipd_pwp_ptr_fifo_ctl.u64 =
0207                     cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
0208                 if (no_wptr)
0209                     cvmx_fpa_free(cvmx_phys_to_ptr
0210                               ((uint64_t)
0211                                ipd_pwp_ptr_fifo_ctl.s.
0212                                ptr << 7),
0213                               CVMX_FPA_PACKET_POOL, 0);
0214                 else
0215                     cvmx_fpa_free(cvmx_phys_to_ptr
0216                               ((uint64_t)
0217                                ipd_pwp_ptr_fifo_ctl.s.
0218                                ptr << 7),
0219                               CVMX_FPA_WQE_POOL, 0);
0220             }
0221             ipd_pwp_ptr_fifo_ctl.s.cena = 1;
0222             cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL,
0223                        ipd_pwp_ptr_fifo_ctl.u64);
0224         }
0225 
0226         /* Free the prefetched packet */
0227         if (ipd_ptr_count.s.pktv_cnt) {
0228             union cvmx_ipd_pkt_ptr_valid ipd_pkt_ptr_valid;
0229             ipd_pkt_ptr_valid.u64 =
0230                 cvmx_read_csr(CVMX_IPD_PKT_PTR_VALID);
0231             cvmx_fpa_free(cvmx_phys_to_ptr
0232                       (ipd_pkt_ptr_valid.s.ptr << 7),
0233                       CVMX_FPA_PACKET_POOL, 0);
0234         }
0235 
0236         /* Free the per port prefetched packets */
0237         if (1) {
0238             int i;
0239             union cvmx_ipd_prc_port_ptr_fifo_ctl
0240                 ipd_prc_port_ptr_fifo_ctl;
0241             ipd_prc_port_ptr_fifo_ctl.u64 =
0242                 cvmx_read_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL);
0243 
0244             for (i = 0; i < ipd_prc_port_ptr_fifo_ctl.s.max_pkt;
0245                  i++) {
0246                 ipd_prc_port_ptr_fifo_ctl.s.cena = 0;
0247                 ipd_prc_port_ptr_fifo_ctl.s.raddr =
0248                     i % ipd_prc_port_ptr_fifo_ctl.s.max_pkt;
0249                 cvmx_write_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL,
0250                            ipd_prc_port_ptr_fifo_ctl.u64);
0251                 ipd_prc_port_ptr_fifo_ctl.u64 =
0252                     cvmx_read_csr
0253                     (CVMX_IPD_PRC_PORT_PTR_FIFO_CTL);
0254                 cvmx_fpa_free(cvmx_phys_to_ptr
0255                           ((uint64_t)
0256                            ipd_prc_port_ptr_fifo_ctl.s.
0257                            ptr << 7), CVMX_FPA_PACKET_POOL,
0258                           0);
0259             }
0260             ipd_prc_port_ptr_fifo_ctl.s.cena = 1;
0261             cvmx_write_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL,
0262                        ipd_prc_port_ptr_fifo_ctl.u64);
0263         }
0264 
0265         /* Free all packets in the holding fifo */
0266         if (ipd_ptr_count.s.pfif_cnt) {
0267             int i;
0268             union cvmx_ipd_prc_hold_ptr_fifo_ctl
0269                 ipd_prc_hold_ptr_fifo_ctl;
0270 
0271             ipd_prc_hold_ptr_fifo_ctl.u64 =
0272                 cvmx_read_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL);
0273 
0274             for (i = 0; i < ipd_ptr_count.s.pfif_cnt; i++) {
0275                 ipd_prc_hold_ptr_fifo_ctl.s.cena = 0;
0276                 ipd_prc_hold_ptr_fifo_ctl.s.raddr =
0277                     (ipd_prc_hold_ptr_fifo_ctl.s.praddr +
0278                      i) % ipd_prc_hold_ptr_fifo_ctl.s.max_pkt;
0279                 cvmx_write_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL,
0280                            ipd_prc_hold_ptr_fifo_ctl.u64);
0281                 ipd_prc_hold_ptr_fifo_ctl.u64 =
0282                     cvmx_read_csr
0283                     (CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL);
0284                 cvmx_fpa_free(cvmx_phys_to_ptr
0285                           ((uint64_t)
0286                            ipd_prc_hold_ptr_fifo_ctl.s.
0287                            ptr << 7), CVMX_FPA_PACKET_POOL,
0288                           0);
0289             }
0290             ipd_prc_hold_ptr_fifo_ctl.s.cena = 1;
0291             cvmx_write_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL,
0292                        ipd_prc_hold_ptr_fifo_ctl.u64);
0293         }
0294 
0295         /* Free all packets in the fifo */
0296         if (ipd_ptr_count.s.pkt_pcnt) {
0297             int i;
0298             union cvmx_ipd_pwp_ptr_fifo_ctl ipd_pwp_ptr_fifo_ctl;
0299             ipd_pwp_ptr_fifo_ctl.u64 =
0300                 cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
0301 
0302             for (i = 0; i < ipd_ptr_count.s.pkt_pcnt; i++) {
0303                 ipd_pwp_ptr_fifo_ctl.s.cena = 0;
0304                 ipd_pwp_ptr_fifo_ctl.s.raddr =
0305                     (ipd_pwp_ptr_fifo_ctl.s.praddr +
0306                      i) % ipd_pwp_ptr_fifo_ctl.s.max_cnts;
0307                 cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL,
0308                            ipd_pwp_ptr_fifo_ctl.u64);
0309                 ipd_pwp_ptr_fifo_ctl.u64 =
0310                     cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
0311                 cvmx_fpa_free(cvmx_phys_to_ptr
0312                           ((uint64_t) ipd_pwp_ptr_fifo_ctl.
0313                            s.ptr << 7),
0314                           CVMX_FPA_PACKET_POOL, 0);
0315             }
0316             ipd_pwp_ptr_fifo_ctl.s.cena = 1;
0317             cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL,
0318                        ipd_pwp_ptr_fifo_ctl.u64);
0319         }
0320 
0321         /* Reset the IPD to get all buffers out of it */
0322         {
0323             union cvmx_ipd_ctl_status ipd_ctl_status;
0324             ipd_ctl_status.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
0325             ipd_ctl_status.s.reset = 1;
0326             cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_ctl_status.u64);
0327         }
0328 
0329         /* Reset the PIP */
0330         {
0331             union cvmx_pip_sft_rst pip_sft_rst;
0332             pip_sft_rst.u64 = cvmx_read_csr(CVMX_PIP_SFT_RST);
0333             pip_sft_rst.s.rst = 1;
0334             cvmx_write_csr(CVMX_PIP_SFT_RST, pip_sft_rst.u64);
0335         }
0336     }
0337 }
0338 
0339 #endif /*  __CVMX_IPD_H__ */