Re: an driver / Cisco Aironet 340 stopped working

From: Doug Ambrisko <ambrisko_at_ambrisko.com>
Date: Mon, 18 Aug 2003 19:47:45 -0700 (PDT)
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:
Received on Mon Aug 18 2003 - 17:47:48 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:37:19 UTC