MFC
This commit is contained in:
commit
739e31f6d7
@ -26,7 +26,6 @@ LDADD= -lmd
|
||||
CFLAGS+= -DFTP_COMBINE_CWDS
|
||||
|
||||
CSTD?= c99
|
||||
WARNS?= 2
|
||||
|
||||
SHLIB_MAJOR= 6
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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"));
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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. */
|
||||
|
@ -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",
|
||||
|
@ -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)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user