an driver / Cisco Aironet 340 stopped working
Doug Ambrisko
ambrisko at ambrisko.com
Mon Aug 18 19:47:48 PDT 2003
Tomi Vainio - Sun Finland writes:
| I've used my Cisco WLAN with Toshiba Portege 3440 couple years but now
| it's broken. I just upgraded to new Toshiba Tecra M1 and reinstalled
| FreeBSD there and now I get "an0: record length mismatch -- expected
| 430, got 440 for Rid ff68" errors. I already tried with old laptop
| with latest kernel and old kernel from Jun 26th but it's also broken
| there so I cannot say who long this has been broken.
I assume you are using a pccard version.
It only a problem newer firmware. It works ... just noisy!
You can try this patch to -current that should make it quiet.
There is a bug with -current and setting the TX speed that I need
to work on. Looks like things changed in the wlan module.
I may commit this but there is an issue with the mpi-350 support.
They changed the programing paradigm and after 14 packets the
TX engine stalls. I'm still working on tweaks to that.
I had hoped to get that working and commit all of this.
Let me know how this works. It should just work.
Doug A.
Index: sys/dev/an/if_aironet_ieee.h
===================================================================
RCS file: /cvs/src/sys/dev/an/if_aironet_ieee.h,v
retrieving revision 1.11
diff -c -r1.11 if_aironet_ieee.h
*** sys/dev/an/if_aironet_ieee.h 29 Dec 2002 19:22:06 -0000 1.11
--- sys/dev/an/if_aironet_ieee.h 19 Aug 2003 02:41:06 -0000
***************
*** 63,69 ****
* data, which is 240 words long, so 256 should be a safe
* value.
*/
! #define AN_MAX_DATALEN 512
struct an_req {
u_int16_t an_len;
--- 63,69 ----
* data, which is 240 words long, so 256 should be a safe
* value.
*/
! #define AN_MAX_DATALEN 4096
struct an_req {
u_int16_t an_len;
***************
*** 261,267 ****
u_int32_t an_uptime_usecs; /* 0x178 */
u_int32_t an_uptime_secs; /* 0x17C */
u_int32_t an_lostsync_better_ap; /* 0x180 */
! u_int32_t an_rsvd[10];
};
/*
--- 261,267 ----
u_int32_t an_uptime_usecs; /* 0x178 */
u_int32_t an_uptime_secs; /* 0x17C */
u_int32_t an_lostsync_better_ap; /* 0x180 */
! u_int32_t an_rsvd[15];
};
/*
***************
*** 337,342 ****
--- 337,343 ----
u_int8_t an_magic_packet_action; /* 0x98 */
u_int8_t an_magic_packet_ctl; /* 0x99 */
u_int16_t an_rsvd9;
+ u_int16_t an_spare[13];
};
#define AN_OPMODE_IBSS_ADHOC 0x0000
***************
*** 417,422 ****
--- 418,435 ----
char an_ssid3[32];
};
+ struct an_ltv_ssid_entry{
+ u_int16_t an_len;
+ char an_ssid[32];
+ };
+
+ #define MAX_SSIDS 25
+ struct an_ltv_ssidlist_new {
+ u_int16_t an_len;
+ u_int16_t an_type;
+ struct an_ltv_ssid_entry an_entry[MAX_SSIDS];
+ };
+
/*
* Valid AP list.
*/
***************
*** 501,507 ****
u_int16_t an_softcaps; /* 0x7C */
u_int16_t an_bootblockrev; /* 0x7E */
u_int16_t an_req_hw_support; /* 0x80 */
! u_int16_t an_unknown; /* 0x82 */
};
/*
--- 514,520 ----
u_int16_t an_softcaps; /* 0x7C */
u_int16_t an_bootblockrev; /* 0x7E */
u_int16_t an_req_hw_support; /* 0x80 */
! u_int16_t an_unknown[31]; /* 0x82 */
};
/*
***************
*** 580,586 ****
u_int8_t an_avg_noise_prev_min_db; /* 0x7D */
u_int8_t an_max_noise_prev_min_pc; /* 0x7E */
u_int8_t an_max_noise_prev_min_db; /* 0x7F */
! u_int16_t an_spare[5];
};
#define AN_STATUS_OPMODE_CONFIGURED 0x0001
--- 593,599 ----
u_int8_t an_avg_noise_prev_min_db; /* 0x7D */
u_int8_t an_max_noise_prev_min_pc; /* 0x7E */
u_int8_t an_max_noise_prev_min_db; /* 0x7F */
! u_int16_t an_spare[8];
};
#define AN_STATUS_OPMODE_CONFIGURED 0x0001
Index: sys/dev/an/if_an.c
===================================================================
RCS file: /cvs/src/sys/dev/an/if_an.c,v
retrieving revision 1.51
diff -c -r1.51 if_an.c
*** sys/dev/an/if_an.c 28 Jun 2003 06:13:27 -0000 1.51
--- sys/dev/an/if_an.c 19 Aug 2003 02:41:06 -0000
***************
*** 313,319 ****
device_t dev;
{
struct an_softc *sc = device_get_softc(dev);
! struct an_ltv_ssidlist ssid;
int error;
bzero((char *)&ssid, sizeof(ssid));
--- 313,319 ----
device_t dev;
{
struct an_softc *sc = device_get_softc(dev);
! struct an_ltv_ssidlist_new ssid;
int error;
bzero((char *)&ssid, sizeof(ssid));
***************
*** 339,349 ****
ssid.an_type = AN_RID_SSIDLIST;
/* Make sure interrupts are disabled. */
CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), 0);
CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), 0xFFFF);
an_reset(sc);
- /* No need for an_init_mpi350_desc since it will be done in attach */
if (an_cmd(sc, AN_CMD_READCFG, 0))
return(0);
--- 339,349 ----
ssid.an_type = AN_RID_SSIDLIST;
/* Make sure interrupts are disabled. */
+ sc->mpi350 = 0;
CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), 0);
CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), 0xFFFF);
an_reset(sc);
if (an_cmd(sc, AN_CMD_READCFG, 0))
return(0);
***************
*** 352,358 ****
return(0);
/* See if the ssid matches what we expect ... but doesn't have to */
! if (strcmp(ssid.an_ssid1, AN_DEF_SSID))
return(0);
return(AN_IOSIZ);
--- 352,358 ----
return(0);
/* See if the ssid matches what we expect ... but doesn't have to */
! if (strcmp(ssid.an_entry[0].an_ssid, AN_DEF_SSID))
return(0);
return(AN_IOSIZ);
***************
*** 715,721 ****
/* Read ssid list */
sc->an_ssidlist.an_type = AN_RID_SSIDLIST;
! sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist);
if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) {
printf("an%d: read record failed\n", sc->an_unit);
goto fail;
--- 715,721 ----
/* Read ssid list */
sc->an_ssidlist.an_type = AN_RID_SSIDLIST;
! sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist_new);
if (an_read_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) {
printf("an%d: read record failed\n", sc->an_unit);
goto fail;
***************
*** 769,778 ****
bcopy(AN_DEFAULT_NODENAME, sc->an_config.an_nodename,
sizeof(AN_DEFAULT_NODENAME) - 1);
! bzero(sc->an_ssidlist.an_ssid1, sizeof(sc->an_ssidlist.an_ssid1));
! bcopy(AN_DEFAULT_NETNAME, sc->an_ssidlist.an_ssid1,
sizeof(AN_DEFAULT_NETNAME) - 1);
! sc->an_ssidlist.an_ssid1_len = strlen(AN_DEFAULT_NETNAME);
sc->an_config.an_opmode =
AN_OPMODE_INFRASTRUCTURE_STATION;
--- 769,779 ----
bcopy(AN_DEFAULT_NODENAME, sc->an_config.an_nodename,
sizeof(AN_DEFAULT_NODENAME) - 1);
! bzero(sc->an_ssidlist.an_entry[0].an_ssid,
! sizeof(sc->an_ssidlist.an_entry[0].an_ssid));
! bcopy(AN_DEFAULT_NETNAME, sc->an_ssidlist.an_entry[0].an_ssid,
sizeof(AN_DEFAULT_NETNAME) - 1);
! sc->an_ssidlist.an_entry[0].an_len = strlen(AN_DEFAULT_NETNAME);
sc->an_config.an_opmode =
AN_OPMODE_INFRASTRUCTURE_STATION;
***************
*** 1088,1094 ****
ifp->if_flags &= ~IFF_OACTIVE;
if (!sc->mpi350) {
! id = CSR_READ_2(sc, AN_TX_CMP_FID);
if (status & AN_EV_TX_EXC) {
ifp->if_oerrors++;
--- 1089,1095 ----
ifp->if_flags &= ~IFF_OACTIVE;
if (!sc->mpi350) {
! id = CSR_READ_2(sc, AN_TX_CMP_FID(sc->mpi350));
if (status & AN_EV_TX_EXC) {
ifp->if_oerrors++;
***************
*** 1104,1115 ****
AN_INC(sc->an_rdata.an_tx_cons, AN_TX_RING_CNT);
} else { /* MPI 350 */
! AN_INC(sc->an_rdata.an_tx_cons, AN_MAX_TX_DESC);
! if (sc->an_rdata.an_tx_prod ==
! sc->an_rdata.an_tx_cons)
! sc->an_rdata.an_tx_empty = 1;
}
-
return;
}
--- 1105,1122 ----
AN_INC(sc->an_rdata.an_tx_cons, AN_TX_RING_CNT);
} else { /* MPI 350 */
! id = CSR_READ_2(sc, AN_TX_CMP_FID(sc->mpi350));
! if (!sc->an_rdata.an_tx_empty){
! if (status & AN_EV_TX_EXC) {
! ifp->if_oerrors++;
! } else
! ifp->if_opackets++;
! AN_INC(sc->an_rdata.an_tx_cons, AN_MAX_TX_DESC);
! if (sc->an_rdata.an_tx_prod ==
! sc->an_rdata.an_tx_cons)
! sc->an_rdata.an_tx_empty = 1;
! }
}
return;
}
***************
*** 1179,1188 ****
CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), 0);
status = CSR_READ_2(sc, AN_EVENT_STAT(sc->mpi350));
! CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), ~AN_INTRS);
! if (status & AN_EV_AWAKE) {
! CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_AWAKE);
}
if (status & AN_EV_LINKSTAT) {
--- 1186,1195 ----
CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), 0);
status = CSR_READ_2(sc, AN_EVENT_STAT(sc->mpi350));
! CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), ~AN_INTRS(sc->mpi350));
! if (status & AN_EV_MIC) {
! CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_MIC);
}
if (status & AN_EV_LINKSTAT) {
***************
*** 1199,1207 ****
CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_RX);
}
if (status & AN_EV_TX) {
an_txeof(sc, status);
! CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_TX);
}
if (status & AN_EV_TX_EXC) {
--- 1206,1221 ----
CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_RX);
}
+ if (sc->mpi350 && status & AN_EV_TX_CPY) {
+ an_txeof(sc, status);
+ CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350),
+ AN_EV_TX_CPY);
+ }
+
if (status & AN_EV_TX) {
an_txeof(sc, status);
! CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350),
! AN_EV_TX);
}
if (status & AN_EV_TX_EXC) {
***************
*** 1213,1219 ****
CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_ALLOC);
/* Re-enable interrupts. */
! CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), AN_INTRS);
if ((ifp->if_flags & IFF_UP) && (ifp->if_snd.ifq_head != NULL))
an_start(ifp);
--- 1227,1233 ----
CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_ALLOC);
/* Re-enable interrupts. */
! CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), AN_INTRS(sc->mpi350));
if ((ifp->if_flags & IFF_UP) && (ifp->if_snd.ifq_head != NULL))
an_start(ifp);
***************
*** 1238,1243 ****
--- 1252,1258 ----
} else
break;
}
+
if( i == AN_TIMEOUT) {
printf("BUSY\n");
return(ETIMEDOUT);
***************
*** 1260,1266 ****
reply->an_status = CSR_READ_2(sc, AN_STATUS(sc->mpi350));
if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY)
! CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_CLR_STUCK_BUSY);
/* Ack the command */
CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_CMD);
--- 1275,1282 ----
reply->an_status = CSR_READ_2(sc, AN_STATUS(sc->mpi350));
if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY)
! CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350),
! AN_EV_CLR_STUCK_BUSY);
/* Ack the command */
CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_CMD);
***************
*** 1728,1734 ****
struct ifaddr *ifa;
struct ifnet *ifp;
struct an_ltv_genconfig *cfg;
! struct an_ltv_ssidlist *ssid;
struct an_ltv_aplist *ap;
struct an_ltv_gen *sp;
--- 1744,1750 ----
struct ifaddr *ifa;
struct ifnet *ifp;
struct an_ltv_genconfig *cfg;
! struct an_ltv_ssidlist_new *ssid;
struct an_ltv_aplist *ap;
struct an_ltv_gen *sp;
***************
*** 1748,1756 ****
sizeof(struct an_ltv_genconfig));
break;
case AN_RID_SSIDLIST:
! ssid = (struct an_ltv_ssidlist *)areq;
bcopy((char *)ssid, (char *)&sc->an_ssidlist,
! sizeof(struct an_ltv_ssidlist));
break;
case AN_RID_APLIST:
ap = (struct an_ltv_aplist *)areq;
--- 1764,1772 ----
sizeof(struct an_ltv_genconfig));
break;
case AN_RID_SSIDLIST:
! ssid = (struct an_ltv_ssidlist_new *)areq;
bcopy((char *)ssid, (char *)&sc->an_ssidlist,
! sizeof(struct an_ltv_ssidlist_new));
break;
case AN_RID_APLIST:
ap = (struct an_ltv_aplist *)areq;
***************
*** 1859,1865 ****
{
int error = 0;
int len;
! int i;
struct an_softc *sc;
struct ifreq *ifr;
struct thread *td = curthread;
--- 1875,1881 ----
{
int error = 0;
int len;
! int i, max;
struct an_softc *sc;
struct ifreq *ifr;
struct thread *td = curthread;
***************
*** 1869,1875 ****
struct an_ltv_genconfig *config;
struct an_ltv_key *key;
struct an_ltv_status *status;
! struct an_ltv_ssidlist *ssids;
int mode;
struct aironet_ioctl l_ioctl;
--- 1885,1891 ----
struct an_ltv_genconfig *config;
struct an_ltv_key *key;
struct an_ltv_status *status;
! struct an_ltv_ssidlist_new *ssids;
int mode;
struct aironet_ioctl l_ioctl;
***************
*** 1881,1887 ****
config = (struct an_ltv_genconfig *)&sc->areq;
key = (struct an_ltv_key *)&sc->areq;
status = (struct an_ltv_status *)&sc->areq;
! ssids = (struct an_ltv_ssidlist *)&sc->areq;
if (sc->an_gone) {
error = ENODEV;
--- 1897,1903 ----
config = (struct an_ltv_genconfig *)&sc->areq;
key = (struct an_ltv_key *)&sc->areq;
status = (struct an_ltv_status *)&sc->areq;
! ssids = (struct an_ltv_ssidlist_new *)&sc->areq;
if (sc->an_gone) {
error = ENODEV;
***************
*** 2004,2021 ****
error = EINVAL;
break;
}
! if (ireq->i_val == 0) {
! len = ssids->an_ssid1_len;
! tmpptr = ssids->an_ssid1;
! } else if (ireq->i_val == 1) {
! len = ssids->an_ssid2_len;
! tmpptr = ssids->an_ssid2;
! } else if (ireq->i_val == 2) {
! len = ssids->an_ssid3_len;
! tmpptr = ssids->an_ssid3;
! } else {
error = EINVAL;
break;
}
} else {
error = EINVAL;
--- 2020,2039 ----
error = EINVAL;
break;
}
! max = (sc->areq.an_len - 4)
! / sizeof(struct an_ltv_ssid_entry);
! if ( max > MAX_SSIDS ) {
! printf("To many SSIDs only using "
! "%d of %d\n",
! MAX_SSIDS, max);
! max = MAX_SSIDS;
! }
! if (ireq->i_val > max) {
error = EINVAL;
break;
+ } else {
+ len = ssids->an_entry[ireq->i_val].an_len;
+ tmpptr = ssids->an_entry[ireq->i_val].an_ssid;
}
} else {
error = EINVAL;
***************
*** 2032,2038 ****
IEEE80211_NWID_LEN);
break;
case IEEE80211_IOC_NUMSSIDS:
! ireq->i_val = 3;
break;
case IEEE80211_IOC_WEP:
sc->areq.an_type = AN_RID_ACTUALCFG;
--- 2050,2071 ----
IEEE80211_NWID_LEN);
break;
case IEEE80211_IOC_NUMSSIDS:
! sc->areq.an_len = sizeof(sc->areq);
! sc->areq.an_type = AN_RID_SSIDLIST;
! if (an_read_record(sc,
! (struct an_ltv_gen *)&sc->areq)) {
! error = EINVAL;
! break;
! }
! max = (sc->areq.an_len - 4)
! / sizeof(struct an_ltv_ssid_entry);
! if ( max > MAX_SSIDS ) {
! printf("To many SSIDs only using "
! "%d of %d\n",
! MAX_SSIDS, max);
! max = MAX_SSIDS;
! }
! ireq->i_val = max;
break;
case IEEE80211_IOC_WEP:
sc->areq.an_type = AN_RID_ACTUALCFG;
***************
*** 2228,2233 ****
--- 2261,2267 ----
}
switch (ireq->i_type) {
case IEEE80211_IOC_SSID:
+ sc->areq.an_len = sizeof(sc->areq);
sc->areq.an_type = AN_RID_SSIDLIST;
if (an_read_record(sc,
(struct an_ltv_gen *)&sc->areq)) {
***************
*** 2238,2261 ****
error = EINVAL;
break;
}
! switch (ireq->i_val) {
! case 0:
! error = copyin(ireq->i_data,
! ssids->an_ssid1, ireq->i_len);
! ssids->an_ssid1_len = ireq->i_len;
! break;
! case 1:
! error = copyin(ireq->i_data,
! ssids->an_ssid2, ireq->i_len);
! ssids->an_ssid2_len = ireq->i_len;
break;
! case 2:
error = copyin(ireq->i_data,
! ssids->an_ssid3, ireq->i_len);
! ssids->an_ssid3_len = ireq->i_len;
! break;
! default:
! error = EINVAL;
break;
}
break;
--- 2272,2294 ----
error = EINVAL;
break;
}
! max = (sc->areq.an_len - 4)
! / sizeof(struct an_ltv_ssid_entry);
! if ( max > MAX_SSIDS ) {
! printf("To many SSIDs only using "
! "%d of %d\n",
! MAX_SSIDS, max);
! max = MAX_SSIDS;
! }
! if (ireq->i_val > max) {
! error = EINVAL;
break;
! } else {
error = copyin(ireq->i_data,
! ssids->an_entry[ireq->i_val].an_ssid,
! ireq->i_len);
! ssids->an_entry[ireq->i_val].an_len
! = ireq->i_len;
break;
}
break;
***************
*** 2512,2518 ****
/* 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)) {
printf("an%d: failed to set ssid list\n", sc->an_unit);
AN_UNLOCK(sc);
--- 2545,2551 ----
/* Set the ssid list */
sc->an_ssidlist.an_type = AN_RID_SSIDLIST;
! sc->an_ssidlist.an_len = sizeof(struct an_ltv_ssidlist_new);
if (an_write_record(sc, (struct an_ltv_gen *)&sc->an_ssidlist)) {
printf("an%d: failed to set ssid list\n", sc->an_unit);
AN_UNLOCK(sc);
***************
*** 2548,2554 ****
an_cmd(sc, AN_CMD_SET_MODE, 0xffff);
/* enable interrupts */
! CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), AN_INTRS);
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
--- 2581,2587 ----
an_cmd(sc, AN_CMD_SET_MODE, 0xffff);
/* enable interrupts */
! CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), AN_INTRS(sc->mpi350));
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
***************
*** 2570,2576 ****
int id, idx, i;
unsigned char txcontrol;
struct an_card_tx_desc an_tx_desc;
- u_int8_t *ptr;
u_int8_t *buf;
sc = ifp->if_softc;
--- 2603,2608 ----
***************
*** 2650,2657 ****
--- 2682,2715 ----
printf("an%d: xmit failed\n", sc->an_unit);
AN_INC(idx, AN_TX_RING_CNT);
+
+ /*
+ * Set a timeout in case the chip goes out to lunch.
+ */
+ ifp->if_timer = 5;
}
} else { /* MPI-350 */
+ /* HACK */
+ {
+ struct an_command cmd_struct;
+ struct an_reply reply;
+ /*
+ * Allocate TX descriptor
+ */
+
+ bzero(&reply,sizeof(reply));
+ cmd_struct.an_cmd = AN_CMD_ALLOC_DESC;
+ cmd_struct.an_parm0 = AN_DESCRIPTOR_TX;
+ cmd_struct.an_parm1 = AN_TX_DESC_OFFSET;
+ cmd_struct.an_parm2 = AN_MAX_TX_DESC;
+ if (an_cmd_struct(sc, &cmd_struct, &reply)) {
+ printf("an%d: failed to allocate TX "
+ "descriptor\n",
+ sc->an_unit);
+ return;
+ }
+ }
+ /* HACK */
while (sc->an_rdata.an_tx_empty ||
idx != sc->an_rdata.an_tx_cons) {
IF_DEQUEUE(&ifp->if_snd, m0);
***************
*** 2697,2708 ****
an_tx_desc.an_eoc = 1;
an_tx_desc.an_valid = 1;
an_tx_desc.an_len = 0x44 +
! tx_frame_802_3.an_tx_802_3_payload_len;
! an_tx_desc.an_phys = sc->an_tx_buffer[idx].an_dma_paddr;
! ptr = (u_int8_t*)&an_tx_desc;
! for (i = 0; i < sizeof(an_tx_desc); i++) {
! CSR_MEM_AUX_WRITE_1(sc, AN_TX_DESC_OFFSET + i,
! ptr[i]);
}
/*
--- 2755,2769 ----
an_tx_desc.an_eoc = 1;
an_tx_desc.an_valid = 1;
an_tx_desc.an_len = 0x44 +
! tx_frame_802_3.an_tx_802_3_payload_len;
! an_tx_desc.an_phys
! = sc->an_tx_buffer[idx].an_dma_paddr;
! for (i = 0; i < sizeof(an_tx_desc) / 4 ; i++) {
! CSR_MEM_AUX_WRITE_4(sc, AN_TX_DESC_OFFSET
! /* zero for now */
! + (0 * sizeof(an_tx_desc))
! + (i * 4),
! ((u_int32_t*)&an_tx_desc)[i]);
}
/*
***************
*** 2713,2723 ****
m_freem(m0);
m0 = NULL;
-
- CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_ALLOC);
-
AN_INC(idx, AN_MAX_TX_DESC);
sc->an_rdata.an_tx_empty = 0;
}
}
--- 2774,2787 ----
m_freem(m0);
m0 = NULL;
AN_INC(idx, AN_MAX_TX_DESC);
sc->an_rdata.an_tx_empty = 0;
+ CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_ALLOC);
+
+ /*
+ * Set a timeout in case the chip goes out to lunch.
+ */
+ ifp->if_timer = 5;
}
}
***************
*** 2726,2736 ****
sc->an_rdata.an_tx_prod = idx;
- /*
- * Set a timeout in case the chip goes out to lunch.
- */
- ifp->if_timer = 5;
-
return;
}
--- 2790,2795 ----
***************
*** 3069,3081 ****
int otype = sc->an_config.an_opmode;
int orate = sc->an_tx_rate;
! if ((sc->an_ifmedia.ifm_cur->ifm_media & IFM_IEEE80211_ADHOC) != 0)
! sc->an_config.an_opmode = AN_OPMODE_IBSS_ADHOC;
! else
! sc->an_config.an_opmode = AN_OPMODE_INFRASTRUCTURE_STATION;
sc->an_tx_rate = ieee80211_media2rate(
IFM_SUBTYPE(sc->an_ifmedia.ifm_cur->ifm_media));
if (orate != sc->an_tx_rate) {
/* Read the current configuration */
--- 3128,3142 ----
int otype = sc->an_config.an_opmode;
int orate = sc->an_tx_rate;
! printf("Hello %d %d\n",
! sc->an_tx_rate,
! ieee80211_media2rate(
! IFM_SUBTYPE(sc->an_ifmedia.ifm_cur->ifm_media)));
sc->an_tx_rate = ieee80211_media2rate(
IFM_SUBTYPE(sc->an_ifmedia.ifm_cur->ifm_media));
+ if (sc->an_tx_rate < 0)
+ sc->an_tx_rate = 0;
if (orate != sc->an_tx_rate) {
/* Read the current configuration */
***************
*** 3092,3097 ****
--- 3153,3163 ----
sc->an_config.an_type = AN_RID_GENCONFIG;
sc->an_config.an_len = sizeof(struct an_ltv_genconfig);
}
+
+ if ((sc->an_ifmedia.ifm_cur->ifm_media & IFM_IEEE80211_ADHOC) != 0)
+ sc->an_config.an_opmode &= ~AN_OPMODE_INFRASTRUCTURE_STATION;
+ else
+ sc->an_config.an_opmode |= AN_OPMODE_INFRASTRUCTURE_STATION;
if (otype != sc->an_config.an_opmode ||
orate != sc->an_tx_rate)
Index: sys/dev/an/if_an_pci.c
===================================================================
RCS file: /cvs/src/sys/dev/an/if_an_pci.c,v
retrieving revision 1.21
diff -c -r1.21 if_an_pci.c
*** sys/dev/an/if_an_pci.c 1 Jul 2003 15:51:53 -0000 1.21
--- sys/dev/an/if_an_pci.c 19 Aug 2003 02:41:06 -0000
***************
*** 198,204 ****
/* Allocate aux. memory */
sc->mem_aux_rid = PCIR_MAPS + 8;
error = an_alloc_aux_memory(dev, sc->mem_aux_rid,
! AN_AUXMEMSIZE);
if (error) {
printf("an%d: couldn't map aux memory\n", unit);
goto fail;
--- 198,204 ----
/* Allocate aux. memory */
sc->mem_aux_rid = PCIR_MAPS + 8;
error = an_alloc_aux_memory(dev, sc->mem_aux_rid,
! AN_AUX_MEM_SIZE);
if (error) {
printf("an%d: couldn't map aux memory\n", unit);
goto fail;
Index: sys/dev/an/if_anreg.h
===================================================================
RCS file: /cvs/src/sys/dev/an/if_anreg.h,v
retrieving revision 1.17
diff -c -r1.17 if_anreg.h
*** sys/dev/an/if_anreg.h 8 Feb 2003 04:41:17 -0000 1.17
--- sys/dev/an/if_anreg.h 19 Aug 2003 02:41:06 -0000
***************
*** 95,101 ****
/*
* Size of aux. memory space ... probably not needed DJA
*/
! #define AN_AUXMEMSIZE (256 * 1024)
/*
* Hermes register definitions and what little I know about them.
--- 95,101 ----
/*
* Size of aux. memory space ... probably not needed DJA
*/
! #define AN_AUX_MEM_SIZE (256 * 1024)
/*
* Hermes register definitions and what little I know about them.
***************
*** 181,190 ****
u_int64_t an_phys;
};
! #define AN_RID_BUFFER_SIZE 2048
! #define AN_RX_BUFFER_SIZE 1840
! #define AN_TX_BUFFER_SIZE 1840
! #define AN_HOST_DESC_OFFSET 0x8
#define AN_RX_DESC_OFFSET (AN_HOST_DESC_OFFSET + \
sizeof(struct an_card_rid_desc))
#define AN_TX_DESC_OFFSET (AN_RX_DESC_OFFSET + \
--- 181,191 ----
u_int64_t an_phys;
};
! #define AN_RID_BUFFER_SIZE AN_MAX_DATALEN
! #define AN_RX_BUFFER_SIZE AN_HOSTBUFSIZ
! #define AN_TX_BUFFER_SIZE AN_HOSTBUFSIZ
! /*#define AN_HOST_DESC_OFFSET 0xC sort of works */
! #define AN_HOST_DESC_OFFSET 0x800
#define AN_RX_DESC_OFFSET (AN_HOST_DESC_OFFSET + \
sizeof(struct an_card_rid_desc))
#define AN_TX_DESC_OFFSET (AN_RX_DESC_OFFSET + \
***************
*** 243,249 ****
/* memory handle management registers */
#define AN_RX_FID 0x20
#define AN_ALLOC_FID 0x22
! #define AN_TX_CMP_FID 0x24
/*
* Buffer Access Path (BAP) registers.
--- 244,250 ----
/* memory handle management registers */
#define AN_RX_FID 0x20
#define AN_ALLOC_FID 0x22
! #define AN_TX_CMP_FID(x) (x ? 0x1a : 0x24)
/*
* Buffer Access Path (BAP) registers.
***************
*** 276,291 ****
/* Events */
#define AN_EV_CLR_STUCK_BUSY 0x4000 /* clear stuck busy bit */
#define AN_EV_WAKEREQUEST 0x2000 /* awaken from PSP mode */
#define AN_EV_AWAKE 0x0100 /* station woke up from PSP mode*/
#define AN_EV_LINKSTAT 0x0080 /* link status available */
#define AN_EV_CMD 0x0010 /* command completed */
#define AN_EV_ALLOC 0x0008 /* async alloc/reclaim completed */
#define AN_EV_TX_EXC 0x0004 /* async xmit completed with failure */
#define AN_EV_TX 0x0002 /* async xmit completed succesfully */
#define AN_EV_RX 0x0001 /* async rx completed */
! #define AN_INTRS \
! (AN_EV_RX|AN_EV_TX|AN_EV_TX_EXC|AN_EV_ALLOC|AN_EV_LINKSTAT)
/* Host software registers */
#define AN_SW0(x) (x ? 0x50 : 0x28)
--- 277,299 ----
/* Events */
#define AN_EV_CLR_STUCK_BUSY 0x4000 /* clear stuck busy bit */
#define AN_EV_WAKEREQUEST 0x2000 /* awaken from PSP mode */
+ #define AN_EV_MIC 0x1000 /* Message Integrity Check*/
#define AN_EV_AWAKE 0x0100 /* station woke up from PSP mode*/
#define AN_EV_LINKSTAT 0x0080 /* link status available */
#define AN_EV_CMD 0x0010 /* command completed */
#define AN_EV_ALLOC 0x0008 /* async alloc/reclaim completed */
+ #define AN_EV_TX_CPY 0x0400
#define AN_EV_TX_EXC 0x0004 /* async xmit completed with failure */
#define AN_EV_TX 0x0002 /* async xmit completed succesfully */
#define AN_EV_RX 0x0001 /* async rx completed */
! #define AN_INTRS(x) \
! ( x ? (AN_EV_RX|AN_EV_TX|AN_EV_TX_EXC|AN_EV_TX_CPY|AN_EV_ALLOC \
! |AN_EV_LINKSTAT|AN_EV_MIC) \
! : \
! (AN_EV_RX|AN_EV_TX|AN_EV_TX_EXC|AN_EV_ALLOC \
! |AN_EV_LINKSTAT|AN_EV_MIC) \
! )
/* Host software registers */
#define AN_SW0(x) (x ? 0x50 : 0x28)
***************
*** 458,464 ****
bus_dma_tag_t an_dtag;
struct an_ltv_genconfig an_config;
struct an_ltv_caps an_caps;
! struct an_ltv_ssidlist an_ssidlist;
struct an_ltv_aplist an_aplist;
struct an_ltv_key an_temp_keys[4];
int an_tx_rate;
--- 466,472 ----
bus_dma_tag_t an_dtag;
struct an_ltv_genconfig an_config;
struct an_ltv_caps an_caps;
! struct an_ltv_ssidlist_new an_ssidlist;
struct an_ltv_aplist an_aplist;
struct an_ltv_key an_temp_keys[4];
int an_tx_rate;
Index: usr.sbin/ancontrol/ancontrol.c
===================================================================
RCS file: /cvs/src/usr.sbin/ancontrol/ancontrol.c,v
retrieving revision 1.20
diff -c -r1.20 ancontrol.c
*** usr.sbin/ancontrol/ancontrol.c 3 May 2003 21:06:35 -0000 1.20
--- usr.sbin/ancontrol/ancontrol.c 19 Aug 2003 02:41:06 -0000
***************
*** 101,109 ****
#define ACT_DUMPAP 6
#define ACT_SET_OPMODE 7
! #define ACT_SET_SSID1 8
! #define ACT_SET_SSID2 9
! #define ACT_SET_SSID3 10
#define ACT_SET_FREQ 11
#define ACT_SET_AP1 12
#define ACT_SET_AP2 13
--- 101,107 ----
#define ACT_DUMPAP 6
#define ACT_SET_OPMODE 7
! #define ACT_SET_SSID 8
#define ACT_SET_FREQ 11
#define ACT_SET_AP1 12
#define ACT_SET_AP2 13
***************
*** 648,665 ****
static void an_dumpssid(iface)
const char *iface;
{
! struct an_ltv_ssidlist *ssid;
struct an_req areq;
areq.an_len = sizeof(areq);
areq.an_type = AN_RID_SSIDLIST;
an_getval(iface, &areq);
! ssid = (struct an_ltv_ssidlist *)&areq;
! printf("SSID 1:\t\t\t[ %.*s ]\n", ssid->an_ssid1_len, ssid->an_ssid1);
! printf("SSID 2:\t\t\t[ %.*s ]\n", ssid->an_ssid2_len, ssid->an_ssid2);
! printf("SSID 3:\t\t\t[ %.*s ]\n", ssid->an_ssid3_len, ssid->an_ssid3);
return;
}
--- 646,671 ----
static void an_dumpssid(iface)
const char *iface;
{
! struct an_ltv_ssidlist_new *ssid;
struct an_req areq;
+ int i, max;
areq.an_len = sizeof(areq);
areq.an_type = AN_RID_SSIDLIST;
an_getval(iface, &areq);
! max = (areq.an_len - 4) / sizeof(struct an_ltv_ssid_entry);
! if ( max > MAX_SSIDS ) {
! printf("To many SSIDs only printing %d of %d\n",
! MAX_SSIDS, max);
! max = MAX_SSIDS;
! }
! ssid = (struct an_ltv_ssidlist_new *)&areq;
! for (i = 0; i < max; i++)
! printf("SSID %2d:\t\t\t[ %.*s ]\n", i + 1,
! ssid->an_entry[i].an_len,
! ssid->an_entry[i].an_ssid);
return;
}
***************
*** 1182,1217 ****
int act;
void *arg;
{
! struct an_ltv_ssidlist *ssid;
struct an_req areq;
areq.an_len = sizeof(areq);
areq.an_type = AN_RID_SSIDLIST;
an_getval(iface, &areq);
! ssid = (struct an_ltv_ssidlist *)&areq;
! switch (act) {
! case ACT_SET_SSID1:
! bzero(ssid->an_ssid1, sizeof(ssid->an_ssid1));
! strlcpy(ssid->an_ssid1, (char *)arg, sizeof(ssid->an_ssid1));
! ssid->an_ssid1_len = strlen(ssid->an_ssid1);
! break;
! case ACT_SET_SSID2:
! bzero(ssid->an_ssid2, sizeof(ssid->an_ssid2));
! strlcpy(ssid->an_ssid2, (char *)arg, sizeof(ssid->an_ssid2));
! ssid->an_ssid2_len = strlen(ssid->an_ssid2);
! break;
! case ACT_SET_SSID3:
! bzero(ssid->an_ssid3, sizeof(ssid->an_ssid3));
! strlcpy(ssid->an_ssid3, (char *)arg, sizeof(ssid->an_ssid3));
! ssid->an_ssid3_len = strlen(ssid->an_ssid3);
! break;
! default:
! errx(1, "unknown action");
! break;
}
an_setval(iface, &areq);
exit(0);
}
--- 1188,1223 ----
int act;
void *arg;
{
! struct an_ltv_ssidlist_new *ssid;
struct an_req areq;
+ int max;
areq.an_len = sizeof(areq);
areq.an_type = AN_RID_SSIDLIST;
an_getval(iface, &areq);
! ssid = (struct an_ltv_ssidlist_new *)&areq;
! max = (areq.an_len - 4) / sizeof(struct an_ltv_ssid_entry);
! if ( max > MAX_SSIDS ) {
! printf("To many SSIDs only printing %d of %d\n",
! MAX_SSIDS, max);
! max = MAX_SSIDS;
! }
!
! if ( act > max ) {
! errx(1, "bad modifier %d: there "
! "are only %d SSID settings", act, max);
! exit(1);
}
+ bzero(ssid->an_entry[act-1].an_ssid,
+ sizeof(ssid->an_entry[act-1].an_ssid));
+ strlcpy(ssid->an_entry[act-1].an_ssid, (char *)arg,
+ sizeof(ssid->an_entry[act-1].an_ssid));
+ ssid->an_entry[act-1].an_len
+ = strlen(ssid->an_entry[act-1].an_ssid);
+
an_setval(iface, &areq);
exit(0);
}
***************
*** 1702,1724 ****
arg = optarg;
break;
case 'n':
! switch(modifier) {
! case 0:
! case 1:
! act = ACT_SET_SSID1;
! break;
! case 2:
! act = ACT_SET_SSID2;
! break;
! case 3:
! act = ACT_SET_SSID3;
! break;
! default:
! errx(1, "bad modifier %d: there"
! "are only 3 SSID settings", modifier);
! usage(p);
! break;
! }
arg = optarg;
break;
case 'o':
--- 1708,1716 ----
arg = optarg;
break;
case 'n':
! if (modifier == 0)
! modifier = 1;
! act = ACT_SET_SSID;
arg = optarg;
break;
case 'o':
***************
*** 1800,1809 ****
case ACT_DUMPRSSIMAP:
an_dumprssimap(iface);
break;
! case ACT_SET_SSID1:
! case ACT_SET_SSID2:
! case ACT_SET_SSID3:
! an_setssid(iface, act, arg);
break;
case ACT_SET_AP1:
case ACT_SET_AP2:
--- 1792,1799 ----
case ACT_DUMPRSSIMAP:
an_dumprssimap(iface);
break;
! case ACT_SET_SSID:
! an_setssid(iface, modifier, arg);
break;
case ACT_SET_AP1:
case ACT_SET_AP2:
More information about the freebsd-current
mailing list