diff options
author | attilio <attilio@FreeBSD.org> | 2011-05-13 15:20:57 +0000 |
---|---|---|
committer | attilio <attilio@FreeBSD.org> | 2011-05-13 15:20:57 +0000 |
commit | d62a193525b7f197ac10cb251e579ab064483b92 (patch) | |
tree | 908e887ad289c884f244dedf76640b4c8a4086b3 | |
parent | d576c60fd2f8392ecbb5566b3703fa5dac85d9e9 (diff) | |
download | FreeBSD-src-d62a193525b7f197ac10cb251e579ab064483b92.zip FreeBSD-src-d62a193525b7f197ac10cb251e579ab064483b92.tar.gz |
MFC
39 files changed, 690 insertions, 367 deletions
diff --git a/lib/libfetch/Makefile b/lib/libfetch/Makefile index 5091adf..7b29aa2 100644 --- a/lib/libfetch/Makefile +++ b/lib/libfetch/Makefile @@ -26,7 +26,6 @@ LDADD= -lmd CFLAGS+= -DFTP_COMBINE_CWDS CSTD?= c99 -WARNS?= 2 SHLIB_MAJOR= 6 diff --git a/lib/libfetch/common.c b/lib/libfetch/common.c index ff10d27..fefc4c5 100644 --- a/lib/libfetch/common.c +++ b/lib/libfetch/common.c @@ -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); diff --git a/lib/libfetch/file.c b/lib/libfetch/file.c index a1492ba..dffaad8 100644 --- a/lib/libfetch/file.c +++ b/lib/libfetch/file.c @@ -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); } diff --git a/lib/libfetch/ftp.c b/lib/libfetch/ftp.c index d981006..04ae07e 100644 --- a/lib/libfetch/ftp.c +++ b/lib/libfetch/ftp.c @@ -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; diff --git a/lib/libfetch/http.c b/lib/libfetch/http.c index 531342a7..309cbf2 100644 --- a/lib/libfetch/http.c +++ b/lib/libfetch/http.c @@ -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 @@ out: } -/* +/* * 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")); diff --git a/lib/libprocstat/Makefile b/lib/libprocstat/Makefile index dc3dd58..e289ef5 100644 --- a/lib/libprocstat/Makefile +++ b/lib/libprocstat/Makefile @@ -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 diff --git a/lib/libprocstat/libprocstat.c b/lib/libprocstat/libprocstat.c index cfe81a2..95b00d3 100644 --- a/lib/libprocstat/libprocstat.c +++ b/lib/libprocstat/libprocstat.c @@ -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 }; diff --git a/release/powerpc/mkisoimages.sh b/release/powerpc/mkisoimages.sh index 5c4b0df..63619fb 100644 --- a/release/powerpc/mkisoimages.sh +++ b/release/powerpc/mkisoimages.sh @@ -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 + diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416.h b/sys/dev/ath/ath_hal/ar5416/ar5416.h index 3738aaf..14ad03c 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416.h +++ b/sys/dev/ath/ath_hal/ar5416/ar5416.h @@ -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, diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c b/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c index 3336660..35dc3df 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_cal.c @@ -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 diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c index c57e6b9..e8eec86 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c @@ -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)) { @@ -1635,6 +1638,63 @@ ar5416SetBoardValues(struct ath_hal *ah, const struct ieee80211_channel *chan) */ /* + * 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 * * Sets the transmit power in the baseband for the given @@ -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 diff --git a/sys/dev/ath/ath_hal/ar9002/ar9280_olc.c b/sys/dev/ath/ath_hal/ar9002/ar9280_olc.c index da5e4ed..361930b 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9280_olc.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9280_olc.c @@ -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); diff --git a/sys/dev/ath/ath_hal/ar9002/ar9285_diversity.c b/sys/dev/ath/ath_hal/ar9002/ar9285_diversity.c index a1c2bd2..84c7682 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9285_diversity.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9285_diversity.c @@ -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 @@ div_comb_done: 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); diff --git a/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c b/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c index d808703..1a0c77b 100644 --- a/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c +++ b/sys/dev/ath/ath_hal/ar9002/ar9285_reset.c @@ -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]; - - for (i = 0; i < N(targetPowerHt20.tPow2x); i++) { - ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i]; - } + /* Set rates Array from collected data */ + ar5416SetRatesArrayFromTargetPower(ah, chan, ratesArray, + &targetPowerCck, + &targetPowerCckExt, + &targetPowerOfdm, + &targetPowerOfdmExt, + &targetPowerHt20, + &targetPowerHt40); - 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 diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index 9234c26..8f13b26 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -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; diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 10f9847..3d725fc 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -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 { /* diff --git a/sys/dev/bge/if_bgereg.h b/sys/dev/bge/if_bgereg.h index dffec31..9b83021 100644 --- a/sys/dev/bge/if_bgereg.h +++ b/sys/dev/bge/if_bgereg.h @@ -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 diff --git a/sys/dev/bm/if_bm.c b/sys/dev/bm/if_bm.c index 481d7cb..1977f92 100644 --- a/sys/dev/bm/if_bm.c +++ b/sys/dev/bm/if_bm.c @@ -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); diff --git a/sys/dev/bxe/if_bxe.c b/sys/dev/bxe/if_bxe.c index 6b24dc4..cf0a40e 100644 --- a/sys/dev/bxe/if_bxe.c +++ b/sys/dev/bxe/if_bxe.c @@ -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_exit: /* - * 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", diff --git a/sys/dev/bxe/if_bxe.h b/sys/dev/bxe/if_bxe.h index 4f8528f..8da3db4 100644 --- a/sys/dev/bxe/if_bxe.h +++ b/sys/dev/bxe/if_bxe.h @@ -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; diff --git a/sys/dev/mii/atphy.c b/sys/dev/mii/atphy.c index 0d80ba1..b5cf14f 100644 --- a/sys/dev/mii/atphy.c +++ b/sys/dev/mii/atphy.c @@ -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); diff --git a/sys/dev/mii/mii_physubr.c b/sys/dev/mii/mii_physubr.c index b3013ba..be66505 100644 --- a/sys/dev/mii/mii_physubr.c +++ b/sys/dev/mii/mii_physubr.c @@ -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 diff --git a/sys/dev/pci/isa_pci.c b/sys/dev/pci/isa_pci.c index 073aff7..be3f3ac 100644 --- a/sys/dev/pci/isa_pci.c +++ b/sys/dev/pci/isa_pci.c @@ -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)); +} diff --git a/sys/dev/xen/balloon/balloon.c b/sys/dev/xen/balloon/balloon.c index dff80ba..81d1094 100644 --- a/sys/dev/xen/balloon/balloon.c +++ b/sys/dev/xen/balloon/balloon.c @@ -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. */ diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 265a5c4..fbf444a 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -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", diff --git a/sys/i386/xen/clock.c b/sys/i386/xen/clock.c index 091c8c7..f5965bf 100644 --- a/sys/i386/xen/clock.c +++ b/sys/i386/xen/clock.c @@ -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) } - - - diff --git a/sys/i386/xen/mp_machdep.c b/sys/i386/xen/mp_machdep.c index 1146ac2..1565859 100644 --- a/sys/i386/xen/mp_machdep.c +++ b/sys/i386/xen/mp_machdep.c @@ -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); diff --git a/sys/kern/kern_clocksource.c b/sys/kern/kern_clocksource.c index d55d85c..604bd2d 100644 --- a/sys/kern/kern_clocksource.c +++ b/sys/kern/kern_clocksource.c @@ -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 diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index a3e920d..d3aef76 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -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); diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 0f1e357..8d2fdde 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -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(); diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 06e8625..0b5e973 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -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; diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 7bdb29c..2e07cf1 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -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); diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index dead546..741061d 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -718,7 +718,7 @@ next_iter: 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); } } diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 7b5cad1..e8bcc91 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -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; diff --git a/sys/kern/vnode_if.src b/sys/kern/vnode_if.src index f4ac4a2..f75e7df 100644 --- a/sys/kern/vnode_if.src +++ b/sys/kern/vnode_if.src @@ -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; }; diff --git a/sys/sys/priority.h b/sys/sys/priority.h index 8ada2db..6548a35 100644 --- a/sys/sys/priority.h +++ b/sys/sys/priority.h @@ -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. */ diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index a6d4441..a7ae484 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -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); } diff --git a/usr.bin/fstat/fstat.c b/usr.bin/fstat/fstat.c index 9d057e5..531eef2 100644 --- a/usr.bin/fstat/fstat.c +++ b/usr.bin/fstat/fstat.c @@ -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); } diff --git a/usr.bin/mkuzip/mkuzip.c b/usr.bin/mkuzip/mkuzip.c index 02ebefa..08c8ed0 100644 --- a/usr.bin/mkuzip/mkuzip.c +++ b/usr.bin/mkuzip/mkuzip.c @@ -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); |