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
69232812Sjmallett#if !defined(__FreeBSD__) || !defined(_KERNEL)
70232809Sjmallett#include "executive-config.h"
71232812Sjmallett#endif
72232809Sjmallett#include "cvmx.h"
73232809Sjmallett#include "cvmx-sysinfo.h"
74232809Sjmallett#include "cvmx-bootmem.h"
75232809Sjmallett#include "cvmx-version.h"
76232809Sjmallett#include "cvmx-helper-check-defines.h"
77232816Sjmallett#if !defined(__FreeBSD__) || !defined(_KERNEL)
78232809Sjmallett#include "cvmx-error.h"
79232809Sjmallett#include "cvmx-config.h"
80232812Sjmallett#endif
81232809Sjmallett
82232809Sjmallett#include "cvmx-fpa.h"
83232809Sjmallett#include "cvmx-wqe.h"
84232809Sjmallett#include "cvmx-ipd.h"
85232809Sjmallett#include "cvmx-helper-errata.h"
86232809Sjmallett#include "cvmx-helper-cfg.h"
87232809Sjmallett#endif
88232809Sjmallett
89232809Sjmallett#ifdef CVMX_ENABLE_PKO_FUNCTIONS
90232809Sjmallettstatic void __cvmx_ipd_free_ptr_v1(void)
91232809Sjmallett{
92232809Sjmallett    /* Only CN38XXp{1,2} cannot read pointer out of the IPD */
93232809Sjmallett    if (!OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2)) {
94232809Sjmallett	int no_wptr = 0;
95232809Sjmallett	cvmx_ipd_ptr_count_t ipd_ptr_count;
96232809Sjmallett	ipd_ptr_count.u64 = cvmx_read_csr(CVMX_IPD_PTR_COUNT);
97232809Sjmallett
98232809Sjmallett	/* Handle Work Queue Entry in cn56xx and cn52xx */
99232809Sjmallett	if (octeon_has_feature(OCTEON_FEATURE_NO_WPTR)) {
100232809Sjmallett	    cvmx_ipd_ctl_status_t ipd_ctl_status;
101232809Sjmallett	    ipd_ctl_status.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
102232809Sjmallett	    if (ipd_ctl_status.s.no_wptr)
103232809Sjmallett		no_wptr = 1;
104232809Sjmallett	}
105232809Sjmallett
106232809Sjmallett	/* Free the prefetched WQE */
107232809Sjmallett	if (ipd_ptr_count.s.wqev_cnt) {
108232809Sjmallett	    cvmx_ipd_wqe_ptr_valid_t ipd_wqe_ptr_valid;
109232809Sjmallett	    ipd_wqe_ptr_valid.u64 = cvmx_read_csr(CVMX_IPD_WQE_PTR_VALID);
110232809Sjmallett	    if (no_wptr)
111232809Sjmallett	        cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_wqe_ptr_valid.s.ptr<<7), CVMX_FPA_PACKET_POOL, 0);
112232809Sjmallett	    else
113232809Sjmallett	        cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_wqe_ptr_valid.s.ptr<<7), CVMX_FPA_WQE_POOL, 0);
114232809Sjmallett	}
115232809Sjmallett
116232809Sjmallett	/* Free all WQE in the fifo */
117232809Sjmallett	if (ipd_ptr_count.s.wqe_pcnt) {
118232809Sjmallett	    int i;
119232809Sjmallett	    cvmx_ipd_pwp_ptr_fifo_ctl_t ipd_pwp_ptr_fifo_ctl;
120232809Sjmallett	    ipd_pwp_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
121232809Sjmallett	    for (i = 0; i < ipd_ptr_count.s.wqe_pcnt; i++) {
122232809Sjmallett		ipd_pwp_ptr_fifo_ctl.s.cena = 0;
123232809Sjmallett		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;
124232809Sjmallett		cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL, ipd_pwp_ptr_fifo_ctl.u64);
125232809Sjmallett		ipd_pwp_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
126232809Sjmallett		if (no_wptr)
127232809Sjmallett		    cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_pwp_ptr_fifo_ctl.s.ptr<<7), CVMX_FPA_PACKET_POOL, 0);
128232809Sjmallett		else
129232809Sjmallett		    cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_pwp_ptr_fifo_ctl.s.ptr<<7), CVMX_FPA_WQE_POOL, 0);
130232809Sjmallett	    }
131232809Sjmallett	    ipd_pwp_ptr_fifo_ctl.s.cena = 1;
132232809Sjmallett	    cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL, ipd_pwp_ptr_fifo_ctl.u64);
133232809Sjmallett	}
134232809Sjmallett
135232809Sjmallett	/* Free the prefetched packet */
136232809Sjmallett	if (ipd_ptr_count.s.pktv_cnt) {
137232809Sjmallett	    cvmx_ipd_pkt_ptr_valid_t ipd_pkt_ptr_valid;
138232809Sjmallett	    ipd_pkt_ptr_valid.u64 = cvmx_read_csr(CVMX_IPD_PKT_PTR_VALID);
139232809Sjmallett	    cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_pkt_ptr_valid.s.ptr<<7), CVMX_FPA_PACKET_POOL, 0);
140232809Sjmallett	}
141232809Sjmallett
142232809Sjmallett	/* Free the per port prefetched packets */
143232809Sjmallett	if (1) {
144232809Sjmallett	    int i;
145232809Sjmallett	    cvmx_ipd_prc_port_ptr_fifo_ctl_t ipd_prc_port_ptr_fifo_ctl;
146232809Sjmallett	    ipd_prc_port_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL);
147232809Sjmallett
148232809Sjmallett	    for (i = 0; i < ipd_prc_port_ptr_fifo_ctl.s.max_pkt; i++) {
149232809Sjmallett		ipd_prc_port_ptr_fifo_ctl.s.cena = 0;
150232809Sjmallett		ipd_prc_port_ptr_fifo_ctl.s.raddr = i % ipd_prc_port_ptr_fifo_ctl.s.max_pkt;
151232809Sjmallett		cvmx_write_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL, ipd_prc_port_ptr_fifo_ctl.u64);
152232809Sjmallett		ipd_prc_port_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL);
153232809Sjmallett		cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_prc_port_ptr_fifo_ctl.s.ptr<<7), CVMX_FPA_PACKET_POOL, 0);
154232809Sjmallett	    }
155232809Sjmallett	    ipd_prc_port_ptr_fifo_ctl.s.cena = 1;
156232809Sjmallett	    cvmx_write_csr(CVMX_IPD_PRC_PORT_PTR_FIFO_CTL, ipd_prc_port_ptr_fifo_ctl.u64);
157232809Sjmallett	}
158232809Sjmallett
159232809Sjmallett	/* Free all packets in the holding fifo */
160232809Sjmallett	if (ipd_ptr_count.s.pfif_cnt) {
161232809Sjmallett	    int i;
162232809Sjmallett	    cvmx_ipd_prc_hold_ptr_fifo_ctl_t ipd_prc_hold_ptr_fifo_ctl;
163232809Sjmallett
164232809Sjmallett	    ipd_prc_hold_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL);
165232809Sjmallett
166232809Sjmallett	    for (i = 0; i < ipd_ptr_count.s.pfif_cnt; i++) {
167232809Sjmallett		ipd_prc_hold_ptr_fifo_ctl.s.cena = 0;
168232809Sjmallett		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;
169232809Sjmallett		cvmx_write_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL, ipd_prc_hold_ptr_fifo_ctl.u64);
170232809Sjmallett		ipd_prc_hold_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL);
171232809Sjmallett		cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_prc_hold_ptr_fifo_ctl.s.ptr<<7), CVMX_FPA_PACKET_POOL, 0);
172232809Sjmallett	    }
173232809Sjmallett	    ipd_prc_hold_ptr_fifo_ctl.s.cena = 1;
174232809Sjmallett	    cvmx_write_csr(CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL, ipd_prc_hold_ptr_fifo_ctl.u64);
175232809Sjmallett	}
176232809Sjmallett
177232809Sjmallett	/* Free all packets in the fifo */
178232809Sjmallett	if (ipd_ptr_count.s.pkt_pcnt) {
179232809Sjmallett	    int i;
180232809Sjmallett	    cvmx_ipd_pwp_ptr_fifo_ctl_t ipd_pwp_ptr_fifo_ctl;
181232809Sjmallett	    ipd_pwp_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
182232809Sjmallett
183232809Sjmallett	    for (i = 0; i < ipd_ptr_count.s.pkt_pcnt; i++) {
184232809Sjmallett		ipd_pwp_ptr_fifo_ctl.s.cena = 0;
185232809Sjmallett		ipd_pwp_ptr_fifo_ctl.s.raddr = (ipd_pwp_ptr_fifo_ctl.s.praddr+i) % ipd_pwp_ptr_fifo_ctl.s.max_cnts;
186232809Sjmallett		cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL, ipd_pwp_ptr_fifo_ctl.u64);
187232809Sjmallett		ipd_pwp_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_PWP_PTR_FIFO_CTL);
188232809Sjmallett		cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_pwp_ptr_fifo_ctl.s.ptr<<7), CVMX_FPA_PACKET_POOL, 0);
189232809Sjmallett	    }
190232809Sjmallett	    ipd_pwp_ptr_fifo_ctl.s.cena = 1;
191232809Sjmallett	    cvmx_write_csr(CVMX_IPD_PWP_PTR_FIFO_CTL, ipd_pwp_ptr_fifo_ctl.u64);
192232809Sjmallett	}
193232809Sjmallett    }
194232809Sjmallett}
195232809Sjmallett
196232809Sjmallettstatic void __cvmx_ipd_free_ptr_v2(void)
197232809Sjmallett{
198232809Sjmallett    int no_wptr = 0;
199232809Sjmallett    int i;
200232809Sjmallett    cvmx_ipd_port_ptr_fifo_ctl_t ipd_port_ptr_fifo_ctl;
201232809Sjmallett    cvmx_ipd_ptr_count_t ipd_ptr_count;
202232809Sjmallett    ipd_ptr_count.u64 = cvmx_read_csr(CVMX_IPD_PTR_COUNT);
203232809Sjmallett
204232809Sjmallett    /* Handle Work Queue Entry in cn68xx */
205232809Sjmallett    if (octeon_has_feature(OCTEON_FEATURE_NO_WPTR)) {
206232809Sjmallett        cvmx_ipd_ctl_status_t ipd_ctl_status;
207232809Sjmallett        ipd_ctl_status.u64 = cvmx_read_csr(CVMX_IPD_CTL_STATUS);
208232809Sjmallett        if (ipd_ctl_status.s.no_wptr)
209232809Sjmallett            no_wptr = 1;
210232809Sjmallett    }
211232809Sjmallett
212232809Sjmallett    /* Free the prefetched WQE */
213232809Sjmallett    if (ipd_ptr_count.s.wqev_cnt) {
214232809Sjmallett        cvmx_ipd_next_wqe_ptr_t ipd_next_wqe_ptr;
215232809Sjmallett        ipd_next_wqe_ptr.u64 = cvmx_read_csr(CVMX_IPD_NEXT_WQE_PTR);
216232809Sjmallett        if (no_wptr)
217232809Sjmallett            cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_next_wqe_ptr.s.ptr<<7), CVMX_FPA_PACKET_POOL, 0);
218232809Sjmallett        else
219232809Sjmallett            cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_next_wqe_ptr.s.ptr<<7), CVMX_FPA_WQE_POOL, 0);
220232809Sjmallett    }
221232809Sjmallett
222232809Sjmallett
223232809Sjmallett    /* Free all WQE in the fifo */
224232809Sjmallett    if (ipd_ptr_count.s.wqe_pcnt) {
225232809Sjmallett        cvmx_ipd_free_ptr_fifo_ctl_t ipd_free_ptr_fifo_ctl;
226232809Sjmallett        cvmx_ipd_free_ptr_value_t ipd_free_ptr_value;
227232809Sjmallett        ipd_free_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_FREE_PTR_FIFO_CTL);
228232809Sjmallett        for (i = 0; i < ipd_ptr_count.s.wqe_pcnt; i++) {
229232809Sjmallett            ipd_free_ptr_fifo_ctl.s.cena = 0;
230232809Sjmallett            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;
231232809Sjmallett            cvmx_write_csr(CVMX_IPD_FREE_PTR_FIFO_CTL, ipd_free_ptr_fifo_ctl.u64);
232232809Sjmallett            ipd_free_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_FREE_PTR_FIFO_CTL);
233232809Sjmallett            ipd_free_ptr_value.u64 = cvmx_read_csr(CVMX_IPD_FREE_PTR_VALUE);
234232809Sjmallett            if (no_wptr)
235232809Sjmallett                cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_free_ptr_value.s.ptr<<7), CVMX_FPA_PACKET_POOL, 0);
236232809Sjmallett            else
237232809Sjmallett                cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_free_ptr_value.s.ptr<<7), CVMX_FPA_WQE_POOL, 0);
238232809Sjmallett        }
239232809Sjmallett        ipd_free_ptr_fifo_ctl.s.cena = 1;
240232809Sjmallett        cvmx_write_csr(CVMX_IPD_FREE_PTR_FIFO_CTL, ipd_free_ptr_fifo_ctl.u64);
241232809Sjmallett    }
242232809Sjmallett
243232809Sjmallett    /* Free the prefetched packet */
244232809Sjmallett    if (ipd_ptr_count.s.pktv_cnt) {
245232809Sjmallett        cvmx_ipd_next_pkt_ptr_t ipd_next_pkt_ptr;
246232809Sjmallett        ipd_next_pkt_ptr.u64 = cvmx_read_csr(CVMX_IPD_NEXT_PKT_PTR);
247232809Sjmallett        cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_next_pkt_ptr.s.ptr<<7), CVMX_FPA_PACKET_POOL, 0);
248232809Sjmallett    }
249232809Sjmallett
250232809Sjmallett    /* Free the per port prefetched packets */
251232809Sjmallett    ipd_port_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_PORT_PTR_FIFO_CTL);
252232809Sjmallett
253232809Sjmallett    for (i = 0; i < ipd_port_ptr_fifo_ctl.s.max_pkt; i++) {
254232809Sjmallett        ipd_port_ptr_fifo_ctl.s.cena = 0;
255232809Sjmallett        ipd_port_ptr_fifo_ctl.s.raddr = i % ipd_port_ptr_fifo_ctl.s.max_pkt;
256232809Sjmallett        cvmx_write_csr(CVMX_IPD_PORT_PTR_FIFO_CTL, ipd_port_ptr_fifo_ctl.u64);
257232809Sjmallett        ipd_port_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_PORT_PTR_FIFO_CTL);
258232809Sjmallett        cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_port_ptr_fifo_ctl.s.ptr<<7), CVMX_FPA_PACKET_POOL, 0);
259232809Sjmallett    }
260232809Sjmallett    ipd_port_ptr_fifo_ctl.s.cena = 1;
261232809Sjmallett    cvmx_write_csr(CVMX_IPD_PORT_PTR_FIFO_CTL, ipd_port_ptr_fifo_ctl.u64);
262232809Sjmallett
263232809Sjmallett    /* Free all packets in the holding fifo */
264232809Sjmallett    if (ipd_ptr_count.s.pfif_cnt) {
265232809Sjmallett        cvmx_ipd_hold_ptr_fifo_ctl_t ipd_hold_ptr_fifo_ctl;
266232809Sjmallett
267232809Sjmallett        ipd_hold_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_HOLD_PTR_FIFO_CTL);
268232809Sjmallett
269232809Sjmallett        for (i = 0; i < ipd_ptr_count.s.pfif_cnt; i++) {
270232809Sjmallett            ipd_hold_ptr_fifo_ctl.s.cena = 0;
271232809Sjmallett            ipd_hold_ptr_fifo_ctl.s.raddr = (ipd_hold_ptr_fifo_ctl.s.praddr + i) % ipd_hold_ptr_fifo_ctl.s.max_pkt;
272232809Sjmallett            cvmx_write_csr(CVMX_IPD_HOLD_PTR_FIFO_CTL, ipd_hold_ptr_fifo_ctl.u64);
273232809Sjmallett            ipd_hold_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_HOLD_PTR_FIFO_CTL);
274232809Sjmallett            cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_hold_ptr_fifo_ctl.s.ptr<<7), CVMX_FPA_PACKET_POOL, 0);
275232809Sjmallett        }
276232809Sjmallett        ipd_hold_ptr_fifo_ctl.s.cena = 1;
277232809Sjmallett        cvmx_write_csr(CVMX_IPD_HOLD_PTR_FIFO_CTL, ipd_hold_ptr_fifo_ctl.u64);
278232809Sjmallett    }
279232809Sjmallett
280232809Sjmallett    /* Free all packets in the fifo */
281232809Sjmallett    if (ipd_ptr_count.s.pkt_pcnt) {
282232809Sjmallett        cvmx_ipd_free_ptr_fifo_ctl_t ipd_free_ptr_fifo_ctl;
283232809Sjmallett        cvmx_ipd_free_ptr_value_t ipd_free_ptr_value;
284232809Sjmallett        ipd_free_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_FREE_PTR_FIFO_CTL);
285232809Sjmallett
286232809Sjmallett        for (i = 0; i < ipd_ptr_count.s.pkt_pcnt; i++) {
287232809Sjmallett            ipd_free_ptr_fifo_ctl.s.cena = 0;
288232809Sjmallett            ipd_free_ptr_fifo_ctl.s.raddr = (ipd_free_ptr_fifo_ctl.s.praddr+i) % ipd_free_ptr_fifo_ctl.s.max_cnts;
289232809Sjmallett            cvmx_write_csr(CVMX_IPD_FREE_PTR_FIFO_CTL, ipd_free_ptr_fifo_ctl.u64);
290232809Sjmallett            ipd_free_ptr_fifo_ctl.u64 = cvmx_read_csr(CVMX_IPD_FREE_PTR_FIFO_CTL);
291232809Sjmallett            ipd_free_ptr_value.u64 = cvmx_read_csr(CVMX_IPD_FREE_PTR_VALUE);
292232809Sjmallett            cvmx_fpa_free(cvmx_phys_to_ptr((uint64_t)ipd_free_ptr_value.s.ptr<<7), CVMX_FPA_PACKET_POOL, 0);
293232809Sjmallett        }
294232809Sjmallett        ipd_free_ptr_fifo_ctl.s.cena = 1;
295232809Sjmallett        cvmx_write_csr(CVMX_IPD_FREE_PTR_FIFO_CTL, ipd_free_ptr_fifo_ctl.u64);
296232809Sjmallett    }
297232809Sjmallett}
298232809Sjmallett
299232809Sjmallett/**
300232809Sjmallett * @INTERNAL
301232809Sjmallett * This function is called by cvmx_helper_shutdown() to extract
302232809Sjmallett * all FPA buffers out of the IPD and PIP. After this function
303232809Sjmallett * completes, all FPA buffers that were prefetched by IPD and PIP
304232809Sjmallett * wil be in the apropriate FPA pool. This functions does not reset
305232809Sjmallett * PIP or IPD as FPA pool zero must be empty before the reset can
306232809Sjmallett * be performed. WARNING: It is very important that IPD and PIP be
307232809Sjmallett * reset soon after a call to this function.
308232809Sjmallett */
309232809Sjmallettvoid __cvmx_ipd_free_ptr(void)
310232809Sjmallett{
311232809Sjmallett    if (octeon_has_feature(OCTEON_FEATURE_PKND))
312232809Sjmallett        __cvmx_ipd_free_ptr_v2();
313232809Sjmallett    else
314232809Sjmallett        __cvmx_ipd_free_ptr_v1();
315232809Sjmallett}
316232809Sjmallett
317232809Sjmallett#endif
318232809Sjmallett
319