arn_beacon.c revision dd1de3740722a4b99a74005255effebbd20a6d70
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 2008 Atheros Communications Inc.
*
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <inet/wifi_ioctl.h>
#include "arn_core.h"
/*
* This function will modify certain transmit queue properties depending on
* the operating mode of the station (AP or AdHoc). Parameters are AIFS
*/
static int
{
struct ath9k_tx_queue_info qi;
/* Always burst out beacon and CAB traffic. */
} else {
/* Adhoc mode; important thing is to use 2x cwmin. */
}
arn_problem("unable to update h/w beacon queue parameters\n");
return (0);
} else {
/* push to h/w */
return (1);
}
}
/*
* Associates the beacon frame buffer with a transmit descriptor. Will set
* up all required antenna switch parameters, rate codes, and channel flags.
* Beacons are always sent out at the lowest rate, and are not retried.
*/
static void
{
#define USE_SHPREAMBLE(_ic) \
/* LINTED E_FUNC_SET_NOT_USED */
struct ath_rate_table *rt;
int ctsrate = 0;
int ctsduration = 0;
/* set up descriptors */
/*
* Let hardware handle antenna switching.
*/
antenna = 0;
} else {
/*
* Switch antenna every 4 beacons.
* NB: assumes two antenna
*/
}
/*
* Calculate rate code.
* XXX everything at min xmit rate
*/
rix = 0;
ATH9K_PKT_TYPE_BEACON, /* Atheros packet type */
MAX_RATE_POWER, /* FIXME */
ATH9K_TXKEYIX_INVALID, /* no encryption */
ATH9K_KEY_TYPE_CLEAR, /* no encryption */
flags); /* no ack, veol for beacons */
/* NB: beacon's BufLen must be a multiple of 4 bytes */
B_TRUE, /* first segment */
B_TRUE, /* last segment */
ds); /* first descriptor */
}
/*
* Startup beacon transmission for adhoc mode when they are sent entirely
* by the hardware using the self-linked descriptor + veol trick.
*/
static void
{
/* Construct tx descriptor. */
/*
* Stop any current dma and put the new frame on the queue.
* This should never fail since we check above that no frames
* are still pending on the queue.
*/
arn_problem("ath: beacon queue %d did not stop?\n",
sc->sc_beaconq);
}
/* NB: caller is known to have already stopped tx dma */
}
{
struct ath9k_tx_queue_info qi;
/* NB: don't enable any interrupts */
}
int
{
arn_problem("arn: arn_beacon_alloc():"
"no dma buffers");
return (ENOMEM);
}
arn_problem("ath: arn_beacon_alloc():"
"cannot get mbuf\n");
return (ENOMEM);
}
return (0);
}
void
{
}
}
}
}
void
{
struct ath_beacon_config conf;
/* XXX fix me */
/* extract tstamp from last beacon and convert to TU */
// nexttbtt = TSF_TO_TU(sc->bc_tstamp >> 32, sc->bc_tstamp);
/* XXX fix me */
/* XXX conditionalize multi-bss support? */
/*
* For multi-bss ap support beacons are either staggered
* evenly over N slots or burst together. For the former
* arrange for the SWBA to be delivered for each slot.
* Slots that are not occupied will generate nothing.
*/
/* NB: the beacon interval is kept internally in TU's */
} else {
}
if (nexttbtt == 0) /* e.g. for ap mode */
else if (intval) /* NB: can be 0 for monitor mode */
"nexttbtt %u intval %u (%u)\n",
/* Check for ATH9K_M_HOSTAP and sc_nostabeacons for WDS client */
struct ath9k_beacon_state bs;
/*
* Setup dtim and cfp parameters according to
* last beacon we received (which may be none).
*/
if (dtimperiod <= 0) /* NB: 0 if not known */
dtimperiod = 1;
dtimcount = 0;
cfpcount = 0;
if (sleepduration <= 0)
#define FUDGE 2
/*
* Pull nexttbtt forward to reflect the current
* TSF and calculate dtim+cfp state for the result.
*/
do {
if (--dtimcount < 0) {
if (--cfpcount < 0)
}
bs.bs_cfpmaxduration = 0;
/*
* Calculate the number of consecutive beacons to miss
* before taking a BMISS interrupt. The configuration
* is specified in TU so we only need calculate based
* on the beacon interval. Note that we clamp the
* result to at most 15 beacons.
*/
if (sleepduration > intval) {
} else {
/* LINTED E_SUSPICIOUS_COMPARISON */
else if (bs.bs_bmissthreshold <= 0)
}
/*
* Calculate sleep duration. The configuration is
* given in ms. We insure a multiple of the beacon
* period is used. Also, if the sleep duration is
* greater than the DTIM period then it makes senses
* to make it a multiple of that.
*
* XXX fixed at 100ms
*/
"tsf %llu "
"tsf:tu %u "
"intval %u "
"nexttbtt %u "
"dtim %u "
"nextdtim %u "
"bmiss %u "
"sleep %u "
"cfp:period %u "
"maxdur %u "
"next %u "
"timoffset %u\n",
bs.bs_timoffset));
(void) ath9k_hw_set_interrupts(ah, 0);
} else {
(void) ath9k_hw_set_interrupts(ah, 0);
/*
* Pull nexttbtt forward to reflect the current
* TSF
*/
#define FUDGE 2
if (!(intval & ATH9K_BEACON_RESET_TSF)) {
do {
}
"IBSS nexttbtt %u intval %u (%u)\n",
/*
* In IBSS mode enable the beacon timers but only
* enable SWBA interrupts if we need to manually
* prepare beacon frames. Otherwise we use a
* self-linked tx descriptor and let the hardware
* deal with things.
*/
(void) arn_beaconq_config(sc);
/*
* In AP mode we enable the beacon timers and
* SWBA interrupts to prepare beacon frames.
*/
(void) arn_beaconq_config(sc);
}
sc->sc_bmisscount = 0;
/*
* When using a self-linked beacon descriptor in
* ibss mode load it once here.
*/
}
}
void
{
/*
* Resync beacon timers using the tsf of the
* beacon frame we just received.
*/
}
void
arn_bmiss_proc(void *arg)
{
return;
}
" tsf %llu, lastrx %llu (%lld), bmiss %u\n",
ARN_UNLOCK(sc);
/* temp workaround */
}