1*3833Sxw161283 /*
2*3833Sxw161283 * CDDL HEADER START
3*3833Sxw161283 *
4*3833Sxw161283 * The contents of this file are subject to the terms of the
5*3833Sxw161283 * Common Development and Distribution License (the "License").
6*3833Sxw161283 * You may not use this file except in compliance with the License.
7*3833Sxw161283 *
8*3833Sxw161283 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*3833Sxw161283 * or http://www.opensolaris.org/os/licensing.
10*3833Sxw161283 * See the License for the specific language governing permissions
11*3833Sxw161283 * and limitations under the License.
12*3833Sxw161283 *
13*3833Sxw161283 * When distributing Covered Code, include this CDDL HEADER in each
14*3833Sxw161283 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*3833Sxw161283 * If applicable, add the following below this CDDL HEADER, with the
16*3833Sxw161283 * fields enclosed by brackets "[]" replaced with your own identifying
17*3833Sxw161283 * information: Portions Copyright [yyyy] [name of copyright owner]
18*3833Sxw161283 *
19*3833Sxw161283 * CDDL HEADER END
20*3833Sxw161283 */
21*3833Sxw161283
22*3833Sxw161283 /*
23*3833Sxw161283 * Copyright (C) 2003-2005 Chelsio Communications. All rights reserved.
24*3833Sxw161283 */
25*3833Sxw161283
26*3833Sxw161283 #pragma ident "%Z%%M% %I% %E% SMI" /* tp.c */
27*3833Sxw161283
28*3833Sxw161283 #include "common.h"
29*3833Sxw161283 #include "regs.h"
30*3833Sxw161283 #include "tp.h"
31*3833Sxw161283 #ifdef CONFIG_CHELSIO_T1_1G
32*3833Sxw161283 #include "fpga_defs.h"
33*3833Sxw161283 #endif
34*3833Sxw161283
35*3833Sxw161283 struct petp {
36*3833Sxw161283 adapter_t *adapter;
37*3833Sxw161283 };
38*3833Sxw161283
39*3833Sxw161283 /* Pause deadlock avoidance parameters */
40*3833Sxw161283 #define DROP_MSEC 16
41*3833Sxw161283 #define DROP_PKTS_CNT 1
42*3833Sxw161283
43*3833Sxw161283 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
44*3833Sxw161283
pm_num_pages(u32 size,u32 pg_size)45*3833Sxw161283 static inline u32 pm_num_pages(u32 size, u32 pg_size)
46*3833Sxw161283 {
47*3833Sxw161283 u32 num = size / pg_size;
48*3833Sxw161283 num -= num % 24;
49*3833Sxw161283 return num;
50*3833Sxw161283 }
51*3833Sxw161283
tp_pm_configure(adapter_t * adapter,struct tp_params * p)52*3833Sxw161283 static void tp_pm_configure(adapter_t *adapter, struct tp_params *p)
53*3833Sxw161283 {
54*3833Sxw161283 u32 num;
55*3833Sxw161283
56*3833Sxw161283 num = pm_num_pages(p->pm_size - p->pm_rx_base, p->pm_rx_pg_size);
57*3833Sxw161283 if (p->pm_rx_num_pgs > num)
58*3833Sxw161283 p->pm_rx_num_pgs = num;
59*3833Sxw161283
60*3833Sxw161283 num = pm_num_pages(p->pm_rx_base - p->pm_tx_base, p->pm_tx_pg_size);
61*3833Sxw161283 if (p->pm_tx_num_pgs > num)
62*3833Sxw161283 p->pm_tx_num_pgs = num;
63*3833Sxw161283
64*3833Sxw161283 t1_write_reg_4(adapter, A_TP_PM_SIZE, p->pm_size);
65*3833Sxw161283 t1_write_reg_4(adapter, A_TP_PM_RX_BASE, p->pm_rx_base);
66*3833Sxw161283 t1_write_reg_4(adapter, A_TP_PM_TX_BASE, p->pm_tx_base);
67*3833Sxw161283 t1_write_reg_4(adapter, A_TP_PM_DEFRAG_BASE, p->pm_size);
68*3833Sxw161283 t1_write_reg_4(adapter, A_TP_PM_RX_PG_SIZE, p->pm_rx_pg_size);
69*3833Sxw161283 t1_write_reg_4(adapter, A_TP_PM_RX_MAX_PGS, p->pm_rx_num_pgs);
70*3833Sxw161283 t1_write_reg_4(adapter, A_TP_PM_TX_PG_SIZE, p->pm_tx_pg_size);
71*3833Sxw161283 t1_write_reg_4(adapter, A_TP_PM_TX_MAX_PGS, p->pm_tx_num_pgs);
72*3833Sxw161283 }
73*3833Sxw161283
tp_cm_configure(adapter_t * adapter,u32 cm_size)74*3833Sxw161283 static void tp_cm_configure(adapter_t *adapter, u32 cm_size)
75*3833Sxw161283 {
76*3833Sxw161283 u32 mm_base = (cm_size >> 1);
77*3833Sxw161283 u32 mm_sub_size = (cm_size >> 5);
78*3833Sxw161283
79*3833Sxw161283 t1_write_reg_4(adapter, A_TP_CM_SIZE, cm_size);
80*3833Sxw161283 t1_write_reg_4(adapter, A_TP_CM_MM_BASE, mm_base);
81*3833Sxw161283 t1_write_reg_4(adapter, A_TP_CM_TIMER_BASE, (cm_size >> 2) * 3);
82*3833Sxw161283 t1_write_reg_4(adapter, A_TP_CM_MM_P_FLST_BASE,
83*3833Sxw161283 mm_base + 5 * mm_sub_size);
84*3833Sxw161283 t1_write_reg_4(adapter, A_TP_CM_MM_TX_FLST_BASE,
85*3833Sxw161283 mm_base + 6 * mm_sub_size);
86*3833Sxw161283 t1_write_reg_4(adapter, A_TP_CM_MM_RX_FLST_BASE,
87*3833Sxw161283 mm_base + 7 * mm_sub_size);
88*3833Sxw161283 t1_write_reg_4(adapter, A_TP_CM_MM_MAX_P, 0x40000);
89*3833Sxw161283 }
90*3833Sxw161283
tp_delayed_ack_ticks(adapter_t * adap,unsigned int tp_clk)91*3833Sxw161283 static unsigned int tp_delayed_ack_ticks(adapter_t *adap, unsigned int tp_clk)
92*3833Sxw161283 {
93*3833Sxw161283 u32 tr = t1_read_reg_4(adap, A_TP_TIMER_RESOLUTION);
94*3833Sxw161283
95*3833Sxw161283 return tp_clk / (1 << G_DELAYED_ACK_TIMER_RESOLUTION(tr));
96*3833Sxw161283 }
97*3833Sxw161283
t1_tp_ticks_per_sec(adapter_t * adap,unsigned int tp_clk)98*3833Sxw161283 static unsigned int t1_tp_ticks_per_sec(adapter_t *adap, unsigned int tp_clk)
99*3833Sxw161283 {
100*3833Sxw161283 u32 tr = t1_read_reg_4(adap, A_TP_TIMER_RESOLUTION);
101*3833Sxw161283
102*3833Sxw161283 return tp_clk / (1 << G_GENERIC_TIMER_RESOLUTION(tr));
103*3833Sxw161283 }
104*3833Sxw161283
tp_set_tcp_time_params(adapter_t * adapter,unsigned int tp_clk)105*3833Sxw161283 static void tp_set_tcp_time_params(adapter_t *adapter, unsigned int tp_clk)
106*3833Sxw161283 {
107*3833Sxw161283 u32 tps = t1_tp_ticks_per_sec(adapter, tp_clk);
108*3833Sxw161283 u32 tp_scnt;
109*3833Sxw161283
110*3833Sxw161283 #define SECONDS * tps
111*3833Sxw161283 t1_write_reg_4(adapter, A_TP_2MSL, (1 SECONDS)/2);
112*3833Sxw161283 t1_write_reg_4(adapter, A_TP_RXT_MIN, (1 SECONDS)/4);
113*3833Sxw161283 t1_write_reg_4(adapter, A_TP_RXT_MAX, 64 SECONDS);
114*3833Sxw161283 t1_write_reg_4(adapter, A_TP_PERS_MIN, (1 SECONDS)/2);
115*3833Sxw161283 t1_write_reg_4(adapter, A_TP_PERS_MAX, 64 SECONDS);
116*3833Sxw161283 t1_write_reg_4(adapter, A_TP_KEEP_IDLE, 7200 SECONDS);
117*3833Sxw161283 t1_write_reg_4(adapter, A_TP_KEEP_INTVL, 75 SECONDS);
118*3833Sxw161283 t1_write_reg_4(adapter, A_TP_INIT_SRTT, 3 SECONDS);
119*3833Sxw161283 t1_write_reg_4(adapter, A_TP_FINWAIT2_TIME, 60 SECONDS);
120*3833Sxw161283 t1_write_reg_4(adapter, A_TP_FAST_FINWAIT2_TIME, 3 SECONDS);
121*3833Sxw161283 #undef SECONDS
122*3833Sxw161283
123*3833Sxw161283 /* Set Retransmission shift max */
124*3833Sxw161283 tp_scnt = t1_read_reg_4(adapter, A_TP_SHIFT_CNT);
125*3833Sxw161283 tp_scnt &= (~V_RETRANSMISSION_MAX(0x3f));
126*3833Sxw161283 tp_scnt |= V_RETRANSMISSION_MAX(14);
127*3833Sxw161283 t1_write_reg_4(adapter, A_TP_SHIFT_CNT, tp_scnt);
128*3833Sxw161283
129*3833Sxw161283 /* Set DACK timer to 200ms */
130*3833Sxw161283 t1_write_reg_4(adapter, A_TP_DACK_TIME,
131*3833Sxw161283 tp_delayed_ack_ticks(adapter, tp_clk) / 5);
132*3833Sxw161283 }
133*3833Sxw161283
t1_tp_set_coalescing_size(struct petp * tp,unsigned int size)134*3833Sxw161283 int t1_tp_set_coalescing_size(struct petp *tp, unsigned int size)
135*3833Sxw161283 {
136*3833Sxw161283 u32 val;
137*3833Sxw161283
138*3833Sxw161283 if (size > TP_MAX_RX_COALESCING_SIZE)
139*3833Sxw161283 return -EINVAL;
140*3833Sxw161283
141*3833Sxw161283 val = t1_read_reg_4(tp->adapter, A_TP_PARA_REG3);
142*3833Sxw161283
143*3833Sxw161283 if (tp->adapter->params.nports > 1)
144*3833Sxw161283 size = 9904;
145*3833Sxw161283
146*3833Sxw161283 if (size) {
147*3833Sxw161283 u32 v = t1_is_T1B(tp->adapter) ? 0 : V_MAX_RX_SIZE(size);
148*3833Sxw161283
149*3833Sxw161283 /* Set coalescing size. */
150*3833Sxw161283 t1_write_reg_4(tp->adapter, A_TP_PARA_REG2,
151*3833Sxw161283 V_RX_COALESCE_SIZE(size) | v);
152*3833Sxw161283
153*3833Sxw161283 val |= (F_RX_COALESCING_PSH_DELIVER | F_RX_COALESCING_ENABLE);
154*3833Sxw161283 } else
155*3833Sxw161283 val &= ~F_RX_COALESCING_ENABLE;
156*3833Sxw161283
157*3833Sxw161283 t1_write_reg_4(tp->adapter, A_TP_PARA_REG3, val);
158*3833Sxw161283 return 0;
159*3833Sxw161283 }
160*3833Sxw161283
t1_tp_get_mib_statistics(adapter_t * adap,struct tp_mib_statistics * tps)161*3833Sxw161283 void t1_tp_get_mib_statistics(adapter_t *adap, struct tp_mib_statistics *tps)
162*3833Sxw161283 {
163*3833Sxw161283 u32 *data = (u32 *)tps;
164*3833Sxw161283 int i;
165*3833Sxw161283
166*3833Sxw161283 t1_write_reg_4(adap, A_TP_MIB_INDEX, 0);
167*3833Sxw161283
168*3833Sxw161283 for (i = 0; i < sizeof(*tps) / sizeof(u32); i++)
169*3833Sxw161283 *data++ = t1_read_reg_4(adap, A_TP_MIB_DATA);
170*3833Sxw161283 }
171*3833Sxw161283 #endif
172*3833Sxw161283
tp_init(adapter_t * ap,const struct tp_params * p,unsigned int tp_clk)173*3833Sxw161283 static void tp_init(adapter_t *ap, const struct tp_params *p,
174*3833Sxw161283 unsigned int tp_clk)
175*3833Sxw161283 {
176*3833Sxw161283 if (t1_is_asic(ap)) {
177*3833Sxw161283 u32 val;
178*3833Sxw161283
179*3833Sxw161283 val = F_TP_IN_CSPI_CPL | F_TP_IN_CSPI_CHECK_IP_CSUM |
180*3833Sxw161283 F_TP_IN_CSPI_CHECK_TCP_CSUM | F_TP_IN_ESPI_ETHERNET;
181*3833Sxw161283 if (!p->pm_size)
182*3833Sxw161283 val |= F_OFFLOAD_DISABLE;
183*3833Sxw161283 else
184*3833Sxw161283 val |= F_TP_IN_ESPI_CHECK_IP_CSUM |
185*3833Sxw161283 F_TP_IN_ESPI_CHECK_TCP_CSUM;
186*3833Sxw161283 t1_write_reg_4(ap, A_TP_IN_CONFIG, val);
187*3833Sxw161283 t1_write_reg_4(ap, A_TP_OUT_CONFIG, F_TP_OUT_CSPI_CPL |
188*3833Sxw161283 F_TP_OUT_ESPI_ETHERNET |
189*3833Sxw161283 F_TP_OUT_ESPI_GENERATE_IP_CSUM |
190*3833Sxw161283 F_TP_OUT_ESPI_GENERATE_TCP_CSUM);
191*3833Sxw161283 t1_write_reg_4(ap, A_TP_GLOBAL_CONFIG, V_IP_TTL(64) |
192*3833Sxw161283 F_PATH_MTU /* IP DF bit */ |
193*3833Sxw161283 V_5TUPLE_LOOKUP(p->use_5tuple_mode) |
194*3833Sxw161283 V_SYN_COOKIE_PARAMETER(29));
195*3833Sxw161283
196*3833Sxw161283 /*
197*3833Sxw161283 * Enable pause frame deadlock prevention.
198*3833Sxw161283 */
199*3833Sxw161283 if (is_T2(ap) && ap->params.nports > 1) {
200*3833Sxw161283 u32 drop_ticks = DROP_MSEC * (tp_clk / 1000);
201*3833Sxw161283
202*3833Sxw161283 t1_write_reg_4(ap, A_TP_TX_DROP_CONFIG,
203*3833Sxw161283 F_ENABLE_TX_DROP | F_ENABLE_TX_ERROR |
204*3833Sxw161283 V_DROP_TICKS_CNT(drop_ticks) |
205*3833Sxw161283 V_NUM_PKTS_DROPPED(DROP_PKTS_CNT));
206*3833Sxw161283 }
207*3833Sxw161283
208*3833Sxw161283 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
209*3833Sxw161283 t1_write_reg_4(ap, A_TP_GLOBAL_RX_CREDITS, 0xffffffff);
210*3833Sxw161283 val = V_WINDOW_SCALE(1) | F_MSS | V_DEFAULT_PEER_MSS(576);
211*3833Sxw161283
212*3833Sxw161283 /* We don't want timestamps for T204, otherwise we don't know
213*3833Sxw161283 * the MSS.
214*3833Sxw161283 */
215*3833Sxw161283 if (ap->params.nports == 1)
216*3833Sxw161283 val |= V_TIMESTAMP(1);
217*3833Sxw161283 t1_write_reg_4(ap, A_TP_TCP_OPTIONS, val);
218*3833Sxw161283 t1_write_reg_4(ap, A_TP_DACK_CONFIG, V_DACK_MSS_SELECTOR(1) |
219*3833Sxw161283 F_DACK_AUTO_CAREFUL | V_DACK_MODE(1));
220*3833Sxw161283 t1_write_reg_4(ap, A_TP_BACKOFF0, 0x3020100);
221*3833Sxw161283 t1_write_reg_4(ap, A_TP_BACKOFF1, 0x7060504);
222*3833Sxw161283 t1_write_reg_4(ap, A_TP_BACKOFF2, 0xb0a0908);
223*3833Sxw161283 t1_write_reg_4(ap, A_TP_BACKOFF3, 0xf0e0d0c);
224*3833Sxw161283
225*3833Sxw161283 /* We do scheduling in software for T204, increase the cong.
226*3833Sxw161283 * window to avoid TP holding on to payload longer than we
227*3833Sxw161283 * expect.
228*3833Sxw161283 */
229*3833Sxw161283 if (ap->params.nports == 1)
230*3833Sxw161283 t1_write_reg_4(ap, A_TP_PARA_REG0, 0xd1269324);
231*3833Sxw161283 else
232*3833Sxw161283 t1_write_reg_4(ap, A_TP_PARA_REG0, 0xd6269324);
233*3833Sxw161283 t1_write_reg_4(ap, A_TP_SYNC_TIME_HI, 0);
234*3833Sxw161283 t1_write_reg_4(ap, A_TP_SYNC_TIME_LO, 0);
235*3833Sxw161283 t1_write_reg_4(ap, A_TP_INT_ENABLE, 0);
236*3833Sxw161283 t1_write_reg_4(ap, A_TP_CM_FC_MODE, 0); /* Enable CM cache */
237*3833Sxw161283 t1_write_reg_4(ap, A_TP_PC_CONGESTION_CNTL, 0x6186);
238*3833Sxw161283
239*3833Sxw161283 /*
240*3833Sxw161283 * Calculate the time between modulation events, which affects
241*3833Sxw161283 * both the Tx and Rx pipelines. Larger values force the Tx
242*3833Sxw161283 * pipeline to wait before processing modulation events, thus
243*3833Sxw161283 * allowing Rx to use the pipeline. A really small delay can
244*3833Sxw161283 * starve the Rx side from accessing the pipeline.
245*3833Sxw161283 *
246*3833Sxw161283 * A balanced value is optimal. This is roughly 9us per 1G.
247*3833Sxw161283 * The Tx needs a low delay time for handling a lot of small
248*3833Sxw161283 * packets. Too big of a delay could cause Tx not to achieve
249*3833Sxw161283 * line rate.
250*3833Sxw161283 */
251*3833Sxw161283 val = (9 * tp_clk) / 1000000;
252*3833Sxw161283 /* adjust for multiple ports */
253*3833Sxw161283 if (ap->params.nports > 1) {
254*3833Sxw161283 val = 0;
255*3833Sxw161283 }
256*3833Sxw161283 if (is_10G(ap)) /* adjust for 10G */
257*3833Sxw161283 val /= 10;
258*3833Sxw161283 /*
259*3833Sxw161283 * Bit 0 must be 0 to keep the timer insertion property.
260*3833Sxw161283 */
261*3833Sxw161283 t1_write_reg_4(ap, A_TP_TIMER_SEPARATOR, val & ~1);
262*3833Sxw161283
263*3833Sxw161283 t1_write_reg_4(ap, A_TP_TIMER_RESOLUTION, 0xF0011);
264*3833Sxw161283 tp_set_tcp_time_params(ap, tp_clk);
265*3833Sxw161283
266*3833Sxw161283 /* PR3229 */
267*3833Sxw161283 if (is_T2(ap)) {
268*3833Sxw161283 val = t1_read_reg_4(ap, A_TP_PC_CONFIG);
269*3833Sxw161283 val |= V_DIS_TX_FILL_WIN_PUSH(1);
270*3833Sxw161283 t1_write_reg_4(ap, A_TP_PC_CONFIG, val);
271*3833Sxw161283 }
272*3833Sxw161283
273*3833Sxw161283 #ifdef CONFIG_CHELSIO_T1_1G
274*3833Sxw161283 } else { /* FPGA */
275*3833Sxw161283 t1_write_reg_4(ap, A_TP_TIMER_RESOLUTION, 0xD000A);
276*3833Sxw161283 #endif
277*3833Sxw161283 #endif
278*3833Sxw161283 }
279*3833Sxw161283 }
280*3833Sxw161283
t1_tp_destroy(struct petp * tp)281*3833Sxw161283 void t1_tp_destroy(struct petp *tp)
282*3833Sxw161283 {
283*3833Sxw161283 t1_os_free((void *)tp, sizeof(*tp));
284*3833Sxw161283 }
285*3833Sxw161283
t1_tp_create(adapter_t * adapter,struct tp_params * p)286*3833Sxw161283 struct petp * __devinit t1_tp_create(adapter_t *adapter, struct tp_params *p)
287*3833Sxw161283 {
288*3833Sxw161283 struct petp *tp = t1_os_malloc_wait_zero(sizeof(*tp));
289*3833Sxw161283 if (!tp)
290*3833Sxw161283 return NULL;
291*3833Sxw161283
292*3833Sxw161283 tp->adapter = adapter;
293*3833Sxw161283
294*3833Sxw161283 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
295*3833Sxw161283 if (p->pm_size) { /* Default PM partitioning */
296*3833Sxw161283 p->pm_rx_base = p->pm_size >> 1;
297*3833Sxw161283 #ifdef TDI_SUPPORT
298*3833Sxw161283 p->pm_tx_base = 2048 * 1024; /* reserve 2 MByte for REGION MAP */
299*3833Sxw161283 #else
300*3833Sxw161283 p->pm_tx_base = 64 * 1024; /* reserve 64 kbytes for REGION MAP */
301*3833Sxw161283 #endif
302*3833Sxw161283 p->pm_rx_pg_size = 64 * 1024;
303*3833Sxw161283
304*3833Sxw161283 if (adapter->params.nports == 1)
305*3833Sxw161283 p->pm_tx_pg_size = 64 * 1024;
306*3833Sxw161283 else
307*3833Sxw161283 p->pm_tx_pg_size = 16 * 1024;
308*3833Sxw161283 p->pm_rx_num_pgs = pm_num_pages(p->pm_size - p->pm_rx_base,
309*3833Sxw161283 p->pm_rx_pg_size);
310*3833Sxw161283 p->pm_tx_num_pgs = pm_num_pages(p->pm_rx_base - p->pm_tx_base,
311*3833Sxw161283 p->pm_tx_pg_size);
312*3833Sxw161283 }
313*3833Sxw161283 #endif
314*3833Sxw161283 return tp;
315*3833Sxw161283 }
316*3833Sxw161283
t1_tp_intr_enable(struct petp * tp)317*3833Sxw161283 void t1_tp_intr_enable(struct petp *tp)
318*3833Sxw161283 {
319*3833Sxw161283 u32 tp_intr = t1_read_reg_4(tp->adapter, A_PL_ENABLE);
320*3833Sxw161283
321*3833Sxw161283 #ifdef CONFIG_CHELSIO_T1_1G
322*3833Sxw161283 if (!t1_is_asic(tp->adapter)) {
323*3833Sxw161283 /* FPGA */
324*3833Sxw161283 t1_write_reg_4(tp->adapter, FPGA_TP_ADDR_INTERRUPT_ENABLE,
325*3833Sxw161283 0xffffffff);
326*3833Sxw161283 t1_write_reg_4(tp->adapter, A_PL_ENABLE,
327*3833Sxw161283 tp_intr | FPGA_PCIX_INTERRUPT_TP);
328*3833Sxw161283 } else
329*3833Sxw161283 #endif
330*3833Sxw161283 {
331*3833Sxw161283 /* We don't use any TP interrupts */
332*3833Sxw161283 t1_write_reg_4(tp->adapter, A_TP_INT_ENABLE, 0);
333*3833Sxw161283 t1_write_reg_4(tp->adapter, A_PL_ENABLE,
334*3833Sxw161283 tp_intr | F_PL_INTR_TP);
335*3833Sxw161283 }
336*3833Sxw161283 }
337*3833Sxw161283
t1_tp_intr_disable(struct petp * tp)338*3833Sxw161283 void t1_tp_intr_disable(struct petp *tp)
339*3833Sxw161283 {
340*3833Sxw161283 u32 tp_intr = t1_read_reg_4(tp->adapter, A_PL_ENABLE);
341*3833Sxw161283
342*3833Sxw161283 #ifdef CONFIG_CHELSIO_T1_1G
343*3833Sxw161283 if (!t1_is_asic(tp->adapter)) {
344*3833Sxw161283 /* FPGA */
345*3833Sxw161283 t1_write_reg_4(tp->adapter, FPGA_TP_ADDR_INTERRUPT_ENABLE, 0);
346*3833Sxw161283 t1_write_reg_4(tp->adapter, A_PL_ENABLE,
347*3833Sxw161283 tp_intr & ~FPGA_PCIX_INTERRUPT_TP);
348*3833Sxw161283 } else
349*3833Sxw161283 #endif
350*3833Sxw161283 {
351*3833Sxw161283 t1_write_reg_4(tp->adapter, A_TP_INT_ENABLE, 0);
352*3833Sxw161283 t1_write_reg_4(tp->adapter, A_PL_ENABLE,
353*3833Sxw161283 tp_intr & ~F_PL_INTR_TP);
354*3833Sxw161283 }
355*3833Sxw161283 }
356*3833Sxw161283
t1_tp_intr_clear(struct petp * tp)357*3833Sxw161283 void t1_tp_intr_clear(struct petp *tp)
358*3833Sxw161283 {
359*3833Sxw161283 #ifdef CONFIG_CHELSIO_T1_1G
360*3833Sxw161283 if (!t1_is_asic(tp->adapter)) {
361*3833Sxw161283 t1_write_reg_4(tp->adapter, FPGA_TP_ADDR_INTERRUPT_CAUSE,
362*3833Sxw161283 0xffffffff);
363*3833Sxw161283 t1_write_reg_4(tp->adapter, A_PL_CAUSE, FPGA_PCIX_INTERRUPT_TP);
364*3833Sxw161283 return;
365*3833Sxw161283 }
366*3833Sxw161283 #endif
367*3833Sxw161283 t1_write_reg_4(tp->adapter, A_TP_INT_CAUSE, 0xffffffff);
368*3833Sxw161283 t1_write_reg_4(tp->adapter, A_PL_CAUSE, F_PL_INTR_TP);
369*3833Sxw161283 }
370*3833Sxw161283
t1_tp_intr_handler(struct petp * tp)371*3833Sxw161283 int t1_tp_intr_handler(struct petp *tp)
372*3833Sxw161283 {
373*3833Sxw161283 u32 cause;
374*3833Sxw161283
375*3833Sxw161283 #ifdef CONFIG_CHELSIO_T1_1G
376*3833Sxw161283 /* FPGA doesn't support TP interrupts. */
377*3833Sxw161283 if (!t1_is_asic(tp->adapter))
378*3833Sxw161283 return 1;
379*3833Sxw161283 #endif
380*3833Sxw161283
381*3833Sxw161283 cause = t1_read_reg_4(tp->adapter, A_TP_INT_CAUSE);
382*3833Sxw161283 t1_write_reg_4(tp->adapter, A_TP_INT_CAUSE, cause);
383*3833Sxw161283 return 0;
384*3833Sxw161283 }
385*3833Sxw161283
set_csum_offload(struct petp * tp,u32 csum_bit,int enable)386*3833Sxw161283 static void set_csum_offload(struct petp *tp, u32 csum_bit, int enable)
387*3833Sxw161283 {
388*3833Sxw161283 u32 val = t1_read_reg_4(tp->adapter, A_TP_GLOBAL_CONFIG);
389*3833Sxw161283
390*3833Sxw161283 if (enable)
391*3833Sxw161283 val |= csum_bit;
392*3833Sxw161283 else
393*3833Sxw161283 val &= ~csum_bit;
394*3833Sxw161283 t1_write_reg_4(tp->adapter, A_TP_GLOBAL_CONFIG, val);
395*3833Sxw161283 }
396*3833Sxw161283
t1_tp_set_ip_checksum_offload(struct petp * tp,int enable)397*3833Sxw161283 void t1_tp_set_ip_checksum_offload(struct petp *tp, int enable)
398*3833Sxw161283 {
399*3833Sxw161283 set_csum_offload(tp, F_IP_CSUM, enable);
400*3833Sxw161283 }
401*3833Sxw161283
t1_tp_set_udp_checksum_offload(struct petp * tp,int enable)402*3833Sxw161283 void t1_tp_set_udp_checksum_offload(struct petp *tp, int enable)
403*3833Sxw161283 {
404*3833Sxw161283 set_csum_offload(tp, F_UDP_CSUM, enable);
405*3833Sxw161283 }
406*3833Sxw161283
t1_tp_set_tcp_checksum_offload(struct petp * tp,int enable)407*3833Sxw161283 void t1_tp_set_tcp_checksum_offload(struct petp *tp, int enable)
408*3833Sxw161283 {
409*3833Sxw161283 set_csum_offload(tp, F_TCP_CSUM, enable);
410*3833Sxw161283 }
411*3833Sxw161283
412*3833Sxw161283 /*
413*3833Sxw161283 * Initialize TP state. tp_params contains initial settings for some TP
414*3833Sxw161283 * parameters, particularly the one-time PM and CM settings.
415*3833Sxw161283 */
t1_tp_reset(struct petp * tp,struct tp_params * p,unsigned int tp_clk)416*3833Sxw161283 int t1_tp_reset(struct petp *tp, struct tp_params *p, unsigned int tp_clk)
417*3833Sxw161283 {
418*3833Sxw161283 int busy = 0;
419*3833Sxw161283 adapter_t *adapter = tp->adapter;
420*3833Sxw161283
421*3833Sxw161283 tp_init(adapter, p, tp_clk);
422*3833Sxw161283 #ifdef CONFIG_CHELSIO_T1_OFFLOAD
423*3833Sxw161283 if (p->pm_size) {
424*3833Sxw161283 tp_pm_configure(adapter, p);
425*3833Sxw161283 tp_cm_configure(adapter, p->cm_size);
426*3833Sxw161283
427*3833Sxw161283 t1_write_reg_4(adapter, A_TP_RESET, F_CM_MEMMGR_INIT);
428*3833Sxw161283 busy = t1_wait_op_done(adapter, A_TP_RESET, F_CM_MEMMGR_INIT,
429*3833Sxw161283 0, 1000, 5);
430*3833Sxw161283 }
431*3833Sxw161283 #endif
432*3833Sxw161283 if (!busy)
433*3833Sxw161283 t1_write_reg_4(adapter, A_TP_RESET, F_TP_RESET);
434*3833Sxw161283 else
435*3833Sxw161283 CH_ERR("%s: TP initialization timed out\n",
436*3833Sxw161283 adapter_name(adapter));
437*3833Sxw161283 return busy;
438*3833Sxw161283 }
439