1f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger/* $Date: 2006/02/07 04:21:54 $ $RCSfile: tp.c,v $ $Revision: 1.73 $ */ 2f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger#include "common.h" 3f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger#include "regs.h" 4f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger#include "tp.h" 5352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger#ifdef CONFIG_CHELSIO_T1_1G 6352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger#include "fpga_defs.h" 7352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger#endif 8f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 9f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemmingerstruct petp { 10f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger adapter_t *adapter; 11f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger}; 12f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 13f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger/* Pause deadlock avoidance parameters */ 14f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger#define DROP_MSEC 16 15f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger#define DROP_PKTS_CNT 1 16f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 17f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemmingerstatic void tp_init(adapter_t * ap, const struct tp_params *p, 18f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger unsigned int tp_clk) 19f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger{ 20356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu u32 val; 21f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 22356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu if (!t1_is_asic(ap)) 23356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu return; 24f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 25356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu val = F_TP_IN_CSPI_CPL | F_TP_IN_CSPI_CHECK_IP_CSUM | 26356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu F_TP_IN_CSPI_CHECK_TCP_CSUM | F_TP_IN_ESPI_ETHERNET; 27356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu if (!p->pm_size) 28356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu val |= F_OFFLOAD_DISABLE; 29356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu else 30356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu val |= F_TP_IN_ESPI_CHECK_IP_CSUM | F_TP_IN_ESPI_CHECK_TCP_CSUM; 31356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu writel(val, ap->regs + A_TP_IN_CONFIG); 32356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu writel(F_TP_OUT_CSPI_CPL | 33356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu F_TP_OUT_ESPI_ETHERNET | 34356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu F_TP_OUT_ESPI_GENERATE_IP_CSUM | 35356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu F_TP_OUT_ESPI_GENERATE_TCP_CSUM, ap->regs + A_TP_OUT_CONFIG); 36356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu writel(V_IP_TTL(64) | 37356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu F_PATH_MTU /* IP DF bit */ | 38356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu V_5TUPLE_LOOKUP(p->use_5tuple_mode) | 39356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu V_SYN_COOKIE_PARAMETER(29), ap->regs + A_TP_GLOBAL_CONFIG); 40356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu /* 41356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu * Enable pause frame deadlock prevention. 42356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu */ 43356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu if (is_T2(ap) && ap->params.nports > 1) { 44356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu u32 drop_ticks = DROP_MSEC * (tp_clk / 1000); 45f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 46356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu writel(F_ENABLE_TX_DROP | F_ENABLE_TX_ERROR | 47356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu V_DROP_TICKS_CNT(drop_ticks) | 48356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu V_NUM_PKTS_DROPPED(DROP_PKTS_CNT), 49356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu ap->regs + A_TP_TX_DROP_CONFIG); 50f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger } 51f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger} 52f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 53f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemmingervoid t1_tp_destroy(struct petp *tp) 54f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger{ 55f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger kfree(tp); 56f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger} 57f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 58f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemmingerstruct petp *__devinit t1_tp_create(adapter_t * adapter, struct tp_params *p) 59f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger{ 60f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger struct petp *tp = kzalloc(sizeof(*tp), GFP_KERNEL); 61356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu 62f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger if (!tp) 63f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger return NULL; 64f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 65f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger tp->adapter = adapter; 66f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 67f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger return tp; 68f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger} 69f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 70f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemmingervoid t1_tp_intr_enable(struct petp *tp) 71f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger{ 72f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger u32 tp_intr = readl(tp->adapter->regs + A_PL_ENABLE); 73f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 74352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger#ifdef CONFIG_CHELSIO_T1_1G 75352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger if (!t1_is_asic(tp->adapter)) { 76352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger /* FPGA */ 77352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger writel(0xffffffff, 78352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger tp->adapter->regs + FPGA_TP_ADDR_INTERRUPT_ENABLE); 79352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger writel(tp_intr | FPGA_PCIX_INTERRUPT_TP, 80352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger tp->adapter->regs + A_PL_ENABLE); 81352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger } else 82352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger#endif 83f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger { 84f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger /* We don't use any TP interrupts */ 85f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(0, tp->adapter->regs + A_TP_INT_ENABLE); 86f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(tp_intr | F_PL_INTR_TP, 87f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger tp->adapter->regs + A_PL_ENABLE); 88f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger } 89f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger} 90f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 91f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemmingervoid t1_tp_intr_disable(struct petp *tp) 92f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger{ 93f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger u32 tp_intr = readl(tp->adapter->regs + A_PL_ENABLE); 94f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 95352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger#ifdef CONFIG_CHELSIO_T1_1G 96352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger if (!t1_is_asic(tp->adapter)) { 97352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger /* FPGA */ 98352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger writel(0, tp->adapter->regs + FPGA_TP_ADDR_INTERRUPT_ENABLE); 99352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger writel(tp_intr & ~FPGA_PCIX_INTERRUPT_TP, 100352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger tp->adapter->regs + A_PL_ENABLE); 101352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger } else 102352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger#endif 103f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger { 104f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(0, tp->adapter->regs + A_TP_INT_ENABLE); 105f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(tp_intr & ~F_PL_INTR_TP, 106f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger tp->adapter->regs + A_PL_ENABLE); 107f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger } 108f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger} 109f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 110f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemmingervoid t1_tp_intr_clear(struct petp *tp) 111f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger{ 112352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger#ifdef CONFIG_CHELSIO_T1_1G 113352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger if (!t1_is_asic(tp->adapter)) { 114352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger writel(0xffffffff, 115352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger tp->adapter->regs + FPGA_TP_ADDR_INTERRUPT_CAUSE); 116352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger writel(FPGA_PCIX_INTERRUPT_TP, tp->adapter->regs + A_PL_CAUSE); 117352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger return; 118352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger } 119352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger#endif 120f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(0xffffffff, tp->adapter->regs + A_TP_INT_CAUSE); 121f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(F_PL_INTR_TP, tp->adapter->regs + A_PL_CAUSE); 122f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger} 123f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 124f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemmingerint t1_tp_intr_handler(struct petp *tp) 125f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger{ 126f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger u32 cause; 127f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 128352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger#ifdef CONFIG_CHELSIO_T1_1G 129352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger /* FPGA doesn't support TP interrupts. */ 130352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger if (!t1_is_asic(tp->adapter)) 131352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger return 1; 132352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger#endif 133f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 134f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger cause = readl(tp->adapter->regs + A_TP_INT_CAUSE); 135f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(cause, tp->adapter->regs + A_TP_INT_CAUSE); 136f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger return 0; 137f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger} 138f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 139f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemmingerstatic void set_csum_offload(struct petp *tp, u32 csum_bit, int enable) 140f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger{ 141f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger u32 val = readl(tp->adapter->regs + A_TP_GLOBAL_CONFIG); 142f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 143f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger if (enable) 144f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger val |= csum_bit; 145f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger else 146f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger val &= ~csum_bit; 147f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(val, tp->adapter->regs + A_TP_GLOBAL_CONFIG); 148f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger} 149f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 150f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemmingervoid t1_tp_set_ip_checksum_offload(struct petp *tp, int enable) 151f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger{ 152f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger set_csum_offload(tp, F_IP_CSUM, enable); 153f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger} 154f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 155f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemmingervoid t1_tp_set_tcp_checksum_offload(struct petp *tp, int enable) 156f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger{ 157f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger set_csum_offload(tp, F_TCP_CSUM, enable); 158f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger} 159f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 160f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger/* 161f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger * Initialize TP state. tp_params contains initial settings for some TP 162f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger * parameters, particularly the one-time PM and CM settings. 163f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger */ 164f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemmingerint t1_tp_reset(struct petp *tp, struct tp_params *p, unsigned int tp_clk) 165f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger{ 166f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger adapter_t *adapter = tp->adapter; 167f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 168f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger tp_init(adapter, p, tp_clk); 169f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(F_TP_RESET, adapter->regs + A_TP_RESET); 170f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger return 0; 171f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger} 172