aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/via-velocity.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/via-velocity.c')
-rw-r--r--drivers/net/via-velocity.c178
1 files changed, 167 insertions, 11 deletions
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index fd1ff123efa0..4ae05799ac44 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -85,6 +85,163 @@
85static int velocity_nics = 0; 85static int velocity_nics = 0;
86static int msglevel = MSG_LEVEL_INFO; 86static int msglevel = MSG_LEVEL_INFO;
87 87
88/**
89 * mac_get_cam_mask - Read a CAM mask
90 * @regs: register block for this velocity
91 * @mask: buffer to store mask
92 *
93 * Fetch the mask bits of the selected CAM and store them into the
94 * provided mask buffer.
95 */
96
97static void mac_get_cam_mask(struct mac_regs __iomem * regs, u8 * mask)
98{
99 int i;
100
101 /* Select CAM mask */
102 BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
103
104 writeb(0, &regs->CAMADDR);
105
106 /* read mask */
107 for (i = 0; i < 8; i++)
108 *mask++ = readb(&(regs->MARCAM[i]));
109
110 /* disable CAMEN */
111 writeb(0, &regs->CAMADDR);
112
113 /* Select mar */
114 BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
115
116}
117
118
119/**
120 * mac_set_cam_mask - Set a CAM mask
121 * @regs: register block for this velocity
122 * @mask: CAM mask to load
123 *
124 * Store a new mask into a CAM
125 */
126
127static void mac_set_cam_mask(struct mac_regs __iomem * regs, u8 * mask)
128{
129 int i;
130 /* Select CAM mask */
131 BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
132
133 writeb(CAMADDR_CAMEN, &regs->CAMADDR);
134
135 for (i = 0; i < 8; i++) {
136 writeb(*mask++, &(regs->MARCAM[i]));
137 }
138 /* disable CAMEN */
139 writeb(0, &regs->CAMADDR);
140
141 /* Select mar */
142 BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
143}
144
145static void mac_set_vlan_cam_mask(struct mac_regs __iomem * regs, u8 * mask)
146{
147 int i;
148 /* Select CAM mask */
149 BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
150
151 writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL, &regs->CAMADDR);
152
153 for (i = 0; i < 8; i++) {
154 writeb(*mask++, &(regs->MARCAM[i]));
155 }
156 /* disable CAMEN */
157 writeb(0, &regs->CAMADDR);
158
159 /* Select mar */
160 BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
161}
162
163/**
164 * mac_set_cam - set CAM data
165 * @regs: register block of this velocity
166 * @idx: Cam index
167 * @addr: 2 or 6 bytes of CAM data
168 *
169 * Load an address or vlan tag into a CAM
170 */
171
172static void mac_set_cam(struct mac_regs __iomem * regs, int idx, const u8 *addr)
173{
174 int i;
175
176 /* Select CAM mask */
177 BYTE_REG_BITS_SET(CAMCR_PS_CAM_DATA, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
178
179 idx &= (64 - 1);
180
181 writeb(CAMADDR_CAMEN | idx, &regs->CAMADDR);
182
183 for (i = 0; i < 6; i++) {
184 writeb(*addr++, &(regs->MARCAM[i]));
185 }
186 BYTE_REG_BITS_ON(CAMCR_CAMWR, &regs->CAMCR);
187
188 udelay(10);
189
190 writeb(0, &regs->CAMADDR);
191
192 /* Select mar */
193 BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
194}
195
196static void mac_set_vlan_cam(struct mac_regs __iomem * regs, int idx,
197 const u8 *addr)
198{
199
200 /* Select CAM mask */
201 BYTE_REG_BITS_SET(CAMCR_PS_CAM_DATA, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
202
203 idx &= (64 - 1);
204
205 writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL | idx, &regs->CAMADDR);
206 writew(*((u16 *) addr), &regs->MARCAM[0]);
207
208 BYTE_REG_BITS_ON(CAMCR_CAMWR, &regs->CAMCR);
209
210 udelay(10);
211
212 writeb(0, &regs->CAMADDR);
213
214 /* Select mar */
215 BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
216}
217
218
219/**
220 * mac_wol_reset - reset WOL after exiting low power
221 * @regs: register block of this velocity
222 *
223 * Called after we drop out of wake on lan mode in order to
224 * reset the Wake on lan features. This function doesn't restore
225 * the rest of the logic from the result of sleep/wakeup
226 */
227
228static void mac_wol_reset(struct mac_regs __iomem * regs)
229{
230
231 /* Turn off SWPTAG right after leaving power mode */
232 BYTE_REG_BITS_OFF(STICKHW_SWPTAG, &regs->STICKHW);
233 /* clear sticky bits */
234 BYTE_REG_BITS_OFF((STICKHW_DS1 | STICKHW_DS0), &regs->STICKHW);
235
236 BYTE_REG_BITS_OFF(CHIPGCR_FCGMII, &regs->CHIPGCR);
237 BYTE_REG_BITS_OFF(CHIPGCR_FCMODE, &regs->CHIPGCR);
238 /* disable force PME-enable */
239 writeb(WOLCFG_PMEOVR, &regs->WOLCFGClr);
240 /* disable power-event config bit */
241 writew(0xFFFF, &regs->WOLCRClr);
242 /* clear power status */
243 writew(0xFFFF, &regs->WOLSRClr);
244}
88 245
89static int velocity_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); 246static int velocity_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
90static const struct ethtool_ops velocity_ethtool_ops; 247static const struct ethtool_ops velocity_ethtool_ops;
@@ -309,7 +466,7 @@ MODULE_DEVICE_TABLE(pci, velocity_id_table);
309 * a pointer a static string valid while the driver is loaded. 466 * a pointer a static string valid while the driver is loaded.
310 */ 467 */
311 468
312static char __devinit *get_chip_name(enum chip_type chip_id) 469static const char __devinit *get_chip_name(enum chip_type chip_id)
313{ 470{
314 int i; 471 int i;
315 for (i = 0; chip_info_table[i].name != NULL; i++) 472 for (i = 0; chip_info_table[i].name != NULL; i++)
@@ -458,8 +615,8 @@ static void velocity_init_cam_filter(struct velocity_info *vptr)
458 /* Disable all CAMs */ 615 /* Disable all CAMs */
459 memset(vptr->vCAMmask, 0, sizeof(u8) * 8); 616 memset(vptr->vCAMmask, 0, sizeof(u8) * 8);
460 memset(vptr->mCAMmask, 0, sizeof(u8) * 8); 617 memset(vptr->mCAMmask, 0, sizeof(u8) * 8);
461 mac_set_cam_mask(regs, vptr->vCAMmask, VELOCITY_VLAN_ID_CAM); 618 mac_set_vlan_cam_mask(regs, vptr->vCAMmask);
462 mac_set_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM); 619 mac_set_cam_mask(regs, vptr->mCAMmask);
463 620
464 /* Enable first VCAM */ 621 /* Enable first VCAM */
465 if (vptr->vlgrp) { 622 if (vptr->vlgrp) {
@@ -471,17 +628,16 @@ static void velocity_init_cam_filter(struct velocity_info *vptr)
471 if (vid != 0) 628 if (vid != 0)
472 WORD_REG_BITS_ON(MCFG_RTGOPT, &regs->MCFG); 629 WORD_REG_BITS_ON(MCFG_RTGOPT, &regs->MCFG);
473 630
474 mac_set_cam(regs, 0, (u8 *) &vid, 631 mac_set_vlan_cam(regs, 0, (u8 *) &vid);
475 VELOCITY_VLAN_ID_CAM);
476 } 632 }
477 } 633 }
478 vptr->vCAMmask[0] |= 1; 634 vptr->vCAMmask[0] |= 1;
479 mac_set_cam_mask(regs, vptr->vCAMmask, VELOCITY_VLAN_ID_CAM); 635 mac_set_vlan_cam_mask(regs, vptr->vCAMmask);
480 } else { 636 } else {
481 u16 temp = 0; 637 u16 temp = 0;
482 mac_set_cam(regs, 0, (u8 *) &temp, VELOCITY_VLAN_ID_CAM); 638 mac_set_vlan_cam(regs, 0, (u8 *) &temp);
483 temp = 1; 639 temp = 1;
484 mac_set_cam_mask(regs, (u8 *) &temp, VELOCITY_VLAN_ID_CAM); 640 mac_set_vlan_cam_mask(regs, (u8 *) &temp);
485 } 641 }
486} 642}
487 643
@@ -2131,14 +2287,14 @@ static void velocity_set_multi(struct net_device *dev)
2131 rx_mode = (RCR_AM | RCR_AB); 2287 rx_mode = (RCR_AM | RCR_AB);
2132 } else { 2288 } else {
2133 int offset = MCAM_SIZE - vptr->multicast_limit; 2289 int offset = MCAM_SIZE - vptr->multicast_limit;
2134 mac_get_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM); 2290 mac_get_cam_mask(regs, vptr->mCAMmask);
2135 2291
2136 for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) { 2292 for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) {
2137 mac_set_cam(regs, i + offset, mclist->dmi_addr, VELOCITY_MULTICAST_CAM); 2293 mac_set_cam(regs, i + offset, mclist->dmi_addr);
2138 vptr->mCAMmask[(offset + i) / 8] |= 1 << ((offset + i) & 7); 2294 vptr->mCAMmask[(offset + i) / 8] |= 1 << ((offset + i) & 7);
2139 } 2295 }
2140 2296
2141 mac_set_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM); 2297 mac_set_cam_mask(regs, vptr->mCAMmask);
2142 rx_mode = (RCR_AM | RCR_AB); 2298 rx_mode = (RCR_AM | RCR_AB);
2143 } 2299 }
2144 if (dev->mtu > 1500) 2300 if (dev->mtu > 1500)