diff options
Diffstat (limited to 'drivers/net/via-velocity.c')
-rw-r--r-- | drivers/net/via-velocity.c | 178 |
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 @@ | |||
85 | static int velocity_nics = 0; | 85 | static int velocity_nics = 0; |
86 | static int msglevel = MSG_LEVEL_INFO; | 86 | static 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 | |||
97 | static 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, ®s->CAMCR); | ||
103 | |||
104 | writeb(0, ®s->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, ®s->CAMADDR); | ||
112 | |||
113 | /* Select mar */ | ||
114 | BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->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 | |||
127 | static 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, ®s->CAMCR); | ||
132 | |||
133 | writeb(CAMADDR_CAMEN, ®s->CAMADDR); | ||
134 | |||
135 | for (i = 0; i < 8; i++) { | ||
136 | writeb(*mask++, &(regs->MARCAM[i])); | ||
137 | } | ||
138 | /* disable CAMEN */ | ||
139 | writeb(0, ®s->CAMADDR); | ||
140 | |||
141 | /* Select mar */ | ||
142 | BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR); | ||
143 | } | ||
144 | |||
145 | static 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, ®s->CAMCR); | ||
150 | |||
151 | writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL, ®s->CAMADDR); | ||
152 | |||
153 | for (i = 0; i < 8; i++) { | ||
154 | writeb(*mask++, &(regs->MARCAM[i])); | ||
155 | } | ||
156 | /* disable CAMEN */ | ||
157 | writeb(0, ®s->CAMADDR); | ||
158 | |||
159 | /* Select mar */ | ||
160 | BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->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 | |||
172 | static 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, ®s->CAMCR); | ||
178 | |||
179 | idx &= (64 - 1); | ||
180 | |||
181 | writeb(CAMADDR_CAMEN | idx, ®s->CAMADDR); | ||
182 | |||
183 | for (i = 0; i < 6; i++) { | ||
184 | writeb(*addr++, &(regs->MARCAM[i])); | ||
185 | } | ||
186 | BYTE_REG_BITS_ON(CAMCR_CAMWR, ®s->CAMCR); | ||
187 | |||
188 | udelay(10); | ||
189 | |||
190 | writeb(0, ®s->CAMADDR); | ||
191 | |||
192 | /* Select mar */ | ||
193 | BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->CAMCR); | ||
194 | } | ||
195 | |||
196 | static 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, ®s->CAMCR); | ||
202 | |||
203 | idx &= (64 - 1); | ||
204 | |||
205 | writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL | idx, ®s->CAMADDR); | ||
206 | writew(*((u16 *) addr), ®s->MARCAM[0]); | ||
207 | |||
208 | BYTE_REG_BITS_ON(CAMCR_CAMWR, ®s->CAMCR); | ||
209 | |||
210 | udelay(10); | ||
211 | |||
212 | writeb(0, ®s->CAMADDR); | ||
213 | |||
214 | /* Select mar */ | ||
215 | BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, ®s->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 | |||
228 | static 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, ®s->STICKHW); | ||
233 | /* clear sticky bits */ | ||
234 | BYTE_REG_BITS_OFF((STICKHW_DS1 | STICKHW_DS0), ®s->STICKHW); | ||
235 | |||
236 | BYTE_REG_BITS_OFF(CHIPGCR_FCGMII, ®s->CHIPGCR); | ||
237 | BYTE_REG_BITS_OFF(CHIPGCR_FCMODE, ®s->CHIPGCR); | ||
238 | /* disable force PME-enable */ | ||
239 | writeb(WOLCFG_PMEOVR, ®s->WOLCFGClr); | ||
240 | /* disable power-event config bit */ | ||
241 | writew(0xFFFF, ®s->WOLCRClr); | ||
242 | /* clear power status */ | ||
243 | writew(0xFFFF, ®s->WOLSRClr); | ||
244 | } | ||
88 | 245 | ||
89 | static int velocity_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); | 246 | static int velocity_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); |
90 | static const struct ethtool_ops velocity_ethtool_ops; | 247 | static 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 | ||
312 | static char __devinit *get_chip_name(enum chip_type chip_id) | 469 | static 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, ®s->MCFG); | 629 | WORD_REG_BITS_ON(MCFG_RTGOPT, ®s->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) |