cvmx-ipd.c revision 232809
1232809Sjmallett/***********************license start***************
2232809Sjmallett * Copyright (c) 2003-2010  Cavium Inc. (support@cavium.com). All rights
3232809Sjmallett * reserved.
4232809Sjmallett *
5232809Sjmallett *
6232809Sjmallett * Redistribution and use in source and binary forms, with or without
7232809Sjmallett * modification, are permitted provided that the following conditions are
8232809Sjmallett * met:
9232809Sjmallett *
10232809Sjmallett *   * Redistributions of source code must retain the above copyright
11232809Sjmallett *     notice, this list of conditions and the following disclaimer.
12232809Sjmallett *
13232809Sjmallett *   * Redistributions in binary form must reproduce the above
14232809Sjmallett *     copyright notice, this list of conditions and the following
15232809Sjmallett *     disclaimer in the documentation and/or other materials provided
16232809Sjmallett *     with the distribution.
17232809Sjmallett
18232809Sjmallett *   * Neither the name of Cavium Inc. nor the names of
19232809Sjmallett *     its contributors may be used to endorse or promote products
20232809Sjmallett *     derived from this software without specific prior written
21232809Sjmallett *     permission.
22232809Sjmallett
23232809Sjmallett * This Software, including technical data, may be subject to U.S. export  control
24232809Sjmallett * laws, including the U.S. Export Administration Act and its  associated
25232809Sjmallett * regulations, and may be subject to export or import  regulations in other
26232809Sjmallett * countries.
27232809Sjmallett
28232809Sjmallett * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
29232809Sjmallett * AND WITH ALL FAULTS AND CAVIUM INC. MAKES NO PROMISES, REPRESENTATIONS OR
30232809Sjmallett * WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
31232809Sjmallett * THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
32232809Sjmallett * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
33232809Sjmallett * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
34232809Sjmallett * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
35232809Sjmallett * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
36232809Sjmallett * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE  RISK ARISING OUT OF USE OR
37232809Sjmallett * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
38232809Sjmallett ***********************license end**************************************/
39232809Sjmallett
40232809Sjmallett
41232809Sjmallett
42232809Sjmallett
43232809Sjmallett
44232809Sjmallett
45232809Sjmallett
46232809Sjmallett/**
47232809Sjmallett * @file
48232809Sjmallett *
49232809Sjmallett * IPD Support.
50232809Sjmallett *
51232809Sjmallett * <hr>$Revision: 58943 $<hr>
52232809Sjmallett */
53232809Sjmallett#ifdef CVMX_BUILD_FOR_LINUX_KERNEL
54232809Sjmallett#include <linux/module.h>
55232809Sjmallett#include <asm/octeon/cvmx.h>
56232809Sjmallett#include <asm/octeon/cvmx-config.h>
57232809Sjmallett#include <asm/octeon/cvmx-bootmem.h>
58232809Sjmallett#include <asm/octeon/cvmx-pip-defs.h>
59232809Sjmallett#include <asm/octeon/cvmx-dbg-defs.h>
60232809Sjmallett#include <asm/octeon/cvmx-sso-defs.h>
61232809Sjmallett
62232809Sjmallett#include <asm/octeon/cvmx-fpa.h>
63232809Sjmallett#include <asm/octeon/cvmx-wqe.h>
64232809Sjmallett#include <asm/octeon/cvmx-ipd.h>
65232809Sjmallett#include <asm/octeon/cvmx-clock.h>
66232809Sjmallett#include <asm/octeon/cvmx-helper-errata.h>
67232809Sjmallett#include <asm/octeon/cvmx-helper-cfg.h>
68232809Sjmallett#else
69232809Sjmallett#include "executive-config.h"
70232809Sjmallett#include "cvmx.h"
71232809Sjmallett#include "cvmx-sysinfo.h"
72232809Sjmallett#include "cvmx-bootmem.h"
73232809Sjmallett#include "cvmx-version.h"
74232809Sjmallett#include "cvmx-helper-check-defines.h"
75232809Sjmallett#include "cvmx-error.h"
76232809Sjmallett#include "cvmx-config.h"
77232809Sjmallett
78232809Sjmallett#include "cvmx-fpa.h"
79232809Sjmallett#include "cvmx-wqe.h"
80232809Sjmallett#include "cvmx-ipd.h"
81232809Sjmallett#include "cvmx-helper-errata.h"
82232809Sjmallett#include "cvmx-helper-cfg.h"
83232809Sjmallett#endif
84232809Sjmallett
85232809Sjmallett#ifdef CVMX_ENABLE_PKO_FUNCTIONS
86232809Sjmallettstatic void __cvmx_ipd_free_ptr_v1(void)
87232809Sjmallett{
88232809Sjmallett    /* Only CN38XXp{1,2} cannot read pointer out of the IPD */
89232809Sjmallett    if (!OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2)) {
90232809Sjmallett	int no_wptr = 0;
91232809Sjmallett	cvmx_ipd_ptr_count_t ipd_ptr_count;
92232809Sjmallett	ipd_ptr_count.u64 = cvmx_read_csr(CVMX_IPD_PTR_COUNT);
93232809Sjmallett
94232809Sjmallett	/* Handle Work Queue Entry in cn56xx and cn52xx */
95232809Sjmallett	if (octeon_has_feature(OCTEON_FEATURE_NO_WPTR)) {
96232809Sjmallett	    cvmx_ipd_ctl_status_t ipd_ctl_status;
97232809Sjmallett	    ipd_ctl_status.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
98232809Sjmallett	    if (ipd_ctl_status.s.no_wptr)
99232809Sjmallett		no_wptr = 1;
100232809Sjmallett	}
101232809Sjmallett
102232809Sjmallett	/* Free the prefetched WQE */
103232809Sjmallett	if (ipd_ptr_count.s.wqev_cnt) {
104232809Sjmallett	    cvmx_ipd_wqe_ptr_valid_t ipd_wqe_ptr_valid;
105232809Sjmallett	    ipd_wqe_ptr_valid.u64 = cvmx_read_csr(CVMX_IPD_WQE_PTR_VALID);
106232809Sjmallett	    if (no_wptr)
107232809Sjmallett	        cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_wqe_ptr_valid.s.ptr<<7), CVMX_FPA_PACKET_POOL, 0);
108232809Sjmallett	    else
109232809Sjmallett	        cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_wqe_ptr_valid.s.ptr<<7), CVMX_FPA_WQE_POOL, 0);
110232809Sjmallett	}
111232809Sjmallett
112232809Sjmallett	/* Free all WQE in the fifo */
113232809Sjmallett	if (ipd_ptr_count.s.wqe_pcnt) {
114232809Sjmallett	    int i;
115232809Sjmallett	    cvmx_ipd_pwp_ptr_fifo_ctl_t ipd_pwp_ptr_fifo_ctl;
116232809Sjmallett	    ipd_pwp_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
117232809Sjmallett	    for (i = 0; i < ipd_ptr_count.s.wqe_pcnt; i++) {
118232809Sjmallett		ipd_pwp_ptr_fifo_ctl.s.cena = 0;
119232809Sjmallett		ipd_pwp_ptr_fifo_ctl.s.raddr = ipd_pwp_ptr_fifo_ctl.s.max_cnts + (ipd_pwp_ptr_fifo_ctl.s.wraddr+i) % ipd_pwp_ptr_fifo_ctl.s.max_cnts;
120232809Sjmallett		cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL, ipd_pwp_ptr_fifo_ctl.u64);
121232809Sjmallett		ipd_pwp_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
122232809Sjmallett		if (no_wptr)
123232809Sjmallett		    cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_pwp_ptr_fifo_ctl.s.ptr<<7), CVMX_FPA_PACKET_POOL, 0);
124232809Sjmallett		else
125232809Sjmallett		    cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_pwp_ptr_fifo_ctl.s.ptr<<7), CVMX_FPA_WQE_POOL, 0);
126232809Sjmallett	    }
127232809Sjmallett	    ipd_pwp_ptr_fifo_ctl.s.cena = 1;
128232809Sjmallett	    cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL, ipd_pwp_ptr_fifo_ctl.u64);
129232809Sjmallett	}
130232809Sjmallett
131232809Sjmallett	/* Free the prefetched packet */
132232809Sjmallett	if (ipd_ptr_count.s.pktv_cnt) {
133232809Sjmallett	    cvmx_ipd_pkt_ptr_valid_t ipd_pkt_ptr_valid;
134232809Sjmallett	    ipd_pkt_ptr_valid.u64 = cvmx_read_csr(CVMX_IPD_PKT_PTR_VALID);
135232809Sjmallett	    cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_pkt_ptr_valid.s.ptr<<7), CVMX_FPA_PACKET_POOL, 0);
136232809Sjmallett	}
137232809Sjmallett
138232809Sjmallett	/* Free the per port prefetched packets */
139232809Sjmallett	if (1) {
140232809Sjmallett	    int i;
141232809Sjmallett	    cvmx_ipd_prc_port_ptr_fifo_ctl_t ipd_prc_port_ptr_fifo_ctl;
142232809Sjmallett	    ipd_prc_port_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL);
143232809Sjmallett
144232809Sjmallett	    for (i = 0; i < ipd_prc_port_ptr_fifo_ctl.s.max_pkt; i++) {
145232809Sjmallett		ipd_prc_port_ptr_fifo_ctl.s.cena = 0;
146232809Sjmallett		ipd_prc_port_ptr_fifo_ctl.s.raddr = i % ipd_prc_port_ptr_fifo_ctl.s.max_pkt;
147232809Sjmallett		cvmx_write_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL, ipd_prc_port_ptr_fifo_ctl.u64);
148232809Sjmallett		ipd_prc_port_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL);
149232809Sjmallett		cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_prc_port_ptr_fifo_ctl.s.ptr<<7), CVMX_FPA_PACKET_POOL, 0);
150232809Sjmallett	    }
151232809Sjmallett	    ipd_prc_port_ptr_fifo_ctl.s.cena = 1;
152232809Sjmallett	    cvmx_write_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL, ipd_prc_port_ptr_fifo_ctl.u64);
153232809Sjmallett	}
154232809Sjmallett
155232809Sjmallett	/* Free all packets in the holding fifo */
156232809Sjmallett	if (ipd_ptr_count.s.pfif_cnt) {
157232809Sjmallett	    int i;
158232809Sjmallett	    cvmx_ipd_prc_hold_ptr_fifo_ctl_t ipd_prc_hold_ptr_fifo_ctl;
159232809Sjmallett
160232809Sjmallett	    ipd_prc_hold_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL);
161232809Sjmallett
162232809Sjmallett	    for (i = 0; i < ipd_ptr_count.s.pfif_cnt; i++) {
163232809Sjmallett		ipd_prc_hold_ptr_fifo_ctl.s.cena = 0;
164232809Sjmallett		ipd_prc_hold_ptr_fifo_ctl.s.raddr = (ipd_prc_hold_ptr_fifo_ctl.s.praddr + i) % ipd_prc_hold_ptr_fifo_ctl.s.max_pkt;
165232809Sjmallett		cvmx_write_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL, ipd_prc_hold_ptr_fifo_ctl.u64);
166232809Sjmallett		ipd_prc_hold_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL);
167232809Sjmallett		cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_prc_hold_ptr_fifo_ctl.s.ptr<<7), CVMX_FPA_PACKET_POOL, 0);
168232809Sjmallett	    }
169232809Sjmallett	    ipd_prc_hold_ptr_fifo_ctl.s.cena = 1;
170232809Sjmallett	    cvmx_write_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL, ipd_prc_hold_ptr_fifo_ctl.u64);
171232809Sjmallett	}
172232809Sjmallett
173232809Sjmallett	/* Free all packets in the fifo */
174232809Sjmallett	if (ipd_ptr_count.s.pkt_pcnt) {
175232809Sjmallett	    int i;
176232809Sjmallett	    cvmx_ipd_pwp_ptr_fifo_ctl_t ipd_pwp_ptr_fifo_ctl;
177232809Sjmallett	    ipd_pwp_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
178232809Sjmallett
179232809Sjmallett	    for (i = 0; i < ipd_ptr_count.s.pkt_pcnt; i++) {
180232809Sjmallett		ipd_pwp_ptr_fifo_ctl.s.cena = 0;
181232809Sjmallett		ipd_pwp_ptr_fifo_ctl.s.raddr = (ipd_pwp_ptr_fifo_ctl.s.praddr+i) % ipd_pwp_ptr_fifo_ctl.s.max_cnts;
182232809Sjmallett		cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL, ipd_pwp_ptr_fifo_ctl.u64);
183232809Sjmallett		ipd_pwp_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
184232809Sjmallett		cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_pwp_ptr_fifo_ctl.s.ptr<<7), CVMX_FPA_PACKET_POOL, 0);
185232809Sjmallett	    }
186232809Sjmallett	    ipd_pwp_ptr_fifo_ctl.s.cena = 1;
187232809Sjmallett	    cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL, ipd_pwp_ptr_fifo_ctl.u64);
188232809Sjmallett	}
189232809Sjmallett    }
190232809Sjmallett}
191232809Sjmallett
192232809Sjmallettstatic void __cvmx_ipd_free_ptr_v2(void)
193232809Sjmallett{
194232809Sjmallett    int no_wptr = 0;
195232809Sjmallett    int i;
196232809Sjmallett    cvmx_ipd_port_ptr_fifo_ctl_t ipd_port_ptr_fifo_ctl;
197232809Sjmallett    cvmx_ipd_ptr_count_t ipd_ptr_count;
198232809Sjmallett    ipd_ptr_count.u64 = cvmx_read_csr(CVMX_IPD_PTR_COUNT);
199232809Sjmallett
200232809Sjmallett    /* Handle Work Queue Entry in cn68xx */
201232809Sjmallett    if (octeon_has_feature(OCTEON_FEATURE_NO_WPTR)) {
202232809Sjmallett        cvmx_ipd_ctl_status_t ipd_ctl_status;
203232809Sjmallett        ipd_ctl_status.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
204232809Sjmallett        if (ipd_ctl_status.s.no_wptr)
205232809Sjmallett            no_wptr = 1;
206232809Sjmallett    }
207232809Sjmallett
208232809Sjmallett    /* Free the prefetched WQE */
209232809Sjmallett    if (ipd_ptr_count.s.wqev_cnt) {
210232809Sjmallett        cvmx_ipd_next_wqe_ptr_t ipd_next_wqe_ptr;
211232809Sjmallett        ipd_next_wqe_ptr.u64 = cvmx_read_csr(CVMX_IPD_NEXT_WQE_PTR);
212232809Sjmallett        if (no_wptr)
213232809Sjmallett            cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_next_wqe_ptr.s.ptr<<7), CVMX_FPA_PACKET_POOL, 0);
214232809Sjmallett        else
215232809Sjmallett            cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_next_wqe_ptr.s.ptr<<7), CVMX_FPA_WQE_POOL, 0);
216232809Sjmallett    }
217232809Sjmallett
218232809Sjmallett
219232809Sjmallett    /* Free all WQE in the fifo */
220232809Sjmallett    if (ipd_ptr_count.s.wqe_pcnt) {
221232809Sjmallett        cvmx_ipd_free_ptr_fifo_ctl_t ipd_free_ptr_fifo_ctl;
222232809Sjmallett        cvmx_ipd_free_ptr_value_t ipd_free_ptr_value;
223232809Sjmallett        ipd_free_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_FREE_PTR_FIFO_CTL);
224232809Sjmallett        for (i = 0; i < ipd_ptr_count.s.wqe_pcnt; i++) {
225232809Sjmallett            ipd_free_ptr_fifo_ctl.s.cena = 0;
226232809Sjmallett            ipd_free_ptr_fifo_ctl.s.raddr = ipd_free_ptr_fifo_ctl.s.max_cnts + (ipd_free_ptr_fifo_ctl.s.wraddr+i) % ipd_free_ptr_fifo_ctl.s.max_cnts;
227232809Sjmallett            cvmx_write_csr(CVMX_IPD_FREE_PTR_FIFO_CTL, ipd_free_ptr_fifo_ctl.u64);
228232809Sjmallett            ipd_free_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_FREE_PTR_FIFO_CTL);
229232809Sjmallett            ipd_free_ptr_value.u64 = cvmx_read_csr(CVMX_IPD_FREE_PTR_VALUE);
230232809Sjmallett            if (no_wptr)
231232809Sjmallett                cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_free_ptr_value.s.ptr<<7), CVMX_FPA_PACKET_POOL, 0);
232232809Sjmallett            else
233232809Sjmallett                cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_free_ptr_value.s.ptr<<7), CVMX_FPA_WQE_POOL, 0);
234232809Sjmallett        }
235232809Sjmallett        ipd_free_ptr_fifo_ctl.s.cena = 1;
236232809Sjmallett        cvmx_write_csr(CVMX_IPD_FREE_PTR_FIFO_CTL, ipd_free_ptr_fifo_ctl.u64);
237232809Sjmallett    }
238232809Sjmallett
239232809Sjmallett    /* Free the prefetched packet */
240232809Sjmallett    if (ipd_ptr_count.s.pktv_cnt) {
241232809Sjmallett        cvmx_ipd_next_pkt_ptr_t ipd_next_pkt_ptr;
242232809Sjmallett        ipd_next_pkt_ptr.u64 = cvmx_read_csr(CVMX_IPD_NEXT_PKT_PTR);
243232809Sjmallett        cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_next_pkt_ptr.s.ptr<<7), CVMX_FPA_PACKET_POOL, 0);
244232809Sjmallett    }
245232809Sjmallett
246232809Sjmallett    /* Free the per port prefetched packets */
247232809Sjmallett    ipd_port_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_PORT_PTR_FIFO_CTL);
248232809Sjmallett
249232809Sjmallett    for (i = 0; i < ipd_port_ptr_fifo_ctl.s.max_pkt; i++) {
250232809Sjmallett        ipd_port_ptr_fifo_ctl.s.cena = 0;
251232809Sjmallett        ipd_port_ptr_fifo_ctl.s.raddr = i % ipd_port_ptr_fifo_ctl.s.max_pkt;
252232809Sjmallett        cvmx_write_csr(CVMX_IPD_PORT_PTR_FIFO_CTL, ipd_port_ptr_fifo_ctl.u64);
253232809Sjmallett        ipd_port_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_PORT_PTR_FIFO_CTL);
254232809Sjmallett        cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_port_ptr_fifo_ctl.s.ptr<<7), CVMX_FPA_PACKET_POOL, 0);
255232809Sjmallett    }
256232809Sjmallett    ipd_port_ptr_fifo_ctl.s.cena = 1;
257232809Sjmallett    cvmx_write_csr(CVMX_IPD_PORT_PTR_FIFO_CTL, ipd_port_ptr_fifo_ctl.u64);
258232809Sjmallett
259232809Sjmallett    /* Free all packets in the holding fifo */
260232809Sjmallett    if (ipd_ptr_count.s.pfif_cnt) {
261232809Sjmallett        cvmx_ipd_hold_ptr_fifo_ctl_t ipd_hold_ptr_fifo_ctl;
262232809Sjmallett
263232809Sjmallett        ipd_hold_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_HOLD_PTR_FIFO_CTL);
264232809Sjmallett
265232809Sjmallett        for (i = 0; i < ipd_ptr_count.s.pfif_cnt; i++) {
266232809Sjmallett            ipd_hold_ptr_fifo_ctl.s.cena = 0;
267232809Sjmallett            ipd_hold_ptr_fifo_ctl.s.raddr = (ipd_hold_ptr_fifo_ctl.s.praddr + i) % ipd_hold_ptr_fifo_ctl.s.max_pkt;
268232809Sjmallett            cvmx_write_csr(CVMX_IPD_HOLD_PTR_FIFO_CTL, ipd_hold_ptr_fifo_ctl.u64);
269232809Sjmallett            ipd_hold_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_HOLD_PTR_FIFO_CTL);
270232809Sjmallett            cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_hold_ptr_fifo_ctl.s.ptr<<7), CVMX_FPA_PACKET_POOL, 0);
271232809Sjmallett        }
272232809Sjmallett        ipd_hold_ptr_fifo_ctl.s.cena = 1;
273232809Sjmallett        cvmx_write_csr(CVMX_IPD_HOLD_PTR_FIFO_CTL, ipd_hold_ptr_fifo_ctl.u64);
274232809Sjmallett    }
275232809Sjmallett
276232809Sjmallett    /* Free all packets in the fifo */
277232809Sjmallett    if (ipd_ptr_count.s.pkt_pcnt) {
278232809Sjmallett        cvmx_ipd_free_ptr_fifo_ctl_t ipd_free_ptr_fifo_ctl;
279232809Sjmallett        cvmx_ipd_free_ptr_value_t ipd_free_ptr_value;
280232809Sjmallett        ipd_free_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_FREE_PTR_FIFO_CTL);
281232809Sjmallett
282232809Sjmallett        for (i = 0; i < ipd_ptr_count.s.pkt_pcnt; i++) {
283232809Sjmallett            ipd_free_ptr_fifo_ctl.s.cena = 0;
284232809Sjmallett            ipd_free_ptr_fifo_ctl.s.raddr = (ipd_free_ptr_fifo_ctl.s.praddr+i) % ipd_free_ptr_fifo_ctl.s.max_cnts;
285232809Sjmallett            cvmx_write_csr(CVMX_IPD_FREE_PTR_FIFO_CTL, ipd_free_ptr_fifo_ctl.u64);
286232809Sjmallett            ipd_free_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_FREE_PTR_FIFO_CTL);
287232809Sjmallett            ipd_free_ptr_value.u64 = cvmx_read_csr(CVMX_IPD_FREE_PTR_VALUE);
288232809Sjmallett            cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_free_ptr_value.s.ptr<<7), CVMX_FPA_PACKET_POOL, 0);
289232809Sjmallett        }
290232809Sjmallett        ipd_free_ptr_fifo_ctl.s.cena = 1;
291232809Sjmallett        cvmx_write_csr(CVMX_IPD_FREE_PTR_FIFO_CTL, ipd_free_ptr_fifo_ctl.u64);
292232809Sjmallett    }
293232809Sjmallett}
294232809Sjmallett
295232809Sjmallett/**
296232809Sjmallett * @INTERNAL
297232809Sjmallett * This function is called by cvmx_helper_shutdown() to extract
298232809Sjmallett * all FPA buffers out of the IPD and PIP. After this function
299232809Sjmallett * completes, all FPA buffers that were prefetched by IPD and PIP
300232809Sjmallett * wil be in the apropriate FPA pool. This functions does not reset
301232809Sjmallett * PIP or IPD as FPA pool zero must be empty before the reset can
302232809Sjmallett * be performed. WARNING: It is very important that IPD and PIP be
303232809Sjmallett * reset soon after a call to this function.
304232809Sjmallett */
305232809Sjmallettvoid __cvmx_ipd_free_ptr(void)
306232809Sjmallett{
307232809Sjmallett    if (octeon_has_feature(OCTEON_FEATURE_PKND))
308232809Sjmallett        __cvmx_ipd_free_ptr_v2();
309232809Sjmallett    else
310232809Sjmallett        __cvmx_ipd_free_ptr_v1();
311232809Sjmallett}
312232809Sjmallett
313232809Sjmallett#endif
314232809Sjmallett
315