1af866496SDavid Daney /***********************license start*************** 2af866496SDavid Daney * Author: Cavium Networks 3af866496SDavid Daney * 4af866496SDavid Daney * Contact: support@caviumnetworks.com 5af866496SDavid Daney * This file is part of the OCTEON SDK 6af866496SDavid Daney * 7af866496SDavid Daney * Copyright (c) 2003-2008 Cavium Networks 8af866496SDavid Daney * 9af866496SDavid Daney * This file is free software; you can redistribute it and/or modify 10af866496SDavid Daney * it under the terms of the GNU General Public License, Version 2, as 11af866496SDavid Daney * published by the Free Software Foundation. 12af866496SDavid Daney * 13af866496SDavid Daney * This file is distributed in the hope that it will be useful, but 14af866496SDavid Daney * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty 15af866496SDavid Daney * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or 16af866496SDavid Daney * NONINFRINGEMENT. See the GNU General Public License for more 17af866496SDavid Daney * details. 18af866496SDavid Daney * 19af866496SDavid Daney * You should have received a copy of the GNU General Public License 20af866496SDavid Daney * along with this file; if not, write to the Free Software 21af866496SDavid Daney * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22af866496SDavid Daney * or visit http://www.gnu.org/licenses/. 23af866496SDavid Daney * 24af866496SDavid Daney * This file may also be available under a different license from Cavium. 25af866496SDavid Daney * Contact Cavium Networks for more information 26af866496SDavid Daney ***********************license end**************************************/ 27af866496SDavid Daney 28af866496SDavid Daney /** 29af866496SDavid Daney * 30af866496SDavid Daney * Interface to the hardware Input Packet Data unit. 31af866496SDavid Daney */ 32af866496SDavid Daney 33af866496SDavid Daney #ifndef __CVMX_IPD_H__ 34af866496SDavid Daney #define __CVMX_IPD_H__ 35af866496SDavid Daney 36af866496SDavid Daney #include <asm/octeon/octeon-feature.h> 37af866496SDavid Daney 38af866496SDavid Daney #include <asm/octeon/cvmx-ipd-defs.h> 39af866496SDavid Daney 40af866496SDavid Daney enum cvmx_ipd_mode { 41af866496SDavid Daney CVMX_IPD_OPC_MODE_STT = 0LL, /* All blocks DRAM, not cached in L2 */ 42*da66f8e6SAndrea Gelmini CVMX_IPD_OPC_MODE_STF = 1LL, /* All blocks into L2 */ 43af866496SDavid Daney CVMX_IPD_OPC_MODE_STF1_STT = 2LL, /* 1st block L2, rest DRAM */ 44af866496SDavid Daney CVMX_IPD_OPC_MODE_STF2_STT = 3LL /* 1st, 2nd blocks L2, rest DRAM */ 45af866496SDavid Daney }; 46af866496SDavid Daney 47af866496SDavid Daney #ifndef CVMX_ENABLE_LEN_M8_FIX 48af866496SDavid Daney #define CVMX_ENABLE_LEN_M8_FIX 0 49af866496SDavid Daney #endif 50af866496SDavid Daney 51af866496SDavid Daney /* CSR typedefs have been moved to cvmx-csr-*.h */ 52af866496SDavid Daney typedef union cvmx_ipd_1st_mbuff_skip cvmx_ipd_mbuff_first_skip_t; 53af866496SDavid Daney typedef union cvmx_ipd_1st_next_ptr_back cvmx_ipd_first_next_ptr_back_t; 54af866496SDavid Daney 55af866496SDavid Daney typedef cvmx_ipd_mbuff_first_skip_t cvmx_ipd_mbuff_not_first_skip_t; 56af866496SDavid Daney typedef cvmx_ipd_first_next_ptr_back_t cvmx_ipd_second_next_ptr_back_t; 57af866496SDavid Daney 58af866496SDavid Daney /** 59af866496SDavid Daney * Configure IPD 60af866496SDavid Daney * 61af866496SDavid Daney * @mbuff_size: Packets buffer size in 8 byte words 62af866496SDavid Daney * @first_mbuff_skip: 63af866496SDavid Daney * Number of 8 byte words to skip in the first buffer 64af866496SDavid Daney * @not_first_mbuff_skip: 65af866496SDavid Daney * Number of 8 byte words to skip in each following buffer 66af866496SDavid Daney * @first_back: Must be same as first_mbuff_skip / 128 67af866496SDavid Daney * @second_back: 68af866496SDavid Daney * Must be same as not_first_mbuff_skip / 128 69af866496SDavid Daney * @wqe_fpa_pool: 70af866496SDavid Daney * FPA pool to get work entries from 71af866496SDavid Daney * @cache_mode: 72af866496SDavid Daney * @back_pres_enable_flag: 73af866496SDavid Daney * Enable or disable port back pressure 74af866496SDavid Daney */ 75af866496SDavid Daney static inline void cvmx_ipd_config(uint64_t mbuff_size, 76af866496SDavid Daney uint64_t first_mbuff_skip, 77af866496SDavid Daney uint64_t not_first_mbuff_skip, 78af866496SDavid Daney uint64_t first_back, 79af866496SDavid Daney uint64_t second_back, 80af866496SDavid Daney uint64_t wqe_fpa_pool, 81af866496SDavid Daney enum cvmx_ipd_mode cache_mode, 82af866496SDavid Daney uint64_t back_pres_enable_flag) 83af866496SDavid Daney { 84af866496SDavid Daney cvmx_ipd_mbuff_first_skip_t first_skip; 85af866496SDavid Daney cvmx_ipd_mbuff_not_first_skip_t not_first_skip; 86af866496SDavid Daney union cvmx_ipd_packet_mbuff_size size; 87af866496SDavid Daney cvmx_ipd_first_next_ptr_back_t first_back_struct; 88af866496SDavid Daney cvmx_ipd_second_next_ptr_back_t second_back_struct; 89af866496SDavid Daney union cvmx_ipd_wqe_fpa_queue wqe_pool; 90af866496SDavid Daney union cvmx_ipd_ctl_status ipd_ctl_reg; 91af866496SDavid Daney 92af866496SDavid Daney first_skip.u64 = 0; 93af866496SDavid Daney first_skip.s.skip_sz = first_mbuff_skip; 94af866496SDavid Daney cvmx_write_csr(CVMX_IPD_1ST_MBUFF_SKIP, first_skip.u64); 95af866496SDavid Daney 96af866496SDavid Daney not_first_skip.u64 = 0; 97af866496SDavid Daney not_first_skip.s.skip_sz = not_first_mbuff_skip; 98af866496SDavid Daney cvmx_write_csr(CVMX_IPD_NOT_1ST_MBUFF_SKIP, not_first_skip.u64); 99af866496SDavid Daney 100af866496SDavid Daney size.u64 = 0; 101af866496SDavid Daney size.s.mb_size = mbuff_size; 102af866496SDavid Daney cvmx_write_csr(CVMX_IPD_PACKET_MBUFF_SIZE, size.u64); 103af866496SDavid Daney 104af866496SDavid Daney first_back_struct.u64 = 0; 105af866496SDavid Daney first_back_struct.s.back = first_back; 106af866496SDavid Daney cvmx_write_csr(CVMX_IPD_1st_NEXT_PTR_BACK, first_back_struct.u64); 107af866496SDavid Daney 108af866496SDavid Daney second_back_struct.u64 = 0; 109af866496SDavid Daney second_back_struct.s.back = second_back; 110af866496SDavid Daney cvmx_write_csr(CVMX_IPD_2nd_NEXT_PTR_BACK, second_back_struct.u64); 111af866496SDavid Daney 112af866496SDavid Daney wqe_pool.u64 = 0; 113af866496SDavid Daney wqe_pool.s.wqe_pool = wqe_fpa_pool; 114af866496SDavid Daney cvmx_write_csr(CVMX_IPD_WQE_FPA_QUEUE, wqe_pool.u64); 115af866496SDavid Daney 116af866496SDavid Daney ipd_ctl_reg.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS); 117af866496SDavid Daney ipd_ctl_reg.s.opc_mode = cache_mode; 118af866496SDavid Daney ipd_ctl_reg.s.pbp_en = back_pres_enable_flag; 119af866496SDavid Daney cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_ctl_reg.u64); 120af866496SDavid Daney 121af866496SDavid Daney /* Note: the example RED code that used to be here has been moved to 122af866496SDavid Daney cvmx_helper_setup_red */ 123af866496SDavid Daney } 124af866496SDavid Daney 125af866496SDavid Daney /** 126af866496SDavid Daney * Enable IPD 127af866496SDavid Daney */ 128af866496SDavid Daney static inline void cvmx_ipd_enable(void) 129af866496SDavid Daney { 130af866496SDavid Daney union cvmx_ipd_ctl_status ipd_reg; 131af866496SDavid Daney ipd_reg.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS); 132af866496SDavid Daney if (ipd_reg.s.ipd_en) { 133af866496SDavid Daney cvmx_dprintf 134af866496SDavid Daney ("Warning: Enabling IPD when IPD already enabled.\n"); 135af866496SDavid Daney } 136af866496SDavid Daney ipd_reg.s.ipd_en = 1; 137af866496SDavid Daney #if CVMX_ENABLE_LEN_M8_FIX 138af866496SDavid Daney if (!OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2)) 139af866496SDavid Daney ipd_reg.s.len_m8 = TRUE; 140af866496SDavid Daney #endif 141af866496SDavid Daney cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_reg.u64); 142af866496SDavid Daney } 143af866496SDavid Daney 144af866496SDavid Daney /** 145af866496SDavid Daney * Disable IPD 146af866496SDavid Daney */ 147af866496SDavid Daney static inline void cvmx_ipd_disable(void) 148af866496SDavid Daney { 149af866496SDavid Daney union cvmx_ipd_ctl_status ipd_reg; 150af866496SDavid Daney ipd_reg.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS); 151af866496SDavid Daney ipd_reg.s.ipd_en = 0; 152af866496SDavid Daney cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_reg.u64); 153af866496SDavid Daney } 154af866496SDavid Daney 155af866496SDavid Daney /** 156af866496SDavid Daney * Supportive function for cvmx_fpa_shutdown_pool. 157af866496SDavid Daney */ 158af866496SDavid Daney static inline void cvmx_ipd_free_ptr(void) 159af866496SDavid Daney { 160af866496SDavid Daney /* Only CN38XXp{1,2} cannot read pointer out of the IPD */ 161af866496SDavid Daney if (!OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1) 162af866496SDavid Daney && !OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2)) { 163af866496SDavid Daney int no_wptr = 0; 164af866496SDavid Daney union cvmx_ipd_ptr_count ipd_ptr_count; 165af866496SDavid Daney ipd_ptr_count.u64 = cvmx_read_csr(CVMX_IPD_PTR_COUNT); 166af866496SDavid Daney 167af866496SDavid Daney /* Handle Work Queue Entry in cn56xx and cn52xx */ 168af866496SDavid Daney if (octeon_has_feature(OCTEON_FEATURE_NO_WPTR)) { 169af866496SDavid Daney union cvmx_ipd_ctl_status ipd_ctl_status; 170af866496SDavid Daney ipd_ctl_status.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS); 171af866496SDavid Daney if (ipd_ctl_status.s.no_wptr) 172af866496SDavid Daney no_wptr = 1; 173af866496SDavid Daney } 174af866496SDavid Daney 175af866496SDavid Daney /* Free the prefetched WQE */ 176af866496SDavid Daney if (ipd_ptr_count.s.wqev_cnt) { 177af866496SDavid Daney union cvmx_ipd_wqe_ptr_valid ipd_wqe_ptr_valid; 178af866496SDavid Daney ipd_wqe_ptr_valid.u64 = 179af866496SDavid Daney cvmx_read_csr(CVMX_IPD_WQE_PTR_VALID); 180af866496SDavid Daney if (no_wptr) 181af866496SDavid Daney cvmx_fpa_free(cvmx_phys_to_ptr 182af866496SDavid Daney ((uint64_t) ipd_wqe_ptr_valid.s. 183af866496SDavid Daney ptr << 7), CVMX_FPA_PACKET_POOL, 184af866496SDavid Daney 0); 185af866496SDavid Daney else 186af866496SDavid Daney cvmx_fpa_free(cvmx_phys_to_ptr 187af866496SDavid Daney ((uint64_t) ipd_wqe_ptr_valid.s. 188af866496SDavid Daney ptr << 7), CVMX_FPA_WQE_POOL, 0); 189af866496SDavid Daney } 190af866496SDavid Daney 191af866496SDavid Daney /* Free all WQE in the fifo */ 192af866496SDavid Daney if (ipd_ptr_count.s.wqe_pcnt) { 193af866496SDavid Daney int i; 194af866496SDavid Daney union cvmx_ipd_pwp_ptr_fifo_ctl ipd_pwp_ptr_fifo_ctl; 195af866496SDavid Daney ipd_pwp_ptr_fifo_ctl.u64 = 196af866496SDavid Daney cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL); 197af866496SDavid Daney for (i = 0; i < ipd_ptr_count.s.wqe_pcnt; i++) { 198af866496SDavid Daney ipd_pwp_ptr_fifo_ctl.s.cena = 0; 199af866496SDavid Daney ipd_pwp_ptr_fifo_ctl.s.raddr = 200af866496SDavid Daney ipd_pwp_ptr_fifo_ctl.s.max_cnts + 201af866496SDavid Daney (ipd_pwp_ptr_fifo_ctl.s.wraddr + 202af866496SDavid Daney i) % ipd_pwp_ptr_fifo_ctl.s.max_cnts; 203af866496SDavid Daney cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL, 204af866496SDavid Daney ipd_pwp_ptr_fifo_ctl.u64); 205af866496SDavid Daney ipd_pwp_ptr_fifo_ctl.u64 = 206af866496SDavid Daney cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL); 207af866496SDavid Daney if (no_wptr) 208af866496SDavid Daney cvmx_fpa_free(cvmx_phys_to_ptr 209af866496SDavid Daney ((uint64_t) 210af866496SDavid Daney ipd_pwp_ptr_fifo_ctl.s. 211af866496SDavid Daney ptr << 7), 212af866496SDavid Daney CVMX_FPA_PACKET_POOL, 0); 213af866496SDavid Daney else 214af866496SDavid Daney cvmx_fpa_free(cvmx_phys_to_ptr 215af866496SDavid Daney ((uint64_t) 216af866496SDavid Daney ipd_pwp_ptr_fifo_ctl.s. 217af866496SDavid Daney ptr << 7), 218af866496SDavid Daney CVMX_FPA_WQE_POOL, 0); 219af866496SDavid Daney } 220af866496SDavid Daney ipd_pwp_ptr_fifo_ctl.s.cena = 1; 221af866496SDavid Daney cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL, 222af866496SDavid Daney ipd_pwp_ptr_fifo_ctl.u64); 223af866496SDavid Daney } 224af866496SDavid Daney 225af866496SDavid Daney /* Free the prefetched packet */ 226af866496SDavid Daney if (ipd_ptr_count.s.pktv_cnt) { 227af866496SDavid Daney union cvmx_ipd_pkt_ptr_valid ipd_pkt_ptr_valid; 228af866496SDavid Daney ipd_pkt_ptr_valid.u64 = 229af866496SDavid Daney cvmx_read_csr(CVMX_IPD_PKT_PTR_VALID); 230af866496SDavid Daney cvmx_fpa_free(cvmx_phys_to_ptr 231af866496SDavid Daney (ipd_pkt_ptr_valid.s.ptr << 7), 232af866496SDavid Daney CVMX_FPA_PACKET_POOL, 0); 233af866496SDavid Daney } 234af866496SDavid Daney 235af866496SDavid Daney /* Free the per port prefetched packets */ 236af866496SDavid Daney if (1) { 237af866496SDavid Daney int i; 238af866496SDavid Daney union cvmx_ipd_prc_port_ptr_fifo_ctl 239af866496SDavid Daney ipd_prc_port_ptr_fifo_ctl; 240af866496SDavid Daney ipd_prc_port_ptr_fifo_ctl.u64 = 241af866496SDavid Daney cvmx_read_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL); 242af866496SDavid Daney 243af866496SDavid Daney for (i = 0; i < ipd_prc_port_ptr_fifo_ctl.s.max_pkt; 244af866496SDavid Daney i++) { 245af866496SDavid Daney ipd_prc_port_ptr_fifo_ctl.s.cena = 0; 246af866496SDavid Daney ipd_prc_port_ptr_fifo_ctl.s.raddr = 247af866496SDavid Daney i % ipd_prc_port_ptr_fifo_ctl.s.max_pkt; 248af866496SDavid Daney cvmx_write_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL, 249af866496SDavid Daney ipd_prc_port_ptr_fifo_ctl.u64); 250af866496SDavid Daney ipd_prc_port_ptr_fifo_ctl.u64 = 251af866496SDavid Daney cvmx_read_csr 252af866496SDavid Daney (CVMX_IPD_PRC_PORT_PTR_FIFO_CTL); 253af866496SDavid Daney cvmx_fpa_free(cvmx_phys_to_ptr 254af866496SDavid Daney ((uint64_t) 255af866496SDavid Daney ipd_prc_port_ptr_fifo_ctl.s. 256af866496SDavid Daney ptr << 7), CVMX_FPA_PACKET_POOL, 257af866496SDavid Daney 0); 258af866496SDavid Daney } 259af866496SDavid Daney ipd_prc_port_ptr_fifo_ctl.s.cena = 1; 260af866496SDavid Daney cvmx_write_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL, 261af866496SDavid Daney ipd_prc_port_ptr_fifo_ctl.u64); 262af866496SDavid Daney } 263af866496SDavid Daney 264af866496SDavid Daney /* Free all packets in the holding fifo */ 265af866496SDavid Daney if (ipd_ptr_count.s.pfif_cnt) { 266af866496SDavid Daney int i; 267af866496SDavid Daney union cvmx_ipd_prc_hold_ptr_fifo_ctl 268af866496SDavid Daney ipd_prc_hold_ptr_fifo_ctl; 269af866496SDavid Daney 270af866496SDavid Daney ipd_prc_hold_ptr_fifo_ctl.u64 = 271af866496SDavid Daney cvmx_read_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL); 272af866496SDavid Daney 273af866496SDavid Daney for (i = 0; i < ipd_ptr_count.s.pfif_cnt; i++) { 274af866496SDavid Daney ipd_prc_hold_ptr_fifo_ctl.s.cena = 0; 275af866496SDavid Daney ipd_prc_hold_ptr_fifo_ctl.s.raddr = 276af866496SDavid Daney (ipd_prc_hold_ptr_fifo_ctl.s.praddr + 277af866496SDavid Daney i) % ipd_prc_hold_ptr_fifo_ctl.s.max_pkt; 278af866496SDavid Daney cvmx_write_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL, 279af866496SDavid Daney ipd_prc_hold_ptr_fifo_ctl.u64); 280af866496SDavid Daney ipd_prc_hold_ptr_fifo_ctl.u64 = 281af866496SDavid Daney cvmx_read_csr 282af866496SDavid Daney (CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL); 283af866496SDavid Daney cvmx_fpa_free(cvmx_phys_to_ptr 284af866496SDavid Daney ((uint64_t) 285af866496SDavid Daney ipd_prc_hold_ptr_fifo_ctl.s. 286af866496SDavid Daney ptr << 7), CVMX_FPA_PACKET_POOL, 287af866496SDavid Daney 0); 288af866496SDavid Daney } 289af866496SDavid Daney ipd_prc_hold_ptr_fifo_ctl.s.cena = 1; 290af866496SDavid Daney cvmx_write_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL, 291af866496SDavid Daney ipd_prc_hold_ptr_fifo_ctl.u64); 292af866496SDavid Daney } 293af866496SDavid Daney 294af866496SDavid Daney /* Free all packets in the fifo */ 295af866496SDavid Daney if (ipd_ptr_count.s.pkt_pcnt) { 296af866496SDavid Daney int i; 297af866496SDavid Daney union cvmx_ipd_pwp_ptr_fifo_ctl ipd_pwp_ptr_fifo_ctl; 298af866496SDavid Daney ipd_pwp_ptr_fifo_ctl.u64 = 299af866496SDavid Daney cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL); 300af866496SDavid Daney 301af866496SDavid Daney for (i = 0; i < ipd_ptr_count.s.pkt_pcnt; i++) { 302af866496SDavid Daney ipd_pwp_ptr_fifo_ctl.s.cena = 0; 303af866496SDavid Daney ipd_pwp_ptr_fifo_ctl.s.raddr = 304af866496SDavid Daney (ipd_pwp_ptr_fifo_ctl.s.praddr + 305af866496SDavid Daney i) % ipd_pwp_ptr_fifo_ctl.s.max_cnts; 306af866496SDavid Daney cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL, 307af866496SDavid Daney ipd_pwp_ptr_fifo_ctl.u64); 308af866496SDavid Daney ipd_pwp_ptr_fifo_ctl.u64 = 309af866496SDavid Daney cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL); 310af866496SDavid Daney cvmx_fpa_free(cvmx_phys_to_ptr 311af866496SDavid Daney ((uint64_t) ipd_pwp_ptr_fifo_ctl. 312af866496SDavid Daney s.ptr << 7), 313af866496SDavid Daney CVMX_FPA_PACKET_POOL, 0); 314af866496SDavid Daney } 315af866496SDavid Daney ipd_pwp_ptr_fifo_ctl.s.cena = 1; 316af866496SDavid Daney cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL, 317af866496SDavid Daney ipd_pwp_ptr_fifo_ctl.u64); 318af866496SDavid Daney } 319af866496SDavid Daney 320af866496SDavid Daney /* Reset the IPD to get all buffers out of it */ 321af866496SDavid Daney { 322af866496SDavid Daney union cvmx_ipd_ctl_status ipd_ctl_status; 323af866496SDavid Daney ipd_ctl_status.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS); 324af866496SDavid Daney ipd_ctl_status.s.reset = 1; 325af866496SDavid Daney cvmx_write_csr(CVMX_IPD_CTL_STATUS, ipd_ctl_status.u64); 326af866496SDavid Daney } 327af866496SDavid Daney 328af866496SDavid Daney /* Reset the PIP */ 329af866496SDavid Daney { 330af866496SDavid Daney union cvmx_pip_sft_rst pip_sft_rst; 331af866496SDavid Daney pip_sft_rst.u64 = cvmx_read_csr(CVMX_PIP_SFT_RST); 332af866496SDavid Daney pip_sft_rst.s.rst = 1; 333af866496SDavid Daney cvmx_write_csr(CVMX_PIP_SFT_RST, pip_sft_rst.u64); 334af866496SDavid Daney } 335af866496SDavid Daney } 336af866496SDavid Daney } 337af866496SDavid Daney 338af866496SDavid Daney #endif /* __CVMX_IPD_H__ */ 339