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