18199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter/***************************************************************************** 28199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * * 38199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * File: espi.c * 4559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone * $Revision: 1.14 $ * 5559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone * $Date: 2005/05/14 00:59:32 $ * 68199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Description: * 78199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Ethernet SPI functionality. * 88199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * part of the Chelsio 10Gb Ethernet Driver. * 98199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * * 108199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * This program is free software; you can redistribute it and/or modify * 118199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * it under the terms of the GNU General Public License, version 2, as * 128199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * published by the Free Software Foundation. * 138199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * * 148199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * You should have received a copy of the GNU General Public License along * 150ab75ae81da249988bf3c7a38e0a48d4b9be1e0cJeff Kirsher * with this program; if not, see <http://www.gnu.org/licenses/>. * 168199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * * 178199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * 188199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * 198199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * 208199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * * 218199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * http://www.chelsio.com * 228199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * * 238199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. * 248199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * All rights reserved. * 258199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * * 268199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Maintainers: maintainers@chelsio.com * 278199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * * 288199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Authors: Dimitrios Michailidis <dm@chelsio.com> * 298199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Tina Yang <tainay@chelsio.com> * 308199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Felix Marti <felix@chelsio.com> * 318199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Scott Bardone <sbardone@chelsio.com> * 328199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Kurt Ottaway <kottaway@chelsio.com> * 338199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Frank DiMambro <frank@chelsio.com> * 348199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * * 358199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * History: * 368199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * * 378199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ****************************************************************************/ 388199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 398199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#include "common.h" 408199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#include "regs.h" 418199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#include "espi.h" 428199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 438199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstruct peespi { 448199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter adapter_t *adapter; 458199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct espi_intr_counts intr_cnt; 468199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter u32 misc_ctrl; 478199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter spinlock_t lock; 488199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter}; 498199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 508199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#define ESPI_INTR_MASK (F_DIP4ERR | F_RXDROP | F_TXDROP | F_RXOVERFLOW | \ 518199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter F_RAMPARITYERR | F_DIP2PARITYERR) 528199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#define MON_MASK (V_MONITORED_PORT_NUM(3) | F_MONITORED_DIRECTION \ 538199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter | F_MONITORED_INTERFACE) 548199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 558199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#define TRICN_CNFG 14 568199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#define TRICN_CMD_READ 0x11 578199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#define TRICN_CMD_WRITE 0x21 588199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#define TRICN_CMD_ATTEMPTS 10 598199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 608199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic int tricn_write(adapter_t *adapter, int bundle_addr, int module_addr, 618199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter int ch_addr, int reg_offset, u32 wr_data) 628199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 638199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter int busy, attempts = TRICN_CMD_ATTEMPTS; 648199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 65559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(V_WRITE_DATA(wr_data) | 66559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone V_REGISTER_OFFSET(reg_offset) | 67559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone V_CHANNEL_ADDR(ch_addr) | V_MODULE_ADDR(module_addr) | 68559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone V_BUNDLE_ADDR(bundle_addr) | 69559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone V_SPI4_COMMAND(TRICN_CMD_WRITE), 70559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone adapter->regs + A_ESPI_CMD_ADDR); 71559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(0, adapter->regs + A_ESPI_GOSTAT); 728199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 738199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter do { 74559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone busy = readl(adapter->regs + A_ESPI_GOSTAT) & F_ESPI_CMD_BUSY; 758199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } while (busy && --attempts); 768199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 778199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (busy) 78c1f51212eb809849bdc68a856ae5f424dcf20d9bJoe Perches pr_err("%s: TRICN write timed out\n", adapter->name); 798199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 808199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return busy; 818199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 828199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 838199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic int tricn_init(adapter_t *adapter) 848199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 85f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger int i, sme = 1; 868199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 87f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger if (!(readl(adapter->regs + A_ESPI_RX_RESET) & F_RX_CLK_STATUS)) { 88c1f51212eb809849bdc68a856ae5f424dcf20d9bJoe Perches pr_err("%s: ESPI clock not ready\n", adapter->name); 89f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger return -1; 908199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 918199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 92f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(F_ESPI_RX_CORE_RST, adapter->regs + A_ESPI_RX_RESET); 93f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 94f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger if (sme) { 95f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger tricn_write(adapter, 0, 0, 0, TRICN_CNFG, 0x81); 96f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger tricn_write(adapter, 0, 1, 0, TRICN_CNFG, 0x81); 97f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger tricn_write(adapter, 0, 2, 0, TRICN_CNFG, 0x81); 98f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger } 99f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger for (i = 1; i <= 8; i++) 100f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger tricn_write(adapter, 0, 0, i, TRICN_CNFG, 0xf1); 101f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger for (i = 1; i <= 2; i++) 102f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger tricn_write(adapter, 0, 1, i, TRICN_CNFG, 0xf1); 103f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger for (i = 1; i <= 3; i++) 104f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger tricn_write(adapter, 0, 2, i, TRICN_CNFG, 0xe1); 105f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger tricn_write(adapter, 0, 2, 4, TRICN_CNFG, 0xf1); 106f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger tricn_write(adapter, 0, 2, 5, TRICN_CNFG, 0xe1); 107f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger tricn_write(adapter, 0, 2, 6, TRICN_CNFG, 0xf1); 108f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger tricn_write(adapter, 0, 2, 7, TRICN_CNFG, 0x80); 109f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger tricn_write(adapter, 0, 2, 8, TRICN_CNFG, 0xf1); 110f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 111f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(F_ESPI_RX_CORE_RST | F_ESPI_RX_LNK_RST, 112f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger adapter->regs + A_ESPI_RX_RESET); 1138199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 1148199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return 0; 1158199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 1168199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 1178199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lametervoid t1_espi_intr_enable(struct peespi *espi) 1188199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 119559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone u32 enable, pl_intr = readl(espi->adapter->regs + A_PL_ENABLE); 1208199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 1218199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter /* 1228199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Cannot enable ESPI interrupts on T1B because HW asserts the 1238199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * interrupt incorrectly, namely the driver gets ESPI interrupts 1248199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * but no data is actually dropped (can verify this reading the ESPI 1258199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * drop registers). Also, once the ESPI interrupt is asserted it 1268199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * cannot be cleared (HW bug). 1278199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter */ 1288199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter enable = t1_is_T1B(espi->adapter) ? 0 : ESPI_INTR_MASK; 129559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(enable, espi->adapter->regs + A_ESPI_INTR_ENABLE); 130559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(pl_intr | F_PL_INTR_ESPI, espi->adapter->regs + A_PL_ENABLE); 1318199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 1328199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 1338199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lametervoid t1_espi_intr_clear(struct peespi *espi) 1348199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 135f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger readl(espi->adapter->regs + A_ESPI_DIP2_ERR_COUNT); 136559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(0xffffffff, espi->adapter->regs + A_ESPI_INTR_STATUS); 137559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(F_PL_INTR_ESPI, espi->adapter->regs + A_PL_CAUSE); 1388199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 1398199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 1408199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lametervoid t1_espi_intr_disable(struct peespi *espi) 1418199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 142559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone u32 pl_intr = readl(espi->adapter->regs + A_PL_ENABLE); 1438199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 144559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(0, espi->adapter->regs + A_ESPI_INTR_ENABLE); 145559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(pl_intr & ~F_PL_INTR_ESPI, espi->adapter->regs + A_PL_ENABLE); 1468199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 1478199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 1488199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterint t1_espi_intr_handler(struct peespi *espi) 1498199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 150559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone u32 status = readl(espi->adapter->regs + A_ESPI_INTR_STATUS); 1518199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 1528199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (status & F_DIP4ERR) 1538199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter espi->intr_cnt.DIP4_err++; 1548199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (status & F_RXDROP) 1558199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter espi->intr_cnt.rx_drops++; 1568199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (status & F_TXDROP) 1578199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter espi->intr_cnt.tx_drops++; 1588199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (status & F_RXOVERFLOW) 1598199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter espi->intr_cnt.rx_ovflw++; 1608199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (status & F_RAMPARITYERR) 1618199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter espi->intr_cnt.parity_err++; 1628199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (status & F_DIP2PARITYERR) { 1638199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter espi->intr_cnt.DIP2_parity_err++; 1648199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 1658199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter /* 1668199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Must read the error count to clear the interrupt 1678199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * that it causes. 1688199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter */ 169f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger readl(espi->adapter->regs + A_ESPI_DIP2_ERR_COUNT); 1708199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 1718199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 1728199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter /* 1738199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * For T1B we need to write 1 to clear ESPI interrupts. For T2+ we 1748199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * write the status as is. 1758199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter */ 1768199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (status && t1_is_T1B(espi->adapter)) 1778199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter status = 1; 178559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(status, espi->adapter->regs + A_ESPI_INTR_STATUS); 1798199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return 0; 1808199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 1818199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 182559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardoneconst struct espi_intr_counts *t1_espi_get_intr_counts(struct peespi *espi) 1838199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 18411e5a202ca9e93ecb5ff314a6a345e0e4db77d97Stephen Hemminger return &espi->intr_cnt; 1858199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 1868199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 187559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardonestatic void espi_setup_for_pm3393(adapter_t *adapter) 1888199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 1898199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter u32 wmark = t1_is_T1B(adapter) ? 0x4000 : 0x3200; 1908199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 191559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN0); 192559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN1); 193559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN2); 194559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN3); 195559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(0x100, adapter->regs + A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK); 196559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(wmark, adapter->regs + A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK); 197559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(3, adapter->regs + A_ESPI_CALENDAR_LENGTH); 198559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(0x08000008, adapter->regs + A_ESPI_TRAIN); 199559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(V_RX_NPORTS(1) | V_TX_NPORTS(1), adapter->regs + A_PORT_CONFIG); 2008199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 2018199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 202f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemmingerstatic void espi_setup_for_vsc7321(adapter_t *adapter) 203f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger{ 204356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN0); 205356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu writel(0x1f401f4, adapter->regs + A_ESPI_SCH_TOKEN1); 206356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN2); 207f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(0xa00, adapter->regs + A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK); 208f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(0x1ff, adapter->regs + A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK); 209f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(1, adapter->regs + A_ESPI_CALENDAR_LENGTH); 210f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(V_RX_NPORTS(4) | V_TX_NPORTS(4), adapter->regs + A_PORT_CONFIG); 211f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 212f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(0x08000008, adapter->regs + A_ESPI_TRAIN); 213f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger} 214f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 215f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger/* 216f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger * Note that T1B requires at least 2 ports for IXF1010 due to a HW bug. 217f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger */ 218f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemmingerstatic void espi_setup_for_ixf1010(adapter_t *adapter, int nports) 2198199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 220f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(1, adapter->regs + A_ESPI_CALENDAR_LENGTH); 221f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger if (nports == 4) { 222f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger if (is_T2(adapter)) { 223f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(0xf00, adapter->regs + A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK); 224f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(0x3c0, adapter->regs + A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK); 225f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger } else { 226f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(0x7ff, adapter->regs + A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK); 227f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(0x1ff, adapter->regs + A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK); 228f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger } 229f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger } else { 230f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(0x1fff, adapter->regs + A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK); 231f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(0x7ff, adapter->regs + A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK); 232f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger } 233f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(V_RX_NPORTS(nports) | V_TX_NPORTS(nports), adapter->regs + A_PORT_CONFIG); 234559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone 235f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger} 236f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 237f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemmingerint t1_espi_init(struct peespi *espi, int mac_type, int nports) 238f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger{ 2398199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter u32 status_enable_extra = 0; 2408199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter adapter_t *adapter = espi->adapter; 2418199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 2428199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter /* Disable ESPI training. MACs that can handle it enable it below. */ 243559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(0, adapter->regs + A_ESPI_TRAIN); 2448199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 2458199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (is_T2(adapter)) { 246559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(V_OUT_OF_SYNC_COUNT(4) | 247559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone V_DIP2_PARITY_ERR_THRES(3) | 248559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone V_DIP4_THRES(1), adapter->regs + A_ESPI_MISC_CONTROL); 249356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu writel(nports == 4 ? 0x200040 : 0x1000080, 250f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger adapter->regs + A_ESPI_MAXBURST1_MAXBURST2); 251f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger } else 252356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu writel(0x800100, adapter->regs + A_ESPI_MAXBURST1_MAXBURST2); 2538199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 254f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger if (mac_type == CHBT_MAC_PM3393) 2558199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter espi_setup_for_pm3393(adapter); 256f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger else if (mac_type == CHBT_MAC_VSC7321) 257f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger espi_setup_for_vsc7321(adapter); 258f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger else if (mac_type == CHBT_MAC_IXF1010) { 259f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger status_enable_extra = F_INTEL1010MODE; 260f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger espi_setup_for_ixf1010(adapter, nports); 261f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger } else 2628199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return -1; 2638199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 264559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(status_enable_extra | F_RXSTATUSENABLE, 265559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone adapter->regs + A_ESPI_FIFO_STATUS_ENABLE); 2668199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 2678199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (is_T2(adapter)) { 2688199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter tricn_init(adapter); 2698199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter /* 2708199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Always position the control at the 1st port egress IN 2718199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * (sop,eop) counter to reduce PIOs for T/N210 workaround. 2728199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter */ 273f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger espi->misc_ctrl = readl(adapter->regs + A_ESPI_MISC_CONTROL); 274f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger espi->misc_ctrl &= ~MON_MASK; 275f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger espi->misc_ctrl |= F_MONITORED_DIRECTION; 276f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger if (adapter->params.nports == 1) 277f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger espi->misc_ctrl |= F_MONITORED_INTERFACE; 278559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL); 2798199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter spin_lock_init(&espi->lock); 2808199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 2818199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 2828199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return 0; 2838199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 2848199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 2858199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lametervoid t1_espi_destroy(struct peespi *espi) 2868199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 2878199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter kfree(espi); 2888199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 2898199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 2908199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstruct peespi *t1_espi_create(adapter_t *adapter) 2918199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 2922d66806d740eeb410aa785bd7fba3bd24bb082c1Eric Sesterhenn struct peespi *espi = kzalloc(sizeof(*espi), GFP_KERNEL); 2938199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 2948199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (espi) 2958199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter espi->adapter = adapter; 2968199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return espi; 2978199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 2988199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 29968d579fb93df0db0442f90106b19a8dc701ecef1Adrian Bunk#if 0 3008199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lametervoid t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val) 3018199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 3028199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct peespi *espi = adapter->espi; 3038199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 304c697f83e8c880a1e69fb2a45a6e4aa0670e10602Francois Romieu if (!is_T2(adapter)) 305c697f83e8c880a1e69fb2a45a6e4aa0670e10602Francois Romieu return; 3068199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter spin_lock(&espi->lock); 3078199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter espi->misc_ctrl = (val & ~MON_MASK) | 3088199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter (espi->misc_ctrl & MON_MASK); 309559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL); 3108199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter spin_unlock(&espi->lock); 3118199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 31268d579fb93df0db0442f90106b19a8dc701ecef1Adrian Bunk#endif /* 0 */ 3138199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 3148199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameteru32 t1_espi_get_mon(adapter_t *adapter, u32 addr, u8 wait) 3158199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 316559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone struct peespi *espi = adapter->espi; 317f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger u32 sel; 318559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone 3198199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (!is_T2(adapter)) 3208199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return 0; 321f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 3228199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter sel = V_MONITORED_PORT_NUM((addr & 0x3c) >> 2); 3238199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (!wait) { 3248199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (!spin_trylock(&espi->lock)) 3258199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return 0; 326f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger } else 3278199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter spin_lock(&espi->lock); 328f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 3298199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if ((sel != (espi->misc_ctrl & MON_MASK))) { 330559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(((espi->misc_ctrl & ~MON_MASK) | sel), 331559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone adapter->regs + A_ESPI_MISC_CONTROL); 332559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone sel = readl(adapter->regs + A_ESPI_SCH_TOKEN3); 333559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL); 334f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger } else 335559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone sel = readl(adapter->regs + A_ESPI_SCH_TOKEN3); 3368199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter spin_unlock(&espi->lock); 3378199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return sel; 3388199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 339f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 340f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger/* 341f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger * This function is for T204 only. 342f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger * compare with t1_espi_get_mon(), it reads espiInTxSop[0 ~ 3] in 343f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger * one shot, since there is no per port counter on the out side. 344f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger */ 345356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieuint t1_espi_get_mon_t204(adapter_t *adapter, u32 *valp, u8 wait) 346f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger{ 347356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu struct peespi *espi = adapter->espi; 348f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger u8 i, nport = (u8)adapter->params.nports; 349f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 350356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu if (!wait) { 351356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu if (!spin_trylock(&espi->lock)) 352356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu return -1; 353356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu } else 354356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu spin_lock(&espi->lock); 355f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 356356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu if ((espi->misc_ctrl & MON_MASK) != F_MONITORED_DIRECTION) { 357f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger espi->misc_ctrl = (espi->misc_ctrl & ~MON_MASK) | 358f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger F_MONITORED_DIRECTION; 359356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL); 360356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu } 361f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger for (i = 0 ; i < nport; i++, valp++) { 362f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger if (i) { 363f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger writel(espi->misc_ctrl | V_MONITORED_PORT_NUM(i), 364f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger adapter->regs + A_ESPI_MISC_CONTROL); 365f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger } 366356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu *valp = readl(adapter->regs + A_ESPI_SCH_TOKEN3); 367356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu } 368f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 369356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL); 370356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu spin_unlock(&espi->lock); 371356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu return 0; 372f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger} 373