This commit is contained in:
Attilio Rao 2011-05-13 15:20:57 +00:00
commit 739e31f6d7
39 changed files with 690 additions and 367 deletions

View File

@ -26,7 +26,6 @@ LDADD= -lmd
CFLAGS+= -DFTP_COMBINE_CWDS
CSTD?= c99
WARNS?= 2
SHLIB_MAJOR= 6

View File

@ -213,6 +213,7 @@ fetch_reopen(int sd)
/* allocate and fill connection structure */
if ((conn = calloc(1, sizeof(*conn))) == NULL)
return (NULL);
fcntl(sd, F_SETFD, FD_CLOEXEC);
conn->sd = sd;
++conn->ref;
return (conn);

View File

@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
#include <sys/stat.h>
#include <dirent.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
@ -57,6 +58,7 @@ fetchXGetFile(struct url *u, struct url_stat *us, const char *flags)
fetch_syserr();
}
fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
return (f);
}
@ -84,6 +86,7 @@ fetchPutFile(struct url *u, const char *flags)
fetch_syserr();
}
fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
return (f);
}

View File

@ -127,7 +127,7 @@ unmappedaddr(struct sockaddr_in6 *sin6)
!IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
return;
sin4 = (struct sockaddr_in *)sin6;
addr = *(u_int32_t *)&sin6->sin6_addr.s6_addr[12];
addr = *(u_int32_t *)(uintptr_t)&sin6->sin6_addr.s6_addr[12];
port = sin6->sin6_port;
memset(sin4, 0, sizeof(struct sockaddr_in));
sin4->sin_addr.s_addr = addr;

View File

@ -454,7 +454,7 @@ http_match(const char *str, const char *hdr)
* Get the next header and return the appropriate symbolic code. We
* need to read one line ahead for checking for a continuation line
* belonging to the current header (continuation lines start with
* white space).
* white space).
*
* We get called with a fresh line already in the conn buffer, either
* from the previous http_next_header() invocation, or, the first
@ -462,7 +462,7 @@ http_match(const char *str, const char *hdr)
*
* This stops when we encounter an empty line (we dont read beyond the header
* area).
*
*
* Note that the "headerbuf" is just a place to return the result. Its
* contents are not used for the next call. This means that no cleanup
* is needed when ie doing another connection, just call the cleanup when
@ -487,7 +487,7 @@ init_http_headerbuf(http_headerbuf_t *buf)
buf->buflen = 0;
}
static void
static void
clean_http_headerbuf(http_headerbuf_t *buf)
{
if (buf->buf)
@ -496,10 +496,10 @@ clean_http_headerbuf(http_headerbuf_t *buf)
}
/* Remove whitespace at the end of the buffer */
static void
static void
http_conn_trimright(conn_t *conn)
{
while (conn->buflen &&
while (conn->buflen &&
isspace((unsigned char)conn->buf[conn->buflen - 1]))
conn->buflen--;
conn->buf[conn->buflen] = '\0';
@ -508,11 +508,11 @@ http_conn_trimright(conn_t *conn)
static hdr_t
http_next_header(conn_t *conn, http_headerbuf_t *hbuf, const char **p)
{
int i, len;
unsigned int i, len;
/*
/*
* Have to do the stripping here because of the first line. So
* it's done twice for the subsequent lines. No big deal
* it's done twice for the subsequent lines. No big deal
*/
http_conn_trimright(conn);
if (conn->buflen == 0)
@ -527,19 +527,19 @@ http_next_header(conn_t *conn, http_headerbuf_t *hbuf, const char **p)
strcpy(hbuf->buf, conn->buf);
hbuf->buflen = conn->buflen;
/*
/*
* Fetch possible continuation lines. Stop at 1st non-continuation
* and leave it in the conn buffer
*/
* and leave it in the conn buffer
*/
for (i = 0; i < HTTP_MAX_CONT_LINES; i++) {
if (fetch_getln(conn) == -1)
return (hdr_syserror);
/*
/*
* Note: we carry on the idea from the previous version
* that a pure whitespace line is equivalent to an empty
* one (so it's not continuation and will be handled when
* we are called next)
* we are called next)
*/
http_conn_trimright(conn);
if (conn->buf[0] != ' ' && conn->buf[0] != "\t"[0])
@ -555,7 +555,7 @@ http_next_header(conn_t *conn, http_headerbuf_t *hbuf, const char **p)
}
strcpy(hbuf->buf + hbuf->buflen, conn->buf);
hbuf->buflen += conn->buflen;
}
}
/*
* We could check for malformed headers but we don't really care.
@ -574,12 +574,12 @@ http_next_header(conn_t *conn, http_headerbuf_t *hbuf, const char **p)
* [Proxy-]Authenticate header parsing
*/
/*
* Read doublequote-delimited string into output buffer obuf (allocated
/*
* Read doublequote-delimited string into output buffer obuf (allocated
* by caller, whose responsibility it is to ensure that it's big enough)
* cp points to the first char after the initial '"'
* Handles \ quoting
* Returns pointer to the first char after the terminating double quote, or
* Handles \ quoting
* Returns pointer to the first char after the terminating double quote, or
* NULL for error.
*/
static const char *
@ -620,7 +620,7 @@ typedef struct {
int nc; /* Nonce count */
} http_auth_challenge_t;
static void
static void
init_http_auth_challenge(http_auth_challenge_t *b)
{
b->scheme = HTTPAS_UNKNOWN;
@ -628,18 +628,18 @@ init_http_auth_challenge(http_auth_challenge_t *b)
b->stale = b->nc = 0;
}
static void
static void
clean_http_auth_challenge(http_auth_challenge_t *b)
{
if (b->realm)
if (b->realm)
free(b->realm);
if (b->qop)
if (b->qop)
free(b->qop);
if (b->nonce)
if (b->nonce)
free(b->nonce);
if (b->opaque)
if (b->opaque)
free(b->opaque);
if (b->algo)
if (b->algo)
free(b->algo);
init_http_auth_challenge(b);
}
@ -652,7 +652,7 @@ typedef struct {
int valid; /* We did parse an authenticate header */
} http_auth_challenges_t;
static void
static void
init_http_auth_challenges(http_auth_challenges_t *cs)
{
int i;
@ -661,7 +661,7 @@ init_http_auth_challenges(http_auth_challenges_t *cs)
cs->count = cs->valid = 0;
}
static void
static void
clean_http_auth_challenges(http_auth_challenges_t *cs)
{
int i;
@ -675,19 +675,19 @@ clean_http_auth_challenges(http_auth_challenges_t *cs)
init_http_auth_challenges(cs);
}
/*
/*
* Enumeration for lexical elements. Separators will be returned as their own
* ascii value
*/
typedef enum {HTTPHL_WORD=256, HTTPHL_STRING=257, HTTPHL_END=258,
HTTPHL_ERROR = 259} http_header_lex_t;
/*
/*
* Determine what kind of token comes next and return possible value
* in buf, which is supposed to have been allocated big enough by
* caller. Advance input pointer and return element type.
* caller. Advance input pointer and return element type.
*/
static int
static int
http_header_lex(const char **cpp, char *buf)
{
size_t l;
@ -716,7 +716,7 @@ http_header_lex(const char **cpp, char *buf)
return (HTTPHL_WORD);
}
/*
/*
* Read challenges from http xxx-authenticate header and accumulate them
* in the challenges list structure.
*
@ -728,7 +728,7 @@ http_header_lex(const char **cpp, char *buf)
*
* We support both approaches anyway
*/
static int
static int
http_parse_authenticate(const char *cp, http_auth_challenges_t *cs)
{
int ret = -1;
@ -752,7 +752,7 @@ http_parse_authenticate(const char *cp, http_auth_challenges_t *cs)
/* Loop on challenges */
for (; cs->count < MAX_CHALLENGES; cs->count++) {
cs->challenges[cs->count] =
cs->challenges[cs->count] =
malloc(sizeof(http_auth_challenge_t));
if (cs->challenges[cs->count] == NULL) {
fetch_syserr();
@ -765,14 +765,14 @@ http_parse_authenticate(const char *cp, http_auth_challenges_t *cs)
cs->challenges[cs->count]->scheme = HTTPAS_DIGEST;
} else {
cs->challenges[cs->count]->scheme = HTTPAS_UNKNOWN;
/*
* Continue parsing as basic or digest may
/*
* Continue parsing as basic or digest may
* follow, and the syntax is the same for
* all. We'll just ignore this one when
* looking at the list
*/
}
/* Loop on attributes */
for (;;) {
/* Key */
@ -791,31 +791,31 @@ http_parse_authenticate(const char *cp, http_auth_challenges_t *cs)
goto out;
if (!strcasecmp(key, "realm"))
cs->challenges[cs->count]->realm =
cs->challenges[cs->count]->realm =
strdup(value);
else if (!strcasecmp(key, "qop"))
cs->challenges[cs->count]->qop =
cs->challenges[cs->count]->qop =
strdup(value);
else if (!strcasecmp(key, "nonce"))
cs->challenges[cs->count]->nonce =
cs->challenges[cs->count]->nonce =
strdup(value);
else if (!strcasecmp(key, "opaque"))
cs->challenges[cs->count]->opaque =
cs->challenges[cs->count]->opaque =
strdup(value);
else if (!strcasecmp(key, "algorithm"))
cs->challenges[cs->count]->algo =
cs->challenges[cs->count]->algo =
strdup(value);
else if (!strcasecmp(key, "stale"))
cs->challenges[cs->count]->stale =
cs->challenges[cs->count]->stale =
strcasecmp(value, "no");
/* Else ignore unknown attributes */
/* Comma or Next challenge or End */
lex = http_header_lex(&cp, key);
/*
* If we get a word here, this is the beginning of the
* next challenge. Break the attributes loop
*/
/*
* If we get a word here, this is the beginning of the
* next challenge. Break the attributes loop
*/
if (lex == HTTPHL_WORD)
break;
@ -832,10 +832,10 @@ http_parse_authenticate(const char *cp, http_auth_challenges_t *cs)
} /* End attributes loop */
} /* End challenge loop */
/*
* Challenges max count exceeded. This really can't happen
* with normal data, something's fishy -> error
*/
/*
* Challenges max count exceeded. This really can't happen
* with normal data, something's fishy -> error
*/
out:
if (key)
@ -1011,16 +1011,16 @@ init_http_auth_params(http_auth_params_t *s)
s->scheme = s->realm = s->user = s->password = 0;
}
static void
static void
clean_http_auth_params(http_auth_params_t *s)
{
if (s->scheme)
if (s->scheme)
free(s->scheme);
if (s->realm)
if (s->realm)
free(s->realm);
if (s->user)
if (s->user)
free(s->user);
if (s->password)
if (s->password)
free(s->password);
init_http_auth_params(s);
}
@ -1075,7 +1075,7 @@ http_authfromenv(const char *p, http_auth_params_t *parms)
}
ret = 0;
out:
if (ret == -1)
if (ret == -1)
clean_http_auth_params(parms);
if (str)
free(str);
@ -1083,11 +1083,11 @@ http_authfromenv(const char *p, http_auth_params_t *parms)
}
/*
/*
* Digest response: the code to compute the digest is taken from the
* sample implementation in RFC2616
* sample implementation in RFC2616
*/
#define IN
#define IN const
#define OUT
#define HASHLEN 16
@ -1096,7 +1096,7 @@ typedef char HASH[HASHLEN];
typedef char HASHHEX[HASHHEXLEN+1];
static const char *hexchars = "0123456789abcdef";
static void
static void
CvtHex(IN HASH Bin, OUT HASHHEX Hex)
{
unsigned short i;
@ -1112,7 +1112,7 @@ CvtHex(IN HASH Bin, OUT HASHHEX Hex)
};
/* calculate H(A1) as per spec */
static void
static void
DigestCalcHA1(
IN char * pszAlg,
IN char * pszUserName,
@ -1147,7 +1147,7 @@ DigestCalcHA1(
}
/* calculate request-digest/response-digest as per HTTP Digest spec */
static void
static void
DigestCalcResponse(
IN HASHHEX HA1, /* H(A1) */
IN char * pszNonce, /* nonce from server */
@ -1160,7 +1160,7 @@ DigestCalcResponse(
OUT HASHHEX Response /* request-digest or response-digest */
)
{
/* DEBUG(fprintf(stderr,
/* DEBUG(fprintf(stderr,
"Calc: HA1[%s] Nonce[%s] qop[%s] method[%s] URI[%s]\n",
HA1, pszNonce, pszQop, pszMethod, pszDigestUri));*/
MD5_CTX Md5Ctx;
@ -1199,8 +1199,8 @@ DigestCalcResponse(
CvtHex(RespHash, Response);
}
/*
* Generate/Send a Digest authorization header
/*
* Generate/Send a Digest authorization header
* This looks like: [Proxy-]Authorization: credentials
*
* credentials = "Digest" digest-response
@ -1233,10 +1233,10 @@ http_digest_auth(conn_t *conn, const char *hdr, http_auth_challenge_t *c,
DEBUG(fprintf(stderr, "realm/nonce not set in challenge\n"));
return(-1);
}
if (!c->algo)
if (!c->algo)
c->algo = strdup("");
if (asprintf(&options, "%s%s%s%s",
if (asprintf(&options, "%s%s%s%s",
*c->algo? ",algorithm=" : "", c->algo,
c->opaque? ",opaque=" : "", c->opaque?c->opaque:"")== -1)
return (-1);
@ -1264,13 +1264,13 @@ http_digest_auth(conn_t *conn, const char *hdr, http_auth_challenge_t *c,
r = http_cmd(conn, "%s: Digest username=\"%s\",realm=\"%s\","
"nonce=\"%s\",uri=\"%s\",response=\"%s\","
"qop=\"auth\", cnonce=\"%s\", nc=%s%s",
hdr, parms->user, c->realm,
hdr, parms->user, c->realm,
c->nonce, url->doc, digest,
cnonce, noncecount, options);
} else {
r = http_cmd(conn, "%s: Digest username=\"%s\",realm=\"%s\","
"nonce=\"%s\",uri=\"%s\",response=\"%s\"%s",
hdr, parms->user, c->realm,
hdr, parms->user, c->realm,
c->nonce, url->doc, digest, options);
}
if (options)
@ -1301,7 +1301,7 @@ http_basic_auth(conn_t *conn, const char *hdr, const char *usr, const char *pwd)
}
/*
* Chose the challenge to answer and call the appropriate routine to
* Chose the challenge to answer and call the appropriate routine to
* produce the header.
*/
static int
@ -1327,16 +1327,16 @@ http_authorize(conn_t *conn, const char *hdr, http_auth_challenges_t *cs,
}
/* Error if "Digest" was specified and there is no Digest challenge */
if (!digest && (parms->scheme &&
if (!digest && (parms->scheme &&
!strcasecmp(parms->scheme, "digest"))) {
DEBUG(fprintf(stderr,
DEBUG(fprintf(stderr,
"Digest auth in env, not supported by peer\n"));
return (-1);
}
/*
* If "basic" was specified in the environment, or there is no Digest
/*
* If "basic" was specified in the environment, or there is no Digest
* challenge, do the basic thing. Don't need a challenge for this,
* so no need to check basic!=NULL
* so no need to check basic!=NULL
*/
if (!digest || (parms->scheme && !strcasecmp(parms->scheme,"basic")))
return (http_basic_auth(conn,hdr,parms->user,parms->password));
@ -1492,7 +1492,7 @@ http_request(struct url *URL, const char *op, struct url_stat *us,
http_auth_challenges_t proxy_challenges;
/* The following calls don't allocate anything */
init_http_headerbuf(&headerbuf);
init_http_headerbuf(&headerbuf);
init_http_auth_challenges(&server_challenges);
init_http_auth_challenges(&proxy_challenges);
@ -1578,65 +1578,65 @@ http_request(struct url *URL, const char *op, struct url_stat *us,
/* virtual host */
http_cmd(conn, "Host: %s", host);
/*
* Proxy authorization: we only send auth after we received
* a 407 error. We do not first try basic anyway (changed
* when support was added for digest-auth)
*/
/*
* Proxy authorization: we only send auth after we received
* a 407 error. We do not first try basic anyway (changed
* when support was added for digest-auth)
*/
if (purl && proxy_challenges.valid) {
http_auth_params_t aparams;
init_http_auth_params(&aparams);
if (*purl->user || *purl->pwd) {
aparams.user = purl->user ?
aparams.user = purl->user ?
strdup(purl->user) : strdup("");
aparams.password = purl->pwd?
strdup(purl->pwd) : strdup("");
} else if ((p = getenv("HTTP_PROXY_AUTH")) != NULL &&
} else if ((p = getenv("HTTP_PROXY_AUTH")) != NULL &&
*p != '\0') {
if (http_authfromenv(p, &aparams) < 0) {
http_seterr(HTTP_NEED_PROXY_AUTH);
goto ouch;
}
}
http_authorize(conn, "Proxy-Authorization",
http_authorize(conn, "Proxy-Authorization",
&proxy_challenges, &aparams, url);
clean_http_auth_params(&aparams);
}
/*
* Server authorization: we never send "a priori"
/*
* Server authorization: we never send "a priori"
* Basic auth, which used to be done if user/pass were
* set in the url. This would be weird because we'd send the
* password in the clear even if Digest is finally to be
* password in the clear even if Digest is finally to be
* used (it would have made more sense for the
* pre-digest version to do this when Basic was specified
* in the environment)
*/
* pre-digest version to do this when Basic was specified
* in the environment)
*/
if (server_challenges.valid) {
http_auth_params_t aparams;
init_http_auth_params(&aparams);
if (*url->user || *url->pwd) {
aparams.user = url->user ?
aparams.user = url->user ?
strdup(url->user) : strdup("");
aparams.password = url->pwd ?
aparams.password = url->pwd ?
strdup(url->pwd) : strdup("");
} else if ((p = getenv("HTTP_AUTH")) != NULL &&
} else if ((p = getenv("HTTP_AUTH")) != NULL &&
*p != '\0') {
if (http_authfromenv(p, &aparams) < 0) {
http_seterr(HTTP_NEED_AUTH);
goto ouch;
}
} else if (fetchAuthMethod &&
} else if (fetchAuthMethod &&
fetchAuthMethod(url) == 0) {
aparams.user = url->user ?
aparams.user = url->user ?
strdup(url->user) : strdup("");
aparams.password = url->pwd ?
aparams.password = url->pwd ?
strdup(url->pwd) : strdup("");
} else {
http_seterr(HTTP_NEED_AUTH);
goto ouch;
}
http_authorize(conn, "Authorization",
http_authorize(conn, "Authorization",
&server_challenges, &aparams, url);
clean_http_auth_params(&aparams);
}
@ -1804,12 +1804,12 @@ http_request(struct url *URL, const char *op, struct url_stat *us,
} while (h > hdr_end);
/* we need to provide authentication */
if (conn->err == HTTP_NEED_AUTH ||
if (conn->err == HTTP_NEED_AUTH ||
conn->err == HTTP_NEED_PROXY_AUTH) {
e = conn->err;
if ((conn->err == HTTP_NEED_AUTH &&
!server_challenges.valid) ||
(conn->err == HTTP_NEED_PROXY_AUTH &&
if ((conn->err == HTTP_NEED_AUTH &&
!server_challenges.valid) ||
(conn->err == HTTP_NEED_PROXY_AUTH &&
!proxy_challenges.valid)) {
/* 401/7 but no www/proxy-authenticate ?? */
DEBUG(fprintf(stderr, "401/7 and no auth header\n"));

View File

@ -9,7 +9,6 @@ SRCS= cd9660.c \
libprocstat.c \
msdosfs.c \
ntfs.c \
nwfs.c \
smbfs.c \
udf.c
@ -18,9 +17,14 @@ CFLAGS+= -I. -I${.CURDIR} -D_KVM_VNODE
SHLIB_MAJOR= 1
WITHOUT_MAN= yes
.if ${MK_NCP} != "no"
CFLAGS+= -DLIBPROCSTAT_NWFS
SRCS+= nwfs.c
.endif
# XXX This is a hack.
.if ${MK_CDDL} != "no"
CFLAGS+= -DZFS
CFLAGS+= -DLIBPROCSTAT_ZFS
OBJS+= zfs/zfs.o
SOBJS+= zfs/zfs.So
POBJS+= zfs/zfs.po

View File

@ -873,11 +873,13 @@ procstat_get_vnode_info_kvm(kvm_t *kd, struct filestat *fst,
FSTYPE(msdosfs),
FSTYPE(nfs),
FSTYPE(ntfs),
#ifdef LIBPROCSTAT_NWFS
FSTYPE(nwfs),
#endif
FSTYPE(smbfs),
FSTYPE(udf),
FSTYPE(ufs),
#ifdef ZFS
#ifdef LIBPROCSTAT_ZFS
FSTYPE(zfs),
#endif
};

View File

@ -24,6 +24,7 @@
# into base-bits-dir as part of making the image.
if [ "x$1" = "x-b" ]; then
# Apple boot code
uudecode -o /tmp/hfs-boot-block.bz2 `dirname $0`/hfs-boot.bz2.uu
bzip2 -d /tmp/hfs-boot-block.bz2
OFFSET=$(hd /tmp/hfs-boot-block | grep 'Loader START' | cut -f 1 -d ' ')
@ -31,6 +32,17 @@ if [ "x$1" = "x-b" ]; then
dd if=$4/boot/loader of=/tmp/hfs-boot-block seek=$OFFSET conv=notrunc
bootable="-o bootimage=macppc;/tmp/hfs-boot-block -o no-emul-boot"
# pSeries/PAPR boot code
mkdir -p $4/ppc/chrp
cp $4/boot/loader $4/ppc/chrp
cat > $4/ppc/bootinfo.txt << EOF
<chrp-boot>
<description>FreeBSD Install</description>
<os-name>FreeBSD</os-name>
<boot-script>boot &device;:&partition;,\ppc\chrp\loader</boot-script>
</chrp-boot>
EOF
shift
else
bootable=""
@ -48,3 +60,5 @@ echo "/dev/iso9660/`echo $LABEL | tr '[:lower:]' '[:upper:]'` / cd9660 ro 0 0" >
makefs -t cd9660 $bootable -o rockridge -o label=$LABEL $NAME $*
rm $1/etc/fstab
rm /tmp/hfs-boot-block
rm -rf $1/ppc

View File

@ -237,6 +237,15 @@ extern HAL_BOOL ar5416GetChipPowerLimits(struct ath_hal *ah,
struct ieee80211_channel *chan);
extern void ar5416GetChannelCenters(struct ath_hal *,
const struct ieee80211_channel *chan, CHAN_CENTERS *centers);
extern void ar5416SetRatesArrayFromTargetPower(struct ath_hal *ah,
const struct ieee80211_channel *chan,
int16_t *ratesArray,
const CAL_TARGET_POWER_LEG *targetPowerCck,
const CAL_TARGET_POWER_LEG *targetPowerCckExt,
const CAL_TARGET_POWER_LEG *targetPowerOfdm,
const CAL_TARGET_POWER_LEG *targetPowerOfdmExt,
const CAL_TARGET_POWER_HT *targetPowerHt20,
const CAL_TARGET_POWER_HT *targetPowerHt40);
extern void ar5416GetTargetPowers(struct ath_hal *ah,
const struct ieee80211_channel *chan,
CAL_TARGET_POWER_HT *powInfo,

View File

@ -492,8 +492,9 @@ ar5416PerCalibrationN(struct ath_hal *ah, struct ieee80211_channel *chan,
if (AH5416(ah)->ah_cal_pacal)
AH5416(ah)->ah_cal_pacal(ah, AH_FALSE);
/* Do temperature compensation if the chipset needs it */
AH5416(ah)->ah_olcTempCompensation(ah);
/* Do open-loop temperature compensation if the chipset needs it */
if (ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL))
AH5416(ah)->ah_olcTempCompensation(ah);
/*
* Get the value from the previous NF cal

View File

@ -202,8 +202,11 @@ ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode,
*/
ar5416InitChainMasks(ah);
/* Setup the open-loop temperature compensation if required */
AH5416(ah)->ah_olcInit(ah);
/* Setup the open-loop power calibration if required */
if (ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) {
AH5416(ah)->ah_olcInit(ah);
AH5416(ah)->ah_olcTempCompensation(ah);
}
/* Setup the transmit power values. */
if (!ah->ah_setTxPower(ah, chan, rfXpdGain)) {
@ -1634,6 +1637,63 @@ ar5416SetBoardValues(struct ath_hal *ah, const struct ieee80211_channel *chan)
* Helper functions common for AP/CB/XB
*/
/*
* Set the target power array "ratesArray" from the
* given set of target powers.
*
* This is used by the various chipset/EEPROM TX power
* setup routines.
*/
void
ar5416SetRatesArrayFromTargetPower(struct ath_hal *ah,
const struct ieee80211_channel *chan,
int16_t *ratesArray,
const CAL_TARGET_POWER_LEG *targetPowerCck,
const CAL_TARGET_POWER_LEG *targetPowerCckExt,
const CAL_TARGET_POWER_LEG *targetPowerOfdm,
const CAL_TARGET_POWER_LEG *targetPowerOfdmExt,
const CAL_TARGET_POWER_HT *targetPowerHt20,
const CAL_TARGET_POWER_HT *targetPowerHt40)
{
#define N(a) (sizeof(a)/sizeof(a[0]))
int i;
/* Blank the rates array, to be consistent */
for (i = 0; i < Ar5416RateSize; i++)
ratesArray[i] = 0;
/* Set rates Array from collected data */
ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
ratesArray[rate18mb] = ratesArray[rate24mb] = targetPowerOfdm->tPow2x[0];
ratesArray[rate36mb] = targetPowerOfdm->tPow2x[1];
ratesArray[rate48mb] = targetPowerOfdm->tPow2x[2];
ratesArray[rate54mb] = targetPowerOfdm->tPow2x[3];
ratesArray[rateXr] = targetPowerOfdm->tPow2x[0];
for (i = 0; i < N(targetPowerHt20->tPow2x); i++) {
ratesArray[rateHt20_0 + i] = targetPowerHt20->tPow2x[i];
}
if (IEEE80211_IS_CHAN_2GHZ(chan)) {
ratesArray[rate1l] = targetPowerCck->tPow2x[0];
ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck->tPow2x[1];
ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck->tPow2x[2];
ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck->tPow2x[3];
}
if (IEEE80211_IS_CHAN_HT40(chan)) {
for (i = 0; i < N(targetPowerHt40->tPow2x); i++) {
ratesArray[rateHt40_0 + i] = targetPowerHt40->tPow2x[i];
}
ratesArray[rateDupOfdm] = targetPowerHt40->tPow2x[0];
ratesArray[rateDupCck] = targetPowerHt40->tPow2x[0];
ratesArray[rateExtOfdm] = targetPowerOfdmExt->tPow2x[0];
if (IEEE80211_IS_CHAN_2GHZ(chan)) {
ratesArray[rateExtCck] = targetPowerCckExt->tPow2x[0];
}
}
#undef N
}
/*
* ar5416SetPowerPerRateTable
*
@ -1855,33 +1915,13 @@ ar5416SetPowerPerRateTable(struct ath_hal *ah, struct ar5416eeprom *pEepData,
} /* end ctl mode checking */
/* Set rates Array from collected data */
ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] = ratesArray[rate18mb] = ratesArray[rate24mb] = targetPowerOfdm.tPow2x[0];
ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
for (i = 0; i < N(targetPowerHt20.tPow2x); i++) {
ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
}
if (IEEE80211_IS_CHAN_2GHZ(chan)) {
ratesArray[rate1l] = targetPowerCck.tPow2x[0];
ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1];
ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2];
ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3];
}
if (IEEE80211_IS_CHAN_HT40(chan)) {
for (i = 0; i < N(targetPowerHt40.tPow2x); i++) {
ratesArray[rateHt40_0 + i] = targetPowerHt40.tPow2x[i];
}
ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
if (IEEE80211_IS_CHAN_2GHZ(chan)) {
ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0];
}
}
ar5416SetRatesArrayFromTargetPower(ah, chan, ratesArray,
&targetPowerCck,
&targetPowerCckExt,
&targetPowerOfdm,
&targetPowerOfdmExt,
&targetPowerHt20,
&targetPowerHt40);
return AH_TRUE;
#undef EXT_ADDITIVE
#undef CTL_11A_EXT

View File

@ -43,6 +43,12 @@ ar9280olcInit(struct ath_hal *ah)
{
uint32_t i;
/* Only do OLC if it's enabled for this chipset */
if (! ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL))
return;
HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Setting up TX gain tables.\n", __func__);
for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++)
AH9280(ah)->originalGain[i] = MS(OS_REG_READ(ah,
AR_PHY_TX_GAIN_TBL1 + i * 4), AR_PHY_TX_GAIN);
@ -126,6 +132,9 @@ ar9280olcTemperatureCompensation(struct ath_hal *ah)
int delta, currPDADC, regval;
uint8_t hpwr_5g = 0;
if (! ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL))
return;
rddata = OS_REG_READ(ah, AR_PHY_TX_PWRCTRL4);
currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);

View File

@ -368,27 +368,32 @@ ar9285_ant_comb_scan(struct ath_hal *ah, struct ath_rx_status *rs,
int curr_main_set, curr_bias;
int main_rssi = rs->rs_rssi_ctl[0];
int alt_rssi = rs->rs_rssi_ctl[1];
int rx_ant_conf, main_ant_conf;
int rx_ant_conf, main_ant_conf, alt_ant_conf;
HAL_BOOL short_scan = AH_FALSE;
rx_ant_conf = (rs->rs_rssi_ctl[2] >> 4) & ATH_ANT_RX_MASK;
main_ant_conf = (rs->rs_rssi_ctl[2] >> 2) & ATH_ANT_RX_MASK;
alt_ant_conf = (rs->rs_rssi_ctl[2] >> 0) & ATH_ANT_RX_MASK;
#if 0
HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: RSSI %d/%d, conf %x/%x, rxconf %x, LNA: %d; ANT: %d; FastDiv: %d\n",
__func__, main_rssi, alt_rssi, main_ant_conf,alt_ant_conf, rx_ant_conf,
!!(rs->rs_rssi_ctl[2] & 0x80), !!(rs->rs_rssi_ctl[2] & 0x40), !!(rs->rs_rssi_ext[2] & 0x40));
#endif
if (! ar9285_check_div_comb(ah))
return;
if (AH5212(ah)->ah_diversity == AH_FALSE)
return;
rx_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_CURRENT_SHIFT) &
ATH_ANT_RX_MASK;
main_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_MAIN_SHIFT) &
ATH_ANT_RX_MASK;
#if 0
HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: main: %d, alt: %d, rx_ant_conf: %x, main_ant_conf: %x\n",
__func__, main_rssi, alt_rssi, rx_ant_conf, main_ant_conf);
#endif
/* Record packet only when alt_rssi is positive */
if (alt_rssi > 0) {
if (main_rssi > 0 && alt_rssi > 0) {
antcomb->total_pkt_count++;
antcomb->main_total_rssi += main_rssi;
antcomb->alt_total_rssi += alt_rssi;
@ -613,13 +618,13 @@ ar9285_ant_comb_scan(struct ath_hal *ah, struct ath_rx_status *rs,
HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: alt_recv_cnt=%d\n",
__func__, antcomb->alt_recv_cnt);
if (curr_alt_set != div_ant_conf.alt_lna_conf)
// if (curr_alt_set != div_ant_conf.alt_lna_conf)
HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: lna_conf: %x -> %x\n",
__func__, curr_alt_set, div_ant_conf.alt_lna_conf);
if (curr_main_set != div_ant_conf.main_lna_conf)
// if (curr_main_set != div_ant_conf.main_lna_conf)
HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: main_lna_conf: %x -> %x\n",
__func__, curr_main_set, div_ant_conf.main_lna_conf);
if (curr_bias != div_ant_conf.fast_div_bias)
// if (curr_bias != div_ant_conf.fast_div_bias)
HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: fast_div_bias: %x -> %x\n",
__func__, curr_bias, div_ant_conf.fast_div_bias);

View File

@ -533,32 +533,15 @@ ar9285SetPowerPerRateTable(struct ath_hal *ah, struct ar5416eeprom_4k *pEepData,
}
} /* end ctl mode checking */
/* Set rates Array from collected data */
ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] = ratesArray[rate18mb] = ratesArray[rate24mb] = targetPowerOfdm.tPow2x[0];
ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
/* Set rates Array from collected data */
ar5416SetRatesArrayFromTargetPower(ah, chan, ratesArray,
&targetPowerCck,
&targetPowerCckExt,
&targetPowerOfdm,
&targetPowerOfdmExt,
&targetPowerHt20,
&targetPowerHt40);
for (i = 0; i < N(targetPowerHt20.tPow2x); i++) {
ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
}
ratesArray[rate1l] = targetPowerCck.tPow2x[0];
ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1];
ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2];
ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3];
if (IEEE80211_IS_CHAN_HT40(chan)) {
for (i = 0; i < N(targetPowerHt40.tPow2x); i++) {
ratesArray[rateHt40_0 + i] = targetPowerHt40.tPow2x[i];
}
ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
if (IEEE80211_IS_CHAN_2GHZ(chan)) {
ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0];
}
}
return AH_TRUE;
#undef EXT_ADDITIVE
#undef CTL_11G_EXT

View File

@ -1946,17 +1946,15 @@ ath_calcrxfilter(struct ath_softc *sc)
IEEE80211_IS_CHAN_ANYG(ic->ic_curchan))
rfilt |= HAL_RX_FILTER_BEACON;
#if 0
/*
* Enable hardware PS-POLL RX only for hostap mode;
* STA mode sends PS-POLL frames but never
* receives them.
*/
if (ath_hal_getcapability(ah, HAL_CAP_HAS_PSPOLL,
if (ath_hal_getcapability(sc->sc_ah, HAL_CAP_PSPOLL,
0, NULL) == HAL_OK &&
ic->ic_opmode == IEEE80211_M_HOSTAP)
rfilt |= HAL_RX_FILTER_PSPOLL;
#endif
if (sc->sc_nmeshvaps) {
rfilt |= HAL_RX_FILTER_BEACON;

View File

@ -171,6 +171,7 @@ static const struct bge_type {
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5715S },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5717 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5718 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5719 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5720 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5721 },
{ BCOM_VENDORID, BCOM_DEVICEID_BCM5722 },
@ -299,6 +300,7 @@ static const struct bge_revision {
{ BGE_CHIPID_BCM5715_A3, "BCM5715 A3" },
{ BGE_CHIPID_BCM5717_A0, "BCM5717 A0" },
{ BGE_CHIPID_BCM5717_B0, "BCM5717 B0" },
{ BGE_CHIPID_BCM5719_A0, "BCM5719 A0" },
{ BGE_CHIPID_BCM5755_A0, "BCM5755 A0" },
{ BGE_CHIPID_BCM5755_A1, "BCM5755 A1" },
{ BGE_CHIPID_BCM5755_A2, "BCM5755 A2" },
@ -346,6 +348,7 @@ static const struct bge_revision const bge_majorrevs[] = {
{ BGE_ASICREV_BCM57765, "unknown BCM57765" },
{ BGE_ASICREV_BCM57780, "unknown BCM57780" },
{ BGE_ASICREV_BCM5717, "unknown BCM5717" },
{ BGE_ASICREV_BCM5719, "unknown BCM5719" },
{ 0, NULL }
};
@ -1481,6 +1484,14 @@ bge_chipinit(struct bge_softc *sc)
dma_rw_ctl &= ~BGE_PCIDMARWCTL_DIS_CACHE_ALIGNMENT;
if (sc->bge_chipid == BGE_CHIPID_BCM57765_A0)
dma_rw_ctl &= ~BGE_PCIDMARWCTL_CRDRDR_RDMA_MRRS_MSK;
/*
* Enable HW workaround for controllers that misinterpret
* a status tag update and leave interrupts permanently
* disabled.
*/
if (sc->bge_asicrev != BGE_ASICREV_BCM5717 &&
sc->bge_asicrev != BGE_ASICREV_BCM57765)
dma_rw_ctl |= BGE_PCIDMARWCTL_TAGGED_STATUS_WA;
}
pci_write_config(sc->bge_dev, BGE_PCI_DMA_RW_CTL, dma_rw_ctl, 4);
@ -1537,7 +1548,7 @@ bge_blockinit(struct bge_softc *sc)
struct bge_rcb *rcb;
bus_size_t vrcb;
bge_hostaddr taddr;
uint32_t val;
uint32_t dmactl, val;
int i, limit;
/*
@ -1594,8 +1605,16 @@ bge_blockinit(struct bge_softc *sc)
CSR_WRITE_4(sc, BGE_BMAN_DMA_DESCPOOL_HIWAT, 10);
/* Enable buffer manager */
CSR_WRITE_4(sc, BGE_BMAN_MODE,
BGE_BMANMODE_ENABLE | BGE_BMANMODE_LOMBUF_ATTN);
val = BGE_BMANMODE_ENABLE | BGE_BMANMODE_LOMBUF_ATTN;
/*
* Change the arbitration algorithm of TXMBUF read request to
* round-robin instead of priority based for BCM5719. When
* TXFIFO is almost empty, RDMA will hold its request until
* TXFIFO is not almost empty.
*/
if (sc->bge_asicrev == BGE_ASICREV_BCM5719)
val |= BGE_BMANMODE_NO_TX_UNDERRUN;
CSR_WRITE_4(sc, BGE_BMAN_MODE, val);
/* Poll for buffer manager start indication */
for (i = 0; i < BGE_TIMEOUT; i++) {
@ -1692,7 +1711,8 @@ bge_blockinit(struct bge_softc *sc)
rcb->bge_maxlen_flags =
BGE_RCB_MAXLEN_FLAGS(BGE_MAX_FRAMELEN, 0);
}
if (sc->bge_asicrev == BGE_ASICREV_BCM5717)
if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
sc->bge_asicrev == BGE_ASICREV_BCM5719)
rcb->bge_nicaddr = BGE_STD_RX_RINGS_5717;
else
rcb->bge_nicaddr = BGE_STD_RX_RINGS;
@ -1724,7 +1744,8 @@ bge_blockinit(struct bge_softc *sc)
BUS_DMASYNC_PREREAD);
rcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(0,
BGE_RCB_FLAG_USE_EXT_RX_BD | BGE_RCB_FLAG_RING_DISABLED);
if (sc->bge_asicrev == BGE_ASICREV_BCM5717)
if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
sc->bge_asicrev == BGE_ASICREV_BCM5719)
rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS_5717;
else
rcb->bge_nicaddr = BGE_JUMBO_RX_RINGS;
@ -1812,7 +1833,8 @@ bge_blockinit(struct bge_softc *sc)
BGE_HOSTADDR(taddr, sc->bge_ldata.bge_tx_ring_paddr);
RCB_WRITE_4(sc, vrcb, bge_hostaddr.bge_addr_hi, taddr.bge_addr_hi);
RCB_WRITE_4(sc, vrcb, bge_hostaddr.bge_addr_lo, taddr.bge_addr_lo);
if (sc->bge_asicrev == BGE_ASICREV_BCM5717)
if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
sc->bge_asicrev == BGE_ASICREV_BCM5719)
RCB_WRITE_4(sc, vrcb, bge_nicaddr, BGE_SEND_RING_5717);
else
RCB_WRITE_4(sc, vrcb, bge_nicaddr,
@ -1825,7 +1847,8 @@ bge_blockinit(struct bge_softc *sc)
* 'ring diabled' bit in the flags field of all the receive
* return ring control blocks, located in NIC memory.
*/
if (sc->bge_asicrev == BGE_ASICREV_BCM5717) {
if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
sc->bge_asicrev == BGE_ASICREV_BCM5719) {
/* Should be 17, use 16 until we get an SRAM map. */
limit = 16;
} else if (!BGE_IS_5705_PLUS(sc))
@ -2029,15 +2052,35 @@ bge_blockinit(struct bge_softc *sc)
sc->bge_asicrev == BGE_ASICREV_BCM5785 ||
sc->bge_asicrev == BGE_ASICREV_BCM57780 ||
BGE_IS_5717_PLUS(sc)) {
dmactl = CSR_READ_4(sc, BGE_RDMA_RSRVCTRL);
/*
* Adjust tx margin to prevent TX data corruption and
* fix internal FIFO overflow.
*/
if (sc->bge_asicrev == BGE_ASICREV_BCM5719) {
dmactl &= ~(BGE_RDMA_RSRVCTRL_FIFO_LWM_MASK |
BGE_RDMA_RSRVCTRL_FIFO_HWM_MASK |
BGE_RDMA_RSRVCTRL_TXMRGN_MASK);
dmactl |= BGE_RDMA_RSRVCTRL_FIFO_LWM_1_5K |
BGE_RDMA_RSRVCTRL_FIFO_HWM_1_5K |
BGE_RDMA_RSRVCTRL_TXMRGN_320B;
}
/*
* Enable fix for read DMA FIFO overruns.
* The fix is to limit the number of RX BDs
* the hardware would fetch at a fime.
*/
CSR_WRITE_4(sc, BGE_RDMA_RSRVCTRL,
CSR_READ_4(sc, BGE_RDMA_RSRVCTRL) |
CSR_WRITE_4(sc, BGE_RDMA_RSRVCTRL, dmactl |
BGE_RDMA_RSRVCTRL_FIFO_OFLW_FIX);
}
if (sc->bge_asicrev == BGE_ASICREV_BCM5719) {
CSR_WRITE_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL,
CSR_READ_4(sc, BGE_RDMA_LSO_CRPTEN_CTRL) |
BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_4K |
BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K);
}
CSR_WRITE_4(sc, BGE_RDMA_MODE, val);
DELAY(40);
@ -2189,6 +2232,7 @@ bge_probe(device_t dev)
switch (pci_get_device(dev)) {
case BCOM_DEVICEID_BCM5717:
case BCOM_DEVICEID_BCM5718:
case BCOM_DEVICEID_BCM5719:
id = pci_read_config(dev,
BGE_PCI_GEN2_PRODID_ASICREV, 4);
break;
@ -2712,6 +2756,7 @@ bge_attach(device_t dev)
switch (pci_get_device(dev)) {
case BCOM_DEVICEID_BCM5717:
case BCOM_DEVICEID_BCM5718:
case BCOM_DEVICEID_BCM5719:
sc->bge_chipid = pci_read_config(dev,
BGE_PCI_GEN2_PRODID_ASICREV, 4);
break;
@ -2742,11 +2787,13 @@ bge_attach(device_t dev)
* BCM57XX | 1 | X | X | X |
* BCM5704 | 1 | X | 1 | X |
* BCM5717 | 1 | 8 | 2 | 9 |
* BCM5719 | 1 | 8 | 2 | 9 |
*
* Other addresses may respond but they are not
* IEEE compliant PHYs and should be ignored.
*/
if (sc->bge_asicrev == BGE_ASICREV_BCM5717) {
if (sc->bge_asicrev == BGE_ASICREV_BCM5717 ||
sc->bge_asicrev == BGE_ASICREV_BCM5719) {
f = pci_get_function(dev);
if (sc->bge_chipid == BGE_CHIPID_BCM5717_A0) {
if (CSR_READ_4(sc, BGE_SGDIG_STS) &
@ -2754,7 +2801,7 @@ bge_attach(device_t dev)
phy_addr = f + 8;
else
phy_addr = f + 1;
} else if (sc->bge_chipid == BGE_CHIPID_BCM5717_B0) {
} else {
if (CSR_READ_4(sc, BGE_CPMU_PHY_STRAP) &
BGE_CPMU_PHY_STRAP_IS_SERDES)
phy_addr = f + 8;
@ -2780,11 +2827,17 @@ bge_attach(device_t dev)
/* Save chipset family. */
switch (sc->bge_asicrev) {
case BGE_ASICREV_BCM5717:
case BGE_ASICREV_BCM5719:
sc->bge_flags |= BGE_FLAG_SHORT_DMA_BUG;
case BGE_ASICREV_BCM57765:
sc->bge_flags |= BGE_FLAG_5717_PLUS | BGE_FLAG_5755_PLUS |
BGE_FLAG_575X_PLUS | BGE_FLAG_5705_PLUS | BGE_FLAG_JUMBO |
BGE_FLAG_JUMBO_FRAME;
if (sc->bge_asicrev == BGE_ASICREV_BCM5719 &&
sc->bge_chipid == BGE_CHIPID_BCM5719_A0) {
/* Jumbo frame on BCM5719 A0 does not work. */
sc->bge_flags &= ~BGE_FLAG_JUMBO_FRAME;
}
break;
case BGE_ASICREV_BCM5755:
case BGE_ASICREV_BCM5761:
@ -2832,6 +2885,7 @@ bge_attach(device_t dev)
if ((BGE_IS_5705_PLUS(sc)) &&
sc->bge_asicrev != BGE_ASICREV_BCM5906 &&
sc->bge_asicrev != BGE_ASICREV_BCM5717 &&
sc->bge_asicrev != BGE_ASICREV_BCM5719 &&
sc->bge_asicrev != BGE_ASICREV_BCM5785 &&
sc->bge_asicrev != BGE_ASICREV_BCM57765 &&
sc->bge_asicrev != BGE_ASICREV_BCM57780) {
@ -2914,6 +2968,11 @@ bge_attach(device_t dev)
if (BGE_IS_5717_PLUS(sc)) {
/* BCM5717 requires different TSO configuration. */
sc->bge_flags |= BGE_FLAG_TSO3;
if (sc->bge_asicrev == BGE_ASICREV_BCM5719 &&
sc->bge_chipid == BGE_CHIPID_BCM5719_A0) {
/* TSO on BCM5719 A0 does not work. */
sc->bge_flags &= ~BGE_FLAG_TSO3;
}
} else if (BGE_IS_5755_PLUS(sc)) {
/*
* BCM5754 and BCM5787 shares the same ASIC id so
@ -2936,7 +2995,9 @@ bge_attach(device_t dev)
*/
sc->bge_flags |= BGE_FLAG_PCIE;
sc->bge_expcap = reg;
if (pci_get_max_read_req(dev) != 4096)
if (sc->bge_asicrev == BGE_ASICREV_BCM5719)
pci_set_max_read_req(dev, 2048);
else if (pci_get_max_read_req(dev) != 4096)
pci_set_max_read_req(dev, 4096);
} else {
/*

View File

@ -319,6 +319,7 @@
#define BGE_CHIPID_BCM57780_A1 0x57780001
#define BGE_CHIPID_BCM5717_A0 0x05717000
#define BGE_CHIPID_BCM5717_B0 0x05717100
#define BGE_CHIPID_BCM5719_A0 0x05719000
#define BGE_CHIPID_BCM57765_A0 0x57785000
#define BGE_CHIPID_BCM57765_B0 0x57785100
@ -342,6 +343,7 @@
#define BGE_ASICREV_USE_PRODID_REG 0x0f
/* BGE_PCI_PRODID_ASICREV ASIC rev. identifiers. */
#define BGE_ASICREV_BCM5717 0x5717
#define BGE_ASICREV_BCM5719 0x5719
#define BGE_ASICREV_BCM5761 0x5761
#define BGE_ASICREV_BCM5784 0x5784
#define BGE_ASICREV_BCM5785 0x5785
@ -385,6 +387,7 @@
#define BGE_PCIDMARWCTL_RD_CMD_SHIFT(x) ((x) << 24)
#define BGE_PCIDMARWCTL_WR_CMD_SHIFT(x) ((x) << 28)
#define BGE_PCIDMARWCTL_TAGGED_STATUS_WA 0x00000080
#define BGE_PCIDMARWCTL_CRDRDR_RDMA_MRRS_MSK 0x00000380
#define BGE_PCI_READ_BNDRY_DISABLE 0x00000000
@ -1494,6 +1497,7 @@
#define BGE_BMANMODE_ATTN 0x00000004
#define BGE_BMANMODE_TESTMODE 0x00000008
#define BGE_BMANMODE_LOMBUF_ATTN 0x00000010
#define BGE_BMANMODE_NO_TX_UNDERRUN 0x80000000
/* Buffer manager status register */
#define BGE_BMANSTAT_ERRO 0x00000004
@ -1506,6 +1510,7 @@
#define BGE_RDMA_MODE 0x4800
#define BGE_RDMA_STATUS 0x4804
#define BGE_RDMA_RSRVCTRL 0x4900
#define BGE_RDMA_LSO_CRPTEN_CTRL 0x4910
/* Read DMA mode register */
#define BGE_RDMAMODE_RESET 0x00000001
@ -1540,6 +1545,15 @@
/* Read DMA Reserved Control register */
#define BGE_RDMA_RSRVCTRL_FIFO_OFLW_FIX 0x00000004
#define BGE_RDMA_RSRVCTRL_FIFO_LWM_1_5K 0x00000C00
#define BGE_RDMA_RSRVCTRL_FIFO_HWM_1_5K 0x000C0000
#define BGE_RDMA_RSRVCTRL_TXMRGN_320B 0x28000000
#define BGE_RDMA_RSRVCTRL_FIFO_LWM_MASK 0x00000FF0
#define BGE_RDMA_RSRVCTRL_FIFO_HWM_MASK 0x000FF000
#define BGE_RDMA_RSRVCTRL_TXMRGN_MASK 0xFFE00000
#define BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_4K 0x00030000
#define BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K 0x000C0000
/*
* Write DMA control registers
@ -2261,6 +2275,7 @@ struct bge_status_block {
#define BCOM_DEVICEID_BCM5715S 0x1679
#define BCOM_DEVICEID_BCM5717 0x1655
#define BCOM_DEVICEID_BCM5718 0x1656
#define BCOM_DEVICEID_BCM5719 0x1657
#define BCOM_DEVICEID_BCM5720 0x1658
#define BCOM_DEVICEID_BCM5721 0x1659
#define BCOM_DEVICEID_BCM5722 0x165A

View File

@ -1130,21 +1130,11 @@ bm_chip_setup(struct bm_softc *sc)
{
uint16_t reg;
uint16_t *eaddr_sect;
struct mii_data *mii;
struct mii_softc *miisc;
eaddr_sect = (uint16_t *)(sc->sc_enaddr);
dbdma_stop(sc->sc_txdma);
dbdma_stop(sc->sc_rxdma);
/* Reset MII */
mii = device_get_softc(sc->sc_miibus);
LIST_FOREACH(miisc, &mii->mii_phys, mii_list) {
PHY_RESET(miisc);
PHY_WRITE(miisc, MII_BMCR, PHY_READ(miisc, MII_BMCR) &
~BMCR_ISO);
}
/* Reset chip */
CSR_WRITE_2(sc, BM_RX_RESET, 0x0000);
CSR_WRITE_2(sc, BM_TX_RESET, 0x0001);

View File

@ -1330,9 +1330,9 @@ bxe_interrupt_attach(struct bxe_softc *sc)
/* Setup the slowpath deferred task queue. */
TASK_INIT(&sc->task, 0, bxe_task_sp, sc);
sc->tq = taskqueue_create_fast("bxe_spq", M_NOWAIT,
taskqueue_thread_enqueue, &sc->tq);
taskqueue_thread_enqueue, &sc->tq);
taskqueue_start_threads(&sc->tq, 1, PI_NET, "%s spq",
device_get_nameunit(sc->dev));
device_get_nameunit(sc->dev));
#endif
/* Setup interrupt handlers. */
@ -1359,13 +1359,19 @@ bxe_interrupt_attach(struct bxe_softc *sc)
goto bxe_interrupt_attach_exit;
}
#if __FreeBSD_version >= 800504
bus_describe_intr(sc->dev,
sc->bxe_msix_res[0],
sc->bxe_msix_tag[0],
"sp");
#endif
/* Now initialize the fastpath vectors. */
for (i = 0; i < (sc->num_queues); i++) {
fp = &sc->fp[i];
DBPRINT(sc,
(BXE_VERBOSE_LOAD | BXE_VERBOSE_INTR),
"%s(): Enabling MSI-X[%d] vector.\n",
__FUNCTION__, i + 1);
DBPRINT(sc, (BXE_VERBOSE_LOAD | BXE_VERBOSE_INTR),
"%s(): Enabling MSI-X[%d] vector.\n",
__FUNCTION__, i + 1);
/*
* Setup the interrupt handler. Note that we pass the
* fastpath context to the interrupt handler in this
@ -1377,8 +1383,7 @@ bxe_interrupt_attach(struct bxe_softc *sc)
NULL,
bxe_intr_fp,
fp,
&sc->bxe_msix_tag[i + 1]
);
&sc->bxe_msix_tag[i + 1]);
if (rc) {
BXE_PRINTF(
@ -1386,6 +1391,21 @@ bxe_interrupt_attach(struct bxe_softc *sc)
__FILE__, __LINE__, (i + 1));
goto bxe_interrupt_attach_exit;
}
#if __FreeBSD_version >= 800504
bus_describe_intr(sc->dev,
sc->bxe_msix_res[i + 1],
sc->bxe_msix_tag[i + 1],
"fp[%02d]",
i);
#endif
/* Bind the fastpath instance to a CPU. */
if (sc->num_queues > 1) {
bus_bind_intr(sc->dev,
sc->bxe_msix_res[i + 1], i);
}
#ifdef BXE_TASK
TASK_INIT(&fp->task, 0, bxe_task_fp, fp);
fp->tq = taskqueue_create_fast("bxe_fpq", M_NOWAIT,
@ -1418,6 +1438,13 @@ bxe_interrupt_attach(struct bxe_softc *sc)
goto bxe_interrupt_attach_exit;
}
#if __FreeBSD_version >= 800504
bus_describe_intr(sc->dev,
sc->bxe_msi_res[0],
sc->bxe_msi_tag[0],
"sp");
#endif
/* Now initialize the fastpath vectors. */
for (i = 0; i < (sc->num_queues); i++) {
fp = &sc->fp[i];
@ -1445,6 +1472,15 @@ bxe_interrupt_attach(struct bxe_softc *sc)
__FILE__, __LINE__, (i + 1));
goto bxe_interrupt_attach_exit;
}
#if __FreeBSD_version >= 800504
bus_describe_intr(sc->dev,
sc->bxe_msi_res[i + 1],
sc->bxe_msi_tag[i + 1],
"fp[%02d]",
i);
#endif
#ifdef BXE_TASK
TASK_INIT(&fp->task, 0, bxe_task_fp, fp);
fp->tq = taskqueue_create_fast("bxe_fpq", M_NOWAIT,
@ -3646,7 +3682,7 @@ bxe_alloc_buf_rings(struct bxe_softc *sc)
if (fp != NULL) {
fp->br = buf_ring_alloc(BXE_BR_SIZE,
M_DEVBUF, M_WAITOK, &fp->mtx);
M_DEVBUF, M_DONTWAIT, &fp->mtx);
if (fp->br == NULL) {
rc = ENOMEM;
return(rc);
@ -9404,7 +9440,7 @@ bxe_tx_mq_start(struct ifnet *ifp, struct mbuf *m)
/*
* Multiqueue (RSS) transmit routine.
* Multiqueue (TSS) transmit routine.
*
* Returns:
* 0 if transmit succeeds, !0 otherwise.
@ -9415,14 +9451,18 @@ bxe_tx_mq_start_locked(struct ifnet *ifp,
{
struct bxe_softc *sc;
struct mbuf *next;
int rc = 0, tx_count = 0;
int depth, rc = 0, tx_count = 0;
sc = fp->sc;
DBENTER(BXE_EXTREME_SEND);
depth = drbr_inuse(ifp, fp->br);
if (depth > fp->max_drbr_queue_depth) {
fp->max_drbr_queue_depth = depth;
}
DBPRINT(sc, BXE_EXTREME_SEND,
"%s(): fp[%02d], drbr queue depth=%d\n",
__FUNCTION__, fp->index, drbr_inuse(ifp, fp->br));
__FUNCTION__, fp->index, depth);
BXE_FP_LOCK_ASSERT(fp);
@ -10509,11 +10549,11 @@ bxe_alloc_mbuf(struct bxe_fastpath *fp, int size)
/* Check whether the allocation succeeded and handle a failure. */
if (__predict_false(m_new == NULL)) {
DBPRINT(sc, BXE_WARN, "%s(): mbuf allocation failure!\n",
__FUNCTION__);
DBPRINT(sc, BXE_WARN, "%s(): Failed to allocate %d byte "
"mbuf on fp[%02d]!\n", __FUNCTION__, size, fp->index);
fp->mbuf_alloc_failed++;
goto bxe_alloc_mbuf_exit;
}
goto bxe_alloc_mbuf_exit;
}
/* Do a little extra error checking when debugging. */
DBRUN(M_ASSERTPKTHDR(m_new));
@ -10556,7 +10596,7 @@ bxe_map_mbuf(struct bxe_fastpath *fp, struct mbuf *m, bus_dma_tag_t tag,
__FUNCTION__);
sc->debug_mbuf_sim_map_failed++;
fp->mbuf_alloc_failed++;
DBRUN(sc->debug_memory_allocated -= m->m_len);
sc->debug_memory_allocated -= m->m_len;
m_freem(m);
rc = EINVAL;
goto bxe_map_mbuf_exit;
@ -10568,10 +10608,11 @@ bxe_map_mbuf(struct bxe_fastpath *fp, struct mbuf *m, bus_dma_tag_t tag,
/* Handle any mapping errors. */
if (__predict_false(rc)) {
DBPRINT(sc, BXE_WARN, "%s(): mbuf mapping failure (%d)!\n",
__FUNCTION__, rc);
m_freem(m);
DBPRINT(sc, BXE_WARN, "%s(): mbuf mapping failure (%d) on "
"fp[%02d]!\n", __FUNCTION__, rc, fp->index);
fp->mbuf_alloc_failed++;
DBRUN(sc->debug_memory_allocated -= m->m_len);
m_freem(m);
goto bxe_map_mbuf_exit;
}
@ -10583,6 +10624,7 @@ bxe_map_mbuf(struct bxe_fastpath *fp, struct mbuf *m, bus_dma_tag_t tag,
*seg = segs[0];
bxe_map_mbuf_exit:
DBEXIT(BXE_INSANE);
return (rc);
}
@ -10961,6 +11003,19 @@ bxe_init_rx_chains(struct bxe_softc *sc)
}
}
/*
* ToDo: Need a cleanup path if memory allocation
* fails during initializtion. This is especially
* easy if multiqueue is used on a system with
* jumbo frames and many CPUs. On my 16GB system
* with 8 CPUs I get the following defaults:
*
* kern.ipc.nmbjumbo16: 3200
* kern.ipc.nmbjumbo9: 6400
* kern.ipc.nmbjumbop: 12800
* kern.ipc.nmbclusters: 25600
*/
DBEXIT(BXE_VERBOSE_LOAD | BXE_VERBOSE_RESET);
}
@ -15554,7 +15609,7 @@ bxe_txeof(struct bxe_fastpath *fp)
#endif
txbd =
&fp->tx_bd_chain[TX_PAGE(sw_tx_chain_cons)][TX_IDX(sw_tx_chain_cons)].start_bd;
&fp->tx_bd_chain[TX_PAGE(sw_tx_chain_cons)][TX_IDX(sw_tx_chain_cons)].start_bd;
#ifdef BXE_DEBUG
if (txbd == NULL) {
@ -15764,7 +15819,7 @@ bxe_change_mtu(struct bxe_softc *sc, int if_drv_running)
sc->bxe_ifp->if_mtu = ifp->if_mtu;
if (if_drv_running) {
DBPRINT(sc, BXE_INFO_IOCTL, "%s(): Changing the MTU to %d.\n",
__FUNCTION__, sc->port.ether_mtu);
__FUNCTION__, sc->bxe_ifp->if_mtu);
bxe_stop_locked(sc, UNLOAD_NORMAL);
bxe_init_locked(sc, LOAD_NORMAL);
@ -16315,6 +16370,12 @@ bxe_add_sysctls(struct bxe_softc *sc)
"tx_chain_lost_mbuf",
CTLFLAG_RD, &fp->tx_chain_lost_mbuf,
"Mbufs lost on TX chain count");
SYSCTL_ADD_INT(ctx, queue_list, OID_AUTO,
"max_drbr_queue_depth",
CTLFLAG_RD, &fp->max_drbr_queue_depth,
0, "Driver queue maximum dpeth");
#ifdef BXE_DEBUG
SYSCTL_ADD_ULONG(ctx, queue_list, OID_AUTO,
"null_cqe_flags",

View File

@ -1110,6 +1110,8 @@ struct bxe_fastpath {
int sge_mbuf_alloc;
int tpa_mbuf_alloc;
int max_drbr_queue_depth;
uint64_t tpa_queue_used;
unsigned long null_cqe_flags;
@ -1148,7 +1150,6 @@ struct bxe_fastpath {
#define BXE_TX_CHAIN_PAGE_SZ BCM_PAGE_SIZE
#define BXE_RX_CHAIN_PAGE_SZ BCM_PAGE_SIZE
/* ToDo: Audit this structure for unused varaibles. */
struct bxe_softc {
struct ifnet *bxe_ifp;
int media;

View File

@ -359,6 +359,18 @@ atphy_setmedia(struct mii_softc *sc, int media)
(EXTSR_1000TFDX | EXTSR_1000THDX)) != 0)
PHY_WRITE(sc, MII_100T2CR, GTCR_ADV_1000TFDX |
GTCR_ADV_1000THDX);
else if (sc->mii_mpd_model == MII_MODEL_xxATHEROS_F1) {
/*
* AR8132 has 10/100 PHY and the PHY uses the same
* model number of F1 gigabit PHY. The PHY has no
* ability to establish gigabit link so explicitly
* disable 1000baseT configuration for the PHY.
* Otherwise, there is a case that atphy(4) could
* not establish a link against gigabit link partner
* unless the link partner supports down-shifting.
*/
PHY_WRITE(sc, MII_100T2CR, 0);
}
PHY_WRITE(sc, MII_BMCR, BMCR_RESET | BMCR_AUTOEN | BMCR_STARTNEG);
return (EJUSTRETURN);

View File

@ -257,7 +257,7 @@ void
mii_phy_reset(struct mii_softc *sc)
{
struct ifmedia_entry *ife = sc->mii_pdata->mii_media.ifm_cur;
int reg, i;
int i, reg;
if ((sc->mii_flags & MIIF_NOISOLATE) != 0)
reg = BMCR_RESET;
@ -273,11 +273,14 @@ mii_phy_reset(struct mii_softc *sc)
DELAY(1000);
}
if ((sc->mii_flags & MIIF_NOISOLATE) == 0) {
if ((ife == NULL && sc->mii_inst != 0) ||
(ife != NULL && IFM_INST(ife->ifm_media) != sc->mii_inst))
PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
}
/* NB: a PHY may default to isolation. */
reg &= ~BMCR_ISO;
if ((sc->mii_flags & MIIF_NOISOLATE) == 0 &&
((ife == NULL && sc->mii_inst != 0) ||
(ife != NULL && IFM_INST(ife->ifm_media) != sc->mii_inst)))
reg |= BMCR_ISO;
if (PHY_READ(sc, MII_BMCR) != reg)
PHY_WRITE(sc, MII_BMCR, reg);
}
void

View File

@ -45,12 +45,22 @@ __FBSDID("$FreeBSD$");
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
static int isab_probe(device_t dev);
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
static int isab_pci_probe(device_t dev);
static int isab_pci_attach(device_t dev);
static struct resource * isab_pci_alloc_resource(device_t dev,
device_t child, int type, int *rid, u_long start, u_long end, u_long count,
u_int flags);
static int isab_pci_release_resource(device_t dev, device_t child,
int type, int rid, struct resource *r);
static device_method_t isab_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, isab_probe),
DEVMETHOD(device_attach, isab_attach),
DEVMETHOD(device_probe, isab_pci_probe),
DEVMETHOD(device_attach, isab_pci_attach),
DEVMETHOD(device_detach, bus_generic_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
@ -58,8 +68,8 @@ static device_method_t isab_methods[] = {
/* Bus interface */
DEVMETHOD(bus_print_child, bus_generic_print_child),
DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
DEVMETHOD(bus_release_resource, bus_generic_release_resource),
DEVMETHOD(bus_alloc_resource, isab_pci_alloc_resource),
DEVMETHOD(bus_release_resource, isab_pci_release_resource),
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
@ -68,10 +78,19 @@ static device_method_t isab_methods[] = {
{ 0, 0 }
};
struct isab_pci_resource {
struct resource *ip_res;
int ip_refs;
};
struct isab_pci_softc {
struct isab_pci_resource isab_pci_res[PCIR_MAX_BAR_0 + 1];
};
static driver_t isab_driver = {
"isab",
isab_methods,
0,
sizeof(struct isab_pci_softc),
};
DRIVER_MODULE(isab, pci, isab_driver, isab_devclass, 0, 0);
@ -81,7 +100,7 @@ DRIVER_MODULE(isab, pci, isab_driver, isab_devclass, 0, 0);
* report themselves.
*/
static int
isab_probe(device_t dev)
isab_pci_probe(device_t dev)
{
int matched = 0;
@ -139,3 +158,88 @@ isab_probe(device_t dev)
}
return(ENXIO);
}
static int
isab_pci_attach(device_t dev)
{
bus_generic_probe(dev);
return (isab_attach(dev));
}
static struct resource *
isab_pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
struct isab_pci_softc *sc;
int bar;
if (device_get_parent(child) != dev)
return bus_generic_alloc_resource(dev, child, type, rid, start,
end, count, flags);
switch (type) {
case SYS_RES_MEMORY:
case SYS_RES_IOPORT:
/*
* For BARs, we cache the resource so that we only allocate it
* from the PCI bus once.
*/
bar = PCI_RID2BAR(*rid);
if (bar < 0 || bar > PCIR_MAX_BAR_0)
return (NULL);
sc = device_get_softc(dev);
if (sc->isab_pci_res[bar].ip_res == NULL)
sc->isab_pci_res[bar].ip_res = bus_alloc_resource(dev, type,
rid, start, end, count, flags);
if (sc->isab_pci_res[bar].ip_res != NULL)
sc->isab_pci_res[bar].ip_refs++;
return (sc->isab_pci_res[bar].ip_res);
}
return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, type, rid,
start, end, count, flags));
}
static int
isab_pci_release_resource(device_t dev, device_t child, int type, int rid,
struct resource *r)
{
struct isab_pci_softc *sc;
int bar, error;
if (device_get_parent(child) != dev)
return bus_generic_release_resource(dev, child, type, rid, r);
switch (type) {
case SYS_RES_MEMORY:
case SYS_RES_IOPORT:
/*
* For BARs, we release the resource from the PCI bus
* when the last child reference goes away.
*/
bar = PCI_RID2BAR(rid);
if (bar < 0 || bar > PCIR_MAX_BAR_0)
return (EINVAL);
sc = device_get_softc(dev);
if (sc->isab_pci_res[bar].ip_res == NULL)
return (EINVAL);
KASSERT(sc->isab_pci_res[bar].ip_res == r,
("isa_pci resource mismatch"));
if (sc->isab_pci_res[bar].ip_refs > 1) {
sc->isab_pci_res[bar].ip_refs--;
return (0);
}
KASSERT(sc->isab_pci_res[bar].ip_refs > 0,
("isa_pci resource reference count underflow"));
error = bus_release_resource(dev, type, rid, r);
if (error == 0) {
sc->isab_pci_res[bar].ip_res = NULL;
sc->isab_pci_res[bar].ip_refs = 0;
}
return (error);
}
return (BUS_RELEASE_RESOURCE(device_get_parent(dev), child, type,
rid, r));
}

View File

@ -147,12 +147,6 @@ balloon_retrieve(void)
return page;
}
static void
balloon_alarm(void *unused)
{
wakeup(balloon_process);
}
static unsigned long
current_target(void)
{
@ -378,6 +372,8 @@ balloon_process(void *unused)
mtx_lock(&balloon_mutex);
for (;;) {
int sleep_time;
do {
credit = current_target() - bs.current_pages;
if (credit > 0)
@ -389,9 +385,12 @@ balloon_process(void *unused)
/* Schedule more work if there is some still to be done. */
if (current_target() != bs.current_pages)
timeout(balloon_alarm, NULL, ticks + hz);
sleep_time = hz;
else
sleep_time = 0;
msleep(balloon_process, &balloon_mutex, 0, "balloon", -1);
msleep(balloon_process, &balloon_mutex, 0, "balloon",
sleep_time);
}
mtx_unlock(&balloon_mutex);
}
@ -474,9 +473,6 @@ balloon_init(void *arg)
bs.hard_limit = ~0UL;
kproc_create(balloon_process, NULL, NULL, 0, 0, "balloon");
// init_timer(&balloon_timer);
// balloon_timer.data = 0;
// balloon_timer.function = balloon_alarm;
#ifndef XENHVM
/* Initialise the balloon with excess memory space. */

View File

@ -1351,7 +1351,9 @@ void (*cpu_idle_fn)(int) = cpu_idle_acpi;
void
cpu_idle(int busy)
{
#ifndef XEN
uint64_t msr;
#endif
CTR2(KTR_SPARE2, "cpu_idle(%d) at %d",
busy, curcpu);
@ -1367,34 +1369,32 @@ cpu_idle(int busy)
goto out;
}
}
#endif
/* If we have time - switch timers into idle mode. */
if (!busy) {
critical_enter();
cpu_idleclock();
}
#endif
/* Apply AMD APIC timer C1E workaround. */
if (cpu_ident_amdc1e
#ifndef XEN
&& cpu_disable_deep_sleep
#endif
) {
/* Apply AMD APIC timer C1E workaround. */
if (cpu_ident_amdc1e && cpu_disable_deep_sleep) {
msr = rdmsr(MSR_AMDK8_IPM);
if (msr & AMDK8_CMPHALT)
wrmsr(MSR_AMDK8_IPM, msr & ~AMDK8_CMPHALT);
}
#endif
/* Call main idle method. */
cpu_idle_fn(busy);
#ifndef XEN
/* Switch timers mack into active mode. */
if (!busy) {
cpu_activeclock();
critical_exit();
}
#ifndef XEN
out:
#endif
CTR2(KTR_SPARE2, "cpu_idle(%d) at %d done",

View File

@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/time.h>
#include <sys/timeet.h>
#include <sys/timetc.h>
#include <sys/kernel.h>
#include <sys/limits.h>
@ -301,38 +302,44 @@ static struct timecounter xen_timecounter = {
0 /* quality */
};
static struct eventtimer xen_et;
struct xen_et_state {
int mode;
#define MODE_STOP 0
#define MODE_PERIODIC 1
#define MODE_ONESHOT 2
int64_t period;
int64_t next;
};
static DPCPU_DEFINE(struct xen_et_state, et_state);
static int
clkintr(void *arg)
{
int64_t delta_cpu, delta;
struct trapframe *frame = (struct trapframe *)arg;
int64_t now;
int cpu = smp_processor_id();
struct shadow_time_info *shadow = &per_cpu(shadow_time, cpu);
struct xen_et_state *state = DPCPU_PTR(et_state);
do {
__get_time_values_from_xen();
delta = delta_cpu =
shadow->system_timestamp + get_nsec_offset(shadow);
delta -= processed_system_time;
delta_cpu -= per_cpu(processed_system_time, cpu);
now = shadow->system_timestamp + get_nsec_offset(shadow);
} while (!time_values_up_to_date(cpu));
if (unlikely(delta < (int64_t)0) || unlikely(delta_cpu < (int64_t)0)) {
printf("Timer ISR: Time went backwards: %lld\n", delta);
return (FILTER_HANDLED);
}
/* Process elapsed ticks since last call. */
while (delta >= NS_PER_TICK) {
delta -= NS_PER_TICK;
processed_system_time += NS_PER_TICK;
per_cpu(processed_system_time, cpu) += NS_PER_TICK;
if (PCPU_GET(cpuid) == 0)
hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
else
hardclock_cpu(TRAPF_USERMODE(frame));
processed_system_time = now;
if (state->mode == MODE_PERIODIC) {
while (now >= state->next) {
state->next += state->period;
if (xen_et.et_active)
xen_et.et_event_cb(&xen_et, xen_et.et_arg);
}
HYPERVISOR_set_timer_op(state->next + 50000);
} else if (state->mode == MODE_ONESHOT) {
if (xen_et.et_active)
xen_et.et_event_cb(&xen_et, xen_et.et_arg);
}
/*
* Take synchronised time from Xen once a minute if we're not
@ -484,12 +491,14 @@ DELAY(int n)
void
timer_restore(void)
{
struct xen_et_state *state = DPCPU_PTR(et_state);
/* Get timebases for new environment. */
__get_time_values_from_xen();
/* Reset our own concept of passage of system time. */
processed_system_time = per_cpu(shadow_time, 0).system_timestamp;
per_cpu(processed_system_time, 0) = processed_system_time;
state->next = processed_system_time;
}
void
@ -503,7 +512,6 @@ startrtclock()
/* initialize xen values */
__get_time_values_from_xen();
processed_system_time = per_cpu(shadow_time, 0).system_timestamp;
per_cpu(processed_system_time, 0) = processed_system_time;
__cpu_khz = 1000000ULL << 32;
info = &HYPERVISOR_shared_info->vcpu_info[0].time;
@ -759,7 +767,49 @@ resettodr()
}
#endif
static struct vcpu_set_periodic_timer xen_set_periodic_tick;
static int
xen_et_start(struct eventtimer *et,
struct bintime *first, struct bintime *period)
{
struct xen_et_state *state = DPCPU_PTR(et_state);
struct shadow_time_info *shadow;
int64_t fperiod;
__get_time_values_from_xen();
if (period != NULL) {
state->mode = MODE_PERIODIC;
state->period = (1000000000LL *
(uint32_t)(period->frac >> 32)) >> 32;
if (period->sec != 0)
state->period += 1000000000LL * period->sec;
} else {
state->mode = MODE_ONESHOT;
state->period = 0;
}
if (first != NULL) {
fperiod = (1000000000LL * (uint32_t)(first->frac >> 32)) >> 32;
if (first->sec != 0)
fperiod += 1000000000LL * first->sec;
} else
fperiod = state->period;
shadow = &per_cpu(shadow_time, smp_processor_id());
state->next = shadow->system_timestamp + get_nsec_offset(shadow);
state->next += fperiod;
HYPERVISOR_set_timer_op(state->next + 50000);
return (0);
}
static int
xen_et_stop(struct eventtimer *et)
{
struct xen_et_state *state = DPCPU_PTR(et_state);
state->mode = MODE_STOP;
HYPERVISOR_set_timer_op(0);
return (0);
}
/*
* Start clocks running.
@ -770,56 +820,48 @@ cpu_initclocks(void)
unsigned int time_irq;
int error;
xen_set_periodic_tick.period_ns = NS_PER_TICK;
HYPERVISOR_vcpu_op(VCPUOP_set_periodic_timer, 0,
&xen_set_periodic_tick);
error = bind_virq_to_irqhandler(VIRQ_TIMER, 0, "clk",
clkintr, NULL, NULL,
INTR_TYPE_CLK, &time_irq);
HYPERVISOR_vcpu_op(VCPUOP_stop_periodic_timer, 0, NULL);
error = bind_virq_to_irqhandler(VIRQ_TIMER, 0, "cpu0:timer",
clkintr, NULL, NULL, INTR_TYPE_CLK, &time_irq);
if (error)
panic("failed to register clock interrupt\n");
/* should fast clock be enabled ? */
bzero(&xen_et, sizeof(xen_et));
xen_et.et_name = "ixen";
xen_et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT |
ET_FLAGS_PERCPU;
xen_et.et_quality = 600;
xen_et.et_frequency = 0;
xen_et.et_min_period.sec = 0;
xen_et.et_min_period.frac = 0x00400000LL << 32;
xen_et.et_max_period.sec = 2;
xen_et.et_max_period.frac = 0;
xen_et.et_start = xen_et_start;
xen_et.et_stop = xen_et_stop;
xen_et.et_priv = NULL;
et_register(&xen_et);
cpu_initclocks_bsp();
}
int
ap_cpu_initclocks(int cpu)
{
char buf[MAXCOMLEN + 1];
unsigned int time_irq;
int error;
xen_set_periodic_tick.period_ns = NS_PER_TICK;
HYPERVISOR_vcpu_op(VCPUOP_set_periodic_timer, cpu,
&xen_set_periodic_tick);
error = bind_virq_to_irqhandler(VIRQ_TIMER, 0, "clk",
clkintr, NULL, NULL,
INTR_TYPE_CLK, &time_irq);
HYPERVISOR_vcpu_op(VCPUOP_stop_periodic_timer, cpu, NULL);
snprintf(buf, sizeof(buf), "cpu%d:timer", cpu);
error = bind_virq_to_irqhandler(VIRQ_TIMER, cpu, buf,
clkintr, NULL, NULL, INTR_TYPE_CLK, &time_irq);
if (error)
panic("failed to register clock interrupt\n");
return (0);
}
void
cpu_startprofclock(void)
{
printf("cpu_startprofclock: profiling clock is not supported\n");
}
void
cpu_stopprofclock(void)
{
printf("cpu_stopprofclock: profiling clock is not supported\n");
}
#define NSEC_PER_USEC 1000
static uint32_t
xen_get_timecount(struct timecounter *tc)
{
@ -842,45 +884,11 @@ get_system_time(int ticks)
return processed_system_time + (ticks * NS_PER_TICK);
}
/*
* Track behavior of cur_timer->get_offset() functionality in timer_tsc.c
*/
/* Convert jiffies to system time. */
static uint64_t
ticks_to_system_time(int newticks)
{
int delta;
uint64_t st;
delta = newticks - ticks;
if (delta < 1) {
/* Triggers in some wrap-around cases,
* but that's okay:
* we just end up with a shorter timeout. */
st = processed_system_time + NS_PER_TICK;
} else if (((unsigned int)delta >> (BITS_PER_LONG-3)) != 0) {
/* Very long timeout means there is no pending timer.
* We indicate this to Xen by passing zero timeout. */
st = 0;
} else {
st = processed_system_time + delta * (uint64_t)NS_PER_TICK;
}
return (st);
}
void
idle_block(void)
{
uint64_t timeout;
timeout = ticks_to_system_time(ticks + 1) + NS_PER_TICK/2;
__get_time_values_from_xen();
PANIC_IF(HYPERVISOR_set_timer_op(timeout) != 0);
HYPERVISOR_sched_op(SCHEDOP_block, 0);
HYPERVISOR_sched_op(SCHEDOP_block, 0);
}
int
@ -903,6 +911,3 @@ timer_spkr_setfreq(int freq)
}

View File

@ -625,8 +625,11 @@ init_secondary(void)
while (smp_started == 0)
ia32_pause();
PCPU_SET(curthread, PCPU_GET(idlethread));
/* Start per-CPU event timers. */
cpu_initclocks_ap();
/* enter the scheduler */
sched_throw(NULL);

View File

@ -31,9 +31,6 @@ __FBSDID("$FreeBSD$");
* Common routines to manage event timers hardware.
*/
/* XEN has own timer routines now. */
#ifndef XEN
#include "opt_device_polling.h"
#include "opt_kdtrace.h"
@ -899,5 +896,3 @@ sysctl_kern_eventtimer_periodic(SYSCTL_HANDLER_ARGS)
SYSCTL_PROC(_kern_eventtimer, OID_AUTO, periodic,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
0, 0, sysctl_kern_eventtimer_periodic, "I", "Enable event timer periodic mode");
#endif

View File

@ -551,7 +551,7 @@ maybe_yield(void)
{
if (should_yield())
kern_yield(curthread->td_user_pri);
kern_yield(PRI_USER);
}
void
@ -562,6 +562,8 @@ kern_yield(int prio)
td = curthread;
DROP_GIANT();
thread_lock(td);
if (prio == PRI_USER)
prio = td->td_user_pri;
if (prio >= 0)
sched_prio(td, prio);
mi_switch(SW_VOL | SWT_RELINQUISH, NULL);

View File

@ -1590,7 +1590,7 @@ userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
SYSCTL_XUNLOCK();
if (error != EAGAIN)
break;
kern_yield(curthread->td_user_pri);
kern_yield(PRI_USER);
}
CURVNET_RESTORE();

View File

@ -2234,7 +2234,7 @@ buf_daemon()
while (numdirtybuffers > lodirtybuffers) {
if (buf_do_flush(NULL) == 0)
break;
kern_yield(-1);
kern_yield(PRI_UNCHANGED);
}
lodirtybuffers = lodirtysave;

View File

@ -1644,7 +1644,7 @@ __mnt_vnode_next(struct vnode **mvp, struct mount *mp)
KASSERT((*mvp)->v_mount == mp, ("marker vnode mount list mismatch"));
if (should_yield()) {
MNT_IUNLOCK(mp);
kern_yield(-1);
kern_yield(PRI_UNCHANGED);
MNT_ILOCK(mp);
}
vp = TAILQ_NEXT(*mvp, v_nmntvnodes);

View File

@ -718,7 +718,7 @@ vlrureclaim(struct mount *mp)
continue;
MNT_IUNLOCK(mp);
yield:
kern_yield(-1);
kern_yield(PRI_UNCHANGED);
relock_mnt:
MNT_ILOCK(mp);
}
@ -831,7 +831,7 @@ vnlru_proc(void)
vnlru_nowhere++;
tsleep(vnlruproc, PPAUSE, "vlrup", hz * 3);
} else
kern_yield(-1);
kern_yield(PRI_UNCHANGED);
}
}

View File

@ -491,7 +491,7 @@ vn_rdwr_inchunks(rw, vp, base, len, offset, segflg, ioflg, active_cred,
break;
offset += chunk;
base = (char *)base + chunk;
kern_yield(curthread->td_user_pri);
kern_yield(PRI_USER);
} while (len);
if (aresid)
*aresid = len + iaresid;

View File

@ -625,6 +625,6 @@ vop_vptocnp {
vop_allocate {
IN struct vnode *vp;
IN off_t *offset;
IN off_t *len;
INOUT off_t *offset;
INOUT off_t *len;
};

View File

@ -117,6 +117,12 @@
#define PRI_MIN_IDLE (224)
#define PRI_MAX_IDLE (PRI_MAX)
#ifdef _KERNEL
/* Other arguments for kern_yield(9). */
#define PRI_USER -2 /* Change to current user priority. */
#define PRI_UNCHANGED -1 /* Do not change priority. */
#endif
struct priority {
u_char pri_class; /* Scheduling class. */
u_char pri_level; /* Normal priority level. */

View File

@ -1412,7 +1412,7 @@ softdep_process_worklist(mp, full)
*/
if (should_yield()) {
FREE_LOCK(&lk);
kern_yield(-1);
kern_yield(PRI_UNCHANGED);
bwillwrite();
ACQUIRE_LOCK(&lk);
}

View File

@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <libprocstat.h>
#include <limits.h>
#include <pwd.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
@ -452,7 +453,7 @@ print_vnode_info(struct procstat *procstat, struct filestat *fst)
else {
strmode(vn.vn_mode, mode);
}
(void)printf(" %6ld %10s", vn.vn_fileid, mode);
(void)printf(" %6jd %10s", (intmax_t)vn.vn_fileid, mode);
if (vn.vn_type == PS_FST_VTYPE_VBLK || vn.vn_type == PS_FST_VTYPE_VCHR) {
if (nflg || !*vn.vn_devname)
@ -461,7 +462,7 @@ print_vnode_info(struct procstat *procstat, struct filestat *fst)
printf(" %6s", vn.vn_devname);
}
} else
printf(" %6lu", vn.vn_size);
printf(" %6ju", (uintmax_t)vn.vn_size);
print_access_flags(fst->fs_fflags);
}

View File

@ -31,7 +31,7 @@
#define CLOOP_MAGIC_LEN 128
static char CLOOP_MAGIC_START[] = "#!/bin/sh\n#V2.0 Format\n"
"m=geom_uzip\n(kldstat -m $m 2>&-||kldload $m)>&-&&"
"(kldstat -qm g_uzip||kldload geom_uzip)>&-&&"
"mount_cd9660 /dev/`mdconfig -af $0`.uzip $1\nexit $?\n";
static char *readblock(int, char *, u_int32_t);