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 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 { 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 53 void t1_tp_destroy(struct petp *tp) 54 { 55 kfree(tp); 56 } 57 58 struct 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 70 void 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 91 void 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 110 void 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 124 int 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 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_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 */ 164 int 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