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