Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Agere Systems Inc. |
| 3 | * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs |
| 4 | * |
Alan Cox | 64f9303 | 2009-06-10 17:30:41 +0100 | [diff] [blame] | 5 | * Copyright © 2005 Agere Systems Inc. |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 6 | * All rights reserved. |
| 7 | * http://www.agere.com |
| 8 | * |
| 9 | *------------------------------------------------------------------------------ |
| 10 | * |
| 11 | * et1310_mac.c - All code and routines pertaining to the MAC |
| 12 | * |
| 13 | *------------------------------------------------------------------------------ |
| 14 | * |
| 15 | * SOFTWARE LICENSE |
| 16 | * |
| 17 | * This software is provided subject to the following terms and conditions, |
| 18 | * which you should read carefully before using the software. Using this |
| 19 | * software indicates your acceptance of these terms and conditions. If you do |
| 20 | * not agree with these terms and conditions, do not use the software. |
| 21 | * |
Alan Cox | 64f9303 | 2009-06-10 17:30:41 +0100 | [diff] [blame] | 22 | * Copyright © 2005 Agere Systems Inc. |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 23 | * All rights reserved. |
| 24 | * |
| 25 | * Redistribution and use in source or binary forms, with or without |
| 26 | * modifications, are permitted provided that the following conditions are met: |
| 27 | * |
| 28 | * . Redistributions of source code must retain the above copyright notice, this |
| 29 | * list of conditions and the following Disclaimer as comments in the code as |
| 30 | * well as in the documentation and/or other materials provided with the |
| 31 | * distribution. |
| 32 | * |
| 33 | * . Redistributions in binary form must reproduce the above copyright notice, |
| 34 | * this list of conditions and the following Disclaimer in the documentation |
| 35 | * and/or other materials provided with the distribution. |
| 36 | * |
| 37 | * . Neither the name of Agere Systems Inc. nor the names of the contributors |
| 38 | * may be used to endorse or promote products derived from this software |
| 39 | * without specific prior written permission. |
| 40 | * |
| 41 | * Disclaimer |
| 42 | * |
Alan Cox | 64f9303 | 2009-06-10 17:30:41 +0100 | [diff] [blame] | 43 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 44 | * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF |
| 45 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY |
| 46 | * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN |
| 47 | * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY |
| 48 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 49 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 50 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| 51 | * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT |
| 52 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| 53 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
| 54 | * DAMAGE. |
| 55 | * |
| 56 | */ |
| 57 | |
| 58 | #include "et131x_version.h" |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 59 | #include "et131x_defs.h" |
| 60 | |
| 61 | #include <linux/init.h> |
| 62 | #include <linux/module.h> |
| 63 | #include <linux/types.h> |
| 64 | #include <linux/kernel.h> |
| 65 | |
| 66 | #include <linux/sched.h> |
| 67 | #include <linux/ptrace.h> |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 68 | #include <linux/ctype.h> |
| 69 | #include <linux/string.h> |
| 70 | #include <linux/timer.h> |
| 71 | #include <linux/interrupt.h> |
| 72 | #include <linux/in.h> |
| 73 | #include <linux/delay.h> |
Alan Cox | 64f9303 | 2009-06-10 17:30:41 +0100 | [diff] [blame] | 74 | #include <linux/io.h> |
| 75 | #include <linux/bitops.h> |
Alan Cox | 1570003 | 2009-08-27 11:03:09 +0100 | [diff] [blame] | 76 | #include <linux/pci.h> |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 77 | #include <asm/system.h> |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 78 | |
| 79 | #include <linux/netdevice.h> |
| 80 | #include <linux/etherdevice.h> |
| 81 | #include <linux/skbuff.h> |
| 82 | #include <linux/if_arp.h> |
| 83 | #include <linux/ioport.h> |
| 84 | #include <linux/crc32.h> |
| 85 | |
| 86 | #include "et1310_phy.h" |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 87 | #include "et131x_adapter.h" |
Alan Cox | 69ea5fc | 2010-01-18 15:34:24 +0000 | [diff] [blame] | 88 | #include "et131x.h" |
| 89 | |
| 90 | |
| 91 | #define COUNTER_WRAP_28_BIT 0x10000000 |
| 92 | #define COUNTER_WRAP_22_BIT 0x400000 |
| 93 | #define COUNTER_WRAP_16_BIT 0x10000 |
| 94 | #define COUNTER_WRAP_12_BIT 0x1000 |
| 95 | |
| 96 | #define COUNTER_MASK_28_BIT (COUNTER_WRAP_28_BIT - 1) |
| 97 | #define COUNTER_MASK_22_BIT (COUNTER_WRAP_22_BIT - 1) |
| 98 | #define COUNTER_MASK_16_BIT (COUNTER_WRAP_16_BIT - 1) |
| 99 | #define COUNTER_MASK_12_BIT (COUNTER_WRAP_12_BIT - 1) |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 100 | |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 101 | /** |
| 102 | * ConfigMacRegs1 - Initialize the first part of MAC regs |
| 103 | * @pAdpater: pointer to our adapter structure |
| 104 | */ |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 105 | void ConfigMACRegs1(struct et131x_adapter *etdev) |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 106 | { |
Alan Cox | f3f415a | 2009-08-27 10:59:30 +0100 | [diff] [blame] | 107 | struct _MAC_t __iomem *pMac = &etdev->regs->mac; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 108 | MAC_STATION_ADDR1_t station1; |
| 109 | MAC_STATION_ADDR2_t station2; |
Alan Cox | 308e93e | 2009-10-06 15:50:26 +0100 | [diff] [blame] | 110 | u32 ipg; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 111 | |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 112 | /* First we need to reset everything. Write to MAC configuration |
| 113 | * register 1 to perform reset. |
| 114 | */ |
Alan Cox | c9835d97 | 2009-10-06 15:50:45 +0100 | [diff] [blame] | 115 | writel(0xC00F0000, &pMac->cfg1); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 116 | |
| 117 | /* Next lets configure the MAC Inter-packet gap register */ |
Alan Cox | 308e93e | 2009-10-06 15:50:26 +0100 | [diff] [blame] | 118 | ipg = 0x38005860; /* IPG1 0x38 IPG2 0x58 B2B 0x60 */ |
| 119 | ipg |= 0x50 << 8; /* ifg enforce 0x50 */ |
| 120 | writel(ipg, &pMac->ipg); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 121 | |
| 122 | /* Next lets configure the MAC Half Duplex register */ |
Alan Cox | c2f6118 | 2009-10-06 15:50:32 +0100 | [diff] [blame] | 123 | /* BEB trunc 0xA, Ex Defer, Rexmit 0xF Coll 0x37 */ |
| 124 | writel(0x00A1F037, &pMac->hfdp); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 125 | |
| 126 | /* Next lets configure the MAC Interface Control register */ |
Alan Cox | b491f14 | 2009-11-18 14:06:50 +0000 | [diff] [blame] | 127 | writel(0, &pMac->if_ctrl); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 128 | |
Uwe Kleine-König | 658ce9d | 2009-07-23 08:33:56 +0200 | [diff] [blame] | 129 | /* Let's move on to setting up the mii management configuration */ |
Alan Cox | eccdd88 | 2009-10-06 15:50:39 +0100 | [diff] [blame] | 130 | writel(0x07, &pMac->mii_mgmt_cfg); /* Clock reset 0x7 */ |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 131 | |
| 132 | /* Next lets configure the MAC Station Address register. These |
| 133 | * values are read from the EEPROM during initialization and stored |
| 134 | * in the adapter structure. We write what is stored in the adapter |
| 135 | * structure to the MAC Station Address registers high and low. This |
| 136 | * station address is used for generating and checking pause control |
| 137 | * packets. |
| 138 | */ |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 139 | station2.bits.Octet1 = etdev->CurrentAddress[0]; |
| 140 | station2.bits.Octet2 = etdev->CurrentAddress[1]; |
| 141 | station1.bits.Octet3 = etdev->CurrentAddress[2]; |
| 142 | station1.bits.Octet4 = etdev->CurrentAddress[3]; |
| 143 | station1.bits.Octet5 = etdev->CurrentAddress[4]; |
| 144 | station1.bits.Octet6 = etdev->CurrentAddress[5]; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 145 | writel(station1.value, &pMac->station_addr_1.value); |
| 146 | writel(station2.value, &pMac->station_addr_2.value); |
| 147 | |
| 148 | /* Max ethernet packet in bytes that will passed by the mac without |
| 149 | * being truncated. Allow the MAC to pass 4 more than our max packet |
| 150 | * size. This is 4 for the Ethernet CRC. |
| 151 | * |
| 152 | * Packets larger than (RegistryJumboPacket) that do not contain a |
| 153 | * VLAN ID will be dropped by the Rx function. |
| 154 | */ |
Alan Cox | cc5dc29 | 2009-10-06 15:50:51 +0100 | [diff] [blame] | 155 | writel(etdev->RegistryJumboPacket + 4, &pMac->max_fm_len); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 156 | |
| 157 | /* clear out MAC config reset */ |
Alan Cox | c9835d97 | 2009-10-06 15:50:45 +0100 | [diff] [blame] | 158 | writel(0, &pMac->cfg1); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 159 | } |
| 160 | |
| 161 | /** |
| 162 | * ConfigMacRegs2 - Initialize the second part of MAC regs |
| 163 | * @pAdpater: pointer to our adapter structure |
| 164 | */ |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 165 | void ConfigMACRegs2(struct et131x_adapter *etdev) |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 166 | { |
| 167 | int32_t delay = 0; |
Alan Cox | f3f415a | 2009-08-27 10:59:30 +0100 | [diff] [blame] | 168 | struct _MAC_t __iomem *pMac = &etdev->regs->mac; |
Alan Cox | c9835d97 | 2009-10-06 15:50:45 +0100 | [diff] [blame] | 169 | u32 cfg1; |
| 170 | u32 cfg2; |
Alan Cox | b491f14 | 2009-11-18 14:06:50 +0000 | [diff] [blame] | 171 | u32 ifctrl; |
Alan Cox | 6720949 | 2010-01-18 15:34:29 +0000 | [diff] [blame] | 172 | u32 ctl; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 173 | |
Alan Cox | 6720949 | 2010-01-18 15:34:29 +0000 | [diff] [blame] | 174 | ctl = readl(&etdev->regs->txmac.ctl); |
Alan Cox | c9835d97 | 2009-10-06 15:50:45 +0100 | [diff] [blame] | 175 | cfg1 = readl(&pMac->cfg1); |
| 176 | cfg2 = readl(&pMac->cfg2); |
Alan Cox | b491f14 | 2009-11-18 14:06:50 +0000 | [diff] [blame] | 177 | ifctrl = readl(&pMac->if_ctrl); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 178 | |
Alan Cox | c9835d97 | 2009-10-06 15:50:45 +0100 | [diff] [blame] | 179 | /* Set up the if mode bits */ |
| 180 | cfg2 &= ~0x300; |
Alan Cox | 9fa8109 | 2009-08-27 11:00:36 +0100 | [diff] [blame] | 181 | if (etdev->linkspeed == TRUEPHY_SPEED_1000MBPS) { |
Alan Cox | c9835d97 | 2009-10-06 15:50:45 +0100 | [diff] [blame] | 182 | cfg2 |= 0x200; |
Alan Cox | b491f14 | 2009-11-18 14:06:50 +0000 | [diff] [blame] | 183 | /* Phy mode bit */ |
| 184 | ifctrl &= ~(1 << 24); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 185 | } else { |
Alan Cox | c9835d97 | 2009-10-06 15:50:45 +0100 | [diff] [blame] | 186 | cfg2 |= 0x100; |
Alan Cox | b491f14 | 2009-11-18 14:06:50 +0000 | [diff] [blame] | 187 | ifctrl |= (1 << 24); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 188 | } |
| 189 | |
| 190 | /* We need to enable Rx/Tx */ |
Alan Cox | c9835d97 | 2009-10-06 15:50:45 +0100 | [diff] [blame] | 191 | cfg1 |= CFG1_RX_ENABLE|CFG1_TX_ENABLE|CFG1_TX_FLOW; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 192 | /* Initialize loop back to off */ |
Alan Cox | c9835d97 | 2009-10-06 15:50:45 +0100 | [diff] [blame] | 193 | cfg1 &= ~(CFG1_LOOPBACK|CFG1_RX_FLOW); |
| 194 | if (etdev->FlowControl == RxOnly || etdev->FlowControl == Both) |
| 195 | cfg1 |= CFG1_RX_FLOW; |
| 196 | writel(cfg1, &pMac->cfg1); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 197 | |
| 198 | /* Now we need to initialize the MAC Configuration 2 register */ |
Alan Cox | c9835d97 | 2009-10-06 15:50:45 +0100 | [diff] [blame] | 199 | /* preamble 7, check length, huge frame off, pad crc, crc enable |
| 200 | full duplex off */ |
| 201 | cfg2 |= 0x7016; |
| 202 | cfg2 &= ~0x0021; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 203 | |
Alan Cox | c9835d97 | 2009-10-06 15:50:45 +0100 | [diff] [blame] | 204 | /* Turn on duplex if needed */ |
| 205 | if (etdev->duplex_mode) |
| 206 | cfg2 |= 0x01; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 207 | |
Alan Cox | b491f14 | 2009-11-18 14:06:50 +0000 | [diff] [blame] | 208 | ifctrl &= ~(1 << 26); |
| 209 | if (!etdev->duplex_mode) |
| 210 | ifctrl |= (1<<26); /* Enable ghd */ |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 211 | |
Alan Cox | b491f14 | 2009-11-18 14:06:50 +0000 | [diff] [blame] | 212 | writel(ifctrl, &pMac->if_ctrl); |
Alan Cox | c9835d97 | 2009-10-06 15:50:45 +0100 | [diff] [blame] | 213 | writel(cfg2, &pMac->cfg2); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 214 | |
| 215 | do { |
| 216 | udelay(10); |
| 217 | delay++; |
Alan Cox | c9835d97 | 2009-10-06 15:50:45 +0100 | [diff] [blame] | 218 | cfg1 = readl(&pMac->cfg1); |
| 219 | } while ((cfg1 & CFG1_WAIT) != CFG1_WAIT && delay < 100); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 220 | |
| 221 | if (delay == 100) { |
Alan Cox | 1570003 | 2009-08-27 11:03:09 +0100 | [diff] [blame] | 222 | dev_warn(&etdev->pdev->dev, |
Alan Cox | 64f9303 | 2009-06-10 17:30:41 +0100 | [diff] [blame] | 223 | "Syncd bits did not respond correctly cfg1 word 0x%08x\n", |
Alan Cox | c9835d97 | 2009-10-06 15:50:45 +0100 | [diff] [blame] | 224 | cfg1); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 225 | } |
| 226 | |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 227 | /* Enable TXMAC */ |
Nick Bowler | 05ad62a | 2010-03-10 00:10:46 -0500 | [diff] [blame] | 228 | ctl |= 0x09; /* TX mac enable, FC disable */ |
Alan Cox | 6720949 | 2010-01-18 15:34:29 +0000 | [diff] [blame] | 229 | writel(ctl, &etdev->regs->txmac.ctl); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 230 | |
| 231 | /* Ready to start the RXDMA/TXDMA engine */ |
Alan Cox | f6b35d6 | 2009-08-27 11:02:05 +0100 | [diff] [blame] | 232 | if (etdev->Flags & fMP_ADAPTER_LOWER_POWER) { |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 233 | et131x_rx_dma_enable(etdev); |
| 234 | et131x_tx_dma_enable(etdev); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 235 | } |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 236 | } |
| 237 | |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 238 | void ConfigRxMacRegs(struct et131x_adapter *etdev) |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 239 | { |
Alan Cox | f3f415a | 2009-08-27 10:59:30 +0100 | [diff] [blame] | 240 | struct _RXMAC_t __iomem *pRxMac = &etdev->regs->rxmac; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 241 | RXMAC_WOL_SA_LO_t sa_lo; |
| 242 | RXMAC_WOL_SA_HI_t sa_hi; |
Alan Cox | b186f33 | 2010-01-18 15:34:57 +0000 | [diff] [blame] | 243 | u32 pf_ctrl = 0; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 244 | |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 245 | /* Disable the MAC while it is being configured (also disable WOL) */ |
Alan Cox | bd03d0d | 2010-01-18 15:35:30 +0000 | [diff] [blame] | 246 | writel(0x8, &pRxMac->ctrl); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 247 | |
| 248 | /* Initialize WOL to disabled. */ |
Alan Cox | 70a29a2 | 2010-01-18 15:34:51 +0000 | [diff] [blame] | 249 | writel(0, &pRxMac->crc0); |
| 250 | writel(0, &pRxMac->crc12); |
| 251 | writel(0, &pRxMac->crc34); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 252 | |
| 253 | /* We need to set the WOL mask0 - mask4 next. We initialize it to |
| 254 | * its default Values of 0x00000000 because there are not WOL masks |
| 255 | * as of this time. |
| 256 | */ |
| 257 | writel(0, &pRxMac->mask0_word0); |
| 258 | writel(0, &pRxMac->mask0_word1); |
| 259 | writel(0, &pRxMac->mask0_word2); |
| 260 | writel(0, &pRxMac->mask0_word3); |
| 261 | |
| 262 | writel(0, &pRxMac->mask1_word0); |
| 263 | writel(0, &pRxMac->mask1_word1); |
| 264 | writel(0, &pRxMac->mask1_word2); |
| 265 | writel(0, &pRxMac->mask1_word3); |
| 266 | |
| 267 | writel(0, &pRxMac->mask2_word0); |
| 268 | writel(0, &pRxMac->mask2_word1); |
| 269 | writel(0, &pRxMac->mask2_word2); |
| 270 | writel(0, &pRxMac->mask2_word3); |
| 271 | |
| 272 | writel(0, &pRxMac->mask3_word0); |
| 273 | writel(0, &pRxMac->mask3_word1); |
| 274 | writel(0, &pRxMac->mask3_word2); |
| 275 | writel(0, &pRxMac->mask3_word3); |
| 276 | |
| 277 | writel(0, &pRxMac->mask4_word0); |
| 278 | writel(0, &pRxMac->mask4_word1); |
| 279 | writel(0, &pRxMac->mask4_word2); |
| 280 | writel(0, &pRxMac->mask4_word3); |
| 281 | |
| 282 | /* Lets setup the WOL Source Address */ |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 283 | sa_lo.bits.sa3 = etdev->CurrentAddress[2]; |
| 284 | sa_lo.bits.sa4 = etdev->CurrentAddress[3]; |
| 285 | sa_lo.bits.sa5 = etdev->CurrentAddress[4]; |
| 286 | sa_lo.bits.sa6 = etdev->CurrentAddress[5]; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 287 | writel(sa_lo.value, &pRxMac->sa_lo.value); |
| 288 | |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 289 | sa_hi.bits.sa1 = etdev->CurrentAddress[0]; |
| 290 | sa_hi.bits.sa2 = etdev->CurrentAddress[1]; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 291 | writel(sa_hi.value, &pRxMac->sa_hi.value); |
| 292 | |
| 293 | /* Disable all Packet Filtering */ |
Alan Cox | b186f33 | 2010-01-18 15:34:57 +0000 | [diff] [blame] | 294 | writel(0, &pRxMac->pf_ctrl); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 295 | |
| 296 | /* Let's initialize the Unicast Packet filtering address */ |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 297 | if (etdev->PacketFilter & ET131X_PACKET_TYPE_DIRECTED) { |
| 298 | SetupDeviceForUnicast(etdev); |
Alan Cox | b186f33 | 2010-01-18 15:34:57 +0000 | [diff] [blame] | 299 | pf_ctrl |= 4; /* Unicast filter */ |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 300 | } else { |
| 301 | writel(0, &pRxMac->uni_pf_addr1.value); |
| 302 | writel(0, &pRxMac->uni_pf_addr2.value); |
| 303 | writel(0, &pRxMac->uni_pf_addr3.value); |
| 304 | } |
| 305 | |
| 306 | /* Let's initialize the Multicast hash */ |
Alan Cox | b186f33 | 2010-01-18 15:34:57 +0000 | [diff] [blame] | 307 | if (!(etdev->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST)) { |
| 308 | pf_ctrl |= 2; /* Multicast filter */ |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 309 | SetupDeviceForMulticast(etdev); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 310 | } |
| 311 | |
| 312 | /* Runt packet filtering. Didn't work in version A silicon. */ |
Alan Cox | b186f33 | 2010-01-18 15:34:57 +0000 | [diff] [blame] | 313 | pf_ctrl |= (NIC_MIN_PACKET_SIZE + 4) << 16; |
| 314 | pf_ctrl |= 8; /* Fragment filter */ |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 315 | |
Alan Cox | 287acb6 | 2010-01-18 15:35:02 +0000 | [diff] [blame] | 316 | if (etdev->RegistryJumboPacket > 8192) |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 317 | /* In order to transmit jumbo packets greater than 8k, the |
| 318 | * FIFO between RxMAC and RxDMA needs to be reduced in size |
| 319 | * to (16k - Jumbo packet size). In order to implement this, |
| 320 | * we must use "cut through" mode in the RxMAC, which chops |
| 321 | * packets down into segments which are (max_size * 16). In |
| 322 | * this case we selected 256 bytes, since this is the size of |
| 323 | * the PCI-Express TLP's that the 1310 uses. |
Alan Cox | 287acb6 | 2010-01-18 15:35:02 +0000 | [diff] [blame] | 324 | * |
| 325 | * seg_en on, fc_en off, size 0x10 |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 326 | */ |
Alan Cox | 287acb6 | 2010-01-18 15:35:02 +0000 | [diff] [blame] | 327 | writel(0x41, &pRxMac->mcif_ctrl_max_seg); |
| 328 | else |
| 329 | writel(0, &pRxMac->mcif_ctrl_max_seg); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 330 | |
| 331 | /* Initialize the MCIF water marks */ |
Alan Cox | 287acb6 | 2010-01-18 15:35:02 +0000 | [diff] [blame] | 332 | writel(0, &pRxMac->mcif_water_mark); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 333 | |
| 334 | /* Initialize the MIF control */ |
Alan Cox | dcb0789 | 2010-01-18 15:35:19 +0000 | [diff] [blame] | 335 | writel(0, &pRxMac->mif_ctrl); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 336 | |
| 337 | /* Initialize the Space Available Register */ |
Alan Cox | 370d52a | 2010-01-18 15:35:13 +0000 | [diff] [blame] | 338 | writel(0, &pRxMac->space_avail); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 339 | |
| 340 | /* Initialize the the mif_ctrl register |
| 341 | * bit 3: Receive code error. One or more nibbles were signaled as |
| 342 | * errors during the reception of the packet. Clear this |
| 343 | * bit in Gigabit, set it in 100Mbit. This was derived |
| 344 | * experimentally at UNH. |
| 345 | * bit 4: Receive CRC error. The packet's CRC did not match the |
| 346 | * internally generated CRC. |
| 347 | * bit 5: Receive length check error. Indicates that frame length |
| 348 | * field value in the packet does not match the actual data |
| 349 | * byte length and is not a type field. |
| 350 | * bit 16: Receive frame truncated. |
| 351 | * bit 17: Drop packet enable |
| 352 | */ |
Alan Cox | 9fa8109 | 2009-08-27 11:00:36 +0100 | [diff] [blame] | 353 | if (etdev->linkspeed == TRUEPHY_SPEED_100MBPS) |
Alan Cox | dcb0789 | 2010-01-18 15:35:19 +0000 | [diff] [blame] | 354 | writel(0x30038, &pRxMac->mif_ctrl); |
Alan Cox | 64f9303 | 2009-06-10 17:30:41 +0100 | [diff] [blame] | 355 | else |
Alan Cox | dcb0789 | 2010-01-18 15:35:19 +0000 | [diff] [blame] | 356 | writel(0x30030, &pRxMac->mif_ctrl); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 357 | |
| 358 | /* Finally we initialize RxMac to be enabled & WOL disabled. Packet |
| 359 | * filter is always enabled since it is where the runt packets are |
| 360 | * supposed to be dropped. For version A silicon, runt packet |
| 361 | * dropping doesn't work, so it is disabled in the pf_ctrl register, |
| 362 | * but we still leave the packet filter on. |
| 363 | */ |
Alan Cox | b186f33 | 2010-01-18 15:34:57 +0000 | [diff] [blame] | 364 | writel(pf_ctrl, &pRxMac->pf_ctrl); |
Alan Cox | bd03d0d | 2010-01-18 15:35:30 +0000 | [diff] [blame] | 365 | writel(0x9, &pRxMac->ctrl); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 366 | } |
| 367 | |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 368 | void ConfigTxMacRegs(struct et131x_adapter *etdev) |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 369 | { |
Alan Cox | afa7e5e | 2010-01-18 15:34:46 +0000 | [diff] [blame] | 370 | struct txmac_regs *txmac = &etdev->regs->txmac; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 371 | |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 372 | /* We need to update the Control Frame Parameters |
| 373 | * cfpt - control frame pause timer set to 64 (0x40) |
| 374 | * cfep - control frame extended pause timer set to 0x0 |
| 375 | */ |
Alan Cox | f838cab | 2009-11-18 14:07:09 +0000 | [diff] [blame] | 376 | if (etdev->FlowControl == None) |
Alan Cox | afa7e5e | 2010-01-18 15:34:46 +0000 | [diff] [blame] | 377 | writel(0, &txmac->cf_param); |
Alan Cox | f838cab | 2009-11-18 14:07:09 +0000 | [diff] [blame] | 378 | else |
Alan Cox | afa7e5e | 2010-01-18 15:34:46 +0000 | [diff] [blame] | 379 | writel(0x40, &txmac->cf_param); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 380 | } |
| 381 | |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 382 | void ConfigMacStatRegs(struct et131x_adapter *etdev) |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 383 | { |
Alan Cox | dc26ffc | 2010-01-18 15:33:29 +0000 | [diff] [blame] | 384 | struct macstat_regs __iomem *macstat = |
| 385 | &etdev->regs->macstat; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 386 | |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 387 | /* Next we need to initialize all the MAC_STAT registers to zero on |
| 388 | * the device. |
| 389 | */ |
Alan Cox | 74f3863 | 2009-11-18 14:07:03 +0000 | [diff] [blame] | 390 | writel(0, &macstat->RFcs); |
| 391 | writel(0, &macstat->RAln); |
| 392 | writel(0, &macstat->RFlr); |
| 393 | writel(0, &macstat->RDrp); |
| 394 | writel(0, &macstat->RCde); |
| 395 | writel(0, &macstat->ROvr); |
| 396 | writel(0, &macstat->RFrg); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 397 | |
Alan Cox | 74f3863 | 2009-11-18 14:07:03 +0000 | [diff] [blame] | 398 | writel(0, &macstat->TScl); |
| 399 | writel(0, &macstat->TDfr); |
| 400 | writel(0, &macstat->TMcl); |
| 401 | writel(0, &macstat->TLcl); |
| 402 | writel(0, &macstat->TNcl); |
| 403 | writel(0, &macstat->TOvr); |
| 404 | writel(0, &macstat->TUnd); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 405 | |
| 406 | /* Unmask any counters that we want to track the overflow of. |
| 407 | * Initially this will be all counters. It may become clear later |
| 408 | * that we do not need to track all counters. |
| 409 | */ |
Alan Cox | 74f3863 | 2009-11-18 14:07:03 +0000 | [diff] [blame] | 410 | writel(0xFFFFBE32, &macstat->Carry1M); |
| 411 | writel(0xFFFE7E8B, &macstat->Carry2M); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 412 | } |
| 413 | |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 414 | void ConfigFlowControl(struct et131x_adapter *etdev) |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 415 | { |
Alan Cox | 9fa8109 | 2009-08-27 11:00:36 +0100 | [diff] [blame] | 416 | if (etdev->duplex_mode == 0) { |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 417 | etdev->FlowControl = None; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 418 | } else { |
Alan Cox | 74f3863 | 2009-11-18 14:07:03 +0000 | [diff] [blame] | 419 | char remote_pause, remote_async_pause; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 420 | |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 421 | ET1310_PhyAccessMiBit(etdev, |
Alan Cox | 74f3863 | 2009-11-18 14:07:03 +0000 | [diff] [blame] | 422 | TRUEPHY_BIT_READ, 5, 10, &remote_pause); |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 423 | ET1310_PhyAccessMiBit(etdev, |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 424 | TRUEPHY_BIT_READ, 5, 11, |
Alan Cox | 74f3863 | 2009-11-18 14:07:03 +0000 | [diff] [blame] | 425 | &remote_async_pause); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 426 | |
Alan Cox | 74f3863 | 2009-11-18 14:07:03 +0000 | [diff] [blame] | 427 | if ((remote_pause == TRUEPHY_BIT_SET) && |
| 428 | (remote_async_pause == TRUEPHY_BIT_SET)) { |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 429 | etdev->FlowControl = etdev->RegistryFlowControl; |
Alan Cox | 74f3863 | 2009-11-18 14:07:03 +0000 | [diff] [blame] | 430 | } else if ((remote_pause == TRUEPHY_BIT_SET) && |
| 431 | (remote_async_pause == TRUEPHY_BIT_CLEAR)) { |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 432 | if (etdev->RegistryFlowControl == Both) |
| 433 | etdev->FlowControl = Both; |
Alan Cox | 64f9303 | 2009-06-10 17:30:41 +0100 | [diff] [blame] | 434 | else |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 435 | etdev->FlowControl = None; |
Alan Cox | 74f3863 | 2009-11-18 14:07:03 +0000 | [diff] [blame] | 436 | } else if ((remote_pause == TRUEPHY_BIT_CLEAR) && |
| 437 | (remote_async_pause == TRUEPHY_BIT_CLEAR)) { |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 438 | etdev->FlowControl = None; |
Alan Cox | 74f3863 | 2009-11-18 14:07:03 +0000 | [diff] [blame] | 439 | } else {/* if (remote_pause == TRUEPHY_CLEAR_BIT && |
| 440 | remote_async_pause == TRUEPHY_SET_BIT) */ |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 441 | if (etdev->RegistryFlowControl == Both) |
| 442 | etdev->FlowControl = RxOnly; |
Alan Cox | 64f9303 | 2009-06-10 17:30:41 +0100 | [diff] [blame] | 443 | else |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 444 | etdev->FlowControl = None; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 445 | } |
| 446 | } |
| 447 | } |
| 448 | |
| 449 | /** |
| 450 | * UpdateMacStatHostCounters - Update the local copy of the statistics |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 451 | * @etdev: pointer to the adapter structure |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 452 | */ |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 453 | void UpdateMacStatHostCounters(struct et131x_adapter *etdev) |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 454 | { |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 455 | struct _ce_stats_t *stats = &etdev->Stats; |
Alan Cox | dc26ffc | 2010-01-18 15:33:29 +0000 | [diff] [blame] | 456 | struct macstat_regs __iomem *macstat = |
| 457 | &etdev->regs->macstat; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 458 | |
Alan Cox | 74f3863 | 2009-11-18 14:07:03 +0000 | [diff] [blame] | 459 | stats->collisions += readl(&macstat->TNcl); |
| 460 | stats->first_collision += readl(&macstat->TScl); |
| 461 | stats->tx_deferred += readl(&macstat->TDfr); |
| 462 | stats->excessive_collisions += readl(&macstat->TMcl); |
| 463 | stats->late_collisions += readl(&macstat->TLcl); |
| 464 | stats->tx_uflo += readl(&macstat->TUnd); |
| 465 | stats->max_pkt_error += readl(&macstat->TOvr); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 466 | |
Alan Cox | 74f3863 | 2009-11-18 14:07:03 +0000 | [diff] [blame] | 467 | stats->alignment_err += readl(&macstat->RAln); |
| 468 | stats->crc_err += readl(&macstat->RCde); |
| 469 | stats->norcvbuf += readl(&macstat->RDrp); |
| 470 | stats->rx_ov_flow += readl(&macstat->ROvr); |
| 471 | stats->code_violations += readl(&macstat->RFcs); |
| 472 | stats->length_err += readl(&macstat->RFlr); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 473 | |
Alan Cox | 74f3863 | 2009-11-18 14:07:03 +0000 | [diff] [blame] | 474 | stats->other_errors += readl(&macstat->RFrg); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 475 | } |
| 476 | |
| 477 | /** |
| 478 | * HandleMacStatInterrupt |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 479 | * @etdev: pointer to the adapter structure |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 480 | * |
| 481 | * One of the MACSTAT counters has wrapped. Update the local copy of |
| 482 | * the statistics held in the adapter structure, checking the "wrap" |
| 483 | * bit for each counter. |
| 484 | */ |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 485 | void HandleMacStatInterrupt(struct et131x_adapter *etdev) |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 486 | { |
Alan Cox | ae8d9d8 | 2009-11-18 14:06:57 +0000 | [diff] [blame] | 487 | u32 Carry1; |
| 488 | u32 Carry2; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 489 | |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 490 | /* Read the interrupt bits from the register(s). These are Clear On |
| 491 | * Write. |
| 492 | */ |
Alan Cox | dc26ffc | 2010-01-18 15:33:29 +0000 | [diff] [blame] | 493 | Carry1 = readl(&etdev->regs->macstat.Carry1); |
| 494 | Carry2 = readl(&etdev->regs->macstat.Carry2); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 495 | |
Alan Cox | dc26ffc | 2010-01-18 15:33:29 +0000 | [diff] [blame] | 496 | writel(Carry1, &etdev->regs->macstat.Carry1); |
| 497 | writel(Carry2, &etdev->regs->macstat.Carry2); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 498 | |
| 499 | /* We need to do update the host copy of all the MAC_STAT counters. |
| 500 | * For each counter, check it's overflow bit. If the overflow bit is |
| 501 | * set, then increment the host version of the count by one complete |
| 502 | * revolution of the counter. This routine is called when the counter |
| 503 | * block indicates that one of the counters has wrapped. |
| 504 | */ |
Alan Cox | ae8d9d8 | 2009-11-18 14:06:57 +0000 | [diff] [blame] | 505 | if (Carry1 & (1 << 14)) |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 506 | etdev->Stats.code_violations += COUNTER_WRAP_16_BIT; |
Alan Cox | ae8d9d8 | 2009-11-18 14:06:57 +0000 | [diff] [blame] | 507 | if (Carry1 & (1 << 8)) |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 508 | etdev->Stats.alignment_err += COUNTER_WRAP_12_BIT; |
Alan Cox | ae8d9d8 | 2009-11-18 14:06:57 +0000 | [diff] [blame] | 509 | if (Carry1 & (1 << 7)) |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 510 | etdev->Stats.length_err += COUNTER_WRAP_16_BIT; |
Alan Cox | ae8d9d8 | 2009-11-18 14:06:57 +0000 | [diff] [blame] | 511 | if (Carry1 & (1 << 2)) |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 512 | etdev->Stats.other_errors += COUNTER_WRAP_16_BIT; |
Alan Cox | ae8d9d8 | 2009-11-18 14:06:57 +0000 | [diff] [blame] | 513 | if (Carry1 & (1 << 6)) |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 514 | etdev->Stats.crc_err += COUNTER_WRAP_16_BIT; |
Alan Cox | ae8d9d8 | 2009-11-18 14:06:57 +0000 | [diff] [blame] | 515 | if (Carry1 & (1 << 3)) |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 516 | etdev->Stats.rx_ov_flow += COUNTER_WRAP_16_BIT; |
Alan Cox | ae8d9d8 | 2009-11-18 14:06:57 +0000 | [diff] [blame] | 517 | if (Carry1 & (1 << 0)) |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 518 | etdev->Stats.norcvbuf += COUNTER_WRAP_16_BIT; |
Alan Cox | ae8d9d8 | 2009-11-18 14:06:57 +0000 | [diff] [blame] | 519 | if (Carry2 & (1 << 16)) |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 520 | etdev->Stats.max_pkt_error += COUNTER_WRAP_12_BIT; |
Alan Cox | ae8d9d8 | 2009-11-18 14:06:57 +0000 | [diff] [blame] | 521 | if (Carry2 & (1 << 15)) |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 522 | etdev->Stats.tx_uflo += COUNTER_WRAP_12_BIT; |
Alan Cox | ae8d9d8 | 2009-11-18 14:06:57 +0000 | [diff] [blame] | 523 | if (Carry2 & (1 << 6)) |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 524 | etdev->Stats.first_collision += COUNTER_WRAP_12_BIT; |
Alan Cox | ae8d9d8 | 2009-11-18 14:06:57 +0000 | [diff] [blame] | 525 | if (Carry2 & (1 << 8)) |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 526 | etdev->Stats.tx_deferred += COUNTER_WRAP_12_BIT; |
Alan Cox | ae8d9d8 | 2009-11-18 14:06:57 +0000 | [diff] [blame] | 527 | if (Carry2 & (1 << 5)) |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 528 | etdev->Stats.excessive_collisions += COUNTER_WRAP_12_BIT; |
Alan Cox | ae8d9d8 | 2009-11-18 14:06:57 +0000 | [diff] [blame] | 529 | if (Carry2 & (1 << 4)) |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 530 | etdev->Stats.late_collisions += COUNTER_WRAP_12_BIT; |
Alan Cox | ae8d9d8 | 2009-11-18 14:06:57 +0000 | [diff] [blame] | 531 | if (Carry2 & (1 << 2)) |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 532 | etdev->Stats.collisions += COUNTER_WRAP_12_BIT; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 533 | } |
| 534 | |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 535 | void SetupDeviceForMulticast(struct et131x_adapter *etdev) |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 536 | { |
Alan Cox | f3f415a | 2009-08-27 10:59:30 +0100 | [diff] [blame] | 537 | struct _RXMAC_t __iomem *rxmac = &etdev->regs->rxmac; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 538 | uint32_t nIndex; |
| 539 | uint32_t result; |
| 540 | uint32_t hash1 = 0; |
| 541 | uint32_t hash2 = 0; |
| 542 | uint32_t hash3 = 0; |
| 543 | uint32_t hash4 = 0; |
Alan Cox | f2c98d2 | 2009-08-27 11:01:49 +0100 | [diff] [blame] | 544 | u32 pm_csr; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 545 | |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 546 | /* If ET131X_PACKET_TYPE_MULTICAST is specified, then we provision |
| 547 | * the multi-cast LIST. If it is NOT specified, (and "ALL" is not |
| 548 | * specified) then we should pass NO multi-cast addresses to the |
| 549 | * driver. |
| 550 | */ |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 551 | if (etdev->PacketFilter & ET131X_PACKET_TYPE_MULTICAST) { |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 552 | /* Loop through our multicast array and set up the device */ |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 553 | for (nIndex = 0; nIndex < etdev->MCAddressCount; nIndex++) { |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 554 | result = ether_crc(6, etdev->MCList[nIndex]); |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 555 | |
| 556 | result = (result & 0x3F800000) >> 23; |
| 557 | |
| 558 | if (result < 32) { |
| 559 | hash1 |= (1 << result); |
| 560 | } else if ((31 < result) && (result < 64)) { |
| 561 | result -= 32; |
| 562 | hash2 |= (1 << result); |
| 563 | } else if ((63 < result) && (result < 96)) { |
| 564 | result -= 64; |
| 565 | hash3 |= (1 << result); |
| 566 | } else { |
| 567 | result -= 96; |
| 568 | hash4 |= (1 << result); |
| 569 | } |
| 570 | } |
| 571 | } |
| 572 | |
| 573 | /* Write out the new hash to the device */ |
Alan Cox | f2c98d2 | 2009-08-27 11:01:49 +0100 | [diff] [blame] | 574 | pm_csr = readl(&etdev->regs->global.pm_csr); |
| 575 | if ((pm_csr & ET_PM_PHY_SW_COMA) == 0) { |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 576 | writel(hash1, &rxmac->multi_hash1); |
| 577 | writel(hash2, &rxmac->multi_hash2); |
| 578 | writel(hash3, &rxmac->multi_hash3); |
| 579 | writel(hash4, &rxmac->multi_hash4); |
| 580 | } |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 581 | } |
| 582 | |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 583 | void SetupDeviceForUnicast(struct et131x_adapter *etdev) |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 584 | { |
Alan Cox | f3f415a | 2009-08-27 10:59:30 +0100 | [diff] [blame] | 585 | struct _RXMAC_t __iomem *rxmac = &etdev->regs->rxmac; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 586 | RXMAC_UNI_PF_ADDR1_t uni_pf1; |
| 587 | RXMAC_UNI_PF_ADDR2_t uni_pf2; |
| 588 | RXMAC_UNI_PF_ADDR3_t uni_pf3; |
Alan Cox | f2c98d2 | 2009-08-27 11:01:49 +0100 | [diff] [blame] | 589 | u32 pm_csr; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 590 | |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 591 | /* Set up unicast packet filter reg 3 to be the first two octets of |
| 592 | * the MAC address for both address |
| 593 | * |
| 594 | * Set up unicast packet filter reg 2 to be the octets 2 - 5 of the |
| 595 | * MAC address for second address |
| 596 | * |
| 597 | * Set up unicast packet filter reg 3 to be the octets 2 - 5 of the |
| 598 | * MAC address for first address |
| 599 | */ |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 600 | uni_pf3.bits.addr1_1 = etdev->CurrentAddress[0]; |
| 601 | uni_pf3.bits.addr1_2 = etdev->CurrentAddress[1]; |
| 602 | uni_pf3.bits.addr2_1 = etdev->CurrentAddress[0]; |
| 603 | uni_pf3.bits.addr2_2 = etdev->CurrentAddress[1]; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 604 | |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 605 | uni_pf2.bits.addr2_3 = etdev->CurrentAddress[2]; |
| 606 | uni_pf2.bits.addr2_4 = etdev->CurrentAddress[3]; |
| 607 | uni_pf2.bits.addr2_5 = etdev->CurrentAddress[4]; |
| 608 | uni_pf2.bits.addr2_6 = etdev->CurrentAddress[5]; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 609 | |
Alan Cox | 25ad00b | 2009-08-19 18:21:44 +0100 | [diff] [blame] | 610 | uni_pf1.bits.addr1_3 = etdev->CurrentAddress[2]; |
| 611 | uni_pf1.bits.addr1_4 = etdev->CurrentAddress[3]; |
| 612 | uni_pf1.bits.addr1_5 = etdev->CurrentAddress[4]; |
| 613 | uni_pf1.bits.addr1_6 = etdev->CurrentAddress[5]; |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 614 | |
Alan Cox | f2c98d2 | 2009-08-27 11:01:49 +0100 | [diff] [blame] | 615 | pm_csr = readl(&etdev->regs->global.pm_csr); |
| 616 | if ((pm_csr & ET_PM_PHY_SW_COMA) == 0) { |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 617 | writel(uni_pf1.value, &rxmac->uni_pf_addr1.value); |
| 618 | writel(uni_pf2.value, &rxmac->uni_pf_addr2.value); |
| 619 | writel(uni_pf3.value, &rxmac->uni_pf_addr3.value); |
| 620 | } |
Greg Kroah-Hartman | cfb739b | 2008-04-03 17:30:53 -0700 | [diff] [blame] | 621 | } |