aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/chelsio
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2007-02-20 18:58:00 -0500
committerJeff Garzik <jeff@garzik.org>2007-04-28 11:00:55 -0400
commit4d2b8f66b89dd74d76d2b40cb45dffaa5567bb8f (patch)
treef544fe9e68b473493bb63b5df7d20113d0d86338 /drivers/net/chelsio
parent0ae08183d89fa48c0e4be019f45b93ad638c3890 (diff)
chelsio: remove unused code for 1G boards
Some code for Chelsio 1G boards was put in the driver based on the vendor version (minus TOE). Well some of those board versions are only supported with TOE on the vendor driver, so additional dead code was added. Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/chelsio')
-rw-r--r--drivers/net/chelsio/Makefile4
-rw-r--r--drivers/net/chelsio/ixf1010.c505
-rw-r--r--drivers/net/chelsio/vsc8244.c367
-rw-r--r--drivers/net/chelsio/vsc8244_reg.h172
4 files changed, 1 insertions, 1047 deletions
diff --git a/drivers/net/chelsio/Makefile b/drivers/net/chelsio/Makefile
index 382d23f810ab..743ad8b41b5e 100644
--- a/drivers/net/chelsio/Makefile
+++ b/drivers/net/chelsio/Makefile
@@ -4,8 +4,6 @@
4 4
5obj-$(CONFIG_CHELSIO_T1) += cxgb.o 5obj-$(CONFIG_CHELSIO_T1) += cxgb.o
6 6
7cxgb-$(CONFIG_CHELSIO_T1_1G) += ixf1010.o mac.o mv88e1xxx.o vsc7326.o vsc8244.o 7cxgb-$(CONFIG_CHELSIO_T1_1G) += mac.o mv88e1xxx.o vsc7326.o
8cxgb-objs := cxgb2.o espi.o tp.o pm3393.o sge.o subr.o \ 8cxgb-objs := cxgb2.o espi.o tp.o pm3393.o sge.o subr.o \
9 mv88x201x.o my3126.o $(cxgb-y) 9 mv88x201x.o my3126.o $(cxgb-y)
10
11
diff --git a/drivers/net/chelsio/ixf1010.c b/drivers/net/chelsio/ixf1010.c
deleted file mode 100644
index 10b2a9a19006..000000000000
--- a/drivers/net/chelsio/ixf1010.c
+++ /dev/null
@@ -1,505 +0,0 @@
1/* $Date: 2005/11/12 02:13:49 $ $RCSfile: ixf1010.c,v $ $Revision: 1.36 $ */
2#include "gmac.h"
3#include "elmer0.h"
4
5/* Update fast changing statistics every 15 seconds */
6#define STATS_TICK_SECS 15
7/* 30 minutes for full statistics update */
8#define MAJOR_UPDATE_TICKS (1800 / STATS_TICK_SECS)
9
10/*
11 * The IXF1010 can handle frames up to 16383 bytes but it's optimized for
12 * frames up to 9831 (0x2667) bytes, so we limit jumbo frame size to this.
13 * This length includes ethernet header and FCS.
14 */
15#define MAX_FRAME_SIZE 0x2667
16
17/* MAC registers */
18enum {
19 /* Per-port registers */
20 REG_MACADDR_LOW = 0,
21 REG_MACADDR_HIGH = 0x4,
22 REG_FDFC_TYPE = 0xC,
23 REG_FC_TX_TIMER_VALUE = 0x1c,
24 REG_IPG_RX_TIME1 = 0x28,
25 REG_IPG_RX_TIME2 = 0x2c,
26 REG_IPG_TX_TIME = 0x30,
27 REG_PAUSE_THRES = 0x38,
28 REG_MAX_FRAME_SIZE = 0x3c,
29 REG_RGMII_SPEED = 0x40,
30 REG_FC_ENABLE = 0x48,
31 REG_DISCARD_CTRL_FRAMES = 0x54,
32 REG_DIVERSE_CONFIG = 0x60,
33 REG_RX_FILTER = 0x64,
34 REG_MC_ADDR_LOW = 0x68,
35 REG_MC_ADDR_HIGH = 0x6c,
36
37 REG_RX_OCTETS_OK = 0x80,
38 REG_RX_OCTETS_BAD = 0x84,
39 REG_RX_UC_PKTS = 0x88,
40 REG_RX_MC_PKTS = 0x8c,
41 REG_RX_BC_PKTS = 0x90,
42 REG_RX_FCS_ERR = 0xb0,
43 REG_RX_TAGGED = 0xb4,
44 REG_RX_DATA_ERR = 0xb8,
45 REG_RX_ALIGN_ERR = 0xbc,
46 REG_RX_LONG_ERR = 0xc0,
47 REG_RX_JABBER_ERR = 0xc4,
48 REG_RX_PAUSE_FRAMES = 0xc8,
49 REG_RX_UNKNOWN_CTRL_FRAMES = 0xcc,
50 REG_RX_VERY_LONG_ERR = 0xd0,
51 REG_RX_RUNT_ERR = 0xd4,
52 REG_RX_SHORT_ERR = 0xd8,
53 REG_RX_SYMBOL_ERR = 0xe4,
54
55 REG_TX_OCTETS_OK = 0x100,
56 REG_TX_OCTETS_BAD = 0x104,
57 REG_TX_UC_PKTS = 0x108,
58 REG_TX_MC_PKTS = 0x10c,
59 REG_TX_BC_PKTS = 0x110,
60 REG_TX_EXCESSIVE_LEN_DROP = 0x14c,
61 REG_TX_UNDERRUN = 0x150,
62 REG_TX_TAGGED = 0x154,
63 REG_TX_PAUSE_FRAMES = 0x15C,
64
65 /* Global registers */
66 REG_PORT_ENABLE = 0x1400,
67
68 REG_JTAG_ID = 0x1430,
69
70 RX_FIFO_HIGH_WATERMARK_BASE = 0x1600,
71 RX_FIFO_LOW_WATERMARK_BASE = 0x1628,
72 RX_FIFO_FRAMES_REMOVED_BASE = 0x1650,
73
74 REG_RX_ERR_DROP = 0x167c,
75 REG_RX_FIFO_OVERFLOW_EVENT = 0x1680,
76
77 TX_FIFO_HIGH_WATERMARK_BASE = 0x1800,
78 TX_FIFO_LOW_WATERMARK_BASE = 0x1828,
79 TX_FIFO_XFER_THRES_BASE = 0x1850,
80
81 REG_TX_FIFO_OVERFLOW_EVENT = 0x1878,
82 REG_TX_FIFO_OOS_EVENT = 0x1884,
83
84 TX_FIFO_FRAMES_REMOVED_BASE = 0x1888,
85
86 REG_SPI_RX_BURST = 0x1c00,
87 REG_SPI_RX_TRAINING = 0x1c04,
88 REG_SPI_RX_CALENDAR = 0x1c08,
89 REG_SPI_TX_SYNC = 0x1c0c
90};
91
92enum { /* RMON registers */
93 REG_RxOctetsTotalOK = 0x80,
94 REG_RxOctetsBad = 0x84,
95 REG_RxUCPkts = 0x88,
96 REG_RxMCPkts = 0x8c,
97 REG_RxBCPkts = 0x90,
98 REG_RxJumboPkts = 0xac,
99 REG_RxFCSErrors = 0xb0,
100 REG_RxDataErrors = 0xb8,
101 REG_RxAlignErrors = 0xbc,
102 REG_RxLongErrors = 0xc0,
103 REG_RxJabberErrors = 0xc4,
104 REG_RxPauseMacControlCounter = 0xc8,
105 REG_RxVeryLongErrors = 0xd0,
106 REG_RxRuntErrors = 0xd4,
107 REG_RxShortErrors = 0xd8,
108 REG_RxSequenceErrors = 0xe0,
109 REG_RxSymbolErrors = 0xe4,
110
111 REG_TxOctetsTotalOK = 0x100,
112 REG_TxOctetsBad = 0x104,
113 REG_TxUCPkts = 0x108,
114 REG_TxMCPkts = 0x10c,
115 REG_TxBCPkts = 0x110,
116 REG_TxJumboPkts = 0x12C,
117 REG_TxTotalCollisions = 0x134,
118 REG_TxExcessiveLengthDrop = 0x14c,
119 REG_TxUnderrun = 0x150,
120 REG_TxCRCErrors = 0x158,
121 REG_TxPauseFrames = 0x15c
122};
123
124enum {
125 DIVERSE_CONFIG_PAD_ENABLE = 0x80,
126 DIVERSE_CONFIG_CRC_ADD = 0x40
127};
128
129#define MACREG_BASE 0
130#define MACREG(mac, mac_reg) ((mac)->instance->mac_base + (mac_reg))
131
132struct _cmac_instance {
133 u32 mac_base;
134 u32 index;
135 u32 version;
136 u32 ticks;
137};
138
139static void disable_port(struct cmac *mac)
140{
141 u32 val;
142
143 t1_tpi_read(mac->adapter, REG_PORT_ENABLE, &val);
144 val &= ~(1 << mac->instance->index);
145 t1_tpi_write(mac->adapter, REG_PORT_ENABLE, val);
146}
147
148/*
149 * Read the current values of the RMON counters and add them to the cumulative
150 * port statistics. The HW RMON counters are cleared by this operation.
151 */
152static void port_stats_update(struct cmac *mac)
153{
154 static struct {
155 unsigned int reg;
156 unsigned int offset;
157 } hw_stats[] = {
158
159#define HW_STAT(name, stat_name) \
160 { REG_##name, \
161 (&((struct cmac_statistics *)NULL)->stat_name) - (u64 *)NULL }
162
163 /* Rx stats */
164 HW_STAT(RxOctetsTotalOK, RxOctetsOK),
165 HW_STAT(RxOctetsBad, RxOctetsBad),
166 HW_STAT(RxUCPkts, RxUnicastFramesOK),
167 HW_STAT(RxMCPkts, RxMulticastFramesOK),
168 HW_STAT(RxBCPkts, RxBroadcastFramesOK),
169 HW_STAT(RxJumboPkts, RxJumboFramesOK),
170 HW_STAT(RxFCSErrors, RxFCSErrors),
171 HW_STAT(RxAlignErrors, RxAlignErrors),
172 HW_STAT(RxLongErrors, RxFrameTooLongErrors),
173 HW_STAT(RxVeryLongErrors, RxFrameTooLongErrors),
174 HW_STAT(RxPauseMacControlCounter, RxPauseFrames),
175 HW_STAT(RxDataErrors, RxDataErrors),
176 HW_STAT(RxJabberErrors, RxJabberErrors),
177 HW_STAT(RxRuntErrors, RxRuntErrors),
178 HW_STAT(RxShortErrors, RxRuntErrors),
179 HW_STAT(RxSequenceErrors, RxSequenceErrors),
180 HW_STAT(RxSymbolErrors, RxSymbolErrors),
181
182 /* Tx stats (skip collision stats as we are full-duplex only) */
183 HW_STAT(TxOctetsTotalOK, TxOctetsOK),
184 HW_STAT(TxOctetsBad, TxOctetsBad),
185 HW_STAT(TxUCPkts, TxUnicastFramesOK),
186 HW_STAT(TxMCPkts, TxMulticastFramesOK),
187 HW_STAT(TxBCPkts, TxBroadcastFramesOK),
188 HW_STAT(TxJumboPkts, TxJumboFramesOK),
189 HW_STAT(TxPauseFrames, TxPauseFrames),
190 HW_STAT(TxExcessiveLengthDrop, TxLengthErrors),
191 HW_STAT(TxUnderrun, TxUnderrun),
192 HW_STAT(TxCRCErrors, TxFCSErrors)
193 }, *p = hw_stats;
194 u64 *stats = (u64 *) &mac->stats;
195 unsigned int i;
196
197 for (i = 0; i < ARRAY_SIZE(hw_stats); i++) {
198 u32 val;
199
200 t1_tpi_read(mac->adapter, MACREG(mac, p->reg), &val);
201 stats[p->offset] += val;
202 }
203}
204
205/* No-op interrupt operation as this MAC does not support interrupts */
206static int mac_intr_op(struct cmac *mac)
207{
208 return 0;
209}
210
211/* Expect MAC address to be in network byte order. */
212static int mac_set_address(struct cmac *mac, u8 addr[6])
213{
214 u32 addr_lo, addr_hi;
215
216 addr_lo = addr[2];
217 addr_lo = (addr_lo << 8) | addr[3];
218 addr_lo = (addr_lo << 8) | addr[4];
219 addr_lo = (addr_lo << 8) | addr[5];
220
221 addr_hi = addr[0];
222 addr_hi = (addr_hi << 8) | addr[1];
223
224 t1_tpi_write(mac->adapter, MACREG(mac, REG_MACADDR_LOW), addr_lo);
225 t1_tpi_write(mac->adapter, MACREG(mac, REG_MACADDR_HIGH), addr_hi);
226 return 0;
227}
228
229static int mac_get_address(struct cmac *mac, u8 addr[6])
230{
231 u32 addr_lo, addr_hi;
232
233 t1_tpi_read(mac->adapter, MACREG(mac, REG_MACADDR_LOW), &addr_lo);
234 t1_tpi_read(mac->adapter, MACREG(mac, REG_MACADDR_HIGH), &addr_hi);
235
236 addr[0] = (u8) (addr_hi >> 8);
237 addr[1] = (u8) addr_hi;
238 addr[2] = (u8) (addr_lo >> 24);
239 addr[3] = (u8) (addr_lo >> 16);
240 addr[4] = (u8) (addr_lo >> 8);
241 addr[5] = (u8) addr_lo;
242 return 0;
243}
244
245/* This is intended to reset a port, not the whole MAC */
246static int mac_reset(struct cmac *mac)
247{
248 return 0;
249}
250
251static int mac_set_rx_mode(struct cmac *mac, struct t1_rx_mode *rm)
252{
253 u32 val, new_mode;
254 adapter_t *adapter = mac->adapter;
255 u32 addr_lo, addr_hi;
256 u8 *addr;
257
258 t1_tpi_read(adapter, MACREG(mac, REG_RX_FILTER), &val);
259 new_mode = val & ~7;
260 if (!t1_rx_mode_promisc(rm) && mac->instance->version > 0)
261 new_mode |= 1; /* only set if version > 0 due to erratum */
262 if (!t1_rx_mode_promisc(rm) && !t1_rx_mode_allmulti(rm)
263 && t1_rx_mode_mc_cnt(rm) <= 1)
264 new_mode |= 2;
265 if (new_mode != val)
266 t1_tpi_write(adapter, MACREG(mac, REG_RX_FILTER), new_mode);
267 switch (t1_rx_mode_mc_cnt(rm)) {
268 case 0:
269 t1_tpi_write(adapter, MACREG(mac, REG_MC_ADDR_LOW), 0);
270 t1_tpi_write(adapter, MACREG(mac, REG_MC_ADDR_HIGH), 0);
271 break;
272 case 1:
273 addr = t1_get_next_mcaddr(rm);
274 addr_lo = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) |
275 addr[5];
276 addr_hi = (addr[0] << 8) | addr[1];
277 t1_tpi_write(adapter, MACREG(mac, REG_MC_ADDR_LOW), addr_lo);
278 t1_tpi_write(adapter, MACREG(mac, REG_MC_ADDR_HIGH), addr_hi);
279 break;
280 default:
281 break;
282 }
283 return 0;
284}
285
286static int mac_set_mtu(struct cmac *mac, int mtu)
287{
288 /* MAX_FRAME_SIZE inludes header + FCS, mtu doesn't */
289 if (mtu > (MAX_FRAME_SIZE - 14 - 4))
290 return -EINVAL;
291 t1_tpi_write(mac->adapter, MACREG(mac, REG_MAX_FRAME_SIZE),
292 mtu + 14 + 4);
293 return 0;
294}
295
296static int mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex,
297 int fc)
298{
299 u32 val;
300
301 if (speed >= 0 && speed != SPEED_100 && speed != SPEED_1000)
302 return -1;
303 if (duplex >= 0 && duplex != DUPLEX_FULL)
304 return -1;
305
306 if (speed >= 0) {
307 val = speed == SPEED_100 ? 1 : 2;
308 t1_tpi_write(mac->adapter, MACREG(mac, REG_RGMII_SPEED), val);
309 }
310
311 t1_tpi_read(mac->adapter, MACREG(mac, REG_FC_ENABLE), &val);
312 val &= ~3;
313 if (fc & PAUSE_RX)
314 val |= 1;
315 if (fc & PAUSE_TX)
316 val |= 2;
317 t1_tpi_write(mac->adapter, MACREG(mac, REG_FC_ENABLE), val);
318 return 0;
319}
320
321static int mac_get_speed_duplex_fc(struct cmac *mac, int *speed, int *duplex,
322 int *fc)
323{
324 u32 val;
325
326 if (duplex)
327 *duplex = DUPLEX_FULL;
328 if (speed) {
329 t1_tpi_read(mac->adapter, MACREG(mac, REG_RGMII_SPEED),
330 &val);
331 *speed = (val & 2) ? SPEED_1000 : SPEED_100;
332 }
333 if (fc) {
334 t1_tpi_read(mac->adapter, MACREG(mac, REG_FC_ENABLE), &val);
335 *fc = 0;
336 if (val & 1)
337 *fc |= PAUSE_RX;
338 if (val & 2)
339 *fc |= PAUSE_TX;
340 }
341 return 0;
342}
343
344static void enable_port(struct cmac *mac)
345{
346 u32 val;
347 u32 index = mac->instance->index;
348 adapter_t *adapter = mac->adapter;
349
350 t1_tpi_read(adapter, MACREG(mac, REG_DIVERSE_CONFIG), &val);
351 val |= DIVERSE_CONFIG_CRC_ADD | DIVERSE_CONFIG_PAD_ENABLE;
352 t1_tpi_write(adapter, MACREG(mac, REG_DIVERSE_CONFIG), val);
353 if (mac->instance->version > 0)
354 t1_tpi_write(adapter, MACREG(mac, REG_RX_FILTER), 3);
355 else /* Don't enable unicast address filtering due to IXF1010 bug */
356 t1_tpi_write(adapter, MACREG(mac, REG_RX_FILTER), 2);
357
358 t1_tpi_read(adapter, REG_RX_ERR_DROP, &val);
359 val |= (1 << index);
360 t1_tpi_write(adapter, REG_RX_ERR_DROP, val);
361
362 /*
363 * Clear the port RMON registers by adding their current values to the
364 * cumulatice port stats and then clearing the stats. Really.
365 */
366 port_stats_update(mac);
367 memset(&mac->stats, 0, sizeof(struct cmac_statistics));
368 mac->instance->ticks = 0;
369
370 t1_tpi_read(adapter, REG_PORT_ENABLE, &val);
371 val |= (1 << index);
372 t1_tpi_write(adapter, REG_PORT_ENABLE, val);
373
374 index <<= 2;
375 if (is_T2(adapter)) {
376 /* T204: set the Fifo water level & threshold */
377 t1_tpi_write(adapter, RX_FIFO_HIGH_WATERMARK_BASE + index, 0x740);
378 t1_tpi_write(adapter, RX_FIFO_LOW_WATERMARK_BASE + index, 0x730);
379 t1_tpi_write(adapter, TX_FIFO_HIGH_WATERMARK_BASE + index, 0x600);
380 t1_tpi_write(adapter, TX_FIFO_LOW_WATERMARK_BASE + index, 0x1d0);
381 t1_tpi_write(adapter, TX_FIFO_XFER_THRES_BASE + index, 0x1100);
382 } else {
383 /*
384 * Set the TX Fifo Threshold to 0x400 instead of 0x100 to work around
385 * Underrun problem. Intel has blessed this solution.
386 */
387 t1_tpi_write(adapter, TX_FIFO_XFER_THRES_BASE + index, 0x400);
388 }
389}
390
391/* IXF1010 ports do not have separate enables for TX and RX */
392static int mac_enable(struct cmac *mac, int which)
393{
394 if (which & (MAC_DIRECTION_RX | MAC_DIRECTION_TX))
395 enable_port(mac);
396 return 0;
397}
398
399static int mac_disable(struct cmac *mac, int which)
400{
401 if (which & (MAC_DIRECTION_RX | MAC_DIRECTION_TX))
402 disable_port(mac);
403 return 0;
404}
405
406#define RMON_UPDATE(mac, name, stat_name) \
407 t1_tpi_read((mac)->adapter, MACREG(mac, REG_##name), &val); \
408 (mac)->stats.stat_name += val;
409
410/*
411 * This function is called periodically to accumulate the current values of the
412 * RMON counters into the port statistics. Since the counters are only 32 bits
413 * some of them can overflow in less than a minute at GigE speeds, so this
414 * function should be called every 30 seconds or so.
415 *
416 * To cut down on reading costs we update only the octet counters at each tick
417 * and do a full update at major ticks, which can be every 30 minutes or more.
418 */
419static const struct cmac_statistics *mac_update_statistics(struct cmac *mac,
420 int flag)
421{
422 if (flag == MAC_STATS_UPDATE_FULL ||
423 MAJOR_UPDATE_TICKS <= mac->instance->ticks) {
424 port_stats_update(mac);
425 mac->instance->ticks = 0;
426 } else {
427 u32 val;
428
429 RMON_UPDATE(mac, RxOctetsTotalOK, RxOctetsOK);
430 RMON_UPDATE(mac, TxOctetsTotalOK, TxOctetsOK);
431 mac->instance->ticks++;
432 }
433 return &mac->stats;
434}
435
436static void mac_destroy(struct cmac *mac)
437{
438 kfree(mac);
439}
440
441static struct cmac_ops ixf1010_ops = {
442 .destroy = mac_destroy,
443 .reset = mac_reset,
444 .interrupt_enable = mac_intr_op,
445 .interrupt_disable = mac_intr_op,
446 .interrupt_clear = mac_intr_op,
447 .enable = mac_enable,
448 .disable = mac_disable,
449 .set_mtu = mac_set_mtu,
450 .set_rx_mode = mac_set_rx_mode,
451 .set_speed_duplex_fc = mac_set_speed_duplex_fc,
452 .get_speed_duplex_fc = mac_get_speed_duplex_fc,
453 .statistics_update = mac_update_statistics,
454 .macaddress_get = mac_get_address,
455 .macaddress_set = mac_set_address,
456};
457
458static int ixf1010_mac_reset(adapter_t *adapter)
459{
460 u32 val;
461
462 t1_tpi_read(adapter, A_ELMER0_GPO, &val);
463 if ((val & 1) != 0) {
464 val &= ~1;
465 t1_tpi_write(adapter, A_ELMER0_GPO, val);
466 udelay(2);
467 }
468 val |= 1;
469 t1_tpi_write(adapter, A_ELMER0_GPO, val);
470 udelay(2);
471
472 t1_tpi_write(adapter, REG_PORT_ENABLE, 0);
473 return 0;
474}
475
476static struct cmac *ixf1010_mac_create(adapter_t *adapter, int index)
477{
478 struct cmac *mac;
479 u32 val;
480
481 if (index > 9)
482 return NULL;
483
484 mac = kzalloc(sizeof(*mac) + sizeof(cmac_instance), GFP_KERNEL);
485 if (!mac)
486 return NULL;
487
488 mac->ops = &ixf1010_ops;
489 mac->instance = (cmac_instance *)(mac + 1);
490
491 mac->instance->mac_base = MACREG_BASE + (index * 0x200);
492 mac->instance->index = index;
493 mac->adapter = adapter;
494 mac->instance->ticks = 0;
495
496 t1_tpi_read(adapter, REG_JTAG_ID, &val);
497 mac->instance->version = val >> 28;
498 return mac;
499}
500
501struct gmac t1_ixf1010_ops = {
502 STATS_TICK_SECS,
503 ixf1010_mac_create,
504 ixf1010_mac_reset
505};
diff --git a/drivers/net/chelsio/vsc8244.c b/drivers/net/chelsio/vsc8244.c
deleted file mode 100644
index 251d4859c91d..000000000000
--- a/drivers/net/chelsio/vsc8244.c
+++ /dev/null
@@ -1,367 +0,0 @@
1/*
2 * This file is part of the Chelsio T2 Ethernet driver.
3 *
4 * Copyright (C) 2005 Chelsio Communications. All rights reserved.
5 *
6 * This program is distributed in the hope that it will be useful, but WITHOUT
7 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8 * FITNESS FOR A PARTICULAR PURPOSE. See the LICENSE file included in this
9 * release for licensing terms and conditions.
10 */
11
12#include "common.h"
13#include "cphy.h"
14#include "elmer0.h"
15
16#ifndef ADVERTISE_PAUSE_CAP
17# define ADVERTISE_PAUSE_CAP 0x400
18#endif
19#ifndef ADVERTISE_PAUSE_ASYM
20# define ADVERTISE_PAUSE_ASYM 0x800
21#endif
22
23/* Gigabit MII registers */
24#ifndef MII_CTRL1000
25# define MII_CTRL1000 9
26#endif
27
28#ifndef ADVERTISE_1000FULL
29# define ADVERTISE_1000FULL 0x200
30# define ADVERTISE_1000HALF 0x100
31#endif
32
33/* VSC8244 PHY specific registers. */
34enum {
35 VSC8244_INTR_ENABLE = 25,
36 VSC8244_INTR_STATUS = 26,
37 VSC8244_AUX_CTRL_STAT = 28,
38};
39
40enum {
41 VSC_INTR_RX_ERR = 1 << 0,
42 VSC_INTR_MS_ERR = 1 << 1, /* master/slave resolution error */
43 VSC_INTR_CABLE = 1 << 2, /* cable impairment */
44 VSC_INTR_FALSE_CARR = 1 << 3, /* false carrier */
45 VSC_INTR_MEDIA_CHG = 1 << 4, /* AMS media change */
46 VSC_INTR_RX_FIFO = 1 << 5, /* Rx FIFO over/underflow */
47 VSC_INTR_TX_FIFO = 1 << 6, /* Tx FIFO over/underflow */
48 VSC_INTR_DESCRAMBL = 1 << 7, /* descrambler lock-lost */
49 VSC_INTR_SYMBOL_ERR = 1 << 8, /* symbol error */
50 VSC_INTR_NEG_DONE = 1 << 10, /* autoneg done */
51 VSC_INTR_NEG_ERR = 1 << 11, /* autoneg error */
52 VSC_INTR_LINK_CHG = 1 << 13, /* link change */
53 VSC_INTR_ENABLE = 1 << 15, /* interrupt enable */
54};
55
56#define CFG_CHG_INTR_MASK (VSC_INTR_LINK_CHG | VSC_INTR_NEG_ERR | \
57 VSC_INTR_NEG_DONE)
58#define INTR_MASK (CFG_CHG_INTR_MASK | VSC_INTR_TX_FIFO | VSC_INTR_RX_FIFO | \
59 VSC_INTR_ENABLE)
60
61/* PHY specific auxiliary control & status register fields */
62#define S_ACSR_ACTIPHY_TMR 0
63#define M_ACSR_ACTIPHY_TMR 0x3
64#define V_ACSR_ACTIPHY_TMR(x) ((x) << S_ACSR_ACTIPHY_TMR)
65
66#define S_ACSR_SPEED 3
67#define M_ACSR_SPEED 0x3
68#define G_ACSR_SPEED(x) (((x) >> S_ACSR_SPEED) & M_ACSR_SPEED)
69
70#define S_ACSR_DUPLEX 5
71#define F_ACSR_DUPLEX (1 << S_ACSR_DUPLEX)
72
73#define S_ACSR_ACTIPHY 6
74#define F_ACSR_ACTIPHY (1 << S_ACSR_ACTIPHY)
75
76/*
77 * Reset the PHY. This PHY completes reset immediately so we never wait.
78 */
79static int vsc8244_reset(struct cphy *cphy, int wait)
80{
81 int err;
82 unsigned int ctl;
83
84 err = simple_mdio_read(cphy, MII_BMCR, &ctl);
85 if (err)
86 return err;
87
88 ctl &= ~BMCR_PDOWN;
89 ctl |= BMCR_RESET;
90 return simple_mdio_write(cphy, MII_BMCR, ctl);
91}
92
93static int vsc8244_intr_enable(struct cphy *cphy)
94{
95 simple_mdio_write(cphy, VSC8244_INTR_ENABLE, INTR_MASK);
96
97 /* Enable interrupts through Elmer */
98 if (t1_is_asic(cphy->adapter)) {
99 u32 elmer;
100
101 t1_tpi_read(cphy->adapter, A_ELMER0_INT_ENABLE, &elmer);
102 elmer |= ELMER0_GP_BIT1;
103 if (is_T2(cphy->adapter))
104 elmer |= ELMER0_GP_BIT2|ELMER0_GP_BIT3|ELMER0_GP_BIT4;
105 t1_tpi_write(cphy->adapter, A_ELMER0_INT_ENABLE, elmer);
106 }
107
108 return 0;
109}
110
111static int vsc8244_intr_disable(struct cphy *cphy)
112{
113 simple_mdio_write(cphy, VSC8244_INTR_ENABLE, 0);
114
115 if (t1_is_asic(cphy->adapter)) {
116 u32 elmer;
117
118 t1_tpi_read(cphy->adapter, A_ELMER0_INT_ENABLE, &elmer);
119 elmer &= ~ELMER0_GP_BIT1;
120 if (is_T2(cphy->adapter))
121 elmer &= ~(ELMER0_GP_BIT2|ELMER0_GP_BIT3|ELMER0_GP_BIT4);
122 t1_tpi_write(cphy->adapter, A_ELMER0_INT_ENABLE, elmer);
123 }
124
125 return 0;
126}
127
128static int vsc8244_intr_clear(struct cphy *cphy)
129{
130 u32 val;
131 u32 elmer;
132
133 /* Clear PHY interrupts by reading the register. */
134 simple_mdio_read(cphy, VSC8244_INTR_ENABLE, &val);
135
136 if (t1_is_asic(cphy->adapter)) {
137 t1_tpi_read(cphy->adapter, A_ELMER0_INT_CAUSE, &elmer);
138 elmer |= ELMER0_GP_BIT1;
139 if (is_T2(cphy->adapter))
140 elmer |= ELMER0_GP_BIT2|ELMER0_GP_BIT3|ELMER0_GP_BIT4;
141 t1_tpi_write(cphy->adapter, A_ELMER0_INT_CAUSE, elmer);
142 }
143
144 return 0;
145}
146
147/*
148 * Force the PHY speed and duplex. This also disables auto-negotiation, except
149 * for 1Gb/s, where auto-negotiation is mandatory.
150 */
151static int vsc8244_set_speed_duplex(struct cphy *phy, int speed, int duplex)
152{
153 int err;
154 unsigned int ctl;
155
156 err = simple_mdio_read(phy, MII_BMCR, &ctl);
157 if (err)
158 return err;
159
160 if (speed >= 0) {
161 ctl &= ~(BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_ANENABLE);
162 if (speed == SPEED_100)
163 ctl |= BMCR_SPEED100;
164 else if (speed == SPEED_1000)
165 ctl |= BMCR_SPEED1000;
166 }
167 if (duplex >= 0) {
168 ctl &= ~(BMCR_FULLDPLX | BMCR_ANENABLE);
169 if (duplex == DUPLEX_FULL)
170 ctl |= BMCR_FULLDPLX;
171 }
172 if (ctl & BMCR_SPEED1000) /* auto-negotiation required for 1Gb/s */
173 ctl |= BMCR_ANENABLE;
174 return simple_mdio_write(phy, MII_BMCR, ctl);
175}
176
177int t1_mdio_set_bits(struct cphy *phy, int mmd, int reg, unsigned int bits)
178{
179 int ret;
180 unsigned int val;
181
182 ret = mdio_read(phy, mmd, reg, &val);
183 if (!ret)
184 ret = mdio_write(phy, mmd, reg, val | bits);
185 return ret;
186}
187
188static int vsc8244_autoneg_enable(struct cphy *cphy)
189{
190 return t1_mdio_set_bits(cphy, 0, MII_BMCR,
191 BMCR_ANENABLE | BMCR_ANRESTART);
192}
193
194static int vsc8244_autoneg_restart(struct cphy *cphy)
195{
196 return t1_mdio_set_bits(cphy, 0, MII_BMCR, BMCR_ANRESTART);
197}
198
199static int vsc8244_advertise(struct cphy *phy, unsigned int advertise_map)
200{
201 int err;
202 unsigned int val = 0;
203
204 err = simple_mdio_read(phy, MII_CTRL1000, &val);
205 if (err)
206 return err;
207
208 val &= ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
209 if (advertise_map & ADVERTISED_1000baseT_Half)
210 val |= ADVERTISE_1000HALF;
211 if (advertise_map & ADVERTISED_1000baseT_Full)
212 val |= ADVERTISE_1000FULL;
213
214 err = simple_mdio_write(phy, MII_CTRL1000, val);
215 if (err)
216 return err;
217
218 val = 1;
219 if (advertise_map & ADVERTISED_10baseT_Half)
220 val |= ADVERTISE_10HALF;
221 if (advertise_map & ADVERTISED_10baseT_Full)
222 val |= ADVERTISE_10FULL;
223 if (advertise_map & ADVERTISED_100baseT_Half)
224 val |= ADVERTISE_100HALF;
225 if (advertise_map & ADVERTISED_100baseT_Full)
226 val |= ADVERTISE_100FULL;
227 if (advertise_map & ADVERTISED_PAUSE)
228 val |= ADVERTISE_PAUSE_CAP;
229 if (advertise_map & ADVERTISED_ASYM_PAUSE)
230 val |= ADVERTISE_PAUSE_ASYM;
231 return simple_mdio_write(phy, MII_ADVERTISE, val);
232}
233
234static int vsc8244_get_link_status(struct cphy *cphy, int *link_ok,
235 int *speed, int *duplex, int *fc)
236{
237 unsigned int bmcr, status, lpa, adv;
238 int err, sp = -1, dplx = -1, pause = 0;
239
240 err = simple_mdio_read(cphy, MII_BMCR, &bmcr);
241 if (!err)
242 err = simple_mdio_read(cphy, MII_BMSR, &status);
243 if (err)
244 return err;
245
246 if (link_ok) {
247 /*
248 * BMSR_LSTATUS is latch-low, so if it is 0 we need to read it
249 * once more to get the current link state.
250 */
251 if (!(status & BMSR_LSTATUS))
252 err = simple_mdio_read(cphy, MII_BMSR, &status);
253 if (err)
254 return err;
255 *link_ok = (status & BMSR_LSTATUS) != 0;
256 }
257 if (!(bmcr & BMCR_ANENABLE)) {
258 dplx = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF;
259 if (bmcr & BMCR_SPEED1000)
260 sp = SPEED_1000;
261 else if (bmcr & BMCR_SPEED100)
262 sp = SPEED_100;
263 else
264 sp = SPEED_10;
265 } else if (status & BMSR_ANEGCOMPLETE) {
266 err = simple_mdio_read(cphy, VSC8244_AUX_CTRL_STAT, &status);
267 if (err)
268 return err;
269
270 dplx = (status & F_ACSR_DUPLEX) ? DUPLEX_FULL : DUPLEX_HALF;
271 sp = G_ACSR_SPEED(status);
272 if (sp == 0)
273 sp = SPEED_10;
274 else if (sp == 1)
275 sp = SPEED_100;
276 else
277 sp = SPEED_1000;
278
279 if (fc && dplx == DUPLEX_FULL) {
280 err = simple_mdio_read(cphy, MII_LPA, &lpa);
281 if (!err)
282 err = simple_mdio_read(cphy, MII_ADVERTISE,
283 &adv);
284 if (err)
285 return err;
286
287 if (lpa & adv & ADVERTISE_PAUSE_CAP)
288 pause = PAUSE_RX | PAUSE_TX;
289 else if ((lpa & ADVERTISE_PAUSE_CAP) &&
290 (lpa & ADVERTISE_PAUSE_ASYM) &&
291 (adv & ADVERTISE_PAUSE_ASYM))
292 pause = PAUSE_TX;
293 else if ((lpa & ADVERTISE_PAUSE_ASYM) &&
294 (adv & ADVERTISE_PAUSE_CAP))
295 pause = PAUSE_RX;
296 }
297 }
298 if (speed)
299 *speed = sp;
300 if (duplex)
301 *duplex = dplx;
302 if (fc)
303 *fc = pause;
304 return 0;
305}
306
307static int vsc8244_intr_handler(struct cphy *cphy)
308{
309 unsigned int cause;
310 int err, cphy_cause = 0;
311
312 err = simple_mdio_read(cphy, VSC8244_INTR_STATUS, &cause);
313 if (err)
314 return err;
315
316 cause &= INTR_MASK;
317 if (cause & CFG_CHG_INTR_MASK)
318 cphy_cause |= cphy_cause_link_change;
319 if (cause & (VSC_INTR_RX_FIFO | VSC_INTR_TX_FIFO))
320 cphy_cause |= cphy_cause_fifo_error;
321 return cphy_cause;
322}
323
324static void vsc8244_destroy(struct cphy *cphy)
325{
326 kfree(cphy);
327}
328
329static struct cphy_ops vsc8244_ops = {
330 .destroy = vsc8244_destroy,
331 .reset = vsc8244_reset,
332 .interrupt_enable = vsc8244_intr_enable,
333 .interrupt_disable = vsc8244_intr_disable,
334 .interrupt_clear = vsc8244_intr_clear,
335 .interrupt_handler = vsc8244_intr_handler,
336 .autoneg_enable = vsc8244_autoneg_enable,
337 .autoneg_restart = vsc8244_autoneg_restart,
338 .advertise = vsc8244_advertise,
339 .set_speed_duplex = vsc8244_set_speed_duplex,
340 .get_link_status = vsc8244_get_link_status
341};
342
343static struct cphy* vsc8244_phy_create(adapter_t *adapter, int phy_addr,
344 struct mdio_ops *mdio_ops)
345{
346 struct cphy *cphy = kzalloc(sizeof(*cphy), GFP_KERNEL);
347
348 if (!cphy)
349 return NULL;
350
351 cphy_init(cphy, adapter, phy_addr, &vsc8244_ops, mdio_ops);
352
353 return cphy;
354}
355
356
357static int vsc8244_phy_reset(adapter_t* adapter)
358{
359 return 0;
360}
361
362struct gphy t1_vsc8244_ops = {
363 vsc8244_phy_create,
364 vsc8244_phy_reset
365};
366
367
diff --git a/drivers/net/chelsio/vsc8244_reg.h b/drivers/net/chelsio/vsc8244_reg.h
deleted file mode 100644
index d3c1829055cb..000000000000
--- a/drivers/net/chelsio/vsc8244_reg.h
+++ /dev/null
@@ -1,172 +0,0 @@
1/* $Date: 2005/11/23 16:28:53 $ $RCSfile: vsc8244_reg.h,v $ $Revision: 1.1 $ */
2#ifndef CHELSIO_MV8E1XXX_H
3#define CHELSIO_MV8E1XXX_H
4
5#ifndef BMCR_SPEED1000
6# define BMCR_SPEED1000 0x40
7#endif
8
9#ifndef ADVERTISE_PAUSE
10# define ADVERTISE_PAUSE 0x400
11#endif
12#ifndef ADVERTISE_PAUSE_ASYM
13# define ADVERTISE_PAUSE_ASYM 0x800
14#endif
15
16/* Gigabit MII registers */
17#define MII_GBMR 1 /* 1000Base-T mode register */
18#define MII_GBCR 9 /* 1000Base-T control register */
19#define MII_GBSR 10 /* 1000Base-T status register */
20
21/* 1000Base-T control register fields */
22#define GBCR_ADV_1000HALF 0x100
23#define GBCR_ADV_1000FULL 0x200
24#define GBCR_PREFER_MASTER 0x400
25#define GBCR_MANUAL_AS_MASTER 0x800
26#define GBCR_MANUAL_CONFIG_ENABLE 0x1000
27
28/* 1000Base-T status register fields */
29#define GBSR_LP_1000HALF 0x400
30#define GBSR_LP_1000FULL 0x800
31#define GBSR_REMOTE_OK 0x1000
32#define GBSR_LOCAL_OK 0x2000
33#define GBSR_LOCAL_MASTER 0x4000
34#define GBSR_MASTER_FAULT 0x8000
35
36/* Vitesse PHY interrupt status bits. */
37#if 0
38#define VSC8244_INTR_JABBER 0x0001
39#define VSC8244_INTR_POLARITY_CHNG 0x0002
40#define VSC8244_INTR_ENG_DETECT_CHNG 0x0010
41#define VSC8244_INTR_DOWNSHIFT 0x0020
42#define VSC8244_INTR_MDI_XOVER_CHNG 0x0040
43#define VSC8244_INTR_FIFO_OVER_UNDER 0x0080
44#define VSC8244_INTR_FALSE_CARRIER 0x0100
45#define VSC8244_INTR_SYMBOL_ERROR 0x0200
46#define VSC8244_INTR_LINK_CHNG 0x0400
47#define VSC8244_INTR_AUTONEG_DONE 0x0800
48#define VSC8244_INTR_PAGE_RECV 0x1000
49#define VSC8244_INTR_DUPLEX_CHNG 0x2000
50#define VSC8244_INTR_SPEED_CHNG 0x4000
51#define VSC8244_INTR_AUTONEG_ERR 0x8000
52#else
53//#define VSC8244_INTR_JABBER 0x0001
54//#define VSC8244_INTR_POLARITY_CHNG 0x0002
55//#define VSC8244_INTR_BIT2 0x0004
56//#define VSC8244_INTR_BIT3 0x0008
57#define VSC8244_INTR_RX_ERR 0x0001
58#define VSC8244_INTR_MASTER_SLAVE 0x0002
59#define VSC8244_INTR_CABLE_IMPAIRED 0x0004
60#define VSC8244_INTR_FALSE_CARRIER 0x0008
61//#define VSC8244_INTR_ENG_DETECT_CHNG 0x0010
62//#define VSC8244_INTR_DOWNSHIFT 0x0020
63//#define VSC8244_INTR_MDI_XOVER_CHNG 0x0040
64//#define VSC8244_INTR_FIFO_OVER_UNDER 0x0080
65#define VSC8244_INTR_BIT4 0x0010
66#define VSC8244_INTR_FIFO_RX 0x0020
67#define VSC8244_INTR_FIFO_OVER_UNDER 0x0040
68#define VSC8244_INTR_LOCK_LOST 0x0080
69//#define VSC8244_INTR_FALSE_CARRIER 0x0100
70//#define VSC8244_INTR_SYMBOL_ERROR 0x0200
71//#define VSC8244_INTR_LINK_CHNG 0x0400
72//#define VSC8244_INTR_AUTONEG_DONE 0x0800
73#define VSC8244_INTR_SYMBOL_ERROR 0x0100
74#define VSC8244_INTR_ENG_DETECT_CHNG 0x0200
75#define VSC8244_INTR_AUTONEG_DONE 0x0400
76#define VSC8244_INTR_AUTONEG_ERR 0x0800
77//#define VSC8244_INTR_PAGE_RECV 0x1000
78//#define VSC8244_INTR_DUPLEX_CHNG 0x2000
79//#define VSC8244_INTR_SPEED_CHNG 0x4000
80//#define VSC8244_INTR_AUTONEG_ERR 0x8000
81#define VSC8244_INTR_DUPLEX_CHNG 0x1000
82#define VSC8244_INTR_LINK_CHNG 0x2000
83#define VSC8244_INTR_SPEED_CHNG 0x4000
84#define VSC8244_INTR_STATUS 0x8000
85#endif
86
87
88/* Vitesse PHY specific registers. */
89#define VSC8244_SPECIFIC_CNTRL_REGISTER 16
90#define VSC8244_SPECIFIC_STATUS_REGISTER 0x1c
91#define VSC8244_INTERRUPT_ENABLE_REGISTER 0x19
92#define VSC8244_INTERRUPT_STATUS_REGISTER 0x1a
93#define VSC8244_EXT_PHY_SPECIFIC_CNTRL_REGISTER 20
94#define VSC8244_RECV_ERR_CNTR_REGISTER 21
95#define VSC8244_RES_REGISTER 22
96#define VSC8244_GLOBAL_STATUS_REGISTER 23
97#define VSC8244_LED_CONTROL_REGISTER 24
98#define VSC8244_MANUAL_LED_OVERRIDE_REGISTER 25
99#define VSC8244_EXT_PHY_SPECIFIC_CNTRL_2_REGISTER 26
100#define VSC8244_EXT_PHY_SPECIFIC_STATUS_REGISTER 27
101#define VSC8244_VIRTUAL_CABLE_TESTER_REGISTER 28
102#define VSC8244_EXTENDED_ADDR_REGISTER 29
103#define VSC8244_EXTENDED_REGISTER 30
104
105/* PHY specific control register fields */
106#define S_PSCR_MDI_XOVER_MODE 5
107#define M_PSCR_MDI_XOVER_MODE 0x3
108#define V_PSCR_MDI_XOVER_MODE(x) ((x) << S_PSCR_MDI_XOVER_MODE)
109#define G_PSCR_MDI_XOVER_MODE(x) (((x) >> S_PSCR_MDI_XOVER_MODE) & M_PSCR_MDI_XOVER_MODE)
110
111/* Extended PHY specific control register fields */
112#define S_DOWNSHIFT_ENABLE 8
113#define V_DOWNSHIFT_ENABLE (1 << S_DOWNSHIFT_ENABLE)
114
115#define S_DOWNSHIFT_CNT 9
116#define M_DOWNSHIFT_CNT 0x7
117#define V_DOWNSHIFT_CNT(x) ((x) << S_DOWNSHIFT_CNT)
118#define G_DOWNSHIFT_CNT(x) (((x) >> S_DOWNSHIFT_CNT) & M_DOWNSHIFT_CNT)
119
120/* PHY specific status register fields */
121#define S_PSSR_JABBER 0
122#define V_PSSR_JABBER (1 << S_PSSR_JABBER)
123
124#define S_PSSR_POLARITY 1
125#define V_PSSR_POLARITY (1 << S_PSSR_POLARITY)
126
127#define S_PSSR_RX_PAUSE 2
128#define V_PSSR_RX_PAUSE (1 << S_PSSR_RX_PAUSE)
129
130#define S_PSSR_TX_PAUSE 3
131#define V_PSSR_TX_PAUSE (1 << S_PSSR_TX_PAUSE)
132
133#define S_PSSR_ENERGY_DETECT 4
134#define V_PSSR_ENERGY_DETECT (1 << S_PSSR_ENERGY_DETECT)
135
136#define S_PSSR_DOWNSHIFT_STATUS 5
137#define V_PSSR_DOWNSHIFT_STATUS (1 << S_PSSR_DOWNSHIFT_STATUS)
138
139#define S_PSSR_MDI 6
140#define V_PSSR_MDI (1 << S_PSSR_MDI)
141
142#define S_PSSR_CABLE_LEN 7
143#define M_PSSR_CABLE_LEN 0x7
144#define V_PSSR_CABLE_LEN(x) ((x) << S_PSSR_CABLE_LEN)
145#define G_PSSR_CABLE_LEN(x) (((x) >> S_PSSR_CABLE_LEN) & M_PSSR_CABLE_LEN)
146
147//#define S_PSSR_LINK 10
148//#define S_PSSR_LINK 13
149#define S_PSSR_LINK 2
150#define V_PSSR_LINK (1 << S_PSSR_LINK)
151
152//#define S_PSSR_STATUS_RESOLVED 11
153//#define S_PSSR_STATUS_RESOLVED 10
154#define S_PSSR_STATUS_RESOLVED 15
155#define V_PSSR_STATUS_RESOLVED (1 << S_PSSR_STATUS_RESOLVED)
156
157#define S_PSSR_PAGE_RECEIVED 12
158#define V_PSSR_PAGE_RECEIVED (1 << S_PSSR_PAGE_RECEIVED)
159
160//#define S_PSSR_DUPLEX 13
161//#define S_PSSR_DUPLEX 12
162#define S_PSSR_DUPLEX 5
163#define V_PSSR_DUPLEX (1 << S_PSSR_DUPLEX)
164
165//#define S_PSSR_SPEED 14
166//#define S_PSSR_SPEED 14
167#define S_PSSR_SPEED 3
168#define M_PSSR_SPEED 0x3
169#define V_PSSR_SPEED(x) ((x) << S_PSSR_SPEED)
170#define G_PSSR_SPEED(x) (((x) >> S_PSSR_SPEED) & M_PSSR_SPEED)
171
172#endif