1/*- 2 * Copyright (c) 1997,1998 Maxim Bolotin and Oleg Sharoiko. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice unmodified, this list of conditions, and the following 10 * disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 */ 28 29#include <sys/cdefs.h>
| 1/*- 2 * Copyright (c) 1997,1998 Maxim Bolotin and Oleg Sharoiko. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice unmodified, this list of conditions, and the following 10 * disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 */ 28 29#include <sys/cdefs.h>
|
30__FBSDID("$FreeBSD: head/sys/dev/cs/if_cs.c 179507 2008-06-03 05:47:28Z imp $");
| 30__FBSDID("$FreeBSD: head/sys/dev/cs/if_cs.c 179532 2008-06-04 06:07:13Z imp $");
|
31 32/* 33 * 34 * Device driver for Crystal Semiconductor CS8920 based ethernet 35 * adapters. By Maxim Bolotin and Oleg Sharoiko, 27-April-1997 36 */ 37 38/* 39#define CS_DEBUG 40 */ 41 42#include <sys/param.h> 43#include <sys/systm.h> 44#include <sys/malloc.h> 45#include <sys/mbuf.h> 46#include <sys/socket.h> 47#include <sys/sockio.h> 48#include <sys/kernel.h> 49#include <sys/sysctl.h> 50#include <sys/syslog.h> 51 52#include <sys/module.h> 53#include <sys/bus.h> 54#include <machine/bus.h> 55#include <sys/rman.h> 56#include <machine/resource.h> 57 58#include <net/if.h> 59#include <net/if_arp.h> 60#include <net/if_dl.h> 61#include <net/if_media.h> 62#include <net/if_types.h> 63#include <net/ethernet.h> 64#include <net/bpf.h> 65 66#include <dev/cs/if_csvar.h> 67#include <dev/cs/if_csreg.h> 68 69#ifdef CS_USE_64K_DMA 70#define CS_DMA_BUFFER_SIZE 65536 71#else 72#define CS_DMA_BUFFER_SIZE 16384 73#endif 74 75static void cs_init(void *); 76static int cs_ioctl(struct ifnet *, u_long, caddr_t); 77static void cs_start(struct ifnet *); 78static void cs_stop(struct cs_softc *); 79static void cs_reset(struct cs_softc *); 80static void cs_watchdog(struct ifnet *); 81 82static int cs_mediachange(struct ifnet *); 83static void cs_mediastatus(struct ifnet *, struct ifmediareq *); 84static int cs_mediaset(struct cs_softc *, int); 85 86static void cs_write_mbufs(struct cs_softc*, struct mbuf*); 87static void cs_xmit_buf(struct cs_softc*); 88static int cs_get_packet(struct cs_softc*); 89static void cs_setmode(struct cs_softc*); 90 91static int get_eeprom_data(struct cs_softc *sc, int, int, uint16_t *); 92static int get_eeprom_cksum(int, int, uint16_t *); 93static int wait_eeprom_ready( struct cs_softc *); 94static void control_dc_dc( struct cs_softc *, int ); 95static int send_test_pkt( struct cs_softc * ); 96static int enable_tp(struct cs_softc *); 97static int enable_aui(struct cs_softc *); 98static int enable_bnc(struct cs_softc *); 99static int cs_duplex_auto(struct cs_softc *); 100 101devclass_t cs_devclass; 102 103/* sysctl vars */ 104SYSCTL_NODE(_hw, OID_AUTO, cs, CTLFLAG_RD, 0, "cs device parameters"); 105 106int cs_debug = 0; 107TUNABLE_INT("hw.cs.debug", &cs_debug); 108SYSCTL_INT(_hw_cs, OID_AUTO, debug, CTLFLAG_RW, 109 &cs_debug, 0, 110 "cs debug"); 111 112int cs_ignore_cksum_failure = 0; 113TUNABLE_INT("hw.cs.ignore_checksum_failure", &cs_ignore_cksum_failure); 114SYSCTL_INT(_hw_cs, OID_AUTO, ignore_checksum_failure, CTLFLAG_RW, 115 &cs_ignore_cksum_failure, 0, 116 "ignore checksum errors in cs card EEPROM"); 117 118static int cs_recv_delay = 570; 119TUNABLE_INT("hw.cs.recv_delay", &cs_recv_delay); 120SYSCTL_INT(_hw_cs, OID_AUTO, recv_delay, CTLFLAG_RW, &cs_recv_delay, 570, ""); 121
| 31 32/* 33 * 34 * Device driver for Crystal Semiconductor CS8920 based ethernet 35 * adapters. By Maxim Bolotin and Oleg Sharoiko, 27-April-1997 36 */ 37 38/* 39#define CS_DEBUG 40 */ 41 42#include <sys/param.h> 43#include <sys/systm.h> 44#include <sys/malloc.h> 45#include <sys/mbuf.h> 46#include <sys/socket.h> 47#include <sys/sockio.h> 48#include <sys/kernel.h> 49#include <sys/sysctl.h> 50#include <sys/syslog.h> 51 52#include <sys/module.h> 53#include <sys/bus.h> 54#include <machine/bus.h> 55#include <sys/rman.h> 56#include <machine/resource.h> 57 58#include <net/if.h> 59#include <net/if_arp.h> 60#include <net/if_dl.h> 61#include <net/if_media.h> 62#include <net/if_types.h> 63#include <net/ethernet.h> 64#include <net/bpf.h> 65 66#include <dev/cs/if_csvar.h> 67#include <dev/cs/if_csreg.h> 68 69#ifdef CS_USE_64K_DMA 70#define CS_DMA_BUFFER_SIZE 65536 71#else 72#define CS_DMA_BUFFER_SIZE 16384 73#endif 74 75static void cs_init(void *); 76static int cs_ioctl(struct ifnet *, u_long, caddr_t); 77static void cs_start(struct ifnet *); 78static void cs_stop(struct cs_softc *); 79static void cs_reset(struct cs_softc *); 80static void cs_watchdog(struct ifnet *); 81 82static int cs_mediachange(struct ifnet *); 83static void cs_mediastatus(struct ifnet *, struct ifmediareq *); 84static int cs_mediaset(struct cs_softc *, int); 85 86static void cs_write_mbufs(struct cs_softc*, struct mbuf*); 87static void cs_xmit_buf(struct cs_softc*); 88static int cs_get_packet(struct cs_softc*); 89static void cs_setmode(struct cs_softc*); 90 91static int get_eeprom_data(struct cs_softc *sc, int, int, uint16_t *); 92static int get_eeprom_cksum(int, int, uint16_t *); 93static int wait_eeprom_ready( struct cs_softc *); 94static void control_dc_dc( struct cs_softc *, int ); 95static int send_test_pkt( struct cs_softc * ); 96static int enable_tp(struct cs_softc *); 97static int enable_aui(struct cs_softc *); 98static int enable_bnc(struct cs_softc *); 99static int cs_duplex_auto(struct cs_softc *); 100 101devclass_t cs_devclass; 102 103/* sysctl vars */ 104SYSCTL_NODE(_hw, OID_AUTO, cs, CTLFLAG_RD, 0, "cs device parameters"); 105 106int cs_debug = 0; 107TUNABLE_INT("hw.cs.debug", &cs_debug); 108SYSCTL_INT(_hw_cs, OID_AUTO, debug, CTLFLAG_RW, 109 &cs_debug, 0, 110 "cs debug"); 111 112int cs_ignore_cksum_failure = 0; 113TUNABLE_INT("hw.cs.ignore_checksum_failure", &cs_ignore_cksum_failure); 114SYSCTL_INT(_hw_cs, OID_AUTO, ignore_checksum_failure, CTLFLAG_RW, 115 &cs_ignore_cksum_failure, 0, 116 "ignore checksum errors in cs card EEPROM"); 117 118static int cs_recv_delay = 570; 119TUNABLE_INT("hw.cs.recv_delay", &cs_recv_delay); 120SYSCTL_INT(_hw_cs, OID_AUTO, recv_delay, CTLFLAG_RW, &cs_recv_delay, 570, ""); 121
|
| 122static int cs8900_eeint2irq[16] = { 123 10, 11, 12, 5, 255, 255, 255, 255, 124 255, 255, 255, 255, 255, 255, 255, 255 125}; 126 127static int cs8900_irq2eeint[16] = { 128 255, 255, 255, 255, 255, 3, 255, 255, 129 255, 0, 1, 2, 255, 255, 255, 255 130}; 131
|
122static int 123get_eeprom_data(struct cs_softc *sc, int off, int len, uint16_t *buffer) 124{ 125 int i; 126 127#ifdef CS_DEBUG 128 printf(CS_NAME":EEPROM data from %x for %x:\n", off, len); 129#endif 130 131 for (i=0; i < len; i++) { 132 if (wait_eeprom_ready(sc) < 0) 133 return (-1); 134 /* Send command to EEPROM to read */ 135 cs_writereg(sc, PP_EECMD, (off + i) | EEPROM_READ_CMD); 136 if (wait_eeprom_ready(sc) < 0) 137 return (-1); 138 buffer[i] = cs_readreg(sc, PP_EEData); 139 140#ifdef CS_DEBUG 141 printf("%02x %02x ",(unsigned char)buffer[i], 142 (unsigned char)buffer[i] >> 8); 143#endif 144 } 145 146#ifdef CS_DEBUG 147 printf("\n"); 148#endif 149 return (0); 150} 151 152static int 153get_eeprom_cksum(int off, int len, uint16_t *buffer) 154{ 155 int i; 156 uint16_t cksum=0; 157 158 for (i = 0; i < len; i++) 159 cksum += buffer[i]; 160 cksum &= 0xffff; 161 if (cksum==0) 162 return (0); 163 if (cs_ignore_cksum_failure) { 164 printf(CS_NAME": checksum mismatch, ignoring\n"); 165 return (0); 166 } 167 return (-1); 168} 169 170static int 171wait_eeprom_ready(struct cs_softc *sc) 172{ 173 DELAY(30000); /* XXX should we do some checks here ? */ 174 return (0); 175} 176 177static void 178control_dc_dc(struct cs_softc *sc, int on_not_off) 179{ 180 unsigned int self_control = HCB1_ENBL; 181 182 if (((sc->adapter_cnf & A_CNF_DC_DC_POLARITY)!=0) ^ on_not_off) 183 self_control |= HCB1; 184 else 185 self_control &= ~HCB1; 186 cs_writereg(sc, PP_SelfCTL, self_control); 187 188 DELAY(500000); 189} 190 191 192static int 193cs_duplex_auto(struct cs_softc *sc) 194{ 195 int i, error=0; 196 197 cs_writereg(sc, PP_AutoNegCTL, 198 RE_NEG_NOW | ALLOW_FDX | AUTO_NEG_ENABLE); 199 for (i=0; cs_readreg(sc, PP_AutoNegST) & AUTO_NEG_BUSY; i++) { 200 if (i > 40000) { 201 device_printf(sc->dev, 202 "full/half duplex auto negotiation timeout\n"); 203 error = ETIMEDOUT; 204 break; 205 } 206 DELAY(1000); 207 } 208 DELAY(1000000); 209 return (error); 210} 211 212static int 213enable_tp(struct cs_softc *sc) 214{ 215 216 cs_writereg(sc, PP_LineCTL, sc->line_ctl & ~AUI_ONLY); 217 control_dc_dc(sc, 0); 218 DELAY( 150000 ); 219 220 if ((cs_readreg(sc, PP_LineST) & LINK_OK)==0) { 221 device_printf(sc->dev, "failed to enable TP\n"); 222 return (EINVAL); 223 } 224 225 return (0); 226} 227 228/* 229 * XXX This was rewritten from Linux driver without any tests. 230 */ 231static int 232send_test_pkt(struct cs_softc *sc) 233{ 234 char test_packet[] = { 0,0,0,0,0,0, 0,0,0,0,0,0, 235 0, 46, /* A 46 in network order */ 236 0, 0, /* DSAP=0 & SSAP=0 fields */ 237 0xf3, 0 /* Control (Test Req + P bit set) */ }; 238 int i; 239 u_char ether_address_backup[ETHER_ADDR_LEN]; 240 241 for (i = 0; i < ETHER_ADDR_LEN; i++) 242 ether_address_backup[i] = sc->enaddr[i]; 243 244 cs_writereg(sc, PP_LineCTL, cs_readreg(sc, PP_LineCTL) | SERIAL_TX_ON); 245 bcopy(test_packet, sc->enaddr, ETHER_ADDR_LEN); 246 bcopy(test_packet+ETHER_ADDR_LEN, 247 sc->enaddr, ETHER_ADDR_LEN); 248 cs_outw(sc, TX_CMD_PORT, sc->send_cmd); 249 cs_outw(sc, TX_LEN_PORT, sizeof(test_packet)); 250 251 /* Wait for chip to allocate memory */ 252 DELAY(50000); 253 if (!(cs_readreg(sc, PP_BusST) & READY_FOR_TX_NOW)) { 254 for (i = 0; i < ETHER_ADDR_LEN; i++) 255 sc->enaddr[i] = ether_address_backup[i]; 256 return (0); 257 } 258 259 outsw(sc->nic_addr + TX_FRAME_PORT, test_packet, sizeof(test_packet)); 260 261 DELAY(30000); 262 263 for (i = 0; i < ETHER_ADDR_LEN; i++) 264 sc->enaddr[i] = ether_address_backup[i]; 265 if ((cs_readreg(sc, PP_TxEvent) & TX_SEND_OK_BITS) == TX_OK) 266 return (1); 267 return (0); 268} 269 270/* 271 * XXX This was rewritten from Linux driver without any tests. 272 */ 273static int 274enable_aui(struct cs_softc *sc) 275{ 276 277 control_dc_dc(sc, 0); 278 cs_writereg(sc, PP_LineCTL, 279 (sc->line_ctl & ~AUTO_AUI_10BASET) | AUI_ONLY); 280 281 if (!send_test_pkt(sc)) { 282 device_printf(sc->dev, "failed to enable AUI\n"); 283 return (EINVAL); 284 } 285 return (0); 286} 287 288/* 289 * XXX This was rewritten from Linux driver without any tests. 290 */ 291static int 292enable_bnc(struct cs_softc *sc) 293{ 294 295 control_dc_dc(sc, 1); 296 cs_writereg(sc, PP_LineCTL, 297 (sc->line_ctl & ~AUTO_AUI_10BASET) | AUI_ONLY); 298 299 if (!send_test_pkt(sc)) { 300 device_printf(sc->dev, "failed to enable BNC\n"); 301 return (EINVAL); 302 } 303 return (0); 304} 305 306int 307cs_cs89x0_probe(device_t dev) 308{ 309 int i; 310 int error; 311 u_long irq, junk; 312 struct cs_softc *sc = device_get_softc(dev); 313 unsigned rev_type = 0; 314 uint16_t id; 315 char chip_revision; 316 uint16_t eeprom_buff[CHKSUM_LEN]; 317 int chip_type, pp_isaint, pp_isadma; 318 319 error = cs_alloc_port(dev, 0, CS_89x0_IO_PORTS); 320 if (error) 321 return (error); 322 323 sc->nic_addr = rman_get_start(sc->port_res); 324 325 if ((cs_inw(sc, ADD_PORT) & ADD_MASK) != ADD_SIG) { 326 /* Chip not detected. Let's try to reset it */ 327 if (bootverbose) 328 device_printf(dev, "trying to reset the chip.\n"); 329 cs_outw(sc, ADD_PORT, PP_SelfCTL); 330 i = cs_inw(sc, DATA_PORT); 331 cs_outw(sc, ADD_PORT, PP_SelfCTL); 332 cs_outw(sc, DATA_PORT, i | POWER_ON_RESET); 333 if ((cs_inw(sc, ADD_PORT) & ADD_MASK) != ADD_SIG) 334 return (ENXIO); 335 } 336 337 for (i = 0; i < 10000; i++) { 338 id = cs_readreg(sc, PP_ChipID); 339 if (id == CHIP_EISA_ID_SIG) 340 break; 341 } 342 if (i == 10000) 343 return (ENXIO); 344 345 rev_type = cs_readreg(sc, PRODUCT_ID_ADD); 346 chip_type = rev_type & ~REVISON_BITS; 347 chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A'; 348 349 sc->chip_type = chip_type; 350
| 132static int 133get_eeprom_data(struct cs_softc *sc, int off, int len, uint16_t *buffer) 134{ 135 int i; 136 137#ifdef CS_DEBUG 138 printf(CS_NAME":EEPROM data from %x for %x:\n", off, len); 139#endif 140 141 for (i=0; i < len; i++) { 142 if (wait_eeprom_ready(sc) < 0) 143 return (-1); 144 /* Send command to EEPROM to read */ 145 cs_writereg(sc, PP_EECMD, (off + i) | EEPROM_READ_CMD); 146 if (wait_eeprom_ready(sc) < 0) 147 return (-1); 148 buffer[i] = cs_readreg(sc, PP_EEData); 149 150#ifdef CS_DEBUG 151 printf("%02x %02x ",(unsigned char)buffer[i], 152 (unsigned char)buffer[i] >> 8); 153#endif 154 } 155 156#ifdef CS_DEBUG 157 printf("\n"); 158#endif 159 return (0); 160} 161 162static int 163get_eeprom_cksum(int off, int len, uint16_t *buffer) 164{ 165 int i; 166 uint16_t cksum=0; 167 168 for (i = 0; i < len; i++) 169 cksum += buffer[i]; 170 cksum &= 0xffff; 171 if (cksum==0) 172 return (0); 173 if (cs_ignore_cksum_failure) { 174 printf(CS_NAME": checksum mismatch, ignoring\n"); 175 return (0); 176 } 177 return (-1); 178} 179 180static int 181wait_eeprom_ready(struct cs_softc *sc) 182{ 183 DELAY(30000); /* XXX should we do some checks here ? */ 184 return (0); 185} 186 187static void 188control_dc_dc(struct cs_softc *sc, int on_not_off) 189{ 190 unsigned int self_control = HCB1_ENBL; 191 192 if (((sc->adapter_cnf & A_CNF_DC_DC_POLARITY)!=0) ^ on_not_off) 193 self_control |= HCB1; 194 else 195 self_control &= ~HCB1; 196 cs_writereg(sc, PP_SelfCTL, self_control); 197 198 DELAY(500000); 199} 200 201 202static int 203cs_duplex_auto(struct cs_softc *sc) 204{ 205 int i, error=0; 206 207 cs_writereg(sc, PP_AutoNegCTL, 208 RE_NEG_NOW | ALLOW_FDX | AUTO_NEG_ENABLE); 209 for (i=0; cs_readreg(sc, PP_AutoNegST) & AUTO_NEG_BUSY; i++) { 210 if (i > 40000) { 211 device_printf(sc->dev, 212 "full/half duplex auto negotiation timeout\n"); 213 error = ETIMEDOUT; 214 break; 215 } 216 DELAY(1000); 217 } 218 DELAY(1000000); 219 return (error); 220} 221 222static int 223enable_tp(struct cs_softc *sc) 224{ 225 226 cs_writereg(sc, PP_LineCTL, sc->line_ctl & ~AUI_ONLY); 227 control_dc_dc(sc, 0); 228 DELAY( 150000 ); 229 230 if ((cs_readreg(sc, PP_LineST) & LINK_OK)==0) { 231 device_printf(sc->dev, "failed to enable TP\n"); 232 return (EINVAL); 233 } 234 235 return (0); 236} 237 238/* 239 * XXX This was rewritten from Linux driver without any tests. 240 */ 241static int 242send_test_pkt(struct cs_softc *sc) 243{ 244 char test_packet[] = { 0,0,0,0,0,0, 0,0,0,0,0,0, 245 0, 46, /* A 46 in network order */ 246 0, 0, /* DSAP=0 & SSAP=0 fields */ 247 0xf3, 0 /* Control (Test Req + P bit set) */ }; 248 int i; 249 u_char ether_address_backup[ETHER_ADDR_LEN]; 250 251 for (i = 0; i < ETHER_ADDR_LEN; i++) 252 ether_address_backup[i] = sc->enaddr[i]; 253 254 cs_writereg(sc, PP_LineCTL, cs_readreg(sc, PP_LineCTL) | SERIAL_TX_ON); 255 bcopy(test_packet, sc->enaddr, ETHER_ADDR_LEN); 256 bcopy(test_packet+ETHER_ADDR_LEN, 257 sc->enaddr, ETHER_ADDR_LEN); 258 cs_outw(sc, TX_CMD_PORT, sc->send_cmd); 259 cs_outw(sc, TX_LEN_PORT, sizeof(test_packet)); 260 261 /* Wait for chip to allocate memory */ 262 DELAY(50000); 263 if (!(cs_readreg(sc, PP_BusST) & READY_FOR_TX_NOW)) { 264 for (i = 0; i < ETHER_ADDR_LEN; i++) 265 sc->enaddr[i] = ether_address_backup[i]; 266 return (0); 267 } 268 269 outsw(sc->nic_addr + TX_FRAME_PORT, test_packet, sizeof(test_packet)); 270 271 DELAY(30000); 272 273 for (i = 0; i < ETHER_ADDR_LEN; i++) 274 sc->enaddr[i] = ether_address_backup[i]; 275 if ((cs_readreg(sc, PP_TxEvent) & TX_SEND_OK_BITS) == TX_OK) 276 return (1); 277 return (0); 278} 279 280/* 281 * XXX This was rewritten from Linux driver without any tests. 282 */ 283static int 284enable_aui(struct cs_softc *sc) 285{ 286 287 control_dc_dc(sc, 0); 288 cs_writereg(sc, PP_LineCTL, 289 (sc->line_ctl & ~AUTO_AUI_10BASET) | AUI_ONLY); 290 291 if (!send_test_pkt(sc)) { 292 device_printf(sc->dev, "failed to enable AUI\n"); 293 return (EINVAL); 294 } 295 return (0); 296} 297 298/* 299 * XXX This was rewritten from Linux driver without any tests. 300 */ 301static int 302enable_bnc(struct cs_softc *sc) 303{ 304 305 control_dc_dc(sc, 1); 306 cs_writereg(sc, PP_LineCTL, 307 (sc->line_ctl & ~AUTO_AUI_10BASET) | AUI_ONLY); 308 309 if (!send_test_pkt(sc)) { 310 device_printf(sc->dev, "failed to enable BNC\n"); 311 return (EINVAL); 312 } 313 return (0); 314} 315 316int 317cs_cs89x0_probe(device_t dev) 318{ 319 int i; 320 int error; 321 u_long irq, junk; 322 struct cs_softc *sc = device_get_softc(dev); 323 unsigned rev_type = 0; 324 uint16_t id; 325 char chip_revision; 326 uint16_t eeprom_buff[CHKSUM_LEN]; 327 int chip_type, pp_isaint, pp_isadma; 328 329 error = cs_alloc_port(dev, 0, CS_89x0_IO_PORTS); 330 if (error) 331 return (error); 332 333 sc->nic_addr = rman_get_start(sc->port_res); 334 335 if ((cs_inw(sc, ADD_PORT) & ADD_MASK) != ADD_SIG) { 336 /* Chip not detected. Let's try to reset it */ 337 if (bootverbose) 338 device_printf(dev, "trying to reset the chip.\n"); 339 cs_outw(sc, ADD_PORT, PP_SelfCTL); 340 i = cs_inw(sc, DATA_PORT); 341 cs_outw(sc, ADD_PORT, PP_SelfCTL); 342 cs_outw(sc, DATA_PORT, i | POWER_ON_RESET); 343 if ((cs_inw(sc, ADD_PORT) & ADD_MASK) != ADD_SIG) 344 return (ENXIO); 345 } 346 347 for (i = 0; i < 10000; i++) { 348 id = cs_readreg(sc, PP_ChipID); 349 if (id == CHIP_EISA_ID_SIG) 350 break; 351 } 352 if (i == 10000) 353 return (ENXIO); 354 355 rev_type = cs_readreg(sc, PRODUCT_ID_ADD); 356 chip_type = rev_type & ~REVISON_BITS; 357 chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A'; 358 359 sc->chip_type = chip_type; 360
|
351 if(chip_type==CS8900) {
| 361 if (chip_type == CS8900) {
|
352 pp_isaint = PP_CS8900_ISAINT; 353 pp_isadma = PP_CS8900_ISADMA; 354 sc->send_cmd = TX_CS8900_AFTER_ALL; 355 } else { 356 pp_isaint = PP_CS8920_ISAINT; 357 pp_isadma = PP_CS8920_ISADMA; 358 sc->send_cmd = TX_CS8920_AFTER_ALL; 359 } 360 361 /* 362 * Clear some fields so that fail of EEPROM will left them clean 363 */ 364 sc->auto_neg_cnf = 0; 365 sc->adapter_cnf = 0; 366 sc->isa_config = 0; 367 368 /*
| 362 pp_isaint = PP_CS8900_ISAINT; 363 pp_isadma = PP_CS8900_ISADMA; 364 sc->send_cmd = TX_CS8900_AFTER_ALL; 365 } else { 366 pp_isaint = PP_CS8920_ISAINT; 367 pp_isadma = PP_CS8920_ISADMA; 368 sc->send_cmd = TX_CS8920_AFTER_ALL; 369 } 370 371 /* 372 * Clear some fields so that fail of EEPROM will left them clean 373 */ 374 sc->auto_neg_cnf = 0; 375 sc->adapter_cnf = 0; 376 sc->isa_config = 0; 377 378 /*
|
369 * If no interrupt specified (or "?"), use what the board tells us.
| 379 * If no interrupt specified, use what the board tells us.
|
370 */ 371 error = bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, &junk); 372 373 /* 374 * Get data from EEPROM 375 */ 376 if((cs_readreg(sc, PP_SelfST) & EEPROM_PRESENT) == 0) { 377 device_printf(dev, "No EEPROM, assuming defaults.\n");
| 380 */ 381 error = bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, &junk); 382 383 /* 384 * Get data from EEPROM 385 */ 386 if((cs_readreg(sc, PP_SelfST) & EEPROM_PRESENT) == 0) { 387 device_printf(dev, "No EEPROM, assuming defaults.\n");
|
| 388 } else if (get_eeprom_data(sc,START_EEPROM_DATA,CHKSUM_LEN, eeprom_buff)<0) { 389 device_printf(dev, "EEPROM read failed, assuming defaults.\n"); 390 } else if (get_eeprom_cksum(START_EEPROM_DATA,CHKSUM_LEN, eeprom_buff)<0) { 391 device_printf(dev, "EEPROM cheksum bad, assuming defaults.\n");
|
378 } else {
| 392 } else {
|
379 if (get_eeprom_data(sc,START_EEPROM_DATA,CHKSUM_LEN, eeprom_buff)<0) { 380 device_printf(dev, "EEPROM read failed, " 381 "assuming defaults.\n"); 382 } else { 383 if (get_eeprom_cksum(START_EEPROM_DATA,CHKSUM_LEN, eeprom_buff)<0) { 384 device_printf(dev, "EEPROM cheksum bad, " 385 "assuming defaults.\n");
| 393 sc->auto_neg_cnf = eeprom_buff[AUTO_NEG_CNF_OFFSET/2]; 394 sc->adapter_cnf = eeprom_buff[ADAPTER_CNF_OFFSET/2]; 395 sc->isa_config = eeprom_buff[ISA_CNF_OFFSET/2]; 396 for (i=0; i<ETHER_ADDR_LEN/2; i++) { 397 sc->enaddr[i*2] = eeprom_buff[i]; 398 sc->enaddr[i*2+1] = eeprom_buff[i] >> 8; 399 } 400 /* 401 * If no interrupt specified, use what the 402 * board tells us. 403 */ 404 if (error) { 405 irq = sc->isa_config & INT_NO_MASK; 406 error = 0; 407 if (chip_type == CS8900) { 408 irq = cs8900_eeint2irq[irq];
|
386 } else {
| 409 } else {
|
387 sc->auto_neg_cnf = 388 eeprom_buff[AUTO_NEG_CNF_OFFSET/2]; 389 sc->adapter_cnf = 390 eeprom_buff[ADAPTER_CNF_OFFSET/2]; 391 sc->isa_config = 392 eeprom_buff[ISA_CNF_OFFSET/2]; 393 394 for (i=0; i<ETHER_ADDR_LEN/2; i++) { 395 sc->enaddr[i*2]= 396 eeprom_buff[i]; 397 sc->enaddr[i*2+1]= 398 eeprom_buff[i] >> 8; 399 } 400 401 /* 402 * If no interrupt specified, 403 * use what the board tells us. 404 */ 405 if (error) { 406 irq = sc->isa_config & INT_NO_MASK; 407 error = 0; 408 if (chip_type==CS8900) { 409 switch(irq) { 410 case 0: 411 irq=10; 412 break; 413 case 1: 414 irq=11; 415 break; 416 case 2: 417 irq=12; 418 break; 419 case 3: 420 irq=5; 421 break; 422 default: 423 device_printf(dev, "invalid irq in EEPROM.\n"); 424 error=EINVAL; 425 } 426 } else { 427 if (irq>CS8920_NO_INTS) { 428 device_printf(dev, "invalid irq in EEPROM.\n"); 429 error=EINVAL; 430 } 431 } 432 if (!error) 433 bus_set_resource(dev, SYS_RES_IRQ, 0, 434 irq, 1); 435 }
| 410 if (irq > CS8920_NO_INTS) 411 irq = 255;
|
436 }
| 412 }
|
| 413 if (irq == 255) { 414 device_printf(dev, "invalid irq in EEPROM.\n"); 415 error = EINVAL; 416 } 417 if (!error) 418 bus_set_resource(dev, SYS_RES_IRQ, 0, 419 irq, 1);
|
437 } 438 } 439
| 420 } 421 } 422
|
440 if (!error) {
| 423 if (!error && !(sc->flags & CS_NO_IRQ)) {
|
441 if (chip_type == CS8900) {
| 424 if (chip_type == CS8900) {
|
442 switch(irq) { 443 case 5: 444 irq = 3; 445 break; 446 case 10: 447 irq = 0; 448 break; 449 case 11: 450 irq = 1; 451 break; 452 case 12: 453 irq = 2; 454 break; 455 default: 456 error = EINVAL; 457 break; 458 }
| 425 if (irq >= 0 || irq < 16) 426 irq = cs8900_irq2eeint[irq]; 427 else 428 irq = 255;
|
459 } else {
| 429 } else {
|
460 if (irq > CS8920_NO_INTS && !(sc->flags & CS_NO_IRQ)) 461 error = EINVAL;
| 430 if (irq > CS8920_NO_INTS) 431 irq = 255;
|
462 }
| 432 }
|
| 433 if (irq == 255) 434 error = EINVAL;
|
463 } 464 465 if (error) { 466 device_printf(dev, "Unknown or invalid irq\n"); 467 return (error); 468 } 469 470 if (!(sc->flags & CS_NO_IRQ)) 471 cs_writereg(sc, pp_isaint, irq); 472 473 /* 474 * Temporary disabled 475 * 476 if (drq>0) 477 cs_writereg(sc, pp_isadma, drq); 478 else { 479 device_printf(dev, "incorrect drq\n",); 480 return (0); 481 } 482 */ 483 484 if (bootverbose) 485 device_printf(dev, "CS89%c0%s rev %c media%s%s%s\n",
| 435 } 436 437 if (error) { 438 device_printf(dev, "Unknown or invalid irq\n"); 439 return (error); 440 } 441 442 if (!(sc->flags & CS_NO_IRQ)) 443 cs_writereg(sc, pp_isaint, irq); 444 445 /* 446 * Temporary disabled 447 * 448 if (drq>0) 449 cs_writereg(sc, pp_isadma, drq); 450 else { 451 device_printf(dev, "incorrect drq\n",); 452 return (0); 453 } 454 */ 455 456 if (bootverbose) 457 device_printf(dev, "CS89%c0%s rev %c media%s%s%s\n",
|
486 chip_type==CS8900 ? '0' : '2', 487 chip_type==CS8920M ? "M" : "",
| 458 chip_type == CS8900 ? '0' : '2', 459 chip_type == CS8920M ? "M" : "",
|
488 chip_revision, 489 (sc->adapter_cnf & A_CNF_10B_T) ? " TP" : "", 490 (sc->adapter_cnf & A_CNF_AUI) ? " AUI" : "", 491 (sc->adapter_cnf & A_CNF_10B_2) ? " BNC" : ""); 492 493 if ((sc->adapter_cnf & A_CNF_EXTND_10B_2) && 494 (sc->adapter_cnf & A_CNF_LOW_RX_SQUELCH)) 495 sc->line_ctl = LOW_RX_SQUELCH; 496 else 497 sc->line_ctl = 0; 498 499 return (0); 500} 501 502/* 503 * Allocate a port resource with the given resource id. 504 */ 505int cs_alloc_port(device_t dev, int rid, int size) 506{ 507 struct cs_softc *sc = device_get_softc(dev); 508 struct resource *res; 509 510 res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 511 0ul, ~0ul, size, RF_ACTIVE); 512 if (res == NULL) 513 return (ENOENT); 514 sc->port_rid = rid; 515 sc->port_res = res; 516 sc->port_used = size; 517 return (0); 518} 519 520/* 521 * Allocate a memory resource with the given resource id. 522 */ 523int cs_alloc_memory(device_t dev, int rid, int size) 524{ 525 struct cs_softc *sc = device_get_softc(dev); 526 struct resource *res; 527 528 res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 529 0ul, ~0ul, size, RF_ACTIVE); 530 if (res == NULL) 531 return (ENOENT); 532 sc->mem_rid = rid; 533 sc->mem_res = res; 534 sc->mem_used = size; 535 return (0); 536} 537 538/* 539 * Allocate an irq resource with the given resource id. 540 */ 541int cs_alloc_irq(device_t dev, int rid, int flags) 542{ 543 struct cs_softc *sc = device_get_softc(dev); 544 struct resource *res; 545 546 res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 547 (RF_ACTIVE | flags)); 548 if (res == NULL) 549 return (ENOENT); 550 sc->irq_rid = rid; 551 sc->irq_res = res; 552 return (0); 553} 554 555/* 556 * Release all resources 557 */ 558void cs_release_resources(device_t dev) 559{ 560 struct cs_softc *sc = device_get_softc(dev); 561 562 if (sc->port_res) { 563 bus_release_resource(dev, SYS_RES_IOPORT, 564 sc->port_rid, sc->port_res); 565 sc->port_res = 0; 566 } 567 if (sc->mem_res) { 568 bus_release_resource(dev, SYS_RES_MEMORY, 569 sc->mem_rid, sc->mem_res); 570 sc->mem_res = 0; 571 } 572 if (sc->irq_res) { 573 bus_release_resource(dev, SYS_RES_IRQ, 574 sc->irq_rid, sc->irq_res); 575 sc->irq_res = 0; 576 } 577} 578 579/* 580 * Install the interface into kernel networking data structures 581 */ 582int 583cs_attach(device_t dev) 584{ 585 int media=0; 586 struct cs_softc *sc = device_get_softc(dev);; 587 struct ifnet *ifp; 588 589 sc->dev = dev; 590 591 ifp = sc->ifp = if_alloc(IFT_ETHER); 592 if (ifp == NULL) { 593 device_printf(dev, "can not if_alloc()\n"); 594 return (0); 595 } 596 597 cs_stop( sc ); 598 599 ifp->if_softc=sc; 600 if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 601 ifp->if_start=cs_start; 602 ifp->if_ioctl=cs_ioctl; 603 ifp->if_watchdog=cs_watchdog; 604 ifp->if_init=cs_init; 605 ifp->if_snd.ifq_maxlen= IFQ_MAXLEN; 606 /* 607 * MIB DATA 608 */ 609 /* 610 ifp->if_linkmib=&sc->mibdata; 611 ifp->if_linkmiblen=sizeof sc->mibdata; 612 */ 613 614 ifp->if_flags=(IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | 615 IFF_NEEDSGIANT); 616 617 /* 618 * this code still in progress (DMA support) 619 * 620 621 sc->recv_ring=malloc(CS_DMA_BUFFER_SIZE<<1, M_DEVBUF, M_NOWAIT); 622 if (sc->recv_ring == NULL) { 623 log(LOG_ERR, 624 "%s: Couldn't allocate memory for NIC\n", ifp->if_xname); 625 return(0); 626 } 627 if ((sc->recv_ring-(sc->recv_ring & 0x1FFFF)) 628 < (128*1024-CS_DMA_BUFFER_SIZE)) 629 sc->recv_ring+=16*1024; 630 631 */ 632 633 sc->buffer=malloc(ETHER_MAX_LEN-ETHER_CRC_LEN,M_DEVBUF,M_NOWAIT); 634 if (sc->buffer == NULL) { 635 device_printf(sc->dev, "Couldn't allocate memory for NIC\n"); 636 return(0); 637 } 638 639 /* 640 * Initialize the media structures. 641 */ 642 ifmedia_init(&sc->media, 0, cs_mediachange, cs_mediastatus); 643 644 if (sc->adapter_cnf & A_CNF_10B_T) { 645 ifmedia_add(&sc->media, IFM_ETHER|IFM_10_T, 0, NULL); 646 if (sc->chip_type != CS8900) { 647 ifmedia_add(&sc->media, 648 IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL); 649 ifmedia_add(&sc->media, 650 IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL); 651 } 652 } 653 654 if (sc->adapter_cnf & A_CNF_10B_2) 655 ifmedia_add(&sc->media, IFM_ETHER|IFM_10_2, 0, NULL); 656 657 if (sc->adapter_cnf & A_CNF_AUI) 658 ifmedia_add(&sc->media, IFM_ETHER|IFM_10_5, 0, NULL); 659 660 if (sc->adapter_cnf & A_CNF_MEDIA) 661 ifmedia_add(&sc->media, IFM_ETHER|IFM_AUTO, 0, NULL); 662 663 /* Set default media from EEPROM */ 664 switch (sc->adapter_cnf & A_CNF_MEDIA_TYPE) { 665 case A_CNF_MEDIA_AUTO: media = IFM_ETHER|IFM_AUTO; break; 666 case A_CNF_MEDIA_10B_T: media = IFM_ETHER|IFM_10_T; break; 667 case A_CNF_MEDIA_10B_2: media = IFM_ETHER|IFM_10_2; break; 668 case A_CNF_MEDIA_AUI: media = IFM_ETHER|IFM_10_5; break; 669 default: 670 device_printf(sc->dev, "no media, assuming 10baseT\n"); 671 sc->adapter_cnf |= A_CNF_10B_T; 672 ifmedia_add(&sc->media, IFM_ETHER|IFM_10_T, 0, NULL); 673 if (sc->chip_type != CS8900) { 674 ifmedia_add(&sc->media, 675 IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL); 676 ifmedia_add(&sc->media, 677 IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL); 678 } 679 media = IFM_ETHER | IFM_10_T; 680 break; 681 } 682 ifmedia_set(&sc->media, media); 683 cs_mediaset(sc, media); 684 685 ether_ifattach(ifp, sc->enaddr); 686 687 return (0); 688} 689 690int 691cs_detach(device_t dev) 692{ 693 struct cs_softc *sc; 694 struct ifnet *ifp; 695 696 sc = device_get_softc(dev); 697 ifp = sc->ifp; 698 699 cs_stop(sc); 700 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 701 ether_ifdetach(ifp); 702 cs_release_resources(dev); 703 if_free(ifp); 704 return (0); 705} 706 707/* 708 * Initialize the board 709 */ 710static void 711cs_init(void *xsc) 712{ 713 struct cs_softc *sc=(struct cs_softc *)xsc; 714 struct ifnet *ifp = sc->ifp; 715 int i, s, rx_cfg; 716 717 /* 718 * reset whatchdog timer 719 */ 720 ifp->if_timer=0; 721 sc->buf_len = 0; 722 723 s=splimp(); 724 725 /* 726 * Hardware initialization of cs 727 */ 728 729 /* Enable receiver and transmitter */ 730 cs_writereg(sc, PP_LineCTL, 731 cs_readreg(sc, PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON); 732 733 /* Configure the receiver mode */ 734 cs_setmode(sc); 735 736 /* 737 * This defines what type of frames will cause interrupts 738 * Bad frames should generate interrupts so that the driver 739 * could track statistics of discarded packets 740 */ 741 rx_cfg = RX_OK_ENBL | RX_CRC_ERROR_ENBL | RX_RUNT_ENBL | 742 RX_EXTRA_DATA_ENBL; 743 if (sc->isa_config & STREAM_TRANSFER) 744 rx_cfg |= RX_STREAM_ENBL; 745 cs_writereg(sc, PP_RxCFG, rx_cfg); 746 cs_writereg(sc, PP_TxCFG, TX_LOST_CRS_ENBL | 747 TX_SQE_ERROR_ENBL | TX_OK_ENBL | TX_LATE_COL_ENBL | 748 TX_JBR_ENBL | TX_ANY_COL_ENBL | TX_16_COL_ENBL); 749 cs_writereg(sc, PP_BufCFG, READY_FOR_TX_ENBL | 750 RX_MISS_COUNT_OVRFLOW_ENBL | TX_COL_COUNT_OVRFLOW_ENBL | 751 TX_UNDERRUN_ENBL /*| RX_DMA_ENBL*/); 752 753 /* Write MAC address into IA filter */ 754 for (i=0; i<ETHER_ADDR_LEN/2; i++) 755 cs_writereg(sc, PP_IA + i * 2, 756 sc->enaddr[i * 2] | 757 (sc->enaddr[i * 2 + 1] << 8) ); 758 759 /* 760 * Now enable everything 761 */ 762/* 763#ifdef CS_USE_64K_DMA 764 cs_writereg(sc, PP_BusCTL, ENABLE_IRQ | RX_DMA_SIZE_64K); 765#else 766 cs_writereg(sc, PP_BusCTL, ENABLE_IRQ); 767#endif 768*/ 769 cs_writereg(sc, PP_BusCTL, ENABLE_IRQ); 770 771 /* 772 * Set running and clear output active flags 773 */ 774 sc->ifp->if_drv_flags |= IFF_DRV_RUNNING; 775 sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 776 777 /* 778 * Start sending process 779 */ 780 cs_start(ifp); 781 782 (void) splx(s); 783} 784 785/* 786 * Get the packet from the board and send it to the upper layer. 787 */ 788static int 789cs_get_packet(struct cs_softc *sc) 790{ 791 struct ifnet *ifp = sc->ifp; 792 int iobase = sc->nic_addr, status, length; 793 struct ether_header *eh; 794 struct mbuf *m; 795 796#ifdef CS_DEBUG 797 int i; 798#endif 799 800 status = cs_inw(sc, RX_FRAME_PORT); 801 length = cs_inw(sc, RX_FRAME_PORT); 802 803#ifdef CS_DEBUG 804 device_printf(sc->dev, "rcvd: stat %x, len %d\n", 805 status, length); 806#endif 807 808 if (!(status & RX_OK)) { 809#ifdef CS_DEBUG 810 device_printf(sc->dev, "bad pkt stat %x\n", status); 811#endif 812 ifp->if_ierrors++; 813 return (-1); 814 } 815 816 MGETHDR(m, M_DONTWAIT, MT_DATA); 817 if (m==NULL) 818 return (-1); 819 820 if (length > MHLEN) { 821 MCLGET(m, M_DONTWAIT); 822 if (!(m->m_flags & M_EXT)) { 823 m_freem(m); 824 return (-1); 825 } 826 } 827 828 /* Initialize packet's header info */ 829 m->m_pkthdr.rcvif = ifp; 830 m->m_pkthdr.len = length; 831 m->m_len = length; 832 833 /* Get the data */ 834 insw(iobase + RX_FRAME_PORT, m->m_data, (length+1)>>1); 835 836 eh = mtod(m, struct ether_header *); 837 838#ifdef CS_DEBUG 839 for (i=0;i<length;i++) 840 printf(" %02x",(unsigned char)*((char *)(m->m_data+i))); 841 printf( "\n" ); 842#endif 843 844 if (status & (RX_IA | RX_BROADCAST) || 845 (ifp->if_flags & IFF_MULTICAST && status & RX_HASHED)) { 846 /* Feed the packet to the upper layer */ 847 (*ifp->if_input)(ifp, m); 848 ifp->if_ipackets++; 849 if (length == ETHER_MAX_LEN-ETHER_CRC_LEN) 850 DELAY(cs_recv_delay); 851 } else { 852 m_freem(m); 853 } 854 855 return (0); 856} 857 858/* 859 * Handle interrupts 860 */ 861void 862csintr(void *arg) 863{ 864 struct cs_softc *sc = (struct cs_softc*) arg; 865 struct ifnet *ifp = sc->ifp; 866 int status; 867 868#ifdef CS_DEBUG 869 device_printf(sc->dev, "Interrupt.\n"); 870#endif 871 872 while ((status=cs_inw(sc, ISQ_PORT))) { 873 874#ifdef CS_DEBUG 875 device_printf(sc->dev, "from ISQ: %04x\n", status); 876#endif 877 878 switch (status & ISQ_EVENT_MASK) { 879 case ISQ_RECEIVER_EVENT: 880 cs_get_packet(sc); 881 break; 882 883 case ISQ_TRANSMITTER_EVENT: 884 if (status & TX_OK) 885 ifp->if_opackets++; 886 else 887 ifp->if_oerrors++; 888 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 889 ifp->if_timer = 0; 890 break; 891 892 case ISQ_BUFFER_EVENT: 893 if (status & READY_FOR_TX) { 894 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 895 ifp->if_timer = 0; 896 } 897 898 if (status & TX_UNDERRUN) { 899 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 900 ifp->if_timer = 0; 901 ifp->if_oerrors++; 902 } 903 break; 904 905 case ISQ_RX_MISS_EVENT: 906 ifp->if_ierrors+=(status>>6); 907 break; 908 909 case ISQ_TX_COL_EVENT: 910 ifp->if_collisions+=(status>>6); 911 break; 912 } 913 } 914 915 if (!(ifp->if_drv_flags & IFF_DRV_OACTIVE)) { 916 cs_start(ifp); 917 } 918} 919 920/* 921 * Save the data in buffer 922 */ 923 924static void 925cs_write_mbufs( struct cs_softc *sc, struct mbuf *m ) 926{ 927 int len; 928 struct mbuf *mp; 929 unsigned char *data, *buf; 930 931 for (mp=m, buf=sc->buffer, sc->buf_len=0; mp != NULL; mp=mp->m_next) { 932 len = mp->m_len; 933 934 /* 935 * Ignore empty parts 936 */ 937 if (!len) 938 continue; 939 940 /* 941 * Find actual data address 942 */ 943 data = mtod(mp, caddr_t); 944 945 bcopy((caddr_t) data, (caddr_t) buf, len); 946 buf += len; 947 sc->buf_len += len; 948 } 949} 950 951 952static void 953cs_xmit_buf( struct cs_softc *sc ) 954{ 955 outsw(sc->nic_addr+TX_FRAME_PORT, sc->buffer, (sc->buf_len+1)>>1); 956 sc->buf_len = 0; 957} 958 959static void 960cs_start(struct ifnet *ifp) 961{ 962 int s, length; 963 struct mbuf *m, *mp; 964 struct cs_softc *sc = ifp->if_softc; 965 966 s = splimp(); 967 968 for (;;) { 969 if (sc->buf_len) 970 length = sc->buf_len; 971 else { 972 IF_DEQUEUE( &ifp->if_snd, m ); 973 974 if (m==NULL) { 975 (void) splx(s); 976 return; 977 } 978 979 for (length=0, mp=m; mp != NULL; mp=mp->m_next) 980 length += mp->m_len; 981 982 /* Skip zero-length packets */ 983 if (length == 0) { 984 m_freem(m); 985 continue; 986 } 987 988 cs_write_mbufs(sc, m); 989 990 BPF_MTAP(ifp, m); 991 992 m_freem(m); 993 } 994 995 /* 996 * Issue a SEND command 997 */ 998 cs_outw(sc, TX_CMD_PORT, sc->send_cmd); 999 cs_outw(sc, TX_LEN_PORT, length ); 1000 1001 /* 1002 * If there's no free space in the buffer then leave 1003 * this packet for the next time: indicate output active 1004 * and return. 1005 */ 1006 if (!(cs_readreg(sc, PP_BusST) & READY_FOR_TX_NOW)) { 1007 ifp->if_timer = sc->buf_len; 1008 (void) splx(s); 1009 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1010 return; 1011 } 1012 1013 cs_xmit_buf(sc); 1014 1015 /* 1016 * Set the watchdog timer in case we never hear 1017 * from board again. (I don't know about correct 1018 * value for this timeout) 1019 */ 1020 ifp->if_timer = length; 1021 1022 (void) splx(s); 1023 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1024 return; 1025 } 1026} 1027 1028/* 1029 * Stop everything on the interface 1030 */ 1031static void 1032cs_stop(struct cs_softc *sc) 1033{ 1034 int s = splimp(); 1035 1036 cs_writereg(sc, PP_RxCFG, 0); 1037 cs_writereg(sc, PP_TxCFG, 0); 1038 cs_writereg(sc, PP_BufCFG, 0); 1039 cs_writereg(sc, PP_BusCTL, 0); 1040 1041 sc->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 1042 sc->ifp->if_timer = 0; 1043 1044 (void) splx(s); 1045} 1046 1047/* 1048 * Reset the interface 1049 */ 1050static void 1051cs_reset(struct cs_softc *sc) 1052{ 1053 cs_stop(sc); 1054 cs_init(sc); 1055} 1056 1057static uint16_t 1058cs_hash_index(struct sockaddr_dl *addr) 1059{ 1060 uint32_t crc; 1061 uint16_t idx; 1062 caddr_t lla; 1063 1064 lla = LLADDR(addr); 1065 crc = ether_crc32_le(lla, ETHER_ADDR_LEN); 1066 idx = crc >> 26; 1067 1068 return (idx); 1069} 1070 1071static void 1072cs_setmode(struct cs_softc *sc) 1073{ 1074 int rx_ctl; 1075 uint16_t af[4]; 1076 uint16_t port, mask, index; 1077 struct ifnet *ifp = sc->ifp; 1078 struct ifmultiaddr *ifma; 1079 1080 /* Stop the receiver while changing filters */ 1081 cs_writereg(sc, PP_LineCTL, cs_readreg(sc, PP_LineCTL) & ~SERIAL_RX_ON); 1082 1083 if (ifp->if_flags & IFF_PROMISC) { 1084 /* Turn on promiscuous mode. */ 1085 rx_ctl = RX_OK_ACCEPT | RX_PROM_ACCEPT; 1086 } else if (ifp->if_flags & IFF_MULTICAST) { 1087 /* Allow receiving frames with multicast addresses */ 1088 rx_ctl = RX_IA_ACCEPT | RX_BROADCAST_ACCEPT | 1089 RX_OK_ACCEPT | RX_MULTCAST_ACCEPT; 1090 1091 /* Start with an empty filter */ 1092 af[0] = af[1] = af[2] = af[3] = 0x0000; 1093 1094 if (ifp->if_flags & IFF_ALLMULTI) { 1095 /* Accept all multicast frames */ 1096 af[0] = af[1] = af[2] = af[3] = 0xffff; 1097 } else { 1098 /* 1099 * Set up the filter to only accept multicast 1100 * frames we're interested in. 1101 */ 1102 IF_ADDR_LOCK(ifp); 1103 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 1104 struct sockaddr_dl *dl = 1105 (struct sockaddr_dl *)ifma->ifma_addr; 1106 1107 index = cs_hash_index(dl); 1108 port = (u_int16_t) (index >> 4); 1109 mask = (u_int16_t) (1 << (index & 0xf)); 1110 af[port] |= mask; 1111 } 1112 IF_ADDR_UNLOCK(ifp); 1113 } 1114 1115 cs_writereg(sc, PP_LAF + 0, af[0]); 1116 cs_writereg(sc, PP_LAF + 2, af[1]); 1117 cs_writereg(sc, PP_LAF + 4, af[2]); 1118 cs_writereg(sc, PP_LAF + 6, af[3]); 1119 } else { 1120 /* 1121 * Receive only good frames addressed for us and 1122 * good broadcasts. 1123 */ 1124 rx_ctl = RX_IA_ACCEPT | RX_BROADCAST_ACCEPT | 1125 RX_OK_ACCEPT; 1126 } 1127 1128 /* Set up the filter */ 1129 cs_writereg(sc, PP_RxCTL, RX_DEF_ACCEPT | rx_ctl); 1130 1131 /* Turn on receiver */ 1132 cs_writereg(sc, PP_LineCTL, cs_readreg(sc, PP_LineCTL) | SERIAL_RX_ON); 1133} 1134 1135static int 1136cs_ioctl(register struct ifnet *ifp, u_long command, caddr_t data) 1137{ 1138 struct cs_softc *sc=ifp->if_softc; 1139 struct ifreq *ifr = (struct ifreq *)data; 1140 int s,error=0; 1141 1142#ifdef CS_DEBUG 1143 if_printf(ifp, "%s command=%lx\n", __func__, command); 1144#endif 1145 1146 s=splimp(); 1147 1148 switch (command) { 1149 case SIOCSIFFLAGS: 1150 /* 1151 * Switch interface state between "running" and 1152 * "stopped", reflecting the UP flag. 1153 */ 1154 if (sc->ifp->if_flags & IFF_UP) { 1155 if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING)==0) { 1156 cs_init(sc); 1157 } 1158 } else { 1159 if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING)!=0) { 1160 cs_stop(sc); 1161 } 1162 } 1163 /* 1164 * Promiscuous and/or multicast flags may have changed, 1165 * so reprogram the multicast filter and/or receive mode. 1166 * 1167 * See note about multicasts in cs_setmode 1168 */ 1169 cs_setmode(sc); 1170 break; 1171 1172 case SIOCADDMULTI: 1173 case SIOCDELMULTI: 1174 /* 1175 * Multicast list has changed; set the hardware filter 1176 * accordingly. 1177 * 1178 * See note about multicasts in cs_setmode 1179 */ 1180 cs_setmode(sc); 1181 error = 0; 1182 break; 1183 1184 case SIOCSIFMEDIA: 1185 case SIOCGIFMEDIA: 1186 error = ifmedia_ioctl(ifp, ifr, &sc->media, command); 1187 break; 1188 1189 default: 1190 error = ether_ioctl(ifp, command, data); 1191 break; 1192 } 1193 1194 (void) splx(s); 1195 return (error); 1196} 1197 1198/* 1199 * Device timeout/watchdog routine. Entered if the device neglects to 1200 * generate an interrupt after a transmit has been started on it. 1201 */ 1202static void 1203cs_watchdog(struct ifnet *ifp) 1204{ 1205 struct cs_softc *sc = ifp->if_softc; 1206 1207 ifp->if_oerrors++; 1208 log(LOG_ERR, "%s: device timeout\n", ifp->if_xname); 1209 1210 /* Reset the interface */ 1211 if (ifp->if_flags & IFF_UP) 1212 cs_reset(sc); 1213 else 1214 cs_stop(sc); 1215} 1216 1217static int 1218cs_mediachange(struct ifnet *ifp) 1219{ 1220 struct cs_softc *sc = ifp->if_softc; 1221 struct ifmedia *ifm = &sc->media; 1222 1223 if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) 1224 return (EINVAL); 1225 1226 return (cs_mediaset(sc, ifm->ifm_media)); 1227} 1228 1229static void 1230cs_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) 1231{ 1232 int line_status; 1233 struct cs_softc *sc = ifp->if_softc; 1234 1235 ifmr->ifm_active = IFM_ETHER; 1236 line_status = cs_readreg(sc, PP_LineST); 1237 if (line_status & TENBASET_ON) { 1238 ifmr->ifm_active |= IFM_10_T; 1239 if (sc->chip_type != CS8900) { 1240 if (cs_readreg(sc, PP_AutoNegST) & FDX_ACTIVE) 1241 ifmr->ifm_active |= IFM_FDX; 1242 if (cs_readreg(sc, PP_AutoNegST) & HDX_ACTIVE) 1243 ifmr->ifm_active |= IFM_HDX; 1244 } 1245 ifmr->ifm_status = IFM_AVALID; 1246 if (line_status & LINK_OK) 1247 ifmr->ifm_status |= IFM_ACTIVE; 1248 } else { 1249 if (line_status & AUI_ON) { 1250 cs_writereg(sc, PP_SelfCTL, cs_readreg(sc, PP_SelfCTL) | 1251 HCB1_ENBL); 1252 if (((sc->adapter_cnf & A_CNF_DC_DC_POLARITY)!=0)^ 1253 (cs_readreg(sc, PP_SelfCTL) & HCB1)) 1254 ifmr->ifm_active |= IFM_10_2; 1255 else 1256 ifmr->ifm_active |= IFM_10_5; 1257 } 1258 } 1259} 1260 1261static int 1262cs_mediaset(struct cs_softc *sc, int media) 1263{
| 460 chip_revision, 461 (sc->adapter_cnf & A_CNF_10B_T) ? " TP" : "", 462 (sc->adapter_cnf & A_CNF_AUI) ? " AUI" : "", 463 (sc->adapter_cnf & A_CNF_10B_2) ? " BNC" : ""); 464 465 if ((sc->adapter_cnf & A_CNF_EXTND_10B_2) && 466 (sc->adapter_cnf & A_CNF_LOW_RX_SQUELCH)) 467 sc->line_ctl = LOW_RX_SQUELCH; 468 else 469 sc->line_ctl = 0; 470 471 return (0); 472} 473 474/* 475 * Allocate a port resource with the given resource id. 476 */ 477int cs_alloc_port(device_t dev, int rid, int size) 478{ 479 struct cs_softc *sc = device_get_softc(dev); 480 struct resource *res; 481 482 res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 483 0ul, ~0ul, size, RF_ACTIVE); 484 if (res == NULL) 485 return (ENOENT); 486 sc->port_rid = rid; 487 sc->port_res = res; 488 sc->port_used = size; 489 return (0); 490} 491 492/* 493 * Allocate a memory resource with the given resource id. 494 */ 495int cs_alloc_memory(device_t dev, int rid, int size) 496{ 497 struct cs_softc *sc = device_get_softc(dev); 498 struct resource *res; 499 500 res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 501 0ul, ~0ul, size, RF_ACTIVE); 502 if (res == NULL) 503 return (ENOENT); 504 sc->mem_rid = rid; 505 sc->mem_res = res; 506 sc->mem_used = size; 507 return (0); 508} 509 510/* 511 * Allocate an irq resource with the given resource id. 512 */ 513int cs_alloc_irq(device_t dev, int rid, int flags) 514{ 515 struct cs_softc *sc = device_get_softc(dev); 516 struct resource *res; 517 518 res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 519 (RF_ACTIVE | flags)); 520 if (res == NULL) 521 return (ENOENT); 522 sc->irq_rid = rid; 523 sc->irq_res = res; 524 return (0); 525} 526 527/* 528 * Release all resources 529 */ 530void cs_release_resources(device_t dev) 531{ 532 struct cs_softc *sc = device_get_softc(dev); 533 534 if (sc->port_res) { 535 bus_release_resource(dev, SYS_RES_IOPORT, 536 sc->port_rid, sc->port_res); 537 sc->port_res = 0; 538 } 539 if (sc->mem_res) { 540 bus_release_resource(dev, SYS_RES_MEMORY, 541 sc->mem_rid, sc->mem_res); 542 sc->mem_res = 0; 543 } 544 if (sc->irq_res) { 545 bus_release_resource(dev, SYS_RES_IRQ, 546 sc->irq_rid, sc->irq_res); 547 sc->irq_res = 0; 548 } 549} 550 551/* 552 * Install the interface into kernel networking data structures 553 */ 554int 555cs_attach(device_t dev) 556{ 557 int media=0; 558 struct cs_softc *sc = device_get_softc(dev);; 559 struct ifnet *ifp; 560 561 sc->dev = dev; 562 563 ifp = sc->ifp = if_alloc(IFT_ETHER); 564 if (ifp == NULL) { 565 device_printf(dev, "can not if_alloc()\n"); 566 return (0); 567 } 568 569 cs_stop( sc ); 570 571 ifp->if_softc=sc; 572 if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 573 ifp->if_start=cs_start; 574 ifp->if_ioctl=cs_ioctl; 575 ifp->if_watchdog=cs_watchdog; 576 ifp->if_init=cs_init; 577 ifp->if_snd.ifq_maxlen= IFQ_MAXLEN; 578 /* 579 * MIB DATA 580 */ 581 /* 582 ifp->if_linkmib=&sc->mibdata; 583 ifp->if_linkmiblen=sizeof sc->mibdata; 584 */ 585 586 ifp->if_flags=(IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | 587 IFF_NEEDSGIANT); 588 589 /* 590 * this code still in progress (DMA support) 591 * 592 593 sc->recv_ring=malloc(CS_DMA_BUFFER_SIZE<<1, M_DEVBUF, M_NOWAIT); 594 if (sc->recv_ring == NULL) { 595 log(LOG_ERR, 596 "%s: Couldn't allocate memory for NIC\n", ifp->if_xname); 597 return(0); 598 } 599 if ((sc->recv_ring-(sc->recv_ring & 0x1FFFF)) 600 < (128*1024-CS_DMA_BUFFER_SIZE)) 601 sc->recv_ring+=16*1024; 602 603 */ 604 605 sc->buffer=malloc(ETHER_MAX_LEN-ETHER_CRC_LEN,M_DEVBUF,M_NOWAIT); 606 if (sc->buffer == NULL) { 607 device_printf(sc->dev, "Couldn't allocate memory for NIC\n"); 608 return(0); 609 } 610 611 /* 612 * Initialize the media structures. 613 */ 614 ifmedia_init(&sc->media, 0, cs_mediachange, cs_mediastatus); 615 616 if (sc->adapter_cnf & A_CNF_10B_T) { 617 ifmedia_add(&sc->media, IFM_ETHER|IFM_10_T, 0, NULL); 618 if (sc->chip_type != CS8900) { 619 ifmedia_add(&sc->media, 620 IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL); 621 ifmedia_add(&sc->media, 622 IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL); 623 } 624 } 625 626 if (sc->adapter_cnf & A_CNF_10B_2) 627 ifmedia_add(&sc->media, IFM_ETHER|IFM_10_2, 0, NULL); 628 629 if (sc->adapter_cnf & A_CNF_AUI) 630 ifmedia_add(&sc->media, IFM_ETHER|IFM_10_5, 0, NULL); 631 632 if (sc->adapter_cnf & A_CNF_MEDIA) 633 ifmedia_add(&sc->media, IFM_ETHER|IFM_AUTO, 0, NULL); 634 635 /* Set default media from EEPROM */ 636 switch (sc->adapter_cnf & A_CNF_MEDIA_TYPE) { 637 case A_CNF_MEDIA_AUTO: media = IFM_ETHER|IFM_AUTO; break; 638 case A_CNF_MEDIA_10B_T: media = IFM_ETHER|IFM_10_T; break; 639 case A_CNF_MEDIA_10B_2: media = IFM_ETHER|IFM_10_2; break; 640 case A_CNF_MEDIA_AUI: media = IFM_ETHER|IFM_10_5; break; 641 default: 642 device_printf(sc->dev, "no media, assuming 10baseT\n"); 643 sc->adapter_cnf |= A_CNF_10B_T; 644 ifmedia_add(&sc->media, IFM_ETHER|IFM_10_T, 0, NULL); 645 if (sc->chip_type != CS8900) { 646 ifmedia_add(&sc->media, 647 IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL); 648 ifmedia_add(&sc->media, 649 IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL); 650 } 651 media = IFM_ETHER | IFM_10_T; 652 break; 653 } 654 ifmedia_set(&sc->media, media); 655 cs_mediaset(sc, media); 656 657 ether_ifattach(ifp, sc->enaddr); 658 659 return (0); 660} 661 662int 663cs_detach(device_t dev) 664{ 665 struct cs_softc *sc; 666 struct ifnet *ifp; 667 668 sc = device_get_softc(dev); 669 ifp = sc->ifp; 670 671 cs_stop(sc); 672 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 673 ether_ifdetach(ifp); 674 cs_release_resources(dev); 675 if_free(ifp); 676 return (0); 677} 678 679/* 680 * Initialize the board 681 */ 682static void 683cs_init(void *xsc) 684{ 685 struct cs_softc *sc=(struct cs_softc *)xsc; 686 struct ifnet *ifp = sc->ifp; 687 int i, s, rx_cfg; 688 689 /* 690 * reset whatchdog timer 691 */ 692 ifp->if_timer=0; 693 sc->buf_len = 0; 694 695 s=splimp(); 696 697 /* 698 * Hardware initialization of cs 699 */ 700 701 /* Enable receiver and transmitter */ 702 cs_writereg(sc, PP_LineCTL, 703 cs_readreg(sc, PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON); 704 705 /* Configure the receiver mode */ 706 cs_setmode(sc); 707 708 /* 709 * This defines what type of frames will cause interrupts 710 * Bad frames should generate interrupts so that the driver 711 * could track statistics of discarded packets 712 */ 713 rx_cfg = RX_OK_ENBL | RX_CRC_ERROR_ENBL | RX_RUNT_ENBL | 714 RX_EXTRA_DATA_ENBL; 715 if (sc->isa_config & STREAM_TRANSFER) 716 rx_cfg |= RX_STREAM_ENBL; 717 cs_writereg(sc, PP_RxCFG, rx_cfg); 718 cs_writereg(sc, PP_TxCFG, TX_LOST_CRS_ENBL | 719 TX_SQE_ERROR_ENBL | TX_OK_ENBL | TX_LATE_COL_ENBL | 720 TX_JBR_ENBL | TX_ANY_COL_ENBL | TX_16_COL_ENBL); 721 cs_writereg(sc, PP_BufCFG, READY_FOR_TX_ENBL | 722 RX_MISS_COUNT_OVRFLOW_ENBL | TX_COL_COUNT_OVRFLOW_ENBL | 723 TX_UNDERRUN_ENBL /*| RX_DMA_ENBL*/); 724 725 /* Write MAC address into IA filter */ 726 for (i=0; i<ETHER_ADDR_LEN/2; i++) 727 cs_writereg(sc, PP_IA + i * 2, 728 sc->enaddr[i * 2] | 729 (sc->enaddr[i * 2 + 1] << 8) ); 730 731 /* 732 * Now enable everything 733 */ 734/* 735#ifdef CS_USE_64K_DMA 736 cs_writereg(sc, PP_BusCTL, ENABLE_IRQ | RX_DMA_SIZE_64K); 737#else 738 cs_writereg(sc, PP_BusCTL, ENABLE_IRQ); 739#endif 740*/ 741 cs_writereg(sc, PP_BusCTL, ENABLE_IRQ); 742 743 /* 744 * Set running and clear output active flags 745 */ 746 sc->ifp->if_drv_flags |= IFF_DRV_RUNNING; 747 sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 748 749 /* 750 * Start sending process 751 */ 752 cs_start(ifp); 753 754 (void) splx(s); 755} 756 757/* 758 * Get the packet from the board and send it to the upper layer. 759 */ 760static int 761cs_get_packet(struct cs_softc *sc) 762{ 763 struct ifnet *ifp = sc->ifp; 764 int iobase = sc->nic_addr, status, length; 765 struct ether_header *eh; 766 struct mbuf *m; 767 768#ifdef CS_DEBUG 769 int i; 770#endif 771 772 status = cs_inw(sc, RX_FRAME_PORT); 773 length = cs_inw(sc, RX_FRAME_PORT); 774 775#ifdef CS_DEBUG 776 device_printf(sc->dev, "rcvd: stat %x, len %d\n", 777 status, length); 778#endif 779 780 if (!(status & RX_OK)) { 781#ifdef CS_DEBUG 782 device_printf(sc->dev, "bad pkt stat %x\n", status); 783#endif 784 ifp->if_ierrors++; 785 return (-1); 786 } 787 788 MGETHDR(m, M_DONTWAIT, MT_DATA); 789 if (m==NULL) 790 return (-1); 791 792 if (length > MHLEN) { 793 MCLGET(m, M_DONTWAIT); 794 if (!(m->m_flags & M_EXT)) { 795 m_freem(m); 796 return (-1); 797 } 798 } 799 800 /* Initialize packet's header info */ 801 m->m_pkthdr.rcvif = ifp; 802 m->m_pkthdr.len = length; 803 m->m_len = length; 804 805 /* Get the data */ 806 insw(iobase + RX_FRAME_PORT, m->m_data, (length+1)>>1); 807 808 eh = mtod(m, struct ether_header *); 809 810#ifdef CS_DEBUG 811 for (i=0;i<length;i++) 812 printf(" %02x",(unsigned char)*((char *)(m->m_data+i))); 813 printf( "\n" ); 814#endif 815 816 if (status & (RX_IA | RX_BROADCAST) || 817 (ifp->if_flags & IFF_MULTICAST && status & RX_HASHED)) { 818 /* Feed the packet to the upper layer */ 819 (*ifp->if_input)(ifp, m); 820 ifp->if_ipackets++; 821 if (length == ETHER_MAX_LEN-ETHER_CRC_LEN) 822 DELAY(cs_recv_delay); 823 } else { 824 m_freem(m); 825 } 826 827 return (0); 828} 829 830/* 831 * Handle interrupts 832 */ 833void 834csintr(void *arg) 835{ 836 struct cs_softc *sc = (struct cs_softc*) arg; 837 struct ifnet *ifp = sc->ifp; 838 int status; 839 840#ifdef CS_DEBUG 841 device_printf(sc->dev, "Interrupt.\n"); 842#endif 843 844 while ((status=cs_inw(sc, ISQ_PORT))) { 845 846#ifdef CS_DEBUG 847 device_printf(sc->dev, "from ISQ: %04x\n", status); 848#endif 849 850 switch (status & ISQ_EVENT_MASK) { 851 case ISQ_RECEIVER_EVENT: 852 cs_get_packet(sc); 853 break; 854 855 case ISQ_TRANSMITTER_EVENT: 856 if (status & TX_OK) 857 ifp->if_opackets++; 858 else 859 ifp->if_oerrors++; 860 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 861 ifp->if_timer = 0; 862 break; 863 864 case ISQ_BUFFER_EVENT: 865 if (status & READY_FOR_TX) { 866 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 867 ifp->if_timer = 0; 868 } 869 870 if (status & TX_UNDERRUN) { 871 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 872 ifp->if_timer = 0; 873 ifp->if_oerrors++; 874 } 875 break; 876 877 case ISQ_RX_MISS_EVENT: 878 ifp->if_ierrors+=(status>>6); 879 break; 880 881 case ISQ_TX_COL_EVENT: 882 ifp->if_collisions+=(status>>6); 883 break; 884 } 885 } 886 887 if (!(ifp->if_drv_flags & IFF_DRV_OACTIVE)) { 888 cs_start(ifp); 889 } 890} 891 892/* 893 * Save the data in buffer 894 */ 895 896static void 897cs_write_mbufs( struct cs_softc *sc, struct mbuf *m ) 898{ 899 int len; 900 struct mbuf *mp; 901 unsigned char *data, *buf; 902 903 for (mp=m, buf=sc->buffer, sc->buf_len=0; mp != NULL; mp=mp->m_next) { 904 len = mp->m_len; 905 906 /* 907 * Ignore empty parts 908 */ 909 if (!len) 910 continue; 911 912 /* 913 * Find actual data address 914 */ 915 data = mtod(mp, caddr_t); 916 917 bcopy((caddr_t) data, (caddr_t) buf, len); 918 buf += len; 919 sc->buf_len += len; 920 } 921} 922 923 924static void 925cs_xmit_buf( struct cs_softc *sc ) 926{ 927 outsw(sc->nic_addr+TX_FRAME_PORT, sc->buffer, (sc->buf_len+1)>>1); 928 sc->buf_len = 0; 929} 930 931static void 932cs_start(struct ifnet *ifp) 933{ 934 int s, length; 935 struct mbuf *m, *mp; 936 struct cs_softc *sc = ifp->if_softc; 937 938 s = splimp(); 939 940 for (;;) { 941 if (sc->buf_len) 942 length = sc->buf_len; 943 else { 944 IF_DEQUEUE( &ifp->if_snd, m ); 945 946 if (m==NULL) { 947 (void) splx(s); 948 return; 949 } 950 951 for (length=0, mp=m; mp != NULL; mp=mp->m_next) 952 length += mp->m_len; 953 954 /* Skip zero-length packets */ 955 if (length == 0) { 956 m_freem(m); 957 continue; 958 } 959 960 cs_write_mbufs(sc, m); 961 962 BPF_MTAP(ifp, m); 963 964 m_freem(m); 965 } 966 967 /* 968 * Issue a SEND command 969 */ 970 cs_outw(sc, TX_CMD_PORT, sc->send_cmd); 971 cs_outw(sc, TX_LEN_PORT, length ); 972 973 /* 974 * If there's no free space in the buffer then leave 975 * this packet for the next time: indicate output active 976 * and return. 977 */ 978 if (!(cs_readreg(sc, PP_BusST) & READY_FOR_TX_NOW)) { 979 ifp->if_timer = sc->buf_len; 980 (void) splx(s); 981 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 982 return; 983 } 984 985 cs_xmit_buf(sc); 986 987 /* 988 * Set the watchdog timer in case we never hear 989 * from board again. (I don't know about correct 990 * value for this timeout) 991 */ 992 ifp->if_timer = length; 993 994 (void) splx(s); 995 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 996 return; 997 } 998} 999 1000/* 1001 * Stop everything on the interface 1002 */ 1003static void 1004cs_stop(struct cs_softc *sc) 1005{ 1006 int s = splimp(); 1007 1008 cs_writereg(sc, PP_RxCFG, 0); 1009 cs_writereg(sc, PP_TxCFG, 0); 1010 cs_writereg(sc, PP_BufCFG, 0); 1011 cs_writereg(sc, PP_BusCTL, 0); 1012 1013 sc->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 1014 sc->ifp->if_timer = 0; 1015 1016 (void) splx(s); 1017} 1018 1019/* 1020 * Reset the interface 1021 */ 1022static void 1023cs_reset(struct cs_softc *sc) 1024{ 1025 cs_stop(sc); 1026 cs_init(sc); 1027} 1028 1029static uint16_t 1030cs_hash_index(struct sockaddr_dl *addr) 1031{ 1032 uint32_t crc; 1033 uint16_t idx; 1034 caddr_t lla; 1035 1036 lla = LLADDR(addr); 1037 crc = ether_crc32_le(lla, ETHER_ADDR_LEN); 1038 idx = crc >> 26; 1039 1040 return (idx); 1041} 1042 1043static void 1044cs_setmode(struct cs_softc *sc) 1045{ 1046 int rx_ctl; 1047 uint16_t af[4]; 1048 uint16_t port, mask, index; 1049 struct ifnet *ifp = sc->ifp; 1050 struct ifmultiaddr *ifma; 1051 1052 /* Stop the receiver while changing filters */ 1053 cs_writereg(sc, PP_LineCTL, cs_readreg(sc, PP_LineCTL) & ~SERIAL_RX_ON); 1054 1055 if (ifp->if_flags & IFF_PROMISC) { 1056 /* Turn on promiscuous mode. */ 1057 rx_ctl = RX_OK_ACCEPT | RX_PROM_ACCEPT; 1058 } else if (ifp->if_flags & IFF_MULTICAST) { 1059 /* Allow receiving frames with multicast addresses */ 1060 rx_ctl = RX_IA_ACCEPT | RX_BROADCAST_ACCEPT | 1061 RX_OK_ACCEPT | RX_MULTCAST_ACCEPT; 1062 1063 /* Start with an empty filter */ 1064 af[0] = af[1] = af[2] = af[3] = 0x0000; 1065 1066 if (ifp->if_flags & IFF_ALLMULTI) { 1067 /* Accept all multicast frames */ 1068 af[0] = af[1] = af[2] = af[3] = 0xffff; 1069 } else { 1070 /* 1071 * Set up the filter to only accept multicast 1072 * frames we're interested in. 1073 */ 1074 IF_ADDR_LOCK(ifp); 1075 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 1076 struct sockaddr_dl *dl = 1077 (struct sockaddr_dl *)ifma->ifma_addr; 1078 1079 index = cs_hash_index(dl); 1080 port = (u_int16_t) (index >> 4); 1081 mask = (u_int16_t) (1 << (index & 0xf)); 1082 af[port] |= mask; 1083 } 1084 IF_ADDR_UNLOCK(ifp); 1085 } 1086 1087 cs_writereg(sc, PP_LAF + 0, af[0]); 1088 cs_writereg(sc, PP_LAF + 2, af[1]); 1089 cs_writereg(sc, PP_LAF + 4, af[2]); 1090 cs_writereg(sc, PP_LAF + 6, af[3]); 1091 } else { 1092 /* 1093 * Receive only good frames addressed for us and 1094 * good broadcasts. 1095 */ 1096 rx_ctl = RX_IA_ACCEPT | RX_BROADCAST_ACCEPT | 1097 RX_OK_ACCEPT; 1098 } 1099 1100 /* Set up the filter */ 1101 cs_writereg(sc, PP_RxCTL, RX_DEF_ACCEPT | rx_ctl); 1102 1103 /* Turn on receiver */ 1104 cs_writereg(sc, PP_LineCTL, cs_readreg(sc, PP_LineCTL) | SERIAL_RX_ON); 1105} 1106 1107static int 1108cs_ioctl(register struct ifnet *ifp, u_long command, caddr_t data) 1109{ 1110 struct cs_softc *sc=ifp->if_softc; 1111 struct ifreq *ifr = (struct ifreq *)data; 1112 int s,error=0; 1113 1114#ifdef CS_DEBUG 1115 if_printf(ifp, "%s command=%lx\n", __func__, command); 1116#endif 1117 1118 s=splimp(); 1119 1120 switch (command) { 1121 case SIOCSIFFLAGS: 1122 /* 1123 * Switch interface state between "running" and 1124 * "stopped", reflecting the UP flag. 1125 */ 1126 if (sc->ifp->if_flags & IFF_UP) { 1127 if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING)==0) { 1128 cs_init(sc); 1129 } 1130 } else { 1131 if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING)!=0) { 1132 cs_stop(sc); 1133 } 1134 } 1135 /* 1136 * Promiscuous and/or multicast flags may have changed, 1137 * so reprogram the multicast filter and/or receive mode. 1138 * 1139 * See note about multicasts in cs_setmode 1140 */ 1141 cs_setmode(sc); 1142 break; 1143 1144 case SIOCADDMULTI: 1145 case SIOCDELMULTI: 1146 /* 1147 * Multicast list has changed; set the hardware filter 1148 * accordingly. 1149 * 1150 * See note about multicasts in cs_setmode 1151 */ 1152 cs_setmode(sc); 1153 error = 0; 1154 break; 1155 1156 case SIOCSIFMEDIA: 1157 case SIOCGIFMEDIA: 1158 error = ifmedia_ioctl(ifp, ifr, &sc->media, command); 1159 break; 1160 1161 default: 1162 error = ether_ioctl(ifp, command, data); 1163 break; 1164 } 1165 1166 (void) splx(s); 1167 return (error); 1168} 1169 1170/* 1171 * Device timeout/watchdog routine. Entered if the device neglects to 1172 * generate an interrupt after a transmit has been started on it. 1173 */ 1174static void 1175cs_watchdog(struct ifnet *ifp) 1176{ 1177 struct cs_softc *sc = ifp->if_softc; 1178 1179 ifp->if_oerrors++; 1180 log(LOG_ERR, "%s: device timeout\n", ifp->if_xname); 1181 1182 /* Reset the interface */ 1183 if (ifp->if_flags & IFF_UP) 1184 cs_reset(sc); 1185 else 1186 cs_stop(sc); 1187} 1188 1189static int 1190cs_mediachange(struct ifnet *ifp) 1191{ 1192 struct cs_softc *sc = ifp->if_softc; 1193 struct ifmedia *ifm = &sc->media; 1194 1195 if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) 1196 return (EINVAL); 1197 1198 return (cs_mediaset(sc, ifm->ifm_media)); 1199} 1200 1201static void 1202cs_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) 1203{ 1204 int line_status; 1205 struct cs_softc *sc = ifp->if_softc; 1206 1207 ifmr->ifm_active = IFM_ETHER; 1208 line_status = cs_readreg(sc, PP_LineST); 1209 if (line_status & TENBASET_ON) { 1210 ifmr->ifm_active |= IFM_10_T; 1211 if (sc->chip_type != CS8900) { 1212 if (cs_readreg(sc, PP_AutoNegST) & FDX_ACTIVE) 1213 ifmr->ifm_active |= IFM_FDX; 1214 if (cs_readreg(sc, PP_AutoNegST) & HDX_ACTIVE) 1215 ifmr->ifm_active |= IFM_HDX; 1216 } 1217 ifmr->ifm_status = IFM_AVALID; 1218 if (line_status & LINK_OK) 1219 ifmr->ifm_status |= IFM_ACTIVE; 1220 } else { 1221 if (line_status & AUI_ON) { 1222 cs_writereg(sc, PP_SelfCTL, cs_readreg(sc, PP_SelfCTL) | 1223 HCB1_ENBL); 1224 if (((sc->adapter_cnf & A_CNF_DC_DC_POLARITY)!=0)^ 1225 (cs_readreg(sc, PP_SelfCTL) & HCB1)) 1226 ifmr->ifm_active |= IFM_10_2; 1227 else 1228 ifmr->ifm_active |= IFM_10_5; 1229 } 1230 } 1231} 1232 1233static int 1234cs_mediaset(struct cs_softc *sc, int media) 1235{
|
1264 int error;
| 1236 int error = 0;
|
1265 1266 /* Stop the receiver & transmitter */ 1267 cs_writereg(sc, PP_LineCTL, cs_readreg(sc, PP_LineCTL) & 1268 ~(SERIAL_RX_ON | SERIAL_TX_ON)); 1269 1270#ifdef CS_DEBUG 1271 device_printf(sc->dev, "%s media=%x\n", __func__, media); 1272#endif 1273 1274 switch (IFM_SUBTYPE(media)) { 1275 default: 1276 case IFM_AUTO: 1277 if ((error=enable_tp(sc))==0) 1278 error = cs_duplex_auto(sc); 1279 else if ((error=enable_bnc(sc)) != 0) 1280 error = enable_aui(sc); 1281 break; 1282 case IFM_10_T:
| 1237 1238 /* Stop the receiver & transmitter */ 1239 cs_writereg(sc, PP_LineCTL, cs_readreg(sc, PP_LineCTL) & 1240 ~(SERIAL_RX_ON | SERIAL_TX_ON)); 1241 1242#ifdef CS_DEBUG 1243 device_printf(sc->dev, "%s media=%x\n", __func__, media); 1244#endif 1245 1246 switch (IFM_SUBTYPE(media)) { 1247 default: 1248 case IFM_AUTO: 1249 if ((error=enable_tp(sc))==0) 1250 error = cs_duplex_auto(sc); 1251 else if ((error=enable_bnc(sc)) != 0) 1252 error = enable_aui(sc); 1253 break; 1254 case IFM_10_T:
|
1283 if ((error=enable_tp(sc)) != 0) 1284 break;
| 1255 enable_tp(sc);
|
1285 if (media & IFM_FDX) 1286 cs_duplex_full(sc); 1287 else if (media & IFM_HDX) 1288 cs_duplex_half(sc); 1289 else 1290 error = cs_duplex_auto(sc); 1291 break; 1292 case IFM_10_2: 1293 error = enable_bnc(sc); 1294 break; 1295 case IFM_10_5: 1296 error = enable_aui(sc); 1297 break; 1298 } 1299 1300 /* 1301 * Turn the transmitter & receiver back on 1302 */ 1303 cs_writereg(sc, PP_LineCTL, cs_readreg(sc, PP_LineCTL) | 1304 SERIAL_RX_ON | SERIAL_TX_ON); 1305 1306 return (error); 1307}
| 1256 if (media & IFM_FDX) 1257 cs_duplex_full(sc); 1258 else if (media & IFM_HDX) 1259 cs_duplex_half(sc); 1260 else 1261 error = cs_duplex_auto(sc); 1262 break; 1263 case IFM_10_2: 1264 error = enable_bnc(sc); 1265 break; 1266 case IFM_10_5: 1267 error = enable_aui(sc); 1268 break; 1269 } 1270 1271 /* 1272 * Turn the transmitter & receiver back on 1273 */ 1274 cs_writereg(sc, PP_LineCTL, cs_readreg(sc, PP_LineCTL) | 1275 SERIAL_RX_ON | SERIAL_TX_ON); 1276 1277 return (error); 1278}
|