Commit | Line | Data |
---|---|---|
f1d3d38a SH |
1 | /* $Date: 2006/02/07 04:21:54 $ $RCSfile: tp.c,v $ $Revision: 1.73 $ */ |
2 | #include "common.h" | |
3 | #include "regs.h" | |
4 | #include "tp.h" | |
352c417d SH |
5 | #ifdef CONFIG_CHELSIO_T1_1G |
6 | #include "fpga_defs.h" | |
7 | #endif | |
f1d3d38a SH |
8 | |
9 | struct petp { | |
10 | adapter_t *adapter; | |
11 | }; | |
12 | ||
13 | /* Pause deadlock avoidance parameters */ | |
14 | #define DROP_MSEC 16 | |
15 | #define DROP_PKTS_CNT 1 | |
16 | ||
17 | static void tp_init(adapter_t * ap, const struct tp_params *p, | |
18 | unsigned int tp_clk) | |
19 | { | |
356bd146 | 20 | u32 val; |
f1d3d38a | 21 | |
356bd146 FR |
22 | if (!t1_is_asic(ap)) |
23 | return; | |
f1d3d38a | 24 | |
356bd146 FR |
25 | val = F_TP_IN_CSPI_CPL | F_TP_IN_CSPI_CHECK_IP_CSUM | |
26 | F_TP_IN_CSPI_CHECK_TCP_CSUM | F_TP_IN_ESPI_ETHERNET; | |
27 | if (!p->pm_size) | |
28 | val |= F_OFFLOAD_DISABLE; | |
29 | else | |
30 | val |= F_TP_IN_ESPI_CHECK_IP_CSUM | F_TP_IN_ESPI_CHECK_TCP_CSUM; | |
31 | writel(val, ap->regs + A_TP_IN_CONFIG); | |
32 | writel(F_TP_OUT_CSPI_CPL | | |
33 | F_TP_OUT_ESPI_ETHERNET | | |
34 | F_TP_OUT_ESPI_GENERATE_IP_CSUM | | |
35 | F_TP_OUT_ESPI_GENERATE_TCP_CSUM, ap->regs + A_TP_OUT_CONFIG); | |
36 | writel(V_IP_TTL(64) | | |
37 | F_PATH_MTU /* IP DF bit */ | | |
38 | V_5TUPLE_LOOKUP(p->use_5tuple_mode) | | |
39 | V_SYN_COOKIE_PARAMETER(29), ap->regs + A_TP_GLOBAL_CONFIG); | |
40 | /* | |
41 | * Enable pause frame deadlock prevention. | |
42 | */ | |
43 | if (is_T2(ap) && ap->params.nports > 1) { | |
44 | u32 drop_ticks = DROP_MSEC * (tp_clk / 1000); | |
f1d3d38a | 45 | |
356bd146 FR |
46 | writel(F_ENABLE_TX_DROP | F_ENABLE_TX_ERROR | |
47 | V_DROP_TICKS_CNT(drop_ticks) | | |
48 | V_NUM_PKTS_DROPPED(DROP_PKTS_CNT), | |
49 | ap->regs + A_TP_TX_DROP_CONFIG); | |
f1d3d38a SH |
50 | } |
51 | } | |
52 | ||
53 | void t1_tp_destroy(struct petp *tp) | |
54 | { | |
55 | kfree(tp); | |
56 | } | |
57 | ||
58 | struct petp *__devinit t1_tp_create(adapter_t * adapter, struct tp_params *p) | |
59 | { | |
60 | struct petp *tp = kzalloc(sizeof(*tp), GFP_KERNEL); | |
356bd146 | 61 | |
f1d3d38a SH |
62 | if (!tp) |
63 | return NULL; | |
64 | ||
65 | tp->adapter = adapter; | |
66 | ||
67 | return tp; | |
68 | } | |
69 | ||
70 | void t1_tp_intr_enable(struct petp *tp) | |
71 | { | |
72 | u32 tp_intr = readl(tp->adapter->regs + A_PL_ENABLE); | |
73 | ||
352c417d SH |
74 | #ifdef CONFIG_CHELSIO_T1_1G |
75 | if (!t1_is_asic(tp->adapter)) { | |
76 | /* FPGA */ | |
77 | writel(0xffffffff, | |
78 | tp->adapter->regs + FPGA_TP_ADDR_INTERRUPT_ENABLE); | |
79 | writel(tp_intr | FPGA_PCIX_INTERRUPT_TP, | |
80 | tp->adapter->regs + A_PL_ENABLE); | |
81 | } else | |
82 | #endif | |
f1d3d38a SH |
83 | { |
84 | /* We don't use any TP interrupts */ | |
85 | writel(0, tp->adapter->regs + A_TP_INT_ENABLE); | |
86 | writel(tp_intr | F_PL_INTR_TP, | |
87 | tp->adapter->regs + A_PL_ENABLE); | |
88 | } | |
89 | } | |
90 | ||
91 | void t1_tp_intr_disable(struct petp *tp) | |
92 | { | |
93 | u32 tp_intr = readl(tp->adapter->regs + A_PL_ENABLE); | |
94 | ||
352c417d SH |
95 | #ifdef CONFIG_CHELSIO_T1_1G |
96 | if (!t1_is_asic(tp->adapter)) { | |
97 | /* FPGA */ | |
98 | writel(0, tp->adapter->regs + FPGA_TP_ADDR_INTERRUPT_ENABLE); | |
99 | writel(tp_intr & ~FPGA_PCIX_INTERRUPT_TP, | |
100 | tp->adapter->regs + A_PL_ENABLE); | |
101 | } else | |
102 | #endif | |
f1d3d38a SH |
103 | { |
104 | writel(0, tp->adapter->regs + A_TP_INT_ENABLE); | |
105 | writel(tp_intr & ~F_PL_INTR_TP, | |
106 | tp->adapter->regs + A_PL_ENABLE); | |
107 | } | |
108 | } | |
109 | ||
110 | void t1_tp_intr_clear(struct petp *tp) | |
111 | { | |
352c417d SH |
112 | #ifdef CONFIG_CHELSIO_T1_1G |
113 | if (!t1_is_asic(tp->adapter)) { | |
114 | writel(0xffffffff, | |
115 | tp->adapter->regs + FPGA_TP_ADDR_INTERRUPT_CAUSE); | |
116 | writel(FPGA_PCIX_INTERRUPT_TP, tp->adapter->regs + A_PL_CAUSE); | |
117 | return; | |
118 | } | |
119 | #endif | |
f1d3d38a SH |
120 | writel(0xffffffff, tp->adapter->regs + A_TP_INT_CAUSE); |
121 | writel(F_PL_INTR_TP, tp->adapter->regs + A_PL_CAUSE); | |
122 | } | |
123 | ||
124 | int t1_tp_intr_handler(struct petp *tp) | |
125 | { | |
126 | u32 cause; | |
127 | ||
352c417d SH |
128 | #ifdef CONFIG_CHELSIO_T1_1G |
129 | /* FPGA doesn't support TP interrupts. */ | |
130 | if (!t1_is_asic(tp->adapter)) | |
131 | return 1; | |
132 | #endif | |
f1d3d38a SH |
133 | |
134 | cause = readl(tp->adapter->regs + A_TP_INT_CAUSE); | |
135 | writel(cause, tp->adapter->regs + A_TP_INT_CAUSE); | |
136 | return 0; | |
137 | } | |
138 | ||
139 | static void set_csum_offload(struct petp *tp, u32 csum_bit, int enable) | |
140 | { | |
141 | u32 val = readl(tp->adapter->regs + A_TP_GLOBAL_CONFIG); | |
142 | ||
143 | if (enable) | |
144 | val |= csum_bit; | |
145 | else | |
146 | val &= ~csum_bit; | |
147 | writel(val, tp->adapter->regs + A_TP_GLOBAL_CONFIG); | |
148 | } | |
149 | ||
150 | void t1_tp_set_ip_checksum_offload(struct petp *tp, int enable) | |
151 | { | |
152 | set_csum_offload(tp, F_IP_CSUM, enable); | |
153 | } | |
154 | ||
155 | void t1_tp_set_udp_checksum_offload(struct petp *tp, int enable) | |
156 | { | |
157 | set_csum_offload(tp, F_UDP_CSUM, enable); | |
158 | } | |
159 | ||
160 | void t1_tp_set_tcp_checksum_offload(struct petp *tp, int enable) | |
161 | { | |
162 | set_csum_offload(tp, F_TCP_CSUM, enable); | |
163 | } | |
164 | ||
165 | /* | |
166 | * Initialize TP state. tp_params contains initial settings for some TP | |
167 | * parameters, particularly the one-time PM and CM settings. | |
168 | */ | |
169 | int t1_tp_reset(struct petp *tp, struct tp_params *p, unsigned int tp_clk) | |
170 | { | |
171 | adapter_t *adapter = tp->adapter; | |
172 | ||
173 | tp_init(adapter, p, tp_clk); | |
174 | writel(F_TP_RESET, adapter->regs + A_TP_RESET); | |
175 | return 0; | |
176 | } |