summaryrefslogtreecommitdiff
path: root/sys/dev/ic/an.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ic/an.c')
-rw-r--r--sys/dev/ic/an.c262
1 files changed, 160 insertions, 102 deletions
diff --git a/sys/dev/ic/an.c b/sys/dev/ic/an.c
index 80b4820cf92..7a10311b013 100644
--- a/sys/dev/ic/an.c
+++ b/sys/dev/ic/an.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: an.c,v 1.17 2001/06/23 23:36:02 mickey Exp $ */
+/* $OpenBSD: an.c,v 1.18 2001/06/25 21:11:16 mickey Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -163,6 +163,13 @@ void an_cache_store __P((struct an_softc *, struct ether_header *,
struct mbuf *, unsigned short));
#endif
+static __inline void
+an_swap16(u_int16_t *p, int cnt)
+{
+ for (; cnt--; p++)
+ *p = swap16(*p);
+}
+
int
an_attach(sc)
struct an_softc *sc;
@@ -321,14 +328,13 @@ an_rxeof(sc)
}
/* Check for insane frame length */
- if (rx_frame_802_3.an_rx_802_3_payload_len > MCLBYTES) {
+ if (letoh16(rx_frame_802_3.an_rx_802_3_payload_len) > MCLBYTES) {
ifp->if_ierrors++;
return;
}
m->m_pkthdr.len = m->m_len =
- rx_frame_802_3.an_rx_802_3_payload_len + 12;
-
+ letoh16(rx_frame_802_3.an_rx_802_3_payload_len) + 12;
bcopy((char *)&rx_frame_802_3.an_rx_dst_addr,
(char *)&eh->ether_dhost, ETHER_ADDR_LEN);
@@ -337,8 +343,7 @@ an_rxeof(sc)
/* in mbuf header type is just before payload */
error = an_read_data(sc, id, 0x44, (caddr_t)&(eh->ether_type),
- rx_frame_802_3.an_rx_802_3_payload_len);
-
+ letoh16(rx_frame_802_3.an_rx_802_3_payload_len));
if (error) {
m_freem(m);
ifp->if_ierrors++;
@@ -362,11 +367,11 @@ an_rxeof(sc)
void
an_txeof(sc, status)
- struct an_softc *sc;
- int status;
+ struct an_softc *sc;
+ int status;
{
- struct ifnet *ifp;
- int id;
+ struct ifnet *ifp;
+ int id;
ifp = &sc->arpcom.ac_if;
@@ -375,9 +380,9 @@ an_txeof(sc, status)
id = CSR_READ_2(sc, AN_TX_CMP_FID);
- if (status & AN_EV_TX_EXC) {
+ if (status & AN_EV_TX_EXC)
ifp->if_oerrors++;
- } else
+ else
ifp->if_opackets++;
if (id != sc->an_rdata.an_tx_ring[sc->an_rdata.an_tx_cons])
@@ -576,8 +581,8 @@ an_read_record(sc, ltv)
struct an_softc *sc;
struct an_ltv_gen *ltv;
{
- u_int16_t *ptr;
- int i, len;
+ u_int16_t *ptr, len;
+ int i;
if (ltv->an_len == 0 || ltv->an_type == 0)
return(EINVAL);
@@ -612,10 +617,51 @@ an_read_record(sc, ltv)
ltv->an_len = len;
/* Now read the data. */
- ptr = &ltv->an_val;
+ ptr = ltv->an_val;
for (i = 0; i < (ltv->an_len - 1) >> 1; i++)
ptr[i] = CSR_READ_2(sc, AN_DATA1);
+#if BYTE_ORDER == BIG_ENDIAN
+ switch (ltv->an_type) {
+ case AN_RID_GENCONFIG:
+ an_swap16(&ltv->an_val[4], 7); /* an_macaddr, an_rates */
+ an_swap16(&ltv->an_val[63], 8); /* an_nodename */
+ break;
+ case AN_RID_SSIDLIST:
+ an_swap16(&ltv->an_val[1], 16); /* an_ssid1 */
+ an_swap16(&ltv->an_val[18], 16); /* an_ssid2 */
+ an_swap16(&ltv->an_val[35], 16); /* an_ssid3 */
+ break;
+ case AN_RID_APLIST:
+ an_swap16(ltv->an_val, 12);
+ break;
+ case AN_RID_DRVNAME:
+ an_swap16(ltv->an_val, 8);
+ break;
+ case AN_RID_CAPABILITIES:
+ an_swap16(ltv->an_val, 2); /* an_oui */
+ an_swap16(&ltv->an_val[3], 34); /* an_manufname .. an_aironetaddr */
+ an_swap16(&ltv->an_val[39], 8); /* an_callid .. an_tx_diversity */
+ break;
+ case AN_RID_STATUS:
+ an_swap16(&ltv->an_val[0], 3); /* an_macaddr */
+ an_swap16(&ltv->an_val[7], 36); /* an_ssid .. an_prev_bssid3 */
+ an_swap16(&ltv->an_val[0x74/2], 2); /* an_ap_ip_addr */
+ break;
+ case AN_RID_WEP_VOLATILE:
+ case AN_RID_WEP_PERMANENT:
+ an_swap16(&ltv->an_val[1], 3); /* an_mac_addr */
+ an_swap16(&ltv->an_val[5], 6);
+ break;
+ case AN_RID_32BITS_CUM:
+ for (i = 0x60; i--; ) {
+ u_int16_t t = ltv->an_val[i * 2] ^ ltv->an_val[i * 2 + 1];
+ ltv->an_val[i * 2] ^= t;
+ ltv->an_val[i * 2 + 1] ^= t;
+ }
+ break;
+ }
+#endif
return(0);
}
@@ -627,8 +673,8 @@ an_write_record(sc, ltv)
struct an_softc *sc;
struct an_ltv_gen *ltv;
{
- u_int16_t *ptr;
- int i;
+ u_int16_t *ptr;
+ int i;
if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_READ, ltv->an_type))
return(EIO);
@@ -636,9 +682,44 @@ an_write_record(sc, ltv)
if (an_seek(sc, ltv->an_type, 0, AN_BAP1))
return(EIO);
+#if BYTE_ORDER == BIG_ENDIAN
+ switch (ltv->an_type) {
+ case AN_RID_GENCONFIG:
+ an_swap16(&ltv->an_val[4], 7); /* an_macaddr, an_rates */
+ an_swap16(&ltv->an_val[63], 8); /* an_nodename */
+ break;
+ case AN_RID_SSIDLIST:
+ an_swap16(&ltv->an_val[1], 16); /* an_ssid1 */
+ an_swap16(&ltv->an_val[18], 16); /* an_ssid2 */
+ an_swap16(&ltv->an_val[35], 16); /* an_ssid3 */
+ break;
+ case AN_RID_APLIST:
+ an_swap16(ltv->an_val, 12);
+ break;
+ case AN_RID_DRVNAME:
+ an_swap16(ltv->an_val, 8);
+ break;
+ case AN_RID_CAPABILITIES:
+ an_swap16(ltv->an_val, 2); /* an_oui */
+ an_swap16(&ltv->an_val[3], 34); /* an_manufname .. an_aironetaddr */
+ an_swap16(&ltv->an_val[39], 8); /* an_callid .. an_tx_diversity */
+ break;
+ case AN_RID_STATUS:
+ an_swap16(&ltv->an_val[0], 3); /* an_macaddr */
+ an_swap16(&ltv->an_val[7], 36); /* an_ssid .. an_prev_bssid3 */
+ an_swap16(&ltv->an_val[0x74/2], 2); /* an_ap_ip_addr */
+ break;
+ case AN_RID_WEP_VOLATILE:
+ case AN_RID_WEP_PERMANENT:
+ an_swap16(&ltv->an_val[1], 3); /* an_mac_addr */
+ an_swap16(&ltv->an_val[5], 6);
+ break;
+ }
+#endif
+
CSR_WRITE_2(sc, AN_DATA1, ltv->an_len);
- ptr = &ltv->an_val;
+ ptr = ltv->an_val;
for (i = 0; i < (ltv->an_len - 1) >> 1; i++)
CSR_WRITE_2(sc, AN_DATA1, ptr[i]);
@@ -668,7 +749,7 @@ an_seek(sc, id, off, chan)
default:
printf("%s: invalid data path: %x\n",
sc->sc_dev.dv_xname, chan);
- return(EIO);
+ return (EIO);
}
CSR_WRITE_2(sc, selreg, id);
@@ -682,7 +763,7 @@ an_seek(sc, id, off, chan)
if (i <= 0)
return(ETIMEDOUT);
- return(0);
+ return (0);
}
int
@@ -692,25 +773,15 @@ an_read_data(sc, id, off, buf, len)
caddr_t buf;
int len;
{
- int i;
- u_int16_t *ptr;
- u_int8_t *ptr2;
-
- if (off != -1) {
- if (an_seek(sc, id, off, AN_BAP1))
- return(EIO);
- }
+ if (off != -1 && an_seek(sc, id, off, AN_BAP1))
+ return(EIO);
- ptr = (u_int16_t *)buf;
- for (i = 0; i < len / 2; i++)
- ptr[i] = CSR_READ_2(sc, AN_DATA1);
- i*=2;
- if (i<len){
- ptr2 = (u_int8_t *)buf;
- ptr2[i] = CSR_READ_1(sc, AN_DATA1);
- }
+ bus_space_read_raw_multi_2(sc->an_btag, sc->an_bhandle,
+ AN_DATA1, buf, len & ~1);
+ if (len & 1)
+ ((u_int8_t *)buf)[len - 1] = CSR_READ_1(sc, AN_DATA1);
- return(0);
+ return (0);
}
int
@@ -720,25 +791,15 @@ an_write_data(sc, id, off, buf, len)
caddr_t buf;
int len;
{
- int i;
- u_int16_t *ptr;
- u_int8_t *ptr2;
-
- if (off != -1) {
- if (an_seek(sc, id, off, AN_BAP0))
- return(EIO);
- }
+ if (off != -1 && an_seek(sc, id, off, AN_BAP0))
+ return(EIO);
- ptr = (u_int16_t *)buf;
- for (i = 0; i < (len / 2); i++)
- CSR_WRITE_2(sc, AN_DATA0, ptr[i]);
- i*=2;
- if (i<len){
- ptr2 = (u_int8_t *)buf;
- CSR_WRITE_1(sc, AN_DATA0, ptr2[i]);
- }
+ bus_space_write_raw_multi_2(sc->an_btag, sc->an_bhandle,
+ AN_DATA0, buf, len & ~1);
+ if (len & 1)
+ CSR_WRITE_1(sc, AN_DATA0, ((u_int8_t *)buf)[len - 1]);
- return(0);
+ return (0);
}
/*
@@ -773,8 +834,9 @@ an_alloc_nicmem(sc, len, id)
if (an_seek(sc, *id, 0, AN_BAP0))
return(EIO);
- for (i = 0; i < len / 2; i++)
- CSR_WRITE_2(sc, AN_DATA0, 0);
+ bus_space_set_multi_2(sc->an_btag, sc->an_bhandle,
+ AN_DATA0, 0, len / 2);
+ CSR_WRITE_1(sc, AN_DATA0, 0);
return(0);
}
@@ -820,7 +882,7 @@ an_setdef(sc, areq)
break;
case AN_RID_TX_SPEED:
sp = (struct an_ltv_gen *)areq;
- sc->an_tx_rate = sp->an_val;
+ sc->an_tx_rate = sp->an_val[0];
break;
case AN_RID_WEP_VOLATILE:
/* Disable the MAC */
@@ -865,13 +927,14 @@ an_promisc(sc, promisc)
struct an_softc *sc;
int promisc;
{
+ struct an_ltv_genconfig genconf;
+
/* Disable the MAC. */
an_cmd(sc, AN_CMD_DISABLE, 0);
/* Set RX mode. */
if (promisc &&
- !(sc->an_config.an_rxmode & AN_RXMODE_LAN_MONITOR_CURBSS)
- ) {
+ !(sc->an_config.an_rxmode & AN_RXMODE_LAN_MONITOR_CURBSS) ) {
sc->an_rxmode = sc->an_config.an_rxmode;
sc->an_config.an_rxmode |=
AN_RXMODE_LAN_MONITOR_CURBSS;
@@ -880,9 +943,10 @@ an_promisc(sc, promisc)
}
/* Transfer the configuration to the NIC */
- sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
- sc->an_config.an_type = AN_RID_GENCONFIG;
- if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_config)) {
+ genconf = sc->an_config;
+ genconf.an_len = sizeof(struct an_ltv_genconfig);
+ genconf.an_type = AN_RID_GENCONFIG;
+ if (an_write_record(sc, (struct an_ltv_gen *)&genconf)) {
printf("%s: failed to set configuration\n",
sc->sc_dev.dv_xname);
return;
@@ -1035,7 +1099,10 @@ an_init(sc)
struct an_softc *sc;
{
struct ifnet *ifp = &sc->arpcom.ac_if;
- int s;
+ struct an_ltv_ssidlist ssid;
+ struct an_ltv_aplist aplist;
+ struct an_ltv_genconfig genconf;
+ int s;
if (sc->an_gone)
return;
@@ -1074,27 +1141,30 @@ an_init(sc)
sc->an_rxmode = sc->an_config.an_rxmode;
/* Set the ssid list */
- sc->an_ssidlist.an_type = AN_RID_SSIDLIST;
- sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist);
- if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) {
+ ssid = sc->an_ssidlist;
+ ssid.an_type = AN_RID_SSIDLIST;
+ ssid.an_len = sizeof(struct an_ltv_ssidlist);
+ if (an_write_record(sc, (struct an_ltv_gen *)&ssid)) {
printf("%s: failed to set ssid list\n", sc->sc_dev.dv_xname);
splx(s);
return;
}
/* Set the AP list */
- sc->an_aplist.an_type = AN_RID_APLIST;
- sc->an_aplist.an_len = sizeof(struct an_ltv_aplist);
- if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_aplist)) {
+ aplist = sc->an_aplist;
+ aplist.an_type = AN_RID_APLIST;
+ aplist.an_len = sizeof(struct an_ltv_aplist);
+ if (an_write_record(sc, (struct an_ltv_gen *)&aplist)) {
printf("%s: failed to set AP list\n", sc->sc_dev.dv_xname);
splx(s);
return;
}
/* Set the configuration in the NIC */
- sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
- sc->an_config.an_type = AN_RID_GENCONFIG;
- if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_config)) {
+ genconf = sc->an_config;
+ genconf.an_len = sizeof(struct an_ltv_genconfig);
+ genconf.an_type = AN_RID_GENCONFIG;
+ if (an_write_record(sc, (struct an_ltv_gen *)&genconf)) {
printf("%s: failed to set configuration\n",
sc->sc_dev.dv_xname);
splx(s);
@@ -1127,6 +1197,7 @@ an_start(ifp)
struct mbuf *m0 = NULL;
struct an_txframe_802_3 tx_frame_802_3;
struct ether_header *eh;
+ u_int16_t len;
int id;
int idx;
unsigned char txcontrol;
@@ -1158,11 +1229,10 @@ an_start(ifp)
bcopy((char *)&eh->ether_shost,
(char *)&tx_frame_802_3.an_tx_src_addr, ETHER_ADDR_LEN);
- tx_frame_802_3.an_tx_802_3_payload_len =
- m0->m_pkthdr.len - 12; /* minus src/dest mac & type */
+ len = m0->m_pkthdr.len - 12; /* minus src/dest mac & type */
+ tx_frame_802_3.an_tx_802_3_payload_len = htole16(len);
- m_copydata(m0, sizeof(struct ether_header) - 2 ,
- tx_frame_802_3.an_tx_802_3_payload_len,
+ m_copydata(m0, sizeof(struct ether_header) - 2, len,
(caddr_t)&sc->an_txbuf);
txcontrol=AN_TXCTL_8023;
@@ -1175,8 +1245,7 @@ an_start(ifp)
sizeof(struct an_txframe_802_3));
/* in mbuf header type is just before payload */
- an_write_data(sc, id, 0x44, (caddr_t)&sc->an_txbuf,
- tx_frame_802_3.an_tx_802_3_payload_len);
+ an_write_data(sc, id, 0x44, (caddr_t)&sc->an_txbuf, len);
/*
* If there's a BPF listner, bounce a copy of
@@ -1339,59 +1408,50 @@ an_cache_store (sc, eh, m, rx_quality)
* keep multicast only.
*/
- if ((ntohs(eh->ether_type) == 0x800)) {
+ if ((ntohs(eh->ether_type) == 0x800))
saanp = 1;
- }
/* filter for ip packets only
*/
- if (sc->an_cache_iponly && !saanp) {
+ if (sc->an_cache_iponly && !saanp)
return;
- }
- /* filter for broadcast/multicast only
- */
- if (sc->an_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0)) {
+ /* filter for broadcast/multicast only */
+ if (sc->an_cache_mcastonly && ((eh->ether_dhost[0] & 1) == 0))
return;
- }
#ifdef SIGDEBUG
printf("an: q value %x (MSB=0x%x, LSB=0x%x) \n",
rx_quality & 0xffff, rx_quality >> 8, rx_quality & 0xff);
#endif
- /* find the ip header. we want to store the ip_src
- * address.
- */
- if (saanp) {
+ /* find the ip header. we want to store the ip_src address */
+ if (saanp)
ip = (struct ip *)(mtod(m, char *) + sizeof(struct ether_header));
- }
/* do a linear search for a matching MAC address
* in the cache table
* . MAC address is 6 bytes,
* . var w_nextitem holds total number of entries already cached
*/
- for(i = 0; i < sc->an_nextitem; i++) {
- if (!bcmp(eh->ether_shost , sc->an_sigcache[i].macsrc, 6)) {
+ for(i = 0; i < sc->an_nextitem; i++)
+ if (!bcmp(eh->ether_shost , sc->an_sigcache[i].macsrc, 6))
/* Match!,
* so we already have this entry, update the data
*/
break;
- }
- }
/* did we find a matching mac address?
* if yes, then overwrite a previously existing cache entry
*/
- if (i < sc->an_nextitem ) {
+ if (i < sc->an_nextitem )
cache_slot = i;
- }
+
/* else, have a new address entry,so
* add this new entry,
* if table full, then we need to replace LRU entry
*/
- else {
+ else {
/* check for space in cache table
* note: an_nextitem also holds number of entries
@@ -1406,9 +1466,8 @@ an_cache_store (sc, eh, m, rx_quality)
* and "zap" the next entry
*/
else {
- if (wrapindex == MAXANCACHE) {
+ if (wrapindex == MAXANCACHE)
wrapindex = 0;
- }
cache_slot = wrapindex++;
}
}
@@ -1428,9 +1487,8 @@ an_cache_store (sc, eh, m, rx_quality)
* .mac src
* .signal, etc.
*/
- if (saanp) {
+ if (saanp)
sc->an_sigcache[cache_slot].ipsrc = ip->ip_src.s_addr;
- }
bcopy( eh->ether_shost, sc->an_sigcache[cache_slot].macsrc, 6);
sc->an_sigcache[cache_slot].signal = rx_quality;