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