153897Smckusick /* 253897Smckusick * Copyright (c) 1992 The Regents of the University of California. 353897Smckusick * All rights reserved. 453897Smckusick * 553897Smckusick * This code is derived from software contributed to Berkeley by 653897Smckusick * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc. 753897Smckusick * 853897Smckusick * %sccs.include.redist.c% 953897Smckusick * 1053897Smckusick * from: $Hdr: if_lance.c,v 4.300 91/06/09 06:25:58 root Rel41 $ SONY 1153897Smckusick * 12*54474Sutashiro * @(#)if_lance.c 7.2 (Berkeley) 06/25/92 1353897Smckusick */ 1453897Smckusick 1553897Smckusick /* 1653897Smckusick * if_lance: Am7990 LANCE driver 1753897Smckusick * 1853897Smckusick * This driver is available only for single CPU machine. 1953897Smckusick */ 2053897Smckusick 2153897Smckusick #define LANCE_LED 2253897Smckusick 2353897Smckusick #include "en.h" 2453897Smckusick 2553897Smckusick #if NEN > 0 2653897Smckusick 2753897Smckusick #include "../include/fix_machine_type.h" 2853897Smckusick #include "../include/adrsmap.h" 2953897Smckusick 3053897Smckusick #include "param.h" 3153897Smckusick 3253897Smckusick #include "../if/lancereg.h" 3353897Smckusick #include "../if/if_lance.h" 3453897Smckusick 3553897Smckusick #ifdef mips 3653897Smckusick #define VOLATILE volatile 3753897Smckusick #else 3853897Smckusick #define VOLATILE 3953897Smckusick #endif 4053897Smckusick 4153897Smckusick #ifdef LANCE_LED 4253897Smckusick #ifdef news3400 4353897Smckusick #define LED_ON { \ 4453897Smckusick VOLATILE u_char *p = (u_char *)DEBUG_PORT; \ 4553897Smckusick *p = DP_WRITE | (*p & ~DP_LED2); \ 4653897Smckusick } 4753897Smckusick #define LED_OFF { \ 4853897Smckusick VOLATILE u_char *p = (u_char *)DEBUG_PORT; \ 4953897Smckusick *p = DP_WRITE | (*p | DP_LED2); \ 5053897Smckusick } 5153897Smckusick #else /* news3400 */ 5253897Smckusick #define LED_ON 5353897Smckusick #define LED_OFF 5453897Smckusick #endif /* news3400 */ 5553897Smckusick #else /* LANCE_LED */ 5653897Smckusick #define LED_ON 5753897Smckusick #define LED_OFF 5853897Smckusick #endif /* LANCE_LED */ 5953897Smckusick 6053897Smckusick /* 6153897Smckusick * LANCE memory configuration 6253897Smckusick */ 6353897Smckusick #define INIT_BLOCK 0x000000 6453897Smckusick #define RECV_MSG_DESC 0x000100 6553897Smckusick #define XMIT_MSG_DESC 0x000200 6653897Smckusick #ifdef mips 6753897Smckusick #define RECV_BUFFER (0x000300 + 2) 6853897Smckusick /* for data alignment to long word */ 6953897Smckusick #else /* mips */ 7053897Smckusick #define RECV_BUFFER 0x000300 7153897Smckusick #endif /* mips */ 7253897Smckusick #define XMIT_BUFFER (RECV_BUFFER+(RECV_BUFFER_SIZE*RECV_BUFFERS)) 7353897Smckusick 7453897Smckusick #define RECV_RING_LEN 3 /* log2(8) */ 7553897Smckusick #define XMIT_RING_LEN 1 /* log2(2) */ 7653897Smckusick 7753897Smckusick #define RECV_BUFFER_SIZE 0x600 7853897Smckusick #define XMIT_BUFFER_SIZE 0x600 7953897Smckusick 8053897Smckusick #define RECV_BUFFERS (1 << RECV_RING_LEN) 8153897Smckusick #define XMIT_BUFFERS (1 << XMIT_RING_LEN) 8253897Smckusick 8353897Smckusick /* 8453897Smckusick * Initialization block 8553897Smckusick */ 8653897Smckusick struct init_block init_block = { 8753897Smckusick 0, 8853897Smckusick 0, 0, 0, 0, 0, 0, 8953897Smckusick 0, 0, 0, 0, 0, 0, 0, 0, 9053897Smckusick RECV_MSG_DESC & 0xffff, 9153897Smckusick (RECV_RING_LEN << 13) | (RECV_MSG_DESC >> 16), 9253897Smckusick XMIT_MSG_DESC & 0xffff, 9353897Smckusick (XMIT_RING_LEN << 13) | (XMIT_MSG_DESC >> 16) 9453897Smckusick }; 9553897Smckusick 9653897Smckusick /* 9753897Smckusick * LANCE control block 9853897Smckusick */ 9953897Smckusick Lance_chan lancesw[NEN] = { 10053897Smckusick { (Lance_reg *)LANCE_PORT, 10153897Smckusick (caddr_t)LANCE_MEMORY, 10253897Smckusick (caddr_t)ETHER_ID }, 10353897Smckusick #if NEN > 1 10453897Smckusick { (Lance_reg *)LANCE_PORT1, 10553897Smckusick (caddr_t)LANCE_MEMORY1, 10653897Smckusick (caddr_t)ETHER_ID1 }, 107*54474Sutashiro #endif 10853897Smckusick #if NEN > 2 10953897Smckusick { (Lance_reg *)LANCE_PORT2, 11053897Smckusick (caddr_t)LANCE_MEMORY2, 11153897Smckusick (caddr_t)ETHER_ID2 }, 112*54474Sutashiro #endif 11353897Smckusick }; 11453897Smckusick 11553897Smckusick lance_probe(chan) 11653897Smckusick int chan; 11753897Smckusick { 11853897Smckusick register Lance_chan *lance = &lancesw[chan]; 11953897Smckusick VOLATILE int *p = (VOLATILE int *)lance->lance_memory; 12053897Smckusick 12153897Smckusick if (badaddr(lance->lance_addr, 1)) 12253897Smckusick return (0); 12353897Smckusick 12453897Smckusick *p = 0x12345678; 12553897Smckusick 12653897Smckusick return (*p == 0x12345678); 12753897Smckusick } 12853897Smckusick 12953897Smckusick lance_open(chan) 13053897Smckusick int chan; 13153897Smckusick { 13253897Smckusick register Lance_chan *lance = &lancesw[chan]; 13353897Smckusick register recv_msg_desc *rmd; 13453897Smckusick register xmit_msg_desc *tmd; 13553897Smckusick register struct init_block *ib; 13653897Smckusick register int buffer, i; 13753897Smckusick 13853897Smckusick if ((lance->lance_flags & LANCE_ACTIVE) == 0) { 13953897Smckusick if (lance->lance_addr == (Lance_reg *)0) 14053897Smckusick return (-1); 14153897Smckusick 14253897Smckusick lance_write_reg(chan, CSR0, CSR_STOP); 14353897Smckusick 14453897Smckusick rmd = (recv_msg_desc *) 14553897Smckusick (RECV_MSG_DESC + lance->lance_memory); 14653897Smckusick lance->lance_last_rmd = 14753897Smckusick (lance->lance_rmd = rmd) + RECV_BUFFERS - 1; 14853897Smckusick buffer = RECV_BUFFER; 14953897Smckusick for (i = 0; i < RECV_BUFFERS; i++) { 15053897Smckusick rmd->rmd_ladr = buffer & 0xffff; 15153897Smckusick rmd->rmd_stat = RMD_OWN | (buffer >> 16); 15253897Smckusick rmd->rmd_bcnt = -RECV_BUFFER_SIZE; 15353897Smckusick rmd->rmd_mcnt = 0; 15453897Smckusick rmd++; 15553897Smckusick buffer += RECV_BUFFER_SIZE; 15653897Smckusick } 15753897Smckusick 15853897Smckusick tmd = (xmit_msg_desc *) 15953897Smckusick (XMIT_MSG_DESC + lance->lance_memory); 16053897Smckusick lance->lance_last_tmd = 16153897Smckusick (lance->lance_tmd = tmd) + XMIT_BUFFERS - 1; 16253897Smckusick buffer = XMIT_BUFFER; 16353897Smckusick for (i = 0; i < XMIT_BUFFERS; i++) { 16453897Smckusick tmd->tmd_ladr = buffer & 0xffff; 16553897Smckusick tmd->tmd_stat = buffer >> 16; 16653897Smckusick tmd->tmd_bcnt = 0; 16753897Smckusick tmd++; 16853897Smckusick buffer += XMIT_BUFFER_SIZE; 16953897Smckusick } 17053897Smckusick get_hard_addr(chan, lance->lance_stats.ens_addr); 17153897Smckusick 17253897Smckusick ib = (struct init_block *)(INIT_BLOCK + lance->lance_memory); 17353897Smckusick lance->lance_ib = ib; 17453897Smckusick *ib = init_block; 17553897Smckusick ib->ib_padr[0] = lance->lance_stats.ens_addr[1]; 17653897Smckusick ib->ib_padr[1] = lance->lance_stats.ens_addr[0]; 17753897Smckusick ib->ib_padr[2] = lance->lance_stats.ens_addr[3]; 17853897Smckusick ib->ib_padr[3] = lance->lance_stats.ens_addr[2]; 17953897Smckusick ib->ib_padr[4] = lance->lance_stats.ens_addr[5]; 18053897Smckusick ib->ib_padr[5] = lance->lance_stats.ens_addr[4]; 18153897Smckusick 18253897Smckusick if (lance->lance_flags & LANCE_PROM) 18353897Smckusick ib->ib_mode |= IB_PROM; 18453897Smckusick 18553897Smckusick lance->lance_flags |= LANCE_ACTIVE; 18653897Smckusick lance_init(chan); 18753897Smckusick 18853897Smckusick if (lance_read_reg(chan, CSR0) != 18953897Smckusick (CSR_INEA|CSR_RXON|CSR_TXON|CSR_STRT|CSR_INIT)) { 19053897Smckusick lance->lance_flags &= ~LANCE_ACTIVE; 19153897Smckusick return (-1); 19253897Smckusick } 19353897Smckusick 19453897Smckusick } 19553897Smckusick 19653897Smckusick return (0); 19753897Smckusick } 19853897Smckusick 19953897Smckusick lance_close(chan) 20053897Smckusick int chan; 20153897Smckusick { 20253897Smckusick register Lance_chan *lance = &lancesw[chan]; 20353897Smckusick 20453897Smckusick lance_write_reg(chan, CSR0, CSR_STOP); 20553897Smckusick lance->lance_flags &= ~LANCE_ACTIVE; 20653897Smckusick 20753897Smckusick } 20853897Smckusick 20953897Smckusick #define RECEIVE(lance, rmd) { \ 21053897Smckusick register int i; \ 21153897Smckusick (rmd) = (lance)->lance_last_rmd + 1; \ 21253897Smckusick if ((rmd) >= (lance)->lance_rmd + RECV_BUFFERS) \ 21353897Smckusick (rmd) = (lance)->lance_rmd; \ 21453897Smckusick if (((rmd)->rmd_stat & RMD_OWN) == 0) \ 21553897Smckusick (lance)->lance_last_rmd = (rmd); \ 21653897Smckusick else \ 21753897Smckusick (rmd) = NULL; \ 21853897Smckusick } 21953897Smckusick #define RECV_BUF(lance, rmd) (char *)((rmd)->rmd_ladr \ 22053897Smckusick + (((rmd)->rmd_stat & RMD_HADR) << 16) \ 22153897Smckusick + (lance)->lance_memory) 22253897Smckusick #define RECV_CNT(rmd) ((rmd)->rmd_mcnt - 4) 22353897Smckusick #define RECV_ERR(rmd) ((rmd)->rmd_stat & RMD_ERR) 22453897Smckusick #define RELEASE_RECV_BUF(rmd) { \ 22553897Smckusick (rmd)->rmd_mcnt = 0; \ 22653897Smckusick (rmd)->rmd_stat = ((rmd)->rmd_stat & RMD_HADR) | RMD_OWN; \ 22753897Smckusick } 22853897Smckusick 22953897Smckusick 23053897Smckusick caddr_t 23153897Smckusick get_recv_buffer(chan) 23253897Smckusick int chan; 23353897Smckusick { 23453897Smckusick register Lance_chan *lance = &lancesw[chan]; 23553897Smckusick register recv_msg_desc *rmd; 23653897Smckusick 23753897Smckusick next: 23853897Smckusick RECEIVE(lance, rmd); 23953897Smckusick if (rmd == NULL) 24053897Smckusick return (NULL); 24153897Smckusick 24253897Smckusick if (RECV_ERR(rmd)) { 24353897Smckusick recv_error(lance, rmd); 24453897Smckusick RELEASE_RECV_BUF(rmd); 24553897Smckusick goto next; 24653897Smckusick } 24753897Smckusick 24853897Smckusick return (RECV_BUF(lance, rmd)); 24953897Smckusick } 25053897Smckusick 25153897Smckusick get_recv_length(chan) 25253897Smckusick int chan; 25353897Smckusick { 25453897Smckusick 25553897Smckusick return (RECV_CNT(lancesw[chan].lance_last_rmd)); 25653897Smckusick } 25753897Smckusick 25853897Smckusick free_recv_buffer(chan) 25953897Smckusick int chan; 26053897Smckusick { 26153897Smckusick register recv_msg_desc *rmd = lancesw[chan].lance_last_rmd; 26253897Smckusick 26353897Smckusick RELEASE_RECV_BUF(rmd); 26453897Smckusick } 26553897Smckusick 26653897Smckusick #define GET_XMIT_BUF(lance, tmd) { \ 26753897Smckusick (tmd) = (lance)->lance_last_tmd + 1; \ 26853897Smckusick if ((tmd) >= (lance)->lance_tmd + XMIT_BUFFERS) \ 26953897Smckusick (tmd) = (lance)->lance_tmd; \ 27053897Smckusick if ((tmd)->tmd_stat & TMD_OWN) \ 27153897Smckusick (tmd) = NULL; \ 27253897Smckusick else \ 27353897Smckusick (lance)->lance_last_tmd = (tmd); \ 27453897Smckusick } 27553897Smckusick #define XMIT_BUF(lance, tmd) (char *)((tmd)->tmd_ladr \ 27653897Smckusick + (((tmd)->tmd_stat & TMD_HADR) << 16) \ 27753897Smckusick + (lance)->lance_memory) 27853897Smckusick #define XMIT_ERR(tmd) ((tmd)->tmd_stat & TMD_ERR) 27953897Smckusick #define TRANSMIT(lance, tmd, count) { \ 28053897Smckusick (tmd)->tmd_bcnt = -(count); \ 28153897Smckusick (tmd)->tmd_error = 0; \ 28253897Smckusick (tmd)->tmd_stat = ((tmd)->tmd_stat & TMD_HADR) | (TMD_OWN|TMD_STP|TMD_ENP); \ 28353897Smckusick (lance)->lance_addr->rap = CSR0; \ 28453897Smckusick (lance)->lance_addr->rdp = (CSR_INEA|CSR_TDMD); \ 28553897Smckusick } 28653897Smckusick 28753897Smckusick caddr_t 28853897Smckusick get_xmit_buffer(chan) 28953897Smckusick int chan; 29053897Smckusick { 29153897Smckusick register Lance_chan *lance = &lancesw[chan]; 29253897Smckusick register xmit_msg_desc *tmd; 29353897Smckusick 29453897Smckusick GET_XMIT_BUF(lance, tmd); 29553897Smckusick if (tmd == NULL) 29653897Smckusick return (NULL); 29753897Smckusick return (XMIT_BUF(lance, tmd)); 29853897Smckusick } 29953897Smckusick 30053897Smckusick lance_transmit(chan, count) 30153897Smckusick int chan; 30253897Smckusick int count; 30353897Smckusick { 30453897Smckusick register Lance_chan *lance = &lancesw[chan]; 30553897Smckusick register xmit_msg_desc *tmd; 30653897Smckusick 30753897Smckusick tmd = lance->lance_last_tmd; 30853897Smckusick TRANSMIT(lance, tmd, count); 30953897Smckusick } 31053897Smckusick 31153897Smckusick lance_xmit_error(chan) 31253897Smckusick int chan; 31353897Smckusick { 31453897Smckusick register Lance_chan *lance = &lancesw[chan]; 31553897Smckusick register xmit_msg_desc *tmd; 31653897Smckusick 31753897Smckusick tmd = lance->lance_last_tmd; 31853897Smckusick if (XMIT_ERR(tmd)) { 31953897Smckusick xmit_error(lance, tmd); 32053897Smckusick return (1); 32153897Smckusick } 32253897Smckusick 32353897Smckusick return (0); 32453897Smckusick } 32553897Smckusick 32653897Smckusick lance_collision(chan) 32753897Smckusick int chan; 32853897Smckusick { 32953897Smckusick register Lance_chan *lance = &lancesw[chan]; 33053897Smckusick 33153897Smckusick if (lance->lance_last_tmd->tmd_stat & (TMD_MORE|TMD_ONE)) { 33253897Smckusick lance->lance_stats.ens_collis++; 33353897Smckusick return (1); 33453897Smckusick } 33553897Smckusick 33653897Smckusick return (0); 33753897Smckusick } 33853897Smckusick 33953897Smckusick lance_get_addr(chan, addr) 34053897Smckusick int chan; 34153897Smckusick caddr_t addr; 34253897Smckusick { 34353897Smckusick register Lance_chan *lance = &lancesw[chan]; 34453897Smckusick 34553897Smckusick bcopy(lance->lance_stats.ens_addr, addr, 34653897Smckusick sizeof(lance->lance_stats.ens_addr)); 34753897Smckusick } 34853897Smckusick 34953897Smckusick lance_prom_mode(chan, cmd) 35053897Smckusick int chan; 35153897Smckusick { 35253897Smckusick register Lance_chan *lance = &lancesw[chan]; 35353897Smckusick 35453897Smckusick lance_close(chan); 35553897Smckusick if (cmd) 35653897Smckusick lance->lance_flags |= LANCE_PROM; 35753897Smckusick else 35853897Smckusick lance->lance_flags &= ~LANCE_PROM; 35953897Smckusick lance_open(chan); 36053897Smckusick } 36153897Smckusick 36253897Smckusick lance_get_status(chan, addr) 36353897Smckusick int chan; 36453897Smckusick caddr_t addr; 36553897Smckusick { 36653897Smckusick register Lance_chan *lance = &lancesw[chan]; 36753897Smckusick register int s; 36853897Smckusick 36953897Smckusick s = splimp(); 37053897Smckusick bcopy(&lance->lance_stats.ens_frames, addr, 37153897Smckusick sizeof(lance->lance_stats) - sizeof (lance->lance_stats.ens_addr)); 37253897Smckusick bzero(&lance->lance_stats.ens_frames, 37353897Smckusick sizeof(lance->lance_stats) - sizeof (lance->lance_stats.ens_addr)); 37453897Smckusick (void) splx(s); 37553897Smckusick } 37653897Smckusick 37753897Smckusick lance_intr() 37853897Smckusick { 37953897Smckusick register Lance_chan *lance; 38053897Smckusick register Lance_reg *reg; 38153897Smckusick register int stat, chan; 38253897Smckusick int retval = 0; 38353897Smckusick 38453897Smckusick LED_ON; 38553897Smckusick 38653897Smckusick for (chan = 0, lance = lancesw; chan < NEN ; lance++, chan++) { 38753897Smckusick if ((lance->lance_flags & LANCE_ACTIVE) == 0) 38853897Smckusick continue; 38953897Smckusick 39053897Smckusick reg = lance->lance_addr; 39153897Smckusick reg->rap = CSR0; 39253897Smckusick stat = reg->rdp & ~CSR_INEA; 39353897Smckusick if ((stat & CSR_INTR) == 0) 39453897Smckusick continue; 39553897Smckusick 39653897Smckusick retval = 1; 39753897Smckusick reg->rdp = stat; 39853897Smckusick reg->rdp = CSR_INEA; 39953897Smckusick 40053897Smckusick if (stat & CSR_ERR) { 40153897Smckusick if (stat & CSR_BABL) 40253897Smckusick printf("lance %d error: babl\n", chan); 40353897Smckusick if (stat & CSR_MISS) 40453897Smckusick lance->lance_stats.ens_lost++; 40553897Smckusick if (stat & CSR_MERR) 40653897Smckusick printf("lance %d error: merr\n", chan); 40753897Smckusick } 40853897Smckusick if (stat & CSR_RINT) { 40953897Smckusick lance->lance_stats.ens_frames++; 41053897Smckusick enrint(chan); 41153897Smckusick } 41253897Smckusick if (stat & CSR_TINT) { 41353897Smckusick lance->lance_stats.ens_xmit++; 41453897Smckusick enxint(chan); 41553897Smckusick } 41653897Smckusick if (stat & CSR_IDON) 41753897Smckusick lance->lance_flags |= LANCE_IDON; 41853897Smckusick } 41953897Smckusick 42053897Smckusick LED_OFF; 42153897Smckusick 42253897Smckusick return (retval); 42353897Smckusick } 42453897Smckusick 42553897Smckusick lance_init(chan) 42653897Smckusick int chan; 42753897Smckusick { 42853897Smckusick register Lance_chan *lance = &lancesw[chan]; 42953897Smckusick register int s; 43053897Smckusick 43153897Smckusick s = splimp(); 43253897Smckusick lance_write_reg(chan, CSR1, INIT_BLOCK & 0xffff); 43353897Smckusick lance_write_reg(chan, CSR2, INIT_BLOCK >> 16); 43453897Smckusick lance_write_reg(chan, CSR3, CSR_BSWP|CSR_BCON); 43553897Smckusick 43653897Smckusick lance_write_reg(chan, CSR0, CSR_INEA|CSR_STRT|CSR_INIT); 43753897Smckusick (void) splx(s); 43853897Smckusick 43953897Smckusick while ((lance->lance_flags & LANCE_IDON) == 0) 44053897Smckusick ; 44153897Smckusick } 44253897Smckusick 44353897Smckusick recv_error(lance, rmd) 44453897Smckusick register Lance_chan *lance; 44553897Smckusick register recv_msg_desc *rmd; 44653897Smckusick { 44753897Smckusick register int status = rmd->rmd_stat; 44853897Smckusick register int chan = lance - lancesw; 44953897Smckusick 45053897Smckusick if (status & RMD_FRAM) 45153897Smckusick lance->lance_stats.ens_align++; 45253897Smckusick if (status & RMD_OFLO) 45353897Smckusick printf("lance %d recv error: overflow\n", chan); 45453897Smckusick if (status & RMD_CRC) 45553897Smckusick lance->lance_stats.ens_crc++; 45653897Smckusick if (status & RMD_BUFF) 45753897Smckusick printf("lance %d:recv error: buffer\n", chan); 45853897Smckusick } 45953897Smckusick 46053897Smckusick xmit_error(lance, tmd) 46153897Smckusick register Lance_chan *lance; 46253897Smckusick register xmit_msg_desc *tmd; 46353897Smckusick { 46453897Smckusick register int status = tmd->tmd_error; 46553897Smckusick register int chan = lance - lancesw; 46653897Smckusick 46753897Smckusick if (status & TMD_BUFF) 46853897Smckusick printf("lance %d: xmit error: buffer\n", chan); 46953897Smckusick if (status & TMD_UFLO) 47053897Smckusick printf("lance %d: xmit error: underflow\n", chan); 47153897Smckusick if (status & TMD_LCOL) { 47253897Smckusick printf("lance %d: xmit error: late collision\n", chan); 47353897Smckusick lance->lance_stats.ens_owcollis++; 47453897Smckusick } 47553897Smckusick if (status & TMD_LCAR) 47653897Smckusick printf("lance %d: xmit error: loss of carrier\n", chan); 47753897Smckusick if (status & TMD_RTRY) { 47853897Smckusick printf("lance %d: xmit error: retry tdr=%d\n", 47953897Smckusick chan, status & TMD_TDR); 48053897Smckusick lance->lance_stats.ens_xcollis++; 48153897Smckusick } 48253897Smckusick } 48353897Smckusick 48453897Smckusick lance_write_reg(chan, reg, data) 48553897Smckusick int chan, reg, data; 48653897Smckusick { 48753897Smckusick register Lance_reg *lance = lancesw[chan].lance_addr; 48853897Smckusick register int s; 48953897Smckusick 49053897Smckusick s = spl7(); 49153897Smckusick lance->rap = reg; 49253897Smckusick lance->rdp = data; 49353897Smckusick (void) splx(s); 49453897Smckusick } 49553897Smckusick 49653897Smckusick lance_read_reg(chan, reg) 49753897Smckusick int chan, reg; 49853897Smckusick { 49953897Smckusick register Lance_reg *lance = lancesw[chan].lance_addr; 50053897Smckusick register int s, d; 50153897Smckusick 50253897Smckusick s = spl7(); 50353897Smckusick lance->rap = reg; 50453897Smckusick d = lance->rdp; 50553897Smckusick (void) splx(s); 50653897Smckusick 50753897Smckusick return (d); 50853897Smckusick } 50953897Smckusick 51053897Smckusick get_hard_addr(chan, addr) 51153897Smckusick int chan; 51253897Smckusick u_short *addr; 51353897Smckusick { 51453897Smckusick register unsigned char *p, *q; 51553897Smckusick register int i; 51653897Smckusick register Lance_chan *lance = &lancesw[chan]; 51753897Smckusick unsigned char hard_addr[6]; 51853897Smckusick 51953897Smckusick p = (unsigned char *)lance->lance_rom + 16; 52053897Smckusick q = hard_addr; 52153897Smckusick for (i = 0; i < 6; i++) { 52253897Smckusick *q = (*p++ & 0xf) << 4; 52353897Smckusick *q++ |= *p++ & 0xf; 52453897Smckusick } 52553897Smckusick 52653897Smckusick bcopy(hard_addr, (char *)addr, 6); 52753897Smckusick } 52853897Smckusick 52953897Smckusick #if defined(mips) && defined(CPU_SINGLE) 53053897Smckusick bxcopy(s, d, n) 53153897Smckusick caddr_t s, d; 53253897Smckusick int n; 53353897Smckusick { 53453897Smckusick 53553897Smckusick if (n <= 0) 53653897Smckusick return; 53753897Smckusick switch ((((int)s & 03) << 2) + ((int)d & 03)) { 53853897Smckusick 53953897Smckusick case 0x0: 54053897Smckusick blcopy((long *)s, (long *)d, n); 54153897Smckusick return; 54253897Smckusick 54353897Smckusick case 0x5: 54453897Smckusick *(char *)d = *(char *)s; 54553897Smckusick blcopy((long *)(s + 1), (long *)(d + 1), n - 1); 54653897Smckusick return; 54753897Smckusick 54853897Smckusick case 0xa: 54953897Smckusick switch (n) { 55053897Smckusick 55153897Smckusick case 1: 55253897Smckusick *(char *)d = *(char *)s; 55353897Smckusick return; 55453897Smckusick 55553897Smckusick case 2: 55653897Smckusick *(short *)d = *(short *)s; 55753897Smckusick return; 55853897Smckusick 55953897Smckusick default: 56053897Smckusick *(short *)d = *(short *)s; 56153897Smckusick blcopy((long *)(s + 2), (long *)(d + 2), n - 2); 56253897Smckusick return; 56353897Smckusick } 56453897Smckusick 56553897Smckusick case 0xf: 56653897Smckusick switch (n) { 56753897Smckusick 56853897Smckusick case 1: 56953897Smckusick *(char *)d = *(char *)s; 57053897Smckusick return; 57153897Smckusick 57253897Smckusick case 2: 57353897Smckusick *(char *)d = *(char *)s; 57453897Smckusick *(char *)(d + 1) = *(char *)(s + 1); 57553897Smckusick return; 57653897Smckusick 57753897Smckusick case 3: 57853897Smckusick *(char *)d = *(char *)s; 57953897Smckusick *(short *)(d + 1) = *(short *)(s + 1); 58053897Smckusick return; 58153897Smckusick 58253897Smckusick default: 58353897Smckusick *(char *)d = *(char *)s; 58453897Smckusick *(short *)(d + 1) = *(short *)(s + 1); 58553897Smckusick blcopy((long *)(s + 3), (long *)(d + 3), n - 3); 58653897Smckusick return; 58753897Smckusick } 58853897Smckusick 58953897Smckusick case 0x7: 59053897Smckusick case 0xd: 59153897Smckusick switch (n) { 59253897Smckusick 59353897Smckusick case 1: 59453897Smckusick *(char *)d = *(char *)s; 59553897Smckusick return; 59653897Smckusick 59753897Smckusick case 2: 59853897Smckusick *(char *)d = *(char *)s; 59953897Smckusick *(char *)(d + 1) = *(char *)(s + 1); 60053897Smckusick return; 60153897Smckusick 60253897Smckusick default: 60353897Smckusick *(char *)d = *(char *)s; 60453897Smckusick bwcopy((short *)(s + 1), (short *)(d + 1), n); 60553897Smckusick return; 60653897Smckusick } 60753897Smckusick 60853897Smckusick case 0x2: 60953897Smckusick case 0x8: 61053897Smckusick bwcopy((short *)s, (short *)d, n); 61153897Smckusick return; 61253897Smckusick 61353897Smckusick default: 61453897Smckusick bbcopy((char *)s, (char *)d, n); 61553897Smckusick return; 61653897Smckusick } 61753897Smckusick } 61853897Smckusick 61953897Smckusick #define COPY(s, d, n, t) \ 62053897Smckusick while ((n) >= 8 * sizeof (t)) { \ 62153897Smckusick int t0, t1, t2, t3, t4, t5, t6, t7; \ 62253897Smckusick t0 = (s)[0]; \ 62353897Smckusick t1 = (s)[1]; \ 62453897Smckusick t2 = (s)[2]; \ 62553897Smckusick t3 = (s)[3]; \ 62653897Smckusick t4 = (s)[4]; \ 62753897Smckusick t5 = (s)[5]; \ 62853897Smckusick t6 = (s)[6]; \ 62953897Smckusick t7 = (s)[7]; \ 63053897Smckusick (d)[0] = t0; \ 63153897Smckusick (d)[1] = t1; \ 63253897Smckusick (d)[2] = t2; \ 63353897Smckusick (d)[3] = t3; \ 63453897Smckusick (d)[4] = t4; \ 63553897Smckusick (d)[5] = t5; \ 63653897Smckusick (d)[6] = t6; \ 63753897Smckusick (d)[7] = t7; \ 63853897Smckusick (s) += 8; \ 63953897Smckusick (d) += 8; \ 64053897Smckusick (n) -= 8 * sizeof (t); \ 64153897Smckusick } \ 64253897Smckusick while ((n) >= sizeof (t)) { \ 64353897Smckusick (d)[0] = (s)[0]; \ 64453897Smckusick (s)++; \ 64553897Smckusick (d)++; \ 64653897Smckusick (n) -= sizeof (t); \ 64753897Smckusick } 64853897Smckusick 64953897Smckusick blcopy(s, d, n) 65053897Smckusick long *s, *d; 65153897Smckusick int n; 65253897Smckusick { 65353897Smckusick 65453897Smckusick COPY(s, d, n, long); 65553897Smckusick switch (n) { 65653897Smckusick 65753897Smckusick case 0: 65853897Smckusick return; 65953897Smckusick 66053897Smckusick case 1: 66153897Smckusick *(char *)d = *(char *)s; 66253897Smckusick return; 66353897Smckusick 66453897Smckusick case 2: 66553897Smckusick *(short *)d = *(short *)s; 66653897Smckusick return; 66753897Smckusick 66853897Smckusick case 3: 66953897Smckusick *(short *)d = *(short *)s; 67053897Smckusick *((char *)d + 2) = *((char *)s + 2); 67153897Smckusick return; 67253897Smckusick } 67353897Smckusick } 67453897Smckusick 67553897Smckusick bwcopy(s, d, n) 67653897Smckusick short *s, *d; 67753897Smckusick int n; 67853897Smckusick { 67953897Smckusick 68053897Smckusick COPY(s, d, n, short); 68153897Smckusick if (n == 1) 68253897Smckusick *(char *)d = *(char *)s; 68353897Smckusick } 68453897Smckusick 68553897Smckusick bbcopy(s, d, n) 68653897Smckusick char *s, *d; 68753897Smckusick int n; 68853897Smckusick { 68953897Smckusick 69053897Smckusick COPY(s, d, n, char); 69153897Smckusick } 69253897Smckusick #endif /* defined(mips) && defined(CPU_SINGLE) */ 69353897Smckusick 69453897Smckusick #endif /* NEN > 0 */ 695