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" 5#ifdef CONFIG_CHELSIO_T1_1G 6#include "fpga_defs.h" 7#endif 8 9struct petp { 10 adapter_t *adapter; 11}; 12 13/* Pause deadlock avoidance parameters */ 14#define DROP_MSEC 16 15#define DROP_PKTS_CNT 1 16 17static void tp_init(adapter_t * ap, const struct tp_params *p, 18 unsigned int tp_clk) 19{ 20 u32 val; 21 22 if (!t1_is_asic(ap)) 23 return; 24 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); 45 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); 50 } 51} 52 53void t1_tp_destroy(struct petp *tp) 54{ 55 kfree(tp); 56} 57 58struct petp *t1_tp_create(adapter_t *adapter, struct tp_params *p) 59{ 60 struct petp *tp = kzalloc(sizeof(*tp), GFP_KERNEL); 61 62 if (!tp) 63 return NULL; 64 65 tp->adapter = adapter; 66 67 return tp; 68} 69 70void t1_tp_intr_enable(struct petp *tp) 71{ 72 u32 tp_intr = readl(tp->adapter->regs + A_PL_ENABLE); 73 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 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 91void t1_tp_intr_disable(struct petp *tp) 92{ 93 u32 tp_intr = readl(tp->adapter->regs + A_PL_ENABLE); 94 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 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 110void t1_tp_intr_clear(struct petp *tp) 111{ 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 120 writel(0xffffffff, tp->adapter->regs + A_TP_INT_CAUSE); 121 writel(F_PL_INTR_TP, tp->adapter->regs + A_PL_CAUSE); 122} 123 124int t1_tp_intr_handler(struct petp *tp) 125{ 126 u32 cause; 127 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 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 139static 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 150void t1_tp_set_ip_checksum_offload(struct petp *tp, int enable) 151{ 152 set_csum_offload(tp, F_IP_CSUM, enable); 153} 154 155void t1_tp_set_tcp_checksum_offload(struct petp *tp, int enable) 156{ 157 set_csum_offload(tp, F_TCP_CSUM, enable); 158} 159 160/* 161 * Initialize TP state. tp_params contains initial settings for some TP 162 * parameters, particularly the one-time PM and CM settings. 163 */ 164int t1_tp_reset(struct petp *tp, struct tp_params *p, unsigned int tp_clk) 165{ 166 adapter_t *adapter = tp->adapter; 167 168 tp_init(adapter, p, tp_clk); 169 writel(F_TP_RESET, adapter->regs + A_TP_RESET); 170 return 0; 171} 172