aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/chelsio/espi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/chelsio/espi.c')
-rw-r--r--drivers/net/chelsio/espi.c168
1 files changed, 64 insertions, 104 deletions
diff --git a/drivers/net/chelsio/espi.c b/drivers/net/chelsio/espi.c
index 7ec2dc7bafac..230642571c92 100644
--- a/drivers/net/chelsio/espi.c
+++ b/drivers/net/chelsio/espi.c
@@ -1,8 +1,8 @@
1/***************************************************************************** 1/*****************************************************************************
2 * * 2 * *
3 * File: espi.c * 3 * File: espi.c *
4 * $Revision: 1.9 $ * 4 * $Revision: 1.14 $ *
5 * $Date: 2005/03/23 07:41:27 $ * 5 * $Date: 2005/05/14 00:59:32 $ *
6 * Description: * 6 * Description: *
7 * Ethernet SPI functionality. * 7 * Ethernet SPI functionality. *
8 * part of the Chelsio 10Gb Ethernet Driver. * 8 * part of the Chelsio 10Gb Ethernet Driver. *
@@ -63,15 +63,16 @@ static int tricn_write(adapter_t *adapter, int bundle_addr, int module_addr,
63{ 63{
64 int busy, attempts = TRICN_CMD_ATTEMPTS; 64 int busy, attempts = TRICN_CMD_ATTEMPTS;
65 65
66 t1_write_reg_4(adapter, A_ESPI_CMD_ADDR, V_WRITE_DATA(wr_data) | 66 writel(V_WRITE_DATA(wr_data) |
67 V_REGISTER_OFFSET(reg_offset) | 67 V_REGISTER_OFFSET(reg_offset) |
68 V_CHANNEL_ADDR(ch_addr) | V_MODULE_ADDR(module_addr) | 68 V_CHANNEL_ADDR(ch_addr) | V_MODULE_ADDR(module_addr) |
69 V_BUNDLE_ADDR(bundle_addr) | 69 V_BUNDLE_ADDR(bundle_addr) |
70 V_SPI4_COMMAND(TRICN_CMD_WRITE)); 70 V_SPI4_COMMAND(TRICN_CMD_WRITE),
71 t1_write_reg_4(adapter, A_ESPI_GOSTAT, 0); 71 adapter->regs + A_ESPI_CMD_ADDR);
72 writel(0, adapter->regs + A_ESPI_GOSTAT);
72 73
73 do { 74 do {
74 busy = t1_read_reg_4(adapter, A_ESPI_GOSTAT) & F_ESPI_CMD_BUSY; 75 busy = readl(adapter->regs + A_ESPI_GOSTAT) & F_ESPI_CMD_BUSY;
75 } while (busy && --attempts); 76 } while (busy && --attempts);
76 77
77 if (busy) 78 if (busy)
@@ -99,12 +100,12 @@ static int tricn_init(adapter_t *adapter)
99 /* 1 */ 100 /* 1 */
100 timeout=1000; 101 timeout=1000;
101 do { 102 do {
102 stat = t1_read_reg_4(adapter, A_ESPI_RX_RESET); 103 stat = readl(adapter->regs + A_ESPI_RX_RESET);
103 is_ready = (stat & 0x4); 104 is_ready = (stat & 0x4);
104 timeout--; 105 timeout--;
105 udelay(5); 106 udelay(5);
106 } while (!is_ready || (timeout==0)); 107 } while (!is_ready || (timeout==0));
107 t1_write_reg_4(adapter, A_ESPI_RX_RESET, 0x2); 108 writel(0x2, adapter->regs + A_ESPI_RX_RESET);
108 if (timeout==0) 109 if (timeout==0)
109 { 110 {
110 CH_ERR("ESPI : ERROR : Timeout tricn_init() \n"); 111 CH_ERR("ESPI : ERROR : Timeout tricn_init() \n");
@@ -127,14 +128,14 @@ static int tricn_init(adapter_t *adapter)
127 for (i=8; i<= 8; i++) tricn_write(adapter, 0, 2, i, TRICN_CNFG, 0xf1); 128 for (i=8; i<= 8; i++) tricn_write(adapter, 0, 2, i, TRICN_CNFG, 0xf1);
128 129
129 /* 3 */ 130 /* 3 */
130 t1_write_reg_4(adapter, A_ESPI_RX_RESET, 0x3); 131 writel(0x3, adapter->regs + A_ESPI_RX_RESET);
131 132
132 return 0; 133 return 0;
133} 134}
134 135
135void t1_espi_intr_enable(struct peespi *espi) 136void t1_espi_intr_enable(struct peespi *espi)
136{ 137{
137 u32 enable, pl_intr = t1_read_reg_4(espi->adapter, A_PL_ENABLE); 138 u32 enable, pl_intr = readl(espi->adapter->regs + A_PL_ENABLE);
138 139
139 /* 140 /*
140 * Cannot enable ESPI interrupts on T1B because HW asserts the 141 * Cannot enable ESPI interrupts on T1B because HW asserts the
@@ -144,28 +145,28 @@ void t1_espi_intr_enable(struct peespi *espi)
144 * cannot be cleared (HW bug). 145 * cannot be cleared (HW bug).
145 */ 146 */
146 enable = t1_is_T1B(espi->adapter) ? 0 : ESPI_INTR_MASK; 147 enable = t1_is_T1B(espi->adapter) ? 0 : ESPI_INTR_MASK;
147 t1_write_reg_4(espi->adapter, A_ESPI_INTR_ENABLE, enable); 148 writel(enable, espi->adapter->regs + A_ESPI_INTR_ENABLE);
148 t1_write_reg_4(espi->adapter, A_PL_ENABLE, pl_intr | F_PL_INTR_ESPI); 149 writel(pl_intr | F_PL_INTR_ESPI, espi->adapter->regs + A_PL_ENABLE);
149} 150}
150 151
151void t1_espi_intr_clear(struct peespi *espi) 152void t1_espi_intr_clear(struct peespi *espi)
152{ 153{
153 t1_write_reg_4(espi->adapter, A_ESPI_INTR_STATUS, 0xffffffff); 154 writel(0xffffffff, espi->adapter->regs + A_ESPI_INTR_STATUS);
154 t1_write_reg_4(espi->adapter, A_PL_CAUSE, F_PL_INTR_ESPI); 155 writel(F_PL_INTR_ESPI, espi->adapter->regs + A_PL_CAUSE);
155} 156}
156 157
157void t1_espi_intr_disable(struct peespi *espi) 158void t1_espi_intr_disable(struct peespi *espi)
158{ 159{
159 u32 pl_intr = t1_read_reg_4(espi->adapter, A_PL_ENABLE); 160 u32 pl_intr = readl(espi->adapter->regs + A_PL_ENABLE);
160 161
161 t1_write_reg_4(espi->adapter, A_ESPI_INTR_ENABLE, 0); 162 writel(0, espi->adapter->regs + A_ESPI_INTR_ENABLE);
162 t1_write_reg_4(espi->adapter, A_PL_ENABLE, pl_intr & ~F_PL_INTR_ESPI); 163 writel(pl_intr & ~F_PL_INTR_ESPI, espi->adapter->regs + A_PL_ENABLE);
163} 164}
164 165
165int t1_espi_intr_handler(struct peespi *espi) 166int t1_espi_intr_handler(struct peespi *espi)
166{ 167{
167 u32 cnt; 168 u32 cnt;
168 u32 status = t1_read_reg_4(espi->adapter, A_ESPI_INTR_STATUS); 169 u32 status = readl(espi->adapter->regs + A_ESPI_INTR_STATUS);
169 170
170 if (status & F_DIP4ERR) 171 if (status & F_DIP4ERR)
171 espi->intr_cnt.DIP4_err++; 172 espi->intr_cnt.DIP4_err++;
@@ -184,7 +185,7 @@ int t1_espi_intr_handler(struct peespi *espi)
184 * Must read the error count to clear the interrupt 185 * Must read the error count to clear the interrupt
185 * that it causes. 186 * that it causes.
186 */ 187 */
187 cnt = t1_read_reg_4(espi->adapter, A_ESPI_DIP2_ERR_COUNT); 188 cnt = readl(espi->adapter->regs + A_ESPI_DIP2_ERR_COUNT);
188 } 189 }
189 190
190 /* 191 /*
@@ -193,68 +194,28 @@ int t1_espi_intr_handler(struct peespi *espi)
193 */ 194 */
194 if (status && t1_is_T1B(espi->adapter)) 195 if (status && t1_is_T1B(espi->adapter))
195 status = 1; 196 status = 1;
196 t1_write_reg_4(espi->adapter, A_ESPI_INTR_STATUS, status); 197 writel(status, espi->adapter->regs + A_ESPI_INTR_STATUS);
197 return 0; 198 return 0;
198} 199}
199 200
200static void espi_setup_for_pm3393(adapter_t *adapter) 201const struct espi_intr_counts *t1_espi_get_intr_counts(struct peespi *espi)
201{ 202{
202 u32 wmark = t1_is_T1B(adapter) ? 0x4000 : 0x3200; 203 return &espi->intr_cnt;
203
204 t1_write_reg_4(adapter, A_ESPI_SCH_TOKEN0, 0x1f4);
205 t1_write_reg_4(adapter, A_ESPI_SCH_TOKEN1, 0x1f4);
206 t1_write_reg_4(adapter, A_ESPI_SCH_TOKEN2, 0x1f4);
207 t1_write_reg_4(adapter, A_ESPI_SCH_TOKEN3, 0x1f4);
208 t1_write_reg_4(adapter, A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK, 0x100);
209 t1_write_reg_4(adapter, A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK, wmark);
210 t1_write_reg_4(adapter, A_ESPI_CALENDAR_LENGTH, 3);
211 t1_write_reg_4(adapter, A_ESPI_TRAIN, 0x08000008);
212 t1_write_reg_4(adapter, A_PORT_CONFIG,
213 V_RX_NPORTS(1) | V_TX_NPORTS(1));
214} 204}
215 205
216static void espi_setup_for_vsc7321(adapter_t *adapter) 206static void espi_setup_for_pm3393(adapter_t *adapter)
217{ 207{
218 u32 wmark = t1_is_T1B(adapter) ? 0x4000 : 0x3200; 208 u32 wmark = t1_is_T1B(adapter) ? 0x4000 : 0x3200;
219 209
220 t1_write_reg_4(adapter, A_ESPI_SCH_TOKEN0, 0x1f4); 210 writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN0);
221 t1_write_reg_4(adapter, A_ESPI_SCH_TOKEN1, 0x1f4); 211 writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN1);
222 t1_write_reg_4(adapter, A_ESPI_SCH_TOKEN2, 0x1f4); 212 writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN2);
223 t1_write_reg_4(adapter, A_ESPI_SCH_TOKEN3, 0x1f4); 213 writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN3);
224 t1_write_reg_4(adapter, A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK, 0x100); 214 writel(0x100, adapter->regs + A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK);
225 t1_write_reg_4(adapter, A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK, wmark); 215 writel(wmark, adapter->regs + A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK);
226 t1_write_reg_4(adapter, A_ESPI_CALENDAR_LENGTH, 3); 216 writel(3, adapter->regs + A_ESPI_CALENDAR_LENGTH);
227 t1_write_reg_4(adapter, A_ESPI_TRAIN, 0x08000008); 217 writel(0x08000008, adapter->regs + A_ESPI_TRAIN);
228 t1_write_reg_4(adapter, A_PORT_CONFIG, 218 writel(V_RX_NPORTS(1) | V_TX_NPORTS(1), adapter->regs + A_PORT_CONFIG);
229 V_RX_NPORTS(1) | V_TX_NPORTS(1));
230}
231
232/*
233 * Note that T1B requires at least 2 ports for IXF1010 due to a HW bug.
234 */
235static void espi_setup_for_ixf1010(adapter_t *adapter, int nports)
236{
237 t1_write_reg_4(adapter, A_ESPI_CALENDAR_LENGTH, 1);
238 if (nports == 4) {
239 if (is_T2(adapter)) {
240 t1_write_reg_4(adapter, A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK,
241 0xf00);
242 t1_write_reg_4(adapter, A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK,
243 0x3c0);
244 } else {
245 t1_write_reg_4(adapter, A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK,
246 0x7ff);
247 t1_write_reg_4(adapter, A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK,
248 0x1ff);
249 }
250 } else {
251 t1_write_reg_4(adapter, A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK,
252 0x1fff);
253 t1_write_reg_4(adapter, A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK,
254 0x7ff);
255 }
256 t1_write_reg_4(adapter, A_PORT_CONFIG,
257 V_RX_NPORTS(nports) | V_TX_NPORTS(nports));
258} 219}
259 220
260/* T2 Init part -- */ 221/* T2 Init part -- */
@@ -263,43 +224,42 @@ static void espi_setup_for_ixf1010(adapter_t *adapter, int nports)
263/* 3. Init TriCN Hard Macro */ 224/* 3. Init TriCN Hard Macro */
264int t1_espi_init(struct peespi *espi, int mac_type, int nports) 225int t1_espi_init(struct peespi *espi, int mac_type, int nports)
265{ 226{
227 u32 cnt;
228
266 u32 status_enable_extra = 0; 229 u32 status_enable_extra = 0;
267 adapter_t *adapter = espi->adapter; 230 adapter_t *adapter = espi->adapter;
268 u32 cnt;
269 u32 status, burstval = 0x800100; 231 u32 status, burstval = 0x800100;
270 232
271 /* Disable ESPI training. MACs that can handle it enable it below. */ 233 /* Disable ESPI training. MACs that can handle it enable it below. */
272 t1_write_reg_4(adapter, A_ESPI_TRAIN, 0); 234 writel(0, adapter->regs + A_ESPI_TRAIN);
273 235
274 if (is_T2(adapter)) { 236 if (is_T2(adapter)) {
275 t1_write_reg_4(adapter, A_ESPI_MISC_CONTROL, 237 writel(V_OUT_OF_SYNC_COUNT(4) |
276 V_OUT_OF_SYNC_COUNT(4) | 238 V_DIP2_PARITY_ERR_THRES(3) |
277 V_DIP2_PARITY_ERR_THRES(3) | V_DIP4_THRES(1)); 239 V_DIP4_THRES(1), adapter->regs + A_ESPI_MISC_CONTROL);
278 if (nports == 4) { 240 if (nports == 4) {
279 /* T204: maxburst1 = 0x40, maxburst2 = 0x20 */ 241 /* T204: maxburst1 = 0x40, maxburst2 = 0x20 */
280 burstval = 0x200040; 242 burstval = 0x200040;
281 } 243 }
282 } 244 }
283 t1_write_reg_4(adapter, A_ESPI_MAXBURST1_MAXBURST2, burstval); 245 writel(burstval, adapter->regs + A_ESPI_MAXBURST1_MAXBURST2);
284 246
285 if (mac_type == CHBT_MAC_PM3393) 247 switch (mac_type) {
248 case CHBT_MAC_PM3393:
286 espi_setup_for_pm3393(adapter); 249 espi_setup_for_pm3393(adapter);
287 else if (mac_type == CHBT_MAC_VSC7321) 250 break;
288 espi_setup_for_vsc7321(adapter); 251 default:
289 else if (mac_type == CHBT_MAC_IXF1010) {
290 status_enable_extra = F_INTEL1010MODE;
291 espi_setup_for_ixf1010(adapter, nports);
292 } else
293 return -1; 252 return -1;
253 }
294 254
295 /* 255 /*
296 * Make sure any pending interrupts from the SPI are 256 * Make sure any pending interrupts from the SPI are
297 * Cleared before enabling the interrupt. 257 * Cleared before enabling the interrupt.
298 */ 258 */
299 t1_write_reg_4(espi->adapter, A_ESPI_INTR_ENABLE, ESPI_INTR_MASK); 259 writel(ESPI_INTR_MASK, espi->adapter->regs + A_ESPI_INTR_ENABLE);
300 status = t1_read_reg_4(espi->adapter, A_ESPI_INTR_STATUS); 260 status = readl(espi->adapter->regs + A_ESPI_INTR_STATUS);
301 if (status & F_DIP2PARITYERR) { 261 if (status & F_DIP2PARITYERR) {
302 cnt = t1_read_reg_4(espi->adapter, A_ESPI_DIP2_ERR_COUNT); 262 cnt = readl(espi->adapter->regs + A_ESPI_DIP2_ERR_COUNT);
303 } 263 }
304 264
305 /* 265 /*
@@ -308,10 +268,10 @@ int t1_espi_init(struct peespi *espi, int mac_type, int nports)
308 */ 268 */
309 if (status && t1_is_T1B(espi->adapter)) 269 if (status && t1_is_T1B(espi->adapter))
310 status = 1; 270 status = 1;
311 t1_write_reg_4(espi->adapter, A_ESPI_INTR_STATUS, status); 271 writel(status, espi->adapter->regs + A_ESPI_INTR_STATUS);
312 272
313 t1_write_reg_4(adapter, A_ESPI_FIFO_STATUS_ENABLE, 273 writel(status_enable_extra | F_RXSTATUSENABLE,
314 status_enable_extra | F_RXSTATUSENABLE); 274 adapter->regs + A_ESPI_FIFO_STATUS_ENABLE);
315 275
316 if (is_T2(adapter)) { 276 if (is_T2(adapter)) {
317 tricn_init(adapter); 277 tricn_init(adapter);
@@ -319,10 +279,10 @@ int t1_espi_init(struct peespi *espi, int mac_type, int nports)
319 * Always position the control at the 1st port egress IN 279 * Always position the control at the 1st port egress IN
320 * (sop,eop) counter to reduce PIOs for T/N210 workaround. 280 * (sop,eop) counter to reduce PIOs for T/N210 workaround.
321 */ 281 */
322 espi->misc_ctrl = (t1_read_reg_4(adapter, A_ESPI_MISC_CONTROL) 282 espi->misc_ctrl = (readl(adapter->regs + A_ESPI_MISC_CONTROL)
323 & ~MON_MASK) | (F_MONITORED_DIRECTION 283 & ~MON_MASK) | (F_MONITORED_DIRECTION
324 | F_MONITORED_INTERFACE); 284 | F_MONITORED_INTERFACE);
325 t1_write_reg_4(adapter, A_ESPI_MISC_CONTROL, espi->misc_ctrl); 285 writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL);
326 spin_lock_init(&espi->lock); 286 spin_lock_init(&espi->lock);
327 } 287 }
328 288
@@ -354,15 +314,16 @@ void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val)
354 spin_lock(&espi->lock); 314 spin_lock(&espi->lock);
355 espi->misc_ctrl = (val & ~MON_MASK) | 315 espi->misc_ctrl = (val & ~MON_MASK) |
356 (espi->misc_ctrl & MON_MASK); 316 (espi->misc_ctrl & MON_MASK);
357 t1_write_reg_4(adapter, A_ESPI_MISC_CONTROL, espi->misc_ctrl); 317 writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL);
358 spin_unlock(&espi->lock); 318 spin_unlock(&espi->lock);
359} 319}
360 320
361u32 t1_espi_get_mon(adapter_t *adapter, u32 addr, u8 wait) 321u32 t1_espi_get_mon(adapter_t *adapter, u32 addr, u8 wait)
362{ 322{
363 struct peespi *espi = adapter->espi;
364 u32 sel; 323 u32 sel;
365 324
325 struct peespi *espi = adapter->espi;
326
366 if (!is_T2(adapter)) 327 if (!is_T2(adapter))
367 return 0; 328 return 0;
368 sel = V_MONITORED_PORT_NUM((addr & 0x3c) >> 2); 329 sel = V_MONITORED_PORT_NUM((addr & 0x3c) >> 2);
@@ -373,14 +334,13 @@ u32 t1_espi_get_mon(adapter_t *adapter, u32 addr, u8 wait)
373 else 334 else
374 spin_lock(&espi->lock); 335 spin_lock(&espi->lock);
375 if ((sel != (espi->misc_ctrl & MON_MASK))) { 336 if ((sel != (espi->misc_ctrl & MON_MASK))) {
376 t1_write_reg_4(adapter, A_ESPI_MISC_CONTROL, 337 writel(((espi->misc_ctrl & ~MON_MASK) | sel),
377 ((espi->misc_ctrl & ~MON_MASK) | sel)); 338 adapter->regs + A_ESPI_MISC_CONTROL);
378 sel = t1_read_reg_4(adapter, A_ESPI_SCH_TOKEN3); 339 sel = readl(adapter->regs + A_ESPI_SCH_TOKEN3);
379 t1_write_reg_4(adapter, A_ESPI_MISC_CONTROL, 340 writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL);
380 espi->misc_ctrl);
381 } 341 }
382 else 342 else
383 sel = t1_read_reg_4(adapter, A_ESPI_SCH_TOKEN3); 343 sel = readl(adapter->regs + A_ESPI_SCH_TOKEN3);
384 spin_unlock(&espi->lock); 344 spin_unlock(&espi->lock);
385 return sel; 345 return sel;
386} 346}