[PATCH] chelsio: add support for other 10G boards
[linux-2.6.git] / drivers / net / chelsio / pm3393.c
1 /*****************************************************************************
2  *                                                                           *
3  * File: pm3393.c                                                            *
4  * $Revision: 1.16 $                                                         *
5  * $Date: 2005/05/14 00:59:32 $                                              *
6  * Description:                                                              *
7  *  PMC/SIERRA (pm3393) MAC-PHY functionality.                               *
8  *  part of the Chelsio 10Gb Ethernet Driver.                                *
9  *                                                                           *
10  * This program is free software; you can redistribute it and/or modify      *
11  * it under the terms of the GNU General Public License, version 2, as       *
12  * published by the Free Software Foundation.                                *
13  *                                                                           *
14  * You should have received a copy of the GNU General Public License along   *
15  * with this program; if not, write to the Free Software Foundation, Inc.,   *
16  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.                 *
17  *                                                                           *
18  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED    *
19  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF      *
20  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.                     *
21  *                                                                           *
22  * http://www.chelsio.com                                                    *
23  *                                                                           *
24  * Copyright (c) 2003 - 2005 Chelsio Communications, Inc.                    *
25  * All rights reserved.                                                      *
26  *                                                                           *
27  * Maintainers: maintainers@chelsio.com                                      *
28  *                                                                           *
29  * Authors: Dimitrios Michailidis   <dm@chelsio.com>                         *
30  *          Tina Yang               <tainay@chelsio.com>                     *
31  *          Felix Marti             <felix@chelsio.com>                      *
32  *          Scott Bardone           <sbardone@chelsio.com>                   *
33  *          Kurt Ottaway            <kottaway@chelsio.com>                   *
34  *          Frank DiMambro          <frank@chelsio.com>                      *
35  *                                                                           *
36  * History:                                                                  *
37  *                                                                           *
38  ****************************************************************************/
39
40 #include "common.h"
41 #include "regs.h"
42 #include "gmac.h"
43 #include "elmer0.h"
44 #include "suni1x10gexp_regs.h"
45
46 /* 802.3ae 10Gb/s MDIO Manageable Device(MMD)
47  */
48 enum {
49         MMD_RESERVED,
50         MMD_PMAPMD,
51         MMD_WIS,
52         MMD_PCS,
53         MMD_PHY_XGXS,   /* XGMII Extender Sublayer */
54         MMD_DTE_XGXS,
55 };
56
57 enum {
58         PHY_XGXS_CTRL_1,
59         PHY_XGXS_STATUS_1
60 };
61
62 #define OFFSET(REG_ADDR)    (REG_ADDR << 2)
63
64 /* Max frame size PM3393 can handle. Includes Ethernet header and CRC. */
65 #define MAX_FRAME_SIZE  9600
66
67 #define IPG 12
68 #define TXXG_CONF1_VAL ((IPG << SUNI1x10GEXP_BITOFF_TXXG_IPGT) | \
69         SUNI1x10GEXP_BITMSK_TXXG_32BIT_ALIGN | SUNI1x10GEXP_BITMSK_TXXG_CRCEN | \
70         SUNI1x10GEXP_BITMSK_TXXG_PADEN)
71 #define RXXG_CONF1_VAL (SUNI1x10GEXP_BITMSK_RXXG_PUREP | 0x14 | \
72         SUNI1x10GEXP_BITMSK_RXXG_FLCHK | SUNI1x10GEXP_BITMSK_RXXG_CRC_STRIP)
73
74 /* Update statistics every 15 minutes */
75 #define STATS_TICK_SECS (15 * 60)
76
77 enum {                     /* RMON registers */
78         RxOctetsReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_1_LOW,
79         RxUnicastFramesReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_4_LOW,
80         RxMulticastFramesReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_5_LOW,
81         RxBroadcastFramesReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_6_LOW,
82         RxPAUSEMACCtrlFramesReceived = SUNI1x10GEXP_REG_MSTAT_COUNTER_8_LOW,
83         RxFrameCheckSequenceErrors = SUNI1x10GEXP_REG_MSTAT_COUNTER_10_LOW,
84         RxFramesLostDueToInternalMACErrors = SUNI1x10GEXP_REG_MSTAT_COUNTER_11_LOW,
85         RxSymbolErrors = SUNI1x10GEXP_REG_MSTAT_COUNTER_12_LOW,
86         RxInRangeLengthErrors = SUNI1x10GEXP_REG_MSTAT_COUNTER_13_LOW,
87         RxFramesTooLongErrors = SUNI1x10GEXP_REG_MSTAT_COUNTER_15_LOW,
88         RxJabbers = SUNI1x10GEXP_REG_MSTAT_COUNTER_16_LOW,
89         RxFragments = SUNI1x10GEXP_REG_MSTAT_COUNTER_17_LOW,
90         RxUndersizedFrames =  SUNI1x10GEXP_REG_MSTAT_COUNTER_18_LOW,
91         RxJumboFramesReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_25_LOW,
92         RxJumboOctetsReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_26_LOW,
93
94         TxOctetsTransmittedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_33_LOW,
95         TxFramesLostDueToInternalMACTransmissionError = SUNI1x10GEXP_REG_MSTAT_COUNTER_35_LOW,
96         TxTransmitSystemError = SUNI1x10GEXP_REG_MSTAT_COUNTER_36_LOW,
97         TxUnicastFramesTransmittedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_38_LOW,
98         TxMulticastFramesTransmittedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_40_LOW,
99         TxBroadcastFramesTransmittedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_42_LOW,
100         TxPAUSEMACCtrlFramesTransmitted = SUNI1x10GEXP_REG_MSTAT_COUNTER_43_LOW,
101         TxJumboFramesReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_51_LOW,
102         TxJumboOctetsReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_52_LOW
103 };
104
105 struct _cmac_instance {
106         u8 enabled;
107         u8 fc;
108         u8 mac_addr[6];
109 };
110
111 static int pmread(struct cmac *cmac, u32 reg, u32 * data32)
112 {
113         t1_tpi_read(cmac->adapter, OFFSET(reg), data32);
114         return 0;
115 }
116
117 static int pmwrite(struct cmac *cmac, u32 reg, u32 data32)
118 {
119         t1_tpi_write(cmac->adapter, OFFSET(reg), data32);
120         return 0;
121 }
122
123 /* Port reset. */
124 static int pm3393_reset(struct cmac *cmac)
125 {
126         return 0;
127 }
128
129 /*
130  * Enable interrupts for the PM3393
131
132         1. Enable PM3393 BLOCK interrupts.
133         2. Enable PM3393 Master Interrupt bit(INTE)
134         3. Enable ELMER's PM3393 bit.
135         4. Enable Terminator external interrupt.
136 */
137 static int pm3393_interrupt_enable(struct cmac *cmac)
138 {
139         u32 pl_intr;
140
141         /* PM3393 - Enabling all hardware block interrupts.
142          */
143         pmwrite(cmac, SUNI1x10GEXP_REG_SERDES_3125_INTERRUPT_ENABLE, 0xffff);
144         pmwrite(cmac, SUNI1x10GEXP_REG_XRF_INTERRUPT_ENABLE, 0xffff);
145         pmwrite(cmac, SUNI1x10GEXP_REG_XRF_DIAG_INTERRUPT_ENABLE, 0xffff);
146         pmwrite(cmac, SUNI1x10GEXP_REG_RXOAM_INTERRUPT_ENABLE, 0xffff);
147
148         /* Don't interrupt on statistics overflow, we are polling */
149         pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_0, 0);
150         pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_1, 0);
151         pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_2, 0);
152         pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_3, 0);
153
154         pmwrite(cmac, SUNI1x10GEXP_REG_IFLX_FIFO_OVERFLOW_ENABLE, 0xffff);
155         pmwrite(cmac, SUNI1x10GEXP_REG_PL4ODP_INTERRUPT_MASK, 0xffff);
156         pmwrite(cmac, SUNI1x10GEXP_REG_XTEF_INTERRUPT_ENABLE, 0xffff);
157         pmwrite(cmac, SUNI1x10GEXP_REG_TXOAM_INTERRUPT_ENABLE, 0xffff);
158         pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_CONFIG_3, 0xffff);
159         pmwrite(cmac, SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_MASK, 0xffff);
160         pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_CONFIG_3, 0xffff);
161         pmwrite(cmac, SUNI1x10GEXP_REG_PL4IDU_INTERRUPT_MASK, 0xffff);
162         pmwrite(cmac, SUNI1x10GEXP_REG_EFLX_FIFO_OVERFLOW_ERROR_ENABLE, 0xffff);
163
164         /* PM3393 - Global interrupt enable
165          */
166         /* TBD XXX Disable for now until we figure out why error interrupts keep asserting. */
167         pmwrite(cmac, SUNI1x10GEXP_REG_GLOBAL_INTERRUPT_ENABLE,
168                 0 /*SUNI1x10GEXP_BITMSK_TOP_INTE */ );
169
170         /* TERMINATOR - PL_INTERUPTS_EXT */
171         pl_intr = readl(cmac->adapter->regs + A_PL_ENABLE);
172         pl_intr |= F_PL_INTR_EXT;
173         writel(pl_intr, cmac->adapter->regs + A_PL_ENABLE);
174         return 0;
175 }
176
177 static int pm3393_interrupt_disable(struct cmac *cmac)
178 {
179         u32 elmer;
180
181         /* PM3393 - Enabling HW interrupt blocks. */
182         pmwrite(cmac, SUNI1x10GEXP_REG_SERDES_3125_INTERRUPT_ENABLE, 0);
183         pmwrite(cmac, SUNI1x10GEXP_REG_XRF_INTERRUPT_ENABLE, 0);
184         pmwrite(cmac, SUNI1x10GEXP_REG_XRF_DIAG_INTERRUPT_ENABLE, 0);
185         pmwrite(cmac, SUNI1x10GEXP_REG_RXOAM_INTERRUPT_ENABLE, 0);
186         pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_0, 0);
187         pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_1, 0);
188         pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_2, 0);
189         pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_3, 0);
190         pmwrite(cmac, SUNI1x10GEXP_REG_IFLX_FIFO_OVERFLOW_ENABLE, 0);
191         pmwrite(cmac, SUNI1x10GEXP_REG_PL4ODP_INTERRUPT_MASK, 0);
192         pmwrite(cmac, SUNI1x10GEXP_REG_XTEF_INTERRUPT_ENABLE, 0);
193         pmwrite(cmac, SUNI1x10GEXP_REG_TXOAM_INTERRUPT_ENABLE, 0);
194         pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_CONFIG_3, 0);
195         pmwrite(cmac, SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_MASK, 0);
196         pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_CONFIG_3, 0);
197         pmwrite(cmac, SUNI1x10GEXP_REG_PL4IDU_INTERRUPT_MASK, 0);
198         pmwrite(cmac, SUNI1x10GEXP_REG_EFLX_FIFO_OVERFLOW_ERROR_ENABLE, 0);
199
200         /* PM3393 - Global interrupt enable */
201         pmwrite(cmac, SUNI1x10GEXP_REG_GLOBAL_INTERRUPT_ENABLE, 0);
202
203         /* ELMER - External chip interrupts. */
204         t1_tpi_read(cmac->adapter, A_ELMER0_INT_ENABLE, &elmer);
205         elmer &= ~ELMER0_GP_BIT1;
206         t1_tpi_write(cmac->adapter, A_ELMER0_INT_ENABLE, elmer);
207
208         /* TERMINATOR - PL_INTERUPTS_EXT */
209         /* DO NOT DISABLE TERMINATOR's EXTERNAL INTERRUPTS. ANOTHER CHIP
210          * COULD WANT THEM ENABLED. We disable PM3393 at the ELMER level.
211          */
212
213         return 0;
214 }
215
216 static int pm3393_interrupt_clear(struct cmac *cmac)
217 {
218         u32 elmer;
219         u32 pl_intr;
220         u32 val32;
221
222         /* PM3393 - Clearing HW interrupt blocks. Note, this assumes
223          *          bit WCIMODE=0 for a clear-on-read.
224          */
225         pmread(cmac, SUNI1x10GEXP_REG_SERDES_3125_INTERRUPT_STATUS, &val32);
226         pmread(cmac, SUNI1x10GEXP_REG_XRF_INTERRUPT_STATUS, &val32);
227         pmread(cmac, SUNI1x10GEXP_REG_XRF_DIAG_INTERRUPT_STATUS, &val32);
228         pmread(cmac, SUNI1x10GEXP_REG_RXOAM_INTERRUPT_STATUS, &val32);
229         pmread(cmac, SUNI1x10GEXP_REG_PL4ODP_INTERRUPT, &val32);
230         pmread(cmac, SUNI1x10GEXP_REG_XTEF_INTERRUPT_STATUS, &val32);
231         pmread(cmac, SUNI1x10GEXP_REG_IFLX_FIFO_OVERFLOW_INTERRUPT, &val32);
232         pmread(cmac, SUNI1x10GEXP_REG_TXOAM_INTERRUPT_STATUS, &val32);
233         pmread(cmac, SUNI1x10GEXP_REG_RXXG_INTERRUPT, &val32);
234         pmread(cmac, SUNI1x10GEXP_REG_TXXG_INTERRUPT, &val32);
235         pmread(cmac, SUNI1x10GEXP_REG_PL4IDU_INTERRUPT, &val32);
236         pmread(cmac, SUNI1x10GEXP_REG_EFLX_FIFO_OVERFLOW_ERROR_INDICATION,
237                &val32);
238         pmread(cmac, SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_STATUS, &val32);
239         pmread(cmac, SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_CHANGE, &val32);
240
241         /* PM3393 - Global interrupt status
242          */
243         pmread(cmac, SUNI1x10GEXP_REG_MASTER_INTERRUPT_STATUS, &val32);
244
245         /* ELMER - External chip interrupts.
246          */
247         t1_tpi_read(cmac->adapter, A_ELMER0_INT_CAUSE, &elmer);
248         elmer |= ELMER0_GP_BIT1;
249         t1_tpi_write(cmac->adapter, A_ELMER0_INT_CAUSE, elmer);
250
251         /* TERMINATOR - PL_INTERUPTS_EXT
252          */
253         pl_intr = readl(cmac->adapter->regs + A_PL_CAUSE);
254         pl_intr |= F_PL_INTR_EXT;
255         writel(pl_intr, cmac->adapter->regs + A_PL_CAUSE);
256
257         return 0;
258 }
259
260 /* Interrupt handler */
261 static int pm3393_interrupt_handler(struct cmac *cmac)
262 {
263         u32 master_intr_status;
264 /*
265         1. Read master interrupt register.
266         2. Read BLOCK's interrupt status registers.
267         3. Handle BLOCK interrupts.
268 */
269         /* Read the master interrupt status register. */
270         pmread(cmac, SUNI1x10GEXP_REG_MASTER_INTERRUPT_STATUS,
271                &master_intr_status);
272         CH_DBG(cmac->adapter, INTR, "PM3393 intr cause 0x%x\n",
273                master_intr_status);
274
275         /* TBD XXX Lets just clear everything for now */
276         pm3393_interrupt_clear(cmac);
277
278         return 0;
279 }
280
281 static int pm3393_enable(struct cmac *cmac, int which)
282 {
283         if (which & MAC_DIRECTION_RX)
284                 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_CONFIG_1,
285                         (RXXG_CONF1_VAL | SUNI1x10GEXP_BITMSK_RXXG_RXEN));
286
287         if (which & MAC_DIRECTION_TX) {
288                 u32 val = TXXG_CONF1_VAL | SUNI1x10GEXP_BITMSK_TXXG_TXEN0;
289
290                 if (cmac->instance->fc & PAUSE_RX)
291                         val |= SUNI1x10GEXP_BITMSK_TXXG_FCRX;
292                 if (cmac->instance->fc & PAUSE_TX)
293                         val |= SUNI1x10GEXP_BITMSK_TXXG_FCTX;
294                 pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_CONFIG_1, val);
295         }
296
297         cmac->instance->enabled |= which;
298         return 0;
299 }
300
301 static int pm3393_enable_port(struct cmac *cmac, int which)
302 {
303         /* Clear port statistics */
304         pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_CONTROL,
305                 SUNI1x10GEXP_BITMSK_MSTAT_CLEAR);
306         udelay(2);
307         memset(&cmac->stats, 0, sizeof(struct cmac_statistics));
308
309         pm3393_enable(cmac, which);
310
311         /*
312          * XXX This should be done by the PHY and preferrably not at all.
313          * The PHY doesn't give us link status indication on its own so have
314          * the link management code query it instead.
315          */
316         t1_link_changed(cmac->adapter, 0);
317         return 0;
318 }
319
320 static int pm3393_disable(struct cmac *cmac, int which)
321 {
322         if (which & MAC_DIRECTION_RX)
323                 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_CONFIG_1, RXXG_CONF1_VAL);
324         if (which & MAC_DIRECTION_TX)
325                 pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_CONFIG_1, TXXG_CONF1_VAL);
326
327         /*
328          * The disable is graceful. Give the PM3393 time.  Can't wait very
329          * long here, we may be holding locks.
330          */
331         udelay(20);
332
333         cmac->instance->enabled &= ~which;
334         return 0;
335 }
336
337 static int pm3393_loopback_enable(struct cmac *cmac)
338 {
339         return 0;
340 }
341
342 static int pm3393_loopback_disable(struct cmac *cmac)
343 {
344         return 0;
345 }
346
347 static int pm3393_set_mtu(struct cmac *cmac, int mtu)
348 {
349         int enabled = cmac->instance->enabled;
350
351         /* MAX_FRAME_SIZE includes header + FCS, mtu doesn't */
352         mtu += 14 + 4;
353         if (mtu > MAX_FRAME_SIZE)
354                 return -EINVAL;
355
356         /* Disable Rx/Tx MAC before configuring it. */
357         if (enabled)
358                 pm3393_disable(cmac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
359
360         pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MAX_FRAME_LENGTH, mtu);
361         pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_MAX_FRAME_SIZE, mtu);
362
363         if (enabled)
364                 pm3393_enable(cmac, enabled);
365         return 0;
366 }
367
368 static u32 calc_crc(u8 *b, int len)
369 {
370         int i;
371         u32 crc = (u32)~0;
372
373         /* calculate crc one bit at a time */
374         while (len--) {
375                 crc ^= *b++;
376                 for (i = 0; i < 8; i++) {
377                         if (crc & 0x1)
378                                 crc = (crc >> 1) ^ 0xedb88320;
379                         else
380                                 crc = (crc >> 1);
381                 }
382         }
383
384         /* reverse bits */
385         crc = ((crc >> 4) & 0x0f0f0f0f) | ((crc << 4) & 0xf0f0f0f0);
386         crc = ((crc >> 2) & 0x33333333) | ((crc << 2) & 0xcccccccc);
387         crc = ((crc >> 1) & 0x55555555) | ((crc << 1) & 0xaaaaaaaa);
388         /* swap bytes */
389         crc = (crc >> 16) | (crc << 16);
390         crc = (crc >> 8 & 0x00ff00ff) | (crc << 8 & 0xff00ff00);
391
392         return crc;
393 }
394
395 static int pm3393_set_rx_mode(struct cmac *cmac, struct t1_rx_mode *rm)
396 {
397         int enabled = cmac->instance->enabled & MAC_DIRECTION_RX;
398         u32 rx_mode;
399
400         /* Disable MAC RX before reconfiguring it */
401         if (enabled)
402                 pm3393_disable(cmac, MAC_DIRECTION_RX);
403
404         pmread(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_2, &rx_mode);
405         rx_mode &= ~(SUNI1x10GEXP_BITMSK_RXXG_PMODE |
406                      SUNI1x10GEXP_BITMSK_RXXG_MHASH_EN);
407         pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_2,
408                 (u16)rx_mode);
409
410         if (t1_rx_mode_promisc(rm)) {
411                 /* Promiscuous mode. */
412                 rx_mode |= SUNI1x10GEXP_BITMSK_RXXG_PMODE;
413         }
414         if (t1_rx_mode_allmulti(rm)) {
415                 /* Accept all multicast. */
416                 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_LOW, 0xffff);
417                 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_MIDLOW, 0xffff);
418                 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_MIDHIGH, 0xffff);
419                 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_HIGH, 0xffff);
420                 rx_mode |= SUNI1x10GEXP_BITMSK_RXXG_MHASH_EN;
421         } else if (t1_rx_mode_mc_cnt(rm)) {
422                 /* Accept one or more multicast(s). */
423                 u8 *addr;
424                 int bit;
425                 u16 mc_filter[4] = { 0, };
426
427                 while ((addr = t1_get_next_mcaddr(rm))) {
428                         bit = (calc_crc(addr, ETH_ALEN) >> 23) & 0x3f;  /* bit[23:28] */
429                         mc_filter[bit >> 4] |= 1 << (bit & 0xf);
430                 }
431                 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_LOW, mc_filter[0]);
432                 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_MIDLOW, mc_filter[1]);
433                 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_MIDHIGH, mc_filter[2]);
434                 pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_HIGH, mc_filter[3]);
435                 rx_mode |= SUNI1x10GEXP_BITMSK_RXXG_MHASH_EN;
436         }
437
438         pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_2, (u16)rx_mode);
439
440         if (enabled)
441                 pm3393_enable(cmac, MAC_DIRECTION_RX);
442
443         return 0;
444 }
445
446 static int pm3393_get_speed_duplex_fc(struct cmac *cmac, int *speed,
447                                       int *duplex, int *fc)
448 {
449         if (speed)
450                 *speed = SPEED_10000;
451         if (duplex)
452                 *duplex = DUPLEX_FULL;
453         if (fc)
454                 *fc = cmac->instance->fc;
455         return 0;
456 }
457
458 static int pm3393_set_speed_duplex_fc(struct cmac *cmac, int speed, int duplex,
459                                       int fc)
460 {
461         if (speed >= 0 && speed != SPEED_10000)
462                 return -1;
463         if (duplex >= 0 && duplex != DUPLEX_FULL)
464                 return -1;
465         if (fc & ~(PAUSE_TX | PAUSE_RX))
466                 return -1;
467
468         if (fc != cmac->instance->fc) {
469                 cmac->instance->fc = (u8) fc;
470                 if (cmac->instance->enabled & MAC_DIRECTION_TX)
471                         pm3393_enable(cmac, MAC_DIRECTION_TX);
472         }
473         return 0;
474 }
475
476 #define RMON_UPDATE(mac, name, stat_name) \
477         { \
478                 t1_tpi_read((mac)->adapter, OFFSET(name), &val0);       \
479                 t1_tpi_read((mac)->adapter, OFFSET(((name)+1)), &val1); \
480                 t1_tpi_read((mac)->adapter, OFFSET(((name)+2)), &val2); \
481                 (mac)->stats.stat_name = ((u64)val0 & 0xffff) | \
482                                                 (((u64)val1 & 0xffff) << 16) | \
483                                                 (((u64)val2 & 0xff) << 32) | \
484                                                 ((mac)->stats.stat_name & \
485                                                         (~(u64)0 << 40)); \
486                 if (ro &        \
487                         ((name -  SUNI1x10GEXP_REG_MSTAT_COUNTER_0_LOW) >> 2)) \
488                         (mac)->stats.stat_name += ((u64)1 << 40); \
489         }
490
491 static const struct cmac_statistics *pm3393_update_statistics(struct cmac *mac,
492                                                               int flag)
493 {
494         u64     ro;
495         u32     val0, val1, val2, val3;
496
497         /* Snap the counters */
498         pmwrite(mac, SUNI1x10GEXP_REG_MSTAT_CONTROL,
499                 SUNI1x10GEXP_BITMSK_MSTAT_SNAP);
500
501         /* Counter rollover, clear on read */
502         pmread(mac, SUNI1x10GEXP_REG_MSTAT_COUNTER_ROLLOVER_0, &val0);
503         pmread(mac, SUNI1x10GEXP_REG_MSTAT_COUNTER_ROLLOVER_1, &val1);
504         pmread(mac, SUNI1x10GEXP_REG_MSTAT_COUNTER_ROLLOVER_2, &val2);
505         pmread(mac, SUNI1x10GEXP_REG_MSTAT_COUNTER_ROLLOVER_3, &val3);
506         ro = ((u64)val0 & 0xffff) | (((u64)val1 & 0xffff) << 16) |
507                 (((u64)val2 & 0xffff) << 32) | (((u64)val3 & 0xffff) << 48);
508
509         /* Rx stats */
510         RMON_UPDATE(mac, RxOctetsReceivedOK, RxOctetsOK);
511         RMON_UPDATE(mac, RxUnicastFramesReceivedOK, RxUnicastFramesOK);
512         RMON_UPDATE(mac, RxMulticastFramesReceivedOK, RxMulticastFramesOK);
513         RMON_UPDATE(mac, RxBroadcastFramesReceivedOK, RxBroadcastFramesOK);
514         RMON_UPDATE(mac, RxPAUSEMACCtrlFramesReceived, RxPauseFrames);
515         RMON_UPDATE(mac, RxFrameCheckSequenceErrors, RxFCSErrors);
516         RMON_UPDATE(mac, RxFramesLostDueToInternalMACErrors,
517                                 RxInternalMACRcvError);
518         RMON_UPDATE(mac, RxSymbolErrors, RxSymbolErrors);
519         RMON_UPDATE(mac, RxInRangeLengthErrors, RxInRangeLengthErrors);
520         RMON_UPDATE(mac, RxFramesTooLongErrors , RxFrameTooLongErrors);
521         RMON_UPDATE(mac, RxJabbers, RxJabberErrors);
522         RMON_UPDATE(mac, RxFragments, RxRuntErrors);
523         RMON_UPDATE(mac, RxUndersizedFrames, RxRuntErrors);
524         RMON_UPDATE(mac, RxJumboFramesReceivedOK, RxJumboFramesOK);
525         RMON_UPDATE(mac, RxJumboOctetsReceivedOK, RxJumboOctetsOK);
526
527         /* Tx stats */
528         RMON_UPDATE(mac, TxOctetsTransmittedOK, TxOctetsOK);
529         RMON_UPDATE(mac, TxFramesLostDueToInternalMACTransmissionError,
530                                 TxInternalMACXmitError);
531         RMON_UPDATE(mac, TxTransmitSystemError, TxFCSErrors);
532         RMON_UPDATE(mac, TxUnicastFramesTransmittedOK, TxUnicastFramesOK);
533         RMON_UPDATE(mac, TxMulticastFramesTransmittedOK, TxMulticastFramesOK);
534         RMON_UPDATE(mac, TxBroadcastFramesTransmittedOK, TxBroadcastFramesOK);
535         RMON_UPDATE(mac, TxPAUSEMACCtrlFramesTransmitted, TxPauseFrames);
536         RMON_UPDATE(mac, TxJumboFramesReceivedOK, TxJumboFramesOK);
537         RMON_UPDATE(mac, TxJumboOctetsReceivedOK, TxJumboOctetsOK);
538
539         return &mac->stats;
540 }
541
542 static int pm3393_macaddress_get(struct cmac *cmac, u8 mac_addr[6])
543 {
544         memcpy(mac_addr, cmac->instance->mac_addr, 6);
545         return 0;
546 }
547
548 static int pm3393_macaddress_set(struct cmac *cmac, u8 ma[6])
549 {
550         u32 val, lo, mid, hi, enabled = cmac->instance->enabled;
551
552         /*
553          * MAC addr: 00:07:43:00:13:09
554          *
555          * ma[5] = 0x09
556          * ma[4] = 0x13
557          * ma[3] = 0x00
558          * ma[2] = 0x43
559          * ma[1] = 0x07
560          * ma[0] = 0x00
561          *
562          * The PM3393 requires byte swapping and reverse order entry
563          * when programming MAC addresses:
564          *
565          * low_bits[15:0]    = ma[1]:ma[0]
566          * mid_bits[31:16]   = ma[3]:ma[2]
567          * high_bits[47:32]  = ma[5]:ma[4]
568          */
569
570         /* Store local copy */
571         memcpy(cmac->instance->mac_addr, ma, 6);
572
573         lo = ((u32) ma[1] << 8) | (u32) ma[0];
574         mid = ((u32) ma[3] << 8) | (u32) ma[2];
575         hi = ((u32) ma[5] << 8) | (u32) ma[4];
576
577         /* Disable Rx/Tx MAC before configuring it. */
578         if (enabled)
579                 pm3393_disable(cmac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
580
581         /* Set RXXG Station Address */
582         pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_SA_15_0, lo);
583         pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_SA_31_16, mid);
584         pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_SA_47_32, hi);
585
586         /* Set TXXG Station Address */
587         pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_SA_15_0, lo);
588         pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_SA_31_16, mid);
589         pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_SA_47_32, hi);
590
591         /* Setup Exact Match Filter 1 with our MAC address
592          *
593          * Must disable exact match filter before configuring it.
594          */
595         pmread(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_0, &val);
596         val &= 0xff0f;
597         pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_0, val);
598
599         pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_1_LOW, lo);
600         pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_1_MID, mid);
601         pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_1_HIGH, hi);
602
603         val |= 0x0090;
604         pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_0, val);
605
606         if (enabled)
607                 pm3393_enable(cmac, enabled);
608         return 0;
609 }
610
611 static void pm3393_destroy(struct cmac *cmac)
612 {
613         kfree(cmac);
614 }
615
616 static struct cmac_ops pm3393_ops = {
617         .destroy                 = pm3393_destroy,
618         .reset                   = pm3393_reset,
619         .interrupt_enable        = pm3393_interrupt_enable,
620         .interrupt_disable       = pm3393_interrupt_disable,
621         .interrupt_clear         = pm3393_interrupt_clear,
622         .interrupt_handler       = pm3393_interrupt_handler,
623         .enable                  = pm3393_enable_port,
624         .disable                 = pm3393_disable,
625         .loopback_enable         = pm3393_loopback_enable,
626         .loopback_disable        = pm3393_loopback_disable,
627         .set_mtu                 = pm3393_set_mtu,
628         .set_rx_mode             = pm3393_set_rx_mode,
629         .get_speed_duplex_fc     = pm3393_get_speed_duplex_fc,
630         .set_speed_duplex_fc     = pm3393_set_speed_duplex_fc,
631         .statistics_update       = pm3393_update_statistics,
632         .macaddress_get          = pm3393_macaddress_get,
633         .macaddress_set          = pm3393_macaddress_set
634 };
635
636 static struct cmac *pm3393_mac_create(adapter_t *adapter, int index)
637 {
638         struct cmac *cmac;
639
640         cmac = kzalloc(sizeof(*cmac) + sizeof(cmac_instance), GFP_KERNEL);
641         if (!cmac)
642                 return NULL;
643
644         cmac->ops = &pm3393_ops;
645         cmac->instance = (cmac_instance *) (cmac + 1);
646         cmac->adapter = adapter;
647         cmac->instance->fc = PAUSE_TX | PAUSE_RX;
648
649         t1_tpi_write(adapter, OFFSET(0x0001), 0x00008000);
650         t1_tpi_write(adapter, OFFSET(0x0001), 0x00000000);
651         t1_tpi_write(adapter, OFFSET(0x2308), 0x00009800);
652         t1_tpi_write(adapter, OFFSET(0x2305), 0x00001001);   /* PL4IO Enable */
653         t1_tpi_write(adapter, OFFSET(0x2320), 0x00008800);
654         t1_tpi_write(adapter, OFFSET(0x2321), 0x00008800);
655         t1_tpi_write(adapter, OFFSET(0x2322), 0x00008800);
656         t1_tpi_write(adapter, OFFSET(0x2323), 0x00008800);
657         t1_tpi_write(adapter, OFFSET(0x2324), 0x00008800);
658         t1_tpi_write(adapter, OFFSET(0x2325), 0x00008800);
659         t1_tpi_write(adapter, OFFSET(0x2326), 0x00008800);
660         t1_tpi_write(adapter, OFFSET(0x2327), 0x00008800);
661         t1_tpi_write(adapter, OFFSET(0x2328), 0x00008800);
662         t1_tpi_write(adapter, OFFSET(0x2329), 0x00008800);
663         t1_tpi_write(adapter, OFFSET(0x232a), 0x00008800);
664         t1_tpi_write(adapter, OFFSET(0x232b), 0x00008800);
665         t1_tpi_write(adapter, OFFSET(0x232c), 0x00008800);
666         t1_tpi_write(adapter, OFFSET(0x232d), 0x00008800);
667         t1_tpi_write(adapter, OFFSET(0x232e), 0x00008800);
668         t1_tpi_write(adapter, OFFSET(0x232f), 0x00008800);
669         t1_tpi_write(adapter, OFFSET(0x230d), 0x00009c00);
670         t1_tpi_write(adapter, OFFSET(0x2304), 0x00000202);      /* PL4IO Calendar Repetitions */
671
672         t1_tpi_write(adapter, OFFSET(0x3200), 0x00008080);      /* EFLX Enable */
673         t1_tpi_write(adapter, OFFSET(0x3210), 0x00000000);      /* EFLX Channel Deprovision */
674         t1_tpi_write(adapter, OFFSET(0x3203), 0x00000000);      /* EFLX Low Limit */
675         t1_tpi_write(adapter, OFFSET(0x3204), 0x00000040);      /* EFLX High Limit */
676         t1_tpi_write(adapter, OFFSET(0x3205), 0x000002cc);      /* EFLX Almost Full */
677         t1_tpi_write(adapter, OFFSET(0x3206), 0x00000199);      /* EFLX Almost Empty */
678         t1_tpi_write(adapter, OFFSET(0x3207), 0x00000240);      /* EFLX Cut Through Threshold */
679         t1_tpi_write(adapter, OFFSET(0x3202), 0x00000000);      /* EFLX Indirect Register Update */
680         t1_tpi_write(adapter, OFFSET(0x3210), 0x00000001);      /* EFLX Channel Provision */
681         t1_tpi_write(adapter, OFFSET(0x3208), 0x0000ffff);      /* EFLX Undocumented */
682         t1_tpi_write(adapter, OFFSET(0x320a), 0x0000ffff);      /* EFLX Undocumented */
683         t1_tpi_write(adapter, OFFSET(0x320c), 0x0000ffff);      /* EFLX enable overflow interrupt The other bit are undocumented */
684         t1_tpi_write(adapter, OFFSET(0x320e), 0x0000ffff);      /* EFLX Undocumented */
685
686         t1_tpi_write(adapter, OFFSET(0x2200), 0x0000c000);      /* IFLX Configuration - enable */
687         t1_tpi_write(adapter, OFFSET(0x2201), 0x00000000);      /* IFLX Channel Deprovision */
688         t1_tpi_write(adapter, OFFSET(0x220e), 0x00000000);      /* IFLX Low Limit */
689         t1_tpi_write(adapter, OFFSET(0x220f), 0x00000100);      /* IFLX High Limit */
690         t1_tpi_write(adapter, OFFSET(0x2210), 0x00000c00);      /* IFLX Almost Full Limit */
691         t1_tpi_write(adapter, OFFSET(0x2211), 0x00000599);      /* IFLX Almost Empty Limit */
692         t1_tpi_write(adapter, OFFSET(0x220d), 0x00000000);      /* IFLX Indirect Register Update */
693         t1_tpi_write(adapter, OFFSET(0x2201), 0x00000001);      /* IFLX Channel Provision */
694         t1_tpi_write(adapter, OFFSET(0x2203), 0x0000ffff);      /* IFLX Undocumented */
695         t1_tpi_write(adapter, OFFSET(0x2205), 0x0000ffff);      /* IFLX Undocumented */
696         t1_tpi_write(adapter, OFFSET(0x2209), 0x0000ffff);      /* IFLX Enable overflow interrupt.  The other bit are undocumented */
697
698         t1_tpi_write(adapter, OFFSET(0x2241), 0xfffffffe);      /* PL4MOS Undocumented */
699         t1_tpi_write(adapter, OFFSET(0x2242), 0x0000ffff);      /* PL4MOS Undocumented */
700         t1_tpi_write(adapter, OFFSET(0x2243), 0x00000008);      /* PL4MOS Starving Burst Size */
701         t1_tpi_write(adapter, OFFSET(0x2244), 0x00000008);      /* PL4MOS Hungry Burst Size */
702         t1_tpi_write(adapter, OFFSET(0x2245), 0x00000008);      /* PL4MOS Transfer Size */
703         t1_tpi_write(adapter, OFFSET(0x2240), 0x00000005);      /* PL4MOS Disable */
704
705         t1_tpi_write(adapter, OFFSET(0x2280), 0x00002103);      /* PL4ODP Training Repeat and SOP rule */
706         t1_tpi_write(adapter, OFFSET(0x2284), 0x00000000);      /* PL4ODP MAX_T setting */
707
708         t1_tpi_write(adapter, OFFSET(0x3280), 0x00000087);      /* PL4IDU Enable data forward, port state machine. Set ALLOW_NON_ZERO_OLB */
709         t1_tpi_write(adapter, OFFSET(0x3282), 0x0000001f);      /* PL4IDU Enable Dip4 check error interrupts */
710
711         t1_tpi_write(adapter, OFFSET(0x3040), 0x0c32);  /* # TXXG Config */
712         /* For T1 use timer based Mac flow control. */
713         t1_tpi_write(adapter, OFFSET(0x304d), 0x8000);
714         t1_tpi_write(adapter, OFFSET(0x2040), 0x059c);  /* # RXXG Config */
715         t1_tpi_write(adapter, OFFSET(0x2049), 0x0001);  /* # RXXG Cut Through */
716         t1_tpi_write(adapter, OFFSET(0x2070), 0x0000);  /* # Disable promiscuous mode */
717
718         /* Setup Exact Match Filter 0 to allow broadcast packets.
719          */
720         t1_tpi_write(adapter, OFFSET(0x206e), 0x0000);  /* # Disable Match Enable bit */
721         t1_tpi_write(adapter, OFFSET(0x204a), 0xffff);  /* # low addr */
722         t1_tpi_write(adapter, OFFSET(0x204b), 0xffff);  /* # mid addr */
723         t1_tpi_write(adapter, OFFSET(0x204c), 0xffff);  /* # high addr */
724         t1_tpi_write(adapter, OFFSET(0x206e), 0x0009);  /* # Enable Match Enable bit */
725
726         t1_tpi_write(adapter, OFFSET(0x0003), 0x0000);  /* # NO SOP/ PAD_EN setup */
727         t1_tpi_write(adapter, OFFSET(0x0100), 0x0ff0);  /* # RXEQB disabled */
728         t1_tpi_write(adapter, OFFSET(0x0101), 0x0f0f);  /* # No Preemphasis */
729
730         return cmac;
731 }
732
733 static int pm3393_mac_reset(adapter_t * adapter)
734 {
735         u32 val;
736         u32 x;
737         u32 is_pl4_reset_finished;
738         u32 is_pl4_outof_lock;
739         u32 is_xaui_mabc_pll_locked;
740         u32 successful_reset;
741         int i;
742
743         /* The following steps are required to properly reset
744          * the PM3393. This information is provided in the
745          * PM3393 datasheet (Issue 2: November 2002)
746          * section 13.1 -- Device Reset.
747          *
748          * The PM3393 has three types of components that are
749          * individually reset:
750          *
751          * DRESETB      - Digital circuitry
752          * PL4_ARESETB  - PL4 analog circuitry
753          * XAUI_ARESETB - XAUI bus analog circuitry
754          *
755          * Steps to reset PM3393 using RSTB pin:
756          *
757          * 1. Assert RSTB pin low ( write 0 )
758          * 2. Wait at least 1ms to initiate a complete initialization of device.
759          * 3. Wait until all external clocks and REFSEL are stable.
760          * 4. Wait minimum of 1ms. (after external clocks and REFEL are stable)
761          * 5. De-assert RSTB ( write 1 )
762          * 6. Wait until internal timers to expires after ~14ms.
763          *    - Allows analog clock synthesizer(PL4CSU) to stabilize to
764          *      selected reference frequency before allowing the digital
765          *      portion of the device to operate.
766          * 7. Wait at least 200us for XAUI interface to stabilize.
767          * 8. Verify the PM3393 came out of reset successfully.
768          *    Set successful reset flag if everything worked else try again
769          *    a few more times.
770          */
771
772         successful_reset = 0;
773         for (i = 0; i < 3 && !successful_reset; i++) {
774                 /* 1 */
775                 t1_tpi_read(adapter, A_ELMER0_GPO, &val);
776                 val &= ~1;
777                 t1_tpi_write(adapter, A_ELMER0_GPO, val);
778
779                 /* 2 */
780                 msleep(1);
781
782                 /* 3 */
783                 msleep(1);
784
785                 /* 4 */
786                 msleep(2 /*1 extra ms for safety */ );
787
788                 /* 5 */
789                 val |= 1;
790                 t1_tpi_write(adapter, A_ELMER0_GPO, val);
791
792                 /* 6 */
793                 msleep(15 /*1 extra ms for safety */ );
794
795                 /* 7 */
796                 msleep(1);
797
798                 /* 8 */
799
800                 /* Has PL4 analog block come out of reset correctly? */
801                 t1_tpi_read(adapter, OFFSET(SUNI1x10GEXP_REG_DEVICE_STATUS), &val);
802                 is_pl4_reset_finished = (val & SUNI1x10GEXP_BITMSK_TOP_EXPIRED);
803
804                 /* TBD XXX SUNI1x10GEXP_BITMSK_TOP_PL4_IS_DOOL gets locked later in the init sequence
805                  *         figure out why? */
806
807                 /* Have all PL4 block clocks locked? */
808                 x = (SUNI1x10GEXP_BITMSK_TOP_PL4_ID_DOOL
809                      /*| SUNI1x10GEXP_BITMSK_TOP_PL4_IS_DOOL */  |
810                      SUNI1x10GEXP_BITMSK_TOP_PL4_ID_ROOL |
811                      SUNI1x10GEXP_BITMSK_TOP_PL4_IS_ROOL |
812                      SUNI1x10GEXP_BITMSK_TOP_PL4_OUT_ROOL);
813                 is_pl4_outof_lock = (val & x);
814
815                 /* ??? If this fails, might be able to software reset the XAUI part
816                  *     and try to recover... thus saving us from doing another HW reset */
817                 /* Has the XAUI MABC PLL circuitry stablized? */
818                 is_xaui_mabc_pll_locked =
819                     (val & SUNI1x10GEXP_BITMSK_TOP_SXRA_EXPIRED);
820
821                 successful_reset = (is_pl4_reset_finished && !is_pl4_outof_lock
822                                     && is_xaui_mabc_pll_locked);
823
824                 CH_DBG(adapter, HW,
825                        "PM3393 HW reset %d: pl4_reset 0x%x, val 0x%x, "
826                        "is_pl4_outof_lock 0x%x, xaui_locked 0x%x\n",
827                        i, is_pl4_reset_finished, val, is_pl4_outof_lock,
828                        is_xaui_mabc_pll_locked);
829         }
830         return successful_reset ? 0 : 1;
831 }
832
833 struct gmac t1_pm3393_ops = {
834         STATS_TICK_SECS,
835         pm3393_mac_create,
836         pm3393_mac_reset
837 };