summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bin/sh/eval.c89
-rw-r--r--bin/sh/eval.h2
-rw-r--r--bin/sh/expand.c215
-rw-r--r--bin/sh/expand.h13
-rw-r--r--bin/sh/var.c28
-rw-r--r--bin/sh/var.h4
-rw-r--r--share/mk/netbsd-tests.test.mk2
-rw-r--r--sys/dev/ath/if_ath.c4
-rw-r--r--sys/dev/ath/if_ath_tx.c33
-rw-r--r--sys/dev/ath/if_ath_tx.h1
-rw-r--r--sys/dev/bwi/if_bwi.c5
-rw-r--r--sys/dev/bwn/if_bwn.c13
-rw-r--r--sys/dev/iwm/if_iwm.c5
-rw-r--r--sys/dev/iwm/if_iwmvar.h2
-rw-r--r--sys/dev/iwn/if_iwn.c13
-rw-r--r--sys/dev/malo/if_malo.c3
-rw-r--r--sys/dev/mwl/if_mwl.c3
-rw-r--r--sys/dev/ntb/if_ntb/if_ntb.c127
-rw-r--r--sys/dev/otus/if_otus.c2
-rw-r--r--sys/dev/otus/if_otusreg.h2
-rw-r--r--sys/dev/ral/rt2560.c3
-rw-r--r--sys/dev/ral/rt2560var.h4
-rw-r--r--sys/dev/ral/rt2661.c3
-rw-r--r--sys/dev/ral/rt2661var.h2
-rw-r--r--sys/dev/ral/rt2860.c5
-rw-r--r--sys/dev/ral/rt2860var.h2
-rw-r--r--sys/dev/usb/wlan/if_rsu.c3
-rw-r--r--sys/dev/usb/wlan/if_rsureg.h2
-rw-r--r--sys/dev/usb/wlan/if_rum.c1
-rw-r--r--sys/dev/usb/wlan/if_run.c1
-rw-r--r--sys/dev/usb/wlan/if_runvar.h2
-rw-r--r--sys/dev/usb/wlan/if_uath.c23
-rw-r--r--sys/dev/usb/wlan/if_uathvar.h2
-rw-r--r--sys/dev/usb/wlan/if_upgt.c3
-rw-r--r--sys/dev/usb/wlan/if_upgtvar.h2
-rw-r--r--sys/dev/usb/wlan/if_ural.c3
-rw-r--r--sys/dev/usb/wlan/if_uralvar.h3
-rw-r--r--sys/dev/usb/wlan/if_urtw.c3
-rw-r--r--sys/dev/usb/wlan/if_urtwn.c17
-rw-r--r--sys/dev/usb/wlan/if_urtwnreg.h191
-rw-r--r--sys/dev/usb/wlan/if_urtwnvar.h203
-rw-r--r--sys/dev/usb/wlan/if_urtwvar.h2
-rw-r--r--sys/dev/usb/wlan/if_zyd.c3
-rw-r--r--sys/dev/usb/wlan/if_zydreg.h2
-rw-r--r--sys/dev/wi/if_wi.c2
-rw-r--r--sys/dev/wpi/if_wpi.c122
-rw-r--r--sys/dev/wpi/if_wpireg.h2
-rw-r--r--sys/dev/wpi/if_wpivar.h1
-rw-r--r--sys/modules/usb/urtwn/Makefile2
-rw-r--r--sys/net80211/ieee80211_freebsd.c15
-rw-r--r--sys/net80211/ieee80211_hostap.c5
-rw-r--r--sys/net80211/ieee80211_mesh.c6
-rw-r--r--sys/net80211/ieee80211_output.c36
-rw-r--r--sys/net80211/ieee80211_power.c7
-rw-r--r--sys/net80211/ieee80211_proto.h1
-rw-r--r--sys/net80211/ieee80211_superg.c8
-rw-r--r--sys/net80211/ieee80211_wds.c6
57 files changed, 597 insertions, 667 deletions
diff --git a/bin/sh/eval.c b/bin/sh/eval.c
index 51206d9..dfbbc04 100644
--- a/bin/sh/eval.c
+++ b/bin/sh/eval.c
@@ -82,7 +82,7 @@ static int builtin_flags; /* evalcommand flags for builtins */
char *commandname;
-struct strlist *cmdenviron;
+struct arglist *cmdenviron;
int exitstatus; /* exit status of last command */
int oexitstatus; /* saved exit status */
@@ -352,20 +352,19 @@ evalfor(union node *n, int flags)
{
struct arglist arglist;
union node *argp;
- struct strlist *sp;
+ int i;
int status;
- arglist.lastp = &arglist.list;
+ emptyarglist(&arglist);
for (argp = n->nfor.args ; argp ; argp = argp->narg.next) {
oexitstatus = exitstatus;
expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
}
- *arglist.lastp = NULL;
loopnest++;
status = 0;
- for (sp = arglist.list ; sp ; sp = sp->next) {
- setvar(n->nfor.var, sp->text, 0);
+ for (i = 0; i < arglist.count; i++) {
+ setvar(n->nfor.var, arglist.args[i], 0);
evaltree(n->nfor.body, flags);
status = exitstatus;
if (evalskip) {
@@ -396,12 +395,12 @@ evalcase(union node *n)
union node *patp;
struct arglist arglist;
- arglist.lastp = &arglist.list;
+ emptyarglist(&arglist);
oexitstatus = exitstatus;
expandarg(n->ncase.expr, &arglist, EXP_TILDE);
for (cp = n->ncase.cases ; cp ; cp = cp->nclist.next) {
for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
- if (casematch(patp, arglist.list->text)) {
+ if (casematch(patp, arglist.args[0])) {
while (cp->nclist.next &&
cp->type == NCLISTFALLTHRU &&
cp->nclist.body == NULL)
@@ -508,7 +507,7 @@ exphere(union node *redir, struct arglist *fn)
else {
handler = &jmploc;
expandarg(redir->nhere.doc, fn, 0);
- redir->nhere.expdoc = fn->list->text;
+ redir->nhere.expdoc = fn->args[0];
INTOFF;
}
handler = savehandler;
@@ -532,7 +531,7 @@ expredir(union node *n)
for (redir = n ; redir ; redir = redir->nfile.next) {
struct arglist fn;
- fn.lastp = &fn.list;
+ emptyarglist(&fn);
switch (redir->type) {
case NFROM:
case NTO:
@@ -540,13 +539,13 @@ expredir(union node *n)
case NAPPEND:
case NCLOBBER:
expandarg(redir->nfile.fname, &fn, EXP_TILDE);
- redir->nfile.expfname = fn.list->text;
+ redir->nfile.expfname = fn.args[0];
break;
case NFROMFD:
case NTOFD:
if (redir->ndup.vname) {
expandarg(redir->ndup.vname, &fn, EXP_TILDE);
- fixredir(redir, fn.list->text, 1);
+ fixredir(redir, fn.args[0], 1);
}
break;
case NXHERE:
@@ -753,28 +752,30 @@ isdeclarationcmd(struct narg *arg)
static void
xtracecommand(struct arglist *varlist, struct arglist *arglist)
{
- struct strlist *sp;
char sep = 0;
- const char *p, *ps4;
+ const char *text, *p, *ps4;
+ int i;
ps4 = expandstr(ps4val());
out2str(ps4 != NULL ? ps4 : ps4val());
- for (sp = varlist->list ; sp ; sp = sp->next) {
+ for (i = 0; i < varlist->count; i++) {
+ text = varlist->args[i];
if (sep != 0)
out2c(' ');
- p = strchr(sp->text, '=');
+ p = strchr(text, '=');
if (p != NULL) {
p++;
- outbin(sp->text, p - sp->text, out2);
+ outbin(text, p - text, out2);
out2qstr(p);
} else
- out2qstr(sp->text);
+ out2qstr(text);
sep = ' ';
}
- for (sp = arglist->list ; sp ; sp = sp->next) {
+ for (i = 0; i < arglist->count; i++) {
+ text = arglist->args[i];
if (sep != 0)
out2c(' ');
- out2qstr(sp->text);
+ out2qstr(text);
sep = ' ';
}
out2c('\n');
@@ -822,7 +823,6 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
int argc;
char **envp;
int varflag;
- struct strlist *sp;
int mode;
int pip[2];
struct cmdentry cmdentry;
@@ -838,11 +838,12 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
int realstatus;
int do_clearcmdentry;
const char *path = pathval();
+ int i;
/* First expand the arguments. */
TRACE(("evalcommand(%p, %d) called\n", (void *)cmd, flags));
- arglist.lastp = &arglist.list;
- varlist.lastp = &varlist.list;
+ emptyarglist(&arglist);
+ emptyarglist(&varlist);
varflag = 1;
jp = NULL;
do_clearcmdentry = 0;
@@ -857,25 +858,17 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
varflag = isdeclarationcmd(&argp->narg) ? 2 : 0;
expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
}
- *arglist.lastp = NULL;
- *varlist.lastp = NULL;
expredir(cmd->ncmd.redirect);
- argc = 0;
- for (sp = arglist.list ; sp ; sp = sp->next)
- argc++;
+ argc = arglist.count;
/* Add one slot at the beginning for tryexec(). */
argv = stalloc(sizeof (char *) * (argc + 2));
argv++;
- for (sp = arglist.list ; sp ; sp = sp->next) {
- TRACE(("evalcommand arg: %s\n", sp->text));
- *argv++ = sp->text;
- }
- *argv = NULL;
+ memcpy(argv, arglist.args, sizeof(*argv) * argc);
+ argv[argc] = NULL;
lastarg = NULL;
if (iflag && funcnest == 0 && argc > 0)
- lastarg = argv[-1];
- argv -= argc;
+ lastarg = argv[argc - 1];
/* Print the command if xflag is set. */
if (xflag)
@@ -895,9 +888,9 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
* Modify the command lookup path, if a PATH= assignment
* is present
*/
- for (sp = varlist.list ; sp ; sp = sp->next)
- if (strncmp(sp->text, PATH, sizeof(PATH) - 1) == 0) {
- path = sp->text + sizeof(PATH) - 1;
+ for (i = 0; i < varlist.count; i++)
+ if (strncmp(varlist.args[i], PATH, sizeof(PATH) - 1) == 0) {
+ path = varlist.args[i] + sizeof(PATH) - 1;
/*
* On `PATH=... command`, we need to make
* sure that the command isn't using the
@@ -999,7 +992,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
}
if (cmdentry.cmdtype == CMDNORMAL &&
cmd->ncmd.redirect == NULL &&
- varlist.list == NULL &&
+ varlist.count == 0 &&
(mode == FORK_FG || mode == FORK_NOJOB) &&
!disvforkset() && !iflag && !mflag) {
vforkexecshell(jp, argv, environment(), path,
@@ -1053,8 +1046,8 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
funcnest++;
redirect(cmd->ncmd.redirect, REDIR_PUSH);
INTON;
- for (sp = varlist.list ; sp ; sp = sp->next)
- mklocal(sp->text);
+ for (i = 0; i < varlist.count; i++)
+ mklocal(varlist.args[i]);
exitstatus = oexitstatus;
evaltree(getfuncnode(cmdentry.u.func),
flags & (EV_TESTED | EV_EXIT));
@@ -1087,7 +1080,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
}
savecmdname = commandname;
savetopfile = getcurrentfile();
- cmdenviron = varlist.list;
+ cmdenviron = &varlist;
e = -1;
savehandler = handler;
if (setjmp(jmploc.loc)) {
@@ -1152,8 +1145,8 @@ cmddone:
trputs("normal command: "); trargs(argv);
#endif
redirect(cmd->ncmd.redirect, 0);
- for (sp = varlist.list ; sp ; sp = sp->next)
- setvareq(sp->text, VEXPORT|VSTACK);
+ for (i = 0; i < varlist.count; i++)
+ setvareq(varlist.args[i], VEXPORT|VSTACK);
envp = environment();
shellexec(argv, envp, path, cmdentry.u.index);
/*NOTREACHED*/
@@ -1336,6 +1329,8 @@ truecmd(int argc __unused, char **argv __unused)
int
execcmd(int argc, char **argv)
{
+ int i;
+
/*
* Because we have historically not supported any options,
* only treat "--" specially.
@@ -1343,13 +1338,11 @@ execcmd(int argc, char **argv)
if (argc > 1 && strcmp(argv[1], "--") == 0)
argc--, argv++;
if (argc > 1) {
- struct strlist *sp;
-
iflag = 0; /* exit on error */
mflag = 0;
optschanged();
- for (sp = cmdenviron; sp ; sp = sp->next)
- setvareq(sp->text, VEXPORT|VSTACK);
+ for (i = 0; i < cmdenviron->count; i++)
+ setvareq(cmdenviron->args[i], VEXPORT|VSTACK);
shellexec(argv + 1, environment(), pathval(), 0);
}
diff --git a/bin/sh/eval.h b/bin/sh/eval.h
index d4092be..e781336 100644
--- a/bin/sh/eval.h
+++ b/bin/sh/eval.h
@@ -36,7 +36,7 @@
extern char *commandname; /* currently executing command */
extern int exitstatus; /* exit status of last command */
extern int oexitstatus; /* saved exit status */
-extern struct strlist *cmdenviron; /* environment for builtin command */
+extern struct arglist *cmdenviron; /* environment for builtin command */
struct backcmd { /* result of evalbackcmd */
diff --git a/bin/sh/expand.c b/bin/sh/expand.c
index 88d80ea..567b8a4 100644
--- a/bin/sh/expand.c
+++ b/bin/sh/expand.c
@@ -96,7 +96,6 @@ static char *expdest; /* output of current string */
static struct nodelist *argbackq; /* list of back quote expressions */
static struct ifsregion ifsfirst; /* first struct in list of ifs regions */
static struct ifsregion *ifslastp; /* last struct in list */
-static struct arglist exparg; /* holds expanded arg list */
static char *argstr(char *, int);
static char *exptilde(char *, int);
@@ -110,15 +109,43 @@ static void varvalue(const char *, int, int, int);
static void recordregion(int, int, int);
static void removerecordregions(int);
static void ifsbreakup(char *, struct arglist *);
-static void expandmeta(struct strlist *);
-static void expmeta(char *, char *);
-static void addfname(char *);
-static struct strlist *expsort(struct strlist *);
-static struct strlist *msort(struct strlist *, int);
+static void expandmeta(struct arglist *, struct arglist *);
+static void expmeta(char *, char *, struct arglist *);
+static int expsortcmp(const void *, const void *);
static int patmatch(const char *, const char *, int);
static char *cvtnum(int, char *);
+static void appendarglist(struct arglist *, char *);
static int collate_range_cmp(wchar_t, wchar_t);
+void
+emptyarglist(struct arglist *list)
+{
+
+ list->args = list->smallarg;
+ list->count = 0;
+ list->capacity = sizeof(list->smallarg) / sizeof(list->smallarg[0]);
+}
+
+static void
+appendarglist(struct arglist *list, char *str)
+{
+ char **newargs;
+ int newcapacity;
+
+ if (list->count >= list->capacity) {
+ newcapacity = list->capacity * 2;
+ if (newcapacity < 16)
+ newcapacity = 16;
+ if (newcapacity > INT_MAX / (int)sizeof(newargs[0]))
+ error("Too many entries in arglist");
+ newargs = stalloc(newcapacity * sizeof(newargs[0]));
+ memcpy(newargs, list->args, list->count * sizeof(newargs[0]));
+ list->args = newargs;
+ list->capacity = newcapacity;
+ }
+ list->args[list->count++] = str;
+}
+
static int
collate_range_cmp(wchar_t c1, wchar_t c2)
{
@@ -157,7 +184,7 @@ stputs_quotes(const char *data, const char *syntax, char *p)
void
expandarg(union node *arg, struct arglist *arglist, int flag)
{
- struct strlist *sp;
+ struct arglist exparg;
char *p;
argbackq = arg->narg.backquote;
@@ -171,18 +198,12 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
}
STPUTC('\0', expdest);
p = grabstackstr(expdest);
- exparg.lastp = &exparg.list;
+ emptyarglist(&exparg);
if (flag & EXP_FULL) {
ifsbreakup(p, &exparg);
- *exparg.lastp = NULL;
- exparg.lastp = &exparg.list;
- expandmeta(exparg.list);
- } else {
- sp = (struct strlist *)stalloc(sizeof (struct strlist));
- sp->text = p;
- *exparg.lastp = sp;
- exparg.lastp = &sp->next;
- }
+ expandmeta(&exparg, arglist);
+ } else
+ appendarglist(arglist, p);
while (ifsfirst.next != NULL) {
struct ifsregion *ifsp;
INTOFF;
@@ -191,11 +212,6 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
ifsfirst.next = ifsp;
INTON;
}
- *exparg.lastp = NULL;
- if (exparg.list) {
- *arglist->lastp = exparg.list;
- arglist->lastp = exparg.lastp;
- }
}
@@ -984,7 +1000,6 @@ static void
ifsbreakup(char *string, struct arglist *arglist)
{
struct ifsregion *ifsp;
- struct strlist *sp;
char *start;
char *p;
char *q;
@@ -996,10 +1011,7 @@ ifsbreakup(char *string, struct arglist *arglist)
if (ifslastp == NULL) {
/* Return entire argument, IFS doesn't apply to any of it */
- sp = (struct strlist *)stalloc(sizeof *sp);
- sp->text = start;
- *arglist->lastp = sp;
- arglist->lastp = &sp->next;
+ appendarglist(arglist, start);
return;
}
@@ -1038,10 +1050,7 @@ ifsbreakup(char *string, struct arglist *arglist)
/* Save this argument... */
*q = '\0';
- sp = (struct strlist *)stalloc(sizeof *sp);
- sp->text = start;
- *arglist->lastp = sp;
- arglist->lastp = &sp->next;
+ appendarglist(arglist, start);
p++;
if (ifsspc != NULL) {
@@ -1071,12 +1080,8 @@ ifsbreakup(char *string, struct arglist *arglist)
* Some recent clarification of the Posix spec say that it
* should only generate one....
*/
- if (had_param_ch || *start != 0) {
- sp = (struct strlist *)stalloc(sizeof *sp);
- sp->text = start;
- *arglist->lastp = sp;
- arglist->lastp = &sp->next;
- }
+ if (had_param_ch || *start != 0)
+ appendarglist(arglist, start);
}
@@ -1086,45 +1091,42 @@ static char expdir[PATH_MAX];
/*
* Perform pathname generation and remove control characters.
* At this point, the only control characters should be CTLESC and CTLQUOTEMARK.
- * The results are stored in the list exparg.
+ * The results are stored in the list dstlist.
*/
static void
-expandmeta(struct strlist *str)
+expandmeta(struct arglist *srclist, struct arglist *dstlist)
{
char *p;
- struct strlist **savelastp;
- struct strlist *sp;
+ int firstmatch;
+ int i;
char c;
- while (str) {
- savelastp = exparg.lastp;
+ for (i = 0; i < srclist->count; i++) {
+ firstmatch = dstlist->count;
if (!fflag) {
- p = str->text;
+ p = srclist->args[i];
for (; (c = *p) != '\0'; p++) {
/* fast check for meta chars */
if (c == '*' || c == '?' || c == '[') {
INTOFF;
- expmeta(expdir, str->text);
+ expmeta(expdir, srclist->args[i],
+ dstlist);
INTON;
break;
}
}
}
- if (exparg.lastp == savelastp) {
+ if (dstlist->count == firstmatch) {
/*
* no matches
*/
- *exparg.lastp = str;
- rmescapes(str->text);
- exparg.lastp = &str->next;
+ rmescapes(srclist->args[i]);
+ appendarglist(dstlist, srclist->args[i]);
} else {
- *exparg.lastp = NULL;
- *savelastp = sp = expsort(*savelastp);
- while (sp->next != NULL)
- sp = sp->next;
- exparg.lastp = &sp->next;
+ qsort(&dstlist->args[firstmatch],
+ dstlist->count - firstmatch,
+ sizeof(dstlist->args[0]), expsortcmp);
}
- str = str->next;
}
}
@@ -1134,7 +1136,7 @@ expandmeta(struct strlist *str)
*/
static void
-expmeta(char *enddir, char *name)
+expmeta(char *enddir, char *name, struct arglist *arglist)
{
const char *p;
const char *q;
@@ -1199,7 +1201,7 @@ expmeta(char *enddir, char *name)
return;
}
if (metaflag == 0 || lstat(expdir, &statb) >= 0)
- addfname(expdir);
+ appendarglist(arglist, stsavestr(expdir));
return;
}
endname = name + (p - name);
@@ -1251,7 +1253,7 @@ expmeta(char *enddir, char *name)
continue;
memcpy(enddir, dp->d_name, namlen + 1);
if (atend)
- addfname(expdir);
+ appendarglist(arglist, stsavestr(expdir));
else {
if (dp->d_type != DT_UNKNOWN &&
dp->d_type != DT_DIR &&
@@ -1261,7 +1263,7 @@ expmeta(char *enddir, char *name)
continue;
enddir[namlen] = '/';
enddir[namlen + 1] = '\0';
- expmeta(enddir + namlen + 1, endname);
+ expmeta(enddir + namlen + 1, endname, arglist);
}
}
}
@@ -1271,81 +1273,13 @@ expmeta(char *enddir, char *name)
}
-/*
- * Add a file name to the list.
- */
-
-static void
-addfname(char *name)
-{
- char *p;
- struct strlist *sp;
-
- p = stsavestr(name);
- sp = (struct strlist *)stalloc(sizeof *sp);
- sp->text = p;
- *exparg.lastp = sp;
- exparg.lastp = &sp->next;
-}
-
-
-/*
- * Sort the results of file name expansion. It calculates the number of
- * strings to sort and then calls msort (short for merge sort) to do the
- * work.
- */
-
-static struct strlist *
-expsort(struct strlist *str)
+static int
+expsortcmp(const void *p1, const void *p2)
{
- int len;
- struct strlist *sp;
-
- len = 0;
- for (sp = str ; sp ; sp = sp->next)
- len++;
- return msort(str, len);
-}
+ const char *s1 = *(const char * const *)p1;
+ const char *s2 = *(const char * const *)p2;
-
-static struct strlist *
-msort(struct strlist *list, int len)
-{
- struct strlist *p, *q = NULL;
- struct strlist **lpp;
- int half;
- int n;
-
- if (len <= 1)
- return list;
- half = len >> 1;
- p = list;
- for (n = half ; --n >= 0 ; ) {
- q = p;
- p = p->next;
- }
- q->next = NULL; /* terminate first half of list */
- q = msort(list, half); /* sort first half of list */
- p = msort(p, len - half); /* sort second half */
- lpp = &list;
- for (;;) {
- if (strcmp(p->text, q->text) < 0) {
- *lpp = p;
- lpp = &p->next;
- if ((p = *lpp) == NULL) {
- *lpp = q;
- break;
- }
- } else {
- *lpp = q;
- lpp = &q->next;
- if ((q = *lpp) == NULL) {
- *lpp = p;
- break;
- }
- }
- }
- return list;
+ return (strcmp(s1, s2));
}
@@ -1666,11 +1600,11 @@ freebsd_wordexpcmd(int argc __unused, char **argv __unused)
{
struct arglist arglist;
union node *args, *n;
- struct strlist *sp;
- size_t count, len;
+ size_t len;
int ch;
int protected = 0;
int fd = -1;
+ int i;
while ((ch = nextopt("f:p")) != '\0') {
switch (ch) {
@@ -1699,14 +1633,13 @@ freebsd_wordexpcmd(int argc __unused, char **argv __unused)
}
}
outcslow(' ', out1);
- arglist.lastp = &arglist.list;
+ emptyarglist(&arglist);
for (n = args; n != NULL; n = n->narg.next)
expandarg(n, &arglist, EXP_FULL | EXP_TILDE);
- *arglist.lastp = NULL;
- for (sp = arglist.list, count = len = 0; sp; sp = sp->next)
- count++, len += strlen(sp->text);
- out1fmt("%016zx %016zx", count, len);
- for (sp = arglist.list; sp; sp = sp->next)
- outbin(sp->text, strlen(sp->text) + 1, out1);
+ for (i = 0, len = 0; i < arglist.count; i++)
+ len += strlen(arglist.args[i]);
+ out1fmt("%016x %016zx", arglist.count, len);
+ for (i = 0; i < arglist.count; i++)
+ outbin(arglist.args[i], strlen(arglist.args[i]) + 1, out1);
return (0);
}
diff --git a/bin/sh/expand.h b/bin/sh/expand.h
index 93c80f3..c377156 100644
--- a/bin/sh/expand.h
+++ b/bin/sh/expand.h
@@ -33,15 +33,11 @@
* $FreeBSD$
*/
-struct strlist {
- struct strlist *next;
- char *text;
-};
-
-
struct arglist {
- struct strlist *list;
- struct strlist **lastp;
+ char **args;
+ int count;
+ int capacity;
+ char *smallarg[1];
};
/*
@@ -55,6 +51,7 @@ struct arglist {
#define EXP_LIT_QUOTED 0x40 /* for EXP_SPLIT_LIT, start off quoted */
+void emptyarglist(struct arglist *);
union node;
void expandarg(union node *, struct arglist *, int);
void rmescapes(char *);
diff --git a/bin/sh/var.c b/bin/sh/var.c
index f60dea1..cfba0ba 100644
--- a/bin/sh/var.c
+++ b/bin/sh/var.c
@@ -403,14 +403,13 @@ setvareq_const(const char *s, int flags)
*/
void
-listsetvar(struct strlist *list, int flags)
+listsetvar(struct arglist *list, int flags)
{
- struct strlist *lp;
+ int i;
INTOFF;
- for (lp = list ; lp ; lp = lp->next) {
- setvareq(savestr(lp->text), flags);
- }
+ for (i = 0; i < list->count; i++)
+ setvareq(savestr(list->args[i]), flags);
INTON;
}
@@ -442,14 +441,14 @@ lookupvar(const char *name)
char *
bltinlookup(const char *name, int doall)
{
- struct strlist *sp;
struct var *v;
char *result;
+ int i;
result = NULL;
- for (sp = cmdenviron ; sp ; sp = sp->next) {
- if (varequal(sp->text, name))
- result = strchr(sp->text, '=') + 1;
+ if (cmdenviron) for (i = 0; i < cmdenviron->count; i++) {
+ if (varequal(cmdenviron->args[i], name))
+ result = strchr(cmdenviron->args[i], '=') + 1;
}
if (result != NULL)
return result;
@@ -468,13 +467,12 @@ bltinlookup(const char *name, int doall)
void
bltinsetlocale(void)
{
- struct strlist *lp;
int act = 0;
char *loc, *locdef;
int i;
- for (lp = cmdenviron ; lp ; lp = lp->next) {
- if (localevar(lp->text)) {
+ if (cmdenviron) for (i = 0; i < cmdenviron->count; i++) {
+ if (localevar(cmdenviron->args[i])) {
act = 1;
break;
}
@@ -507,11 +505,11 @@ bltinsetlocale(void)
void
bltinunsetlocale(void)
{
- struct strlist *lp;
+ int i;
INTOFF;
- for (lp = cmdenviron ; lp ; lp = lp->next) {
- if (localevar(lp->text)) {
+ if (cmdenviron) for (i = 0; i < cmdenviron->count; i++) {
+ if (localevar(cmdenviron->args[i])) {
setlocale(LC_ALL, "");
updatecharset();
return;
diff --git a/bin/sh/var.h b/bin/sh/var.h
index 6e831ae..ede13cf 100644
--- a/bin/sh/var.h
+++ b/bin/sh/var.h
@@ -114,8 +114,8 @@ extern int initial_localeisutf8;
void initvar(void);
void setvar(const char *, const char *, int);
void setvareq(char *, int);
-struct strlist;
-void listsetvar(struct strlist *, int);
+struct arglist;
+void listsetvar(struct arglist *, int);
char *lookupvar(const char *);
char *bltinlookup(const char *, int);
void bltinsetlocale(void);
diff --git a/share/mk/netbsd-tests.test.mk b/share/mk/netbsd-tests.test.mk
index 2186594..7061db6 100644
--- a/share/mk/netbsd-tests.test.mk
+++ b/share/mk/netbsd-tests.test.mk
@@ -3,7 +3,7 @@
.if !target(__netbsd_tests.test.mk__)
__netbsd_tests.test.mk__:
-OBJROOT?= ${.OBJDIR:S/${RELDIR}//}
+OBJTOP?= ${.OBJDIR:S/${RELDIR}//}
TESTSRC?= ${SRCTOP}/contrib/netbsd-tests/${RELDIR:H}
diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c
index 8ba0958..4166bb7 100644
--- a/sys/dev/ath/if_ath.c
+++ b/sys/dev/ath/if_ath.c
@@ -3262,7 +3262,7 @@ ath_transmit(struct ieee80211com *ic, struct mbuf *m)
* XXXGL: is mbuf valid after ath_txfrag_setup? If yes,
* we shouldn't free it but return back.
*/
- ath_freetx(m);
+ ieee80211_free_mbuf(m);
m = NULL;
goto bad;
}
@@ -3356,7 +3356,7 @@ reclaim:
__func__,
ieee80211_state_name[ni->ni_vap->iv_state]);
/* XXX dmamap */
- ath_freetx(next);
+ ieee80211_free_mbuf(next);
goto reclaim;
}
m = next;
diff --git a/sys/dev/ath/if_ath_tx.c b/sys/dev/ath/if_ath_tx.c
index bee6320..7350bb0 100644
--- a/sys/dev/ath/if_ath_tx.c
+++ b/sys/dev/ath/if_ath_tx.c
@@ -283,22 +283,6 @@ ath_txfrag_setup(struct ath_softc *sc, ath_bufhead *frags,
return !TAILQ_EMPTY(frags);
}
-/*
- * Reclaim mbuf resources. For fragmented frames we
- * need to claim each frag chained with m_nextpkt.
- */
-void
-ath_freetx(struct mbuf *m)
-{
- struct mbuf *next;
-
- do {
- next = m->m_nextpkt;
- m->m_nextpkt = NULL;
- m_freem(m);
- } while ((m = next) != NULL);
-}
-
static int
ath_tx_dmasetup(struct ath_softc *sc, struct ath_buf *bf, struct mbuf *m0)
{
@@ -317,7 +301,7 @@ ath_tx_dmasetup(struct ath_softc *sc, struct ath_buf *bf, struct mbuf *m0)
bf->bf_nseg = ATH_MAX_SCATTER + 1;
} else if (error != 0) {
sc->sc_stats.ast_tx_busdma++;
- ath_freetx(m0);
+ ieee80211_free_mbuf(m0);
return error;
}
/*
@@ -329,7 +313,7 @@ ath_tx_dmasetup(struct ath_softc *sc, struct ath_buf *bf, struct mbuf *m0)
sc->sc_stats.ast_tx_linear++;
m = m_collapse(m0, M_NOWAIT, ATH_MAX_SCATTER);
if (m == NULL) {
- ath_freetx(m0);
+ ieee80211_free_mbuf(m0);
sc->sc_stats.ast_tx_nombuf++;
return ENOMEM;
}
@@ -339,14 +323,14 @@ ath_tx_dmasetup(struct ath_softc *sc, struct ath_buf *bf, struct mbuf *m0)
BUS_DMA_NOWAIT);
if (error != 0) {
sc->sc_stats.ast_tx_busdma++;
- ath_freetx(m0);
+ ieee80211_free_mbuf(m0);
return error;
}
KASSERT(bf->bf_nseg <= ATH_MAX_SCATTER,
("too many segments after defrag; nseg %u", bf->bf_nseg));
} else if (bf->bf_nseg == 0) { /* null packet, discard */
sc->sc_stats.ast_tx_nodata++;
- ath_freetx(m0);
+ ieee80211_free_mbuf(m0);
return EIO;
}
DPRINTF(sc, ATH_DEBUG_XMIT, "%s: m %p len %u\n",
@@ -1581,7 +1565,7 @@ ath_tx_normal_setup(struct ath_softc *sc, struct ieee80211_node *ni,
/* Handle encryption twiddling if needed */
if (! ath_tx_tag_crypto(sc, ni, m0, iswep, isfrag, &hdrlen,
&pktlen, &keyix)) {
- ath_freetx(m0);
+ ieee80211_free_mbuf(m0);
return EIO;
}
@@ -1693,7 +1677,7 @@ ath_tx_normal_setup(struct ath_softc *sc, struct ieee80211_node *ni,
wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK, __func__);
/* XXX statistic */
/* XXX free tx dmamap */
- ath_freetx(m0);
+ ieee80211_free_mbuf(m0);
return EIO;
}
@@ -1749,7 +1733,7 @@ ath_tx_normal_setup(struct ath_softc *sc, struct ieee80211_node *ni,
"%s: discard frame, ACK required w/ TDMA\n", __func__);
sc->sc_stats.ast_tdma_ack++;
/* XXX free tx dmamap */
- ath_freetx(m0);
+ ieee80211_free_mbuf(m0);
return EIO;
}
#endif
@@ -2133,7 +2117,7 @@ ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni,
if (! ath_tx_tag_crypto(sc, ni,
m0, params->ibp_flags & IEEE80211_BPF_CRYPTO, 0,
&hdrlen, &pktlen, &keyix)) {
- ath_freetx(m0);
+ ieee80211_free_mbuf(m0);
return EIO;
}
/* packet header may have moved, reset our local pointer */
@@ -2468,7 +2452,6 @@ badbad:
ATH_KTR(sc, ATH_KTR_TX, 2, "ath_raw_xmit: bad0: m=%p, params=%p",
m, params);
sc->sc_stats.ast_tx_raw_fail++;
- ieee80211_free_node(ni);
return error;
}
diff --git a/sys/dev/ath/if_ath_tx.h b/sys/dev/ath/if_ath_tx.h
index 281dbcb..19f7707 100644
--- a/sys/dev/ath/if_ath_tx.h
+++ b/sys/dev/ath/if_ath_tx.h
@@ -85,7 +85,6 @@
*/
#define ATH_AGGR_MAXSIZE 65530
-extern void ath_freetx(struct mbuf *m);
extern void ath_tx_node_flush(struct ath_softc *sc, struct ath_node *an);
extern void ath_tx_txq_drain(struct ath_softc *sc, struct ath_txq *txq);
extern void ath_txfrag_cleanup(struct ath_softc *sc, ath_bufhead *frags,
diff --git a/sys/dev/bwi/if_bwi.c b/sys/dev/bwi/if_bwi.c
index 0a220a1..ebed09c 100644
--- a/sys/dev/bwi/if_bwi.c
+++ b/sys/dev/bwi/if_bwi.c
@@ -1399,7 +1399,6 @@ bwi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
int idx, error;
if ((sc->sc_flags & BWI_F_RUNNING) == 0) {
- ieee80211_free_node(ni);
m_freem(m);
return ENETDOWN;
}
@@ -1424,9 +1423,7 @@ bwi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
tbd->tbd_used++;
tbd->tbd_idx = (idx + 1) % BWI_TX_NDESC;
sc->sc_tx_timer = 5;
- } else
- /* NB: m is reclaimed on encap failure */
- ieee80211_free_node(ni);
+ }
BWI_UNLOCK(sc);
return error;
}
diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c
index 15f6f27..0746a8e 100644
--- a/sys/dev/bwn/if_bwn.c
+++ b/sys/dev/bwn/if_bwn.c
@@ -2684,29 +2684,26 @@ bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
struct ieee80211com *ic = ni->ni_ic;
struct bwn_softc *sc = ic->ic_softc;
struct bwn_mac *mac = sc->sc_curmac;
+ int error;
if ((sc->sc_flags & BWN_FLAG_RUNNING) == 0 ||
mac->mac_status < BWN_MAC_STATUS_STARTED) {
- ieee80211_free_node(ni);
m_freem(m);
return (ENETDOWN);
}
BWN_LOCK(sc);
if (bwn_tx_isfull(sc, m)) {
- ieee80211_free_node(ni);
m_freem(m);
BWN_UNLOCK(sc);
return (ENOBUFS);
}
- if (bwn_tx_start(sc, ni, m) != 0) {
- if (ni != NULL)
- ieee80211_free_node(ni);
- }
- sc->sc_watchdog_timer = 5;
+ error = bwn_tx_start(sc, ni, m);
+ if (error == 0)
+ sc->sc_watchdog_timer = 5;
BWN_UNLOCK(sc);
- return (0);
+ return (error);
}
/*
diff --git a/sys/dev/iwm/if_iwm.c b/sys/dev/iwm/if_iwm.c
index cd2ccd2..df17f93 100644
--- a/sys/dev/iwm/if_iwm.c
+++ b/sys/dev/iwm/if_iwm.c
@@ -2877,7 +2877,6 @@ iwm_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
"->%s begin\n", __func__);
if ((sc->sc_flags & IWM_FLAG_HW_INITED) == 0) {
- ieee80211_free_node(ni);
m_freem(m);
IWM_DPRINTF(sc, IWM_DEBUG_XMIT,
"<-%s not RUNNING\n", __func__);
@@ -2891,10 +2890,6 @@ iwm_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
} else {
error = iwm_tx(sc, m, ni, 0);
}
- if (error != 0) {
- /* NB: m is reclaimed on tx failure */
- ieee80211_free_node(ni);
- }
sc->sc_tx_timer = 5;
IWM_UNLOCK(sc);
diff --git a/sys/dev/iwm/if_iwmvar.h b/sys/dev/iwm/if_iwmvar.h
index ead6904..9434b83 100644
--- a/sys/dev/iwm/if_iwmvar.h
+++ b/sys/dev/iwm/if_iwmvar.h
@@ -496,14 +496,12 @@ struct iwm_softc {
uint8_t pad[IEEE80211_RADIOTAP_HDRLEN];
} sc_rxtapu;
#define sc_rxtap sc_rxtapu.th
- int sc_rxtap_len;
union {
struct iwm_tx_radiotap_header th;
uint8_t pad[IEEE80211_RADIOTAP_HDRLEN];
} sc_txtapu;
#define sc_txtap sc_txtapu.th
- int sc_txtap_len;
int sc_max_rssi;
};
diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c
index c1ed6ab..0cdeafb 100644
--- a/sys/dev/iwn/if_iwn.c
+++ b/sys/dev/iwn/if_iwn.c
@@ -4875,7 +4875,6 @@ iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
DPRINTF(sc, IWN_DEBUG_XMIT | IWN_DEBUG_TRACE, "->%s begin\n", __func__);
if ((sc->sc_flags & IWN_FLAG_RUNNING) == 0) {
- ieee80211_free_node(ni);
m_freem(m);
return ENETDOWN;
}
@@ -4889,9 +4888,6 @@ iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
if (sc->sc_beacon_wait) {
if (iwn_xmit_queue_enqueue(sc, m) != 0) {
m_freem(m);
- if_inc_counter(ni->ni_vap->iv_ifp,
- IFCOUNTER_OERRORS, 1);
- ieee80211_free_node(ni);
IWN_UNLOCK(sc);
return (ENOBUFS);
}
@@ -4913,10 +4909,7 @@ iwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
*/
error = iwn_tx_data_raw(sc, m, ni, params);
}
- if (error != 0) {
- /* NB: m is reclaimed on tx failure */
- ieee80211_free_node(ni);
- } else
+ if (error == 0)
sc->sc_tx_timer = 5;
IWN_UNLOCK(sc);
@@ -4950,9 +4943,7 @@ iwn_transmit(struct ieee80211com *ic, struct mbuf *m)
}
error = iwn_tx_data(sc, m, ni);
- if (error) {
- if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1);
- } else
+ if (!error)
sc->sc_tx_timer = 5;
IWN_UNLOCK(sc);
return (error);
diff --git a/sys/dev/malo/if_malo.c b/sys/dev/malo/if_malo.c
index 251ddc6..d02b6d5 100644
--- a/sys/dev/malo/if_malo.c
+++ b/sys/dev/malo/if_malo.c
@@ -1786,7 +1786,6 @@ malo_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
struct malo_txq *txq;
if (!sc->malo_running || sc->malo_invalid) {
- ieee80211_free_node(ni);
m_freem(m);
return ENETDOWN;
}
@@ -1800,7 +1799,6 @@ malo_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
txq = &sc->malo_txq[0];
bf = malo_getbuf(sc, txq);
if (bf == NULL) {
- ieee80211_free_node(ni);
m_freem(m);
return ENOBUFS;
}
@@ -1816,7 +1814,6 @@ malo_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
txq->nfree++;
MALO_TXQ_UNLOCK(txq);
- ieee80211_free_node(ni);
return EIO; /* XXX */
}
diff --git a/sys/dev/mwl/if_mwl.c b/sys/dev/mwl/if_mwl.c
index 7f9d8e0..d01165c 100644
--- a/sys/dev/mwl/if_mwl.c
+++ b/sys/dev/mwl/if_mwl.c
@@ -1422,7 +1422,6 @@ mwl_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
struct mwl_txq *txq;
if (!sc->sc_running || sc->sc_invalid) {
- ieee80211_free_node(ni);
m_freem(m);
return ENETDOWN;
}
@@ -1438,7 +1437,6 @@ mwl_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
bf = mwl_gettxbuf(sc, txq);
if (bf == NULL) {
sc->sc_stats.mst_tx_qstop++;
- ieee80211_free_node(ni);
m_freem(m);
return ENOBUFS;
}
@@ -1448,7 +1446,6 @@ mwl_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
if (mwl_tx_start(sc, ni, bf, m)) {
mwl_puttxbuf_head(txq, bf);
- ieee80211_free_node(ni);
return EIO; /* XXX */
}
/*
diff --git a/sys/dev/ntb/if_ntb/if_ntb.c b/sys/dev/ntb/if_ntb/if_ntb.c
index 84716d9..461a4a3 100644
--- a/sys/dev/ntb/if_ntb/if_ntb.c
+++ b/sys/dev/ntb/if_ntb/if_ntb.c
@@ -194,11 +194,22 @@ struct ntb_payload_header {
};
enum {
+ /*
+ * The order of this enum is part of the if_ntb remote protocol. Do
+ * not reorder without bumping protocol version (and it's probably best
+ * to keep the protocol in lock-step with the Linux NTB driver.
+ */
IF_NTB_VERSION = 0,
- IF_NTB_MW0_SZ,
- IF_NTB_MW1_SZ,
- IF_NTB_NUM_QPS,
IF_NTB_QP_LINKS,
+ IF_NTB_NUM_QPS,
+ IF_NTB_NUM_MWS,
+ /*
+ * N.B.: transport_link_work assumes MW1 enums = MW0 + 2.
+ */
+ IF_NTB_MW0_SZ_HIGH,
+ IF_NTB_MW0_SZ_LOW,
+ IF_NTB_MW1_SZ_HIGH,
+ IF_NTB_MW1_SZ_LOW,
IF_NTB_MAX_SPAD,
};
@@ -242,6 +253,7 @@ static void ntb_rx_completion_task(void *arg, int pending);
static void ntb_transport_event_callback(void *data, enum ntb_hw_event event);
static void ntb_transport_link_work(void *arg);
static int ntb_set_mw(struct ntb_netdev *nt, int num_mw, unsigned int size);
+static void ntb_free_mw(struct ntb_netdev *nt, int num_mw);
static void ntb_transport_setup_qp_mw(struct ntb_netdev *nt,
unsigned int qp_num);
static void ntb_qp_link_work(void *arg);
@@ -514,9 +526,7 @@ ntb_transport_free(void *transport)
ntb_unregister_event_callback(ntb);
for (i = 0; i < NTB_NUM_MW; i++)
- if (nt->mw[i].virt_addr != NULL)
- contigfree(nt->mw[i].virt_addr, nt->mw[i].size,
- M_NTB_IF);
+ ntb_free_mw(nt, i);
free(nt->qps, M_NTB_IF);
ntb_unregister_transport(ntb);
@@ -548,11 +558,11 @@ ntb_transport_init_queue(struct ntb_netdev *nt, unsigned int qp_num)
(qp_num / NTB_NUM_MW * tx_size));
tx_size -= sizeof(struct ntb_rx_info);
- qp->tx_mw = qp->rx_info + sizeof(struct ntb_rx_info);
+ qp->tx_mw = qp->rx_info + 1;
+ /* Due to house-keeping, there must be at least 2 buffs */
qp->tx_max_frame = min(transport_mtu + sizeof(struct ntb_payload_header),
- tx_size);
+ tx_size / 2);
qp->tx_max_entry = tx_size / qp->tx_max_frame;
- qp->tx_index = 0;
callout_init(&qp->link_work, 0);
callout_init(&qp->queue_full, 1);
@@ -843,7 +853,8 @@ ntb_rx_pendq_full(void *arg)
static void
ntb_transport_rx(struct ntb_transport_qp *qp)
{
- int rc, i;
+ uint64_t i;
+ int rc;
/*
* Limit the number of packets processed in a single interrupt to
@@ -851,7 +862,7 @@ ntb_transport_rx(struct ntb_transport_qp *qp)
*/
mtx_lock(&qp->transport->rx_lock);
CTR0(KTR_NTB, "RX: transport_rx");
- for (i = 0; i < NTB_RX_MAX_PKTS; i++) {
+ for (i = 0; i < qp->rx_max_entry; i++) {
rc = ntb_process_rxc(qp);
if (rc != 0) {
CTR0(KTR_NTB, "RX: process_rxc failed");
@@ -1019,19 +1030,24 @@ ntb_transport_link_work(void *arg)
struct ntb_netdev *nt = arg;
struct ntb_softc *ntb = nt->ntb;
struct ntb_transport_qp *qp;
+ uint64_t val64;
uint32_t val;
int rc, i;
- /* send the local info */
- rc = ntb_write_remote_spad(ntb, IF_NTB_VERSION, NTB_TRANSPORT_VERSION);
- if (rc != 0)
- goto out;
-
- rc = ntb_write_remote_spad(ntb, IF_NTB_MW0_SZ, ntb_get_mw_size(ntb, 0));
- if (rc != 0)
- goto out;
+ /* send the local info, in the opposite order of the way we read it */
+ for (i = 0; i < NTB_NUM_MW; i++) {
+ rc = ntb_write_remote_spad(ntb, IF_NTB_MW0_SZ_HIGH + (i * 2),
+ ntb_get_mw_size(ntb, i) >> 32);
+ if (rc != 0)
+ goto out;
+
+ rc = ntb_write_remote_spad(ntb, IF_NTB_MW0_SZ_LOW + (i * 2),
+ (uint32_t)ntb_get_mw_size(ntb, i));
+ if (rc != 0)
+ goto out;
+ }
- rc = ntb_write_remote_spad(ntb, IF_NTB_MW1_SZ, ntb_get_mw_size(ntb, 1));
+ rc = ntb_write_remote_spad(ntb, IF_NTB_NUM_MWS, NTB_NUM_MW);
if (rc != 0)
goto out;
@@ -1039,11 +1055,7 @@ ntb_transport_link_work(void *arg)
if (rc != 0)
goto out;
- rc = ntb_read_remote_spad(ntb, IF_NTB_QP_LINKS, &val);
- if (rc != 0)
- goto out;
-
- rc = ntb_write_remote_spad(ntb, IF_NTB_QP_LINKS, val);
+ rc = ntb_write_remote_spad(ntb, IF_NTB_VERSION, NTB_TRANSPORT_VERSION);
if (rc != 0)
goto out;
@@ -1062,27 +1074,32 @@ ntb_transport_link_work(void *arg)
if (val != nt->max_qps)
goto out;
- rc = ntb_read_local_spad(ntb, IF_NTB_MW0_SZ, &val);
+ rc = ntb_read_local_spad(ntb, IF_NTB_NUM_MWS, &val);
if (rc != 0)
goto out;
- if (val == 0)
+ if (val != NTB_NUM_MW)
goto out;
- rc = ntb_set_mw(nt, 0, val);
- if (rc != 0)
- return;
+ for (i = 0; i < NTB_NUM_MW; i++) {
+ rc = ntb_read_local_spad(ntb, IF_NTB_MW0_SZ_HIGH + (i * 2),
+ &val);
+ if (rc != 0)
+ goto free_mws;
- rc = ntb_read_local_spad(ntb, IF_NTB_MW1_SZ, &val);
- if (rc != 0)
- goto out;
+ val64 = (uint64_t)val << 32;
- if (val == 0)
- goto out;
+ rc = ntb_read_local_spad(ntb, IF_NTB_MW0_SZ_LOW + (i * 2),
+ &val);
+ if (rc != 0)
+ goto free_mws;
- rc = ntb_set_mw(nt, 1, val);
- if (rc != 0)
- return;
+ val64 |= val;
+
+ rc = ntb_set_mw(nt, i, val64);
+ if (rc != 0)
+ goto free_mws;
+ }
nt->transport_link = NTB_LINK_UP;
if (bootverbose)
@@ -1099,10 +1116,13 @@ ntb_transport_link_work(void *arg)
return;
+free_mws:
+ for (i = 0; i < NTB_NUM_MW; i++)
+ ntb_free_mw(nt, i);
out:
if (ntb_query_link_status(ntb))
callout_reset(&nt->link_work,
- NTB_LINK_DOWN_TIMEOUT * hz / 1000, ntb_transport_link_work, nt);
+ NTB_LINK_DOWN_TIMEOUT * hz / 1000, ntb_transport_link_work, nt);
}
static int
@@ -1110,12 +1130,20 @@ ntb_set_mw(struct ntb_netdev *nt, int num_mw, unsigned int size)
{
struct ntb_transport_mw *mw = &nt->mw[num_mw];
+ /* No need to re-setup */
+ if (mw->size == size)
+ return (0);
+
+ if (mw->size != 0)
+ ntb_free_mw(nt, num_mw);
+
/* Alloc memory for receiving data. Must be 4k aligned */
mw->size = size;
mw->virt_addr = contigmalloc(mw->size, M_NTB_IF, M_ZERO, 0,
BUS_SPACE_MAXADDR, mw->size, 0);
if (mw->virt_addr == NULL) {
+ mw->size = 0;
printf("ntb: Unable to allocate MW buffer of size %d\n",
(int)mw->size);
return (ENOMEM);
@@ -1130,6 +1158,18 @@ ntb_set_mw(struct ntb_netdev *nt, int num_mw, unsigned int size)
}
static void
+ntb_free_mw(struct ntb_netdev *nt, int num_mw)
+{
+ struct ntb_transport_mw *mw = &nt->mw[num_mw];
+
+ if (mw->virt_addr == NULL)
+ return;
+
+ contigfree(mw->virt_addr, mw->size, M_NTB_IF);
+ mw->virt_addr = NULL;
+}
+
+static void
ntb_transport_setup_qp_mw(struct ntb_netdev *nt, unsigned int qp_num)
{
struct ntb_transport_qp *qp = &nt->qps[qp_num];
@@ -1148,14 +1188,14 @@ ntb_transport_setup_qp_mw(struct ntb_netdev *nt, unsigned int qp_num)
(qp_num / NTB_NUM_MW * rx_size));
rx_size -= sizeof(struct ntb_rx_info);
- qp->rx_buff = qp->remote_rx_info + sizeof(struct ntb_rx_info);
+ qp->rx_buff = qp->remote_rx_info + 1;
+ /* Due to house-keeping, there must be at least 2 buffs */
qp->rx_max_frame = min(transport_mtu + sizeof(struct ntb_payload_header),
- rx_size);
+ rx_size / 2);
qp->rx_max_entry = rx_size / qp->rx_max_frame;
qp->rx_index = 0;
- qp->tx_index = 0;
- qp->remote_rx_info->entry = qp->rx_max_entry;
+ qp->remote_rx_info->entry = qp->rx_max_entry - 1;
/* setup the hdr offsets with 0's */
for (i = 0; i < qp->rx_max_entry; i++) {
@@ -1167,6 +1207,7 @@ ntb_transport_setup_qp_mw(struct ntb_netdev *nt, unsigned int qp_num)
qp->rx_pkts = 0;
qp->tx_pkts = 0;
+ qp->tx_index = 0;
}
static void
diff --git a/sys/dev/otus/if_otus.c b/sys/dev/otus/if_otus.c
index e60157a..1808c95 100644
--- a/sys/dev/otus/if_otus.c
+++ b/sys/dev/otus/if_otus.c
@@ -567,7 +567,6 @@ error:
if (bf)
otus_freebuf(sc, bf);
OTUS_UNLOCK(sc);
- ieee80211_free_node(ni);
m_freem(m);
return (ENXIO);
}
@@ -1713,7 +1712,6 @@ otus_sub_rxeof(struct otus_softc *sc, uint8_t *buf, int len, struct mbufq *rxq)
break;
}
mb.m_data = (caddr_t)tap;
- mb.m_len = sc->sc_rxtap_len;
mb.m_next = m;
mb.m_nextpkt = NULL;
mb.m_type = 0;
diff --git a/sys/dev/otus/if_otusreg.h b/sys/dev/otus/if_otusreg.h
index 9f62ebd..4352778 100644
--- a/sys/dev/otus/if_otusreg.h
+++ b/sys/dev/otus/if_otusreg.h
@@ -1017,14 +1017,12 @@ struct otus_softc {
uint8_t pad[64];
} sc_rxtapu;
#define sc_rxtap sc_rxtapu.th
- int sc_rxtap_len;
union {
struct otus_tx_radiotap_header th;
uint8_t pad[64];
} sc_txtapu;
#define sc_txtap sc_txtapu.th
- int sc_txtap_len;
};
#endif /* __IF_OTUSREG_H__ */
diff --git a/sys/dev/ral/rt2560.c b/sys/dev/ral/rt2560.c
index b03e8fa..e5d7518 100644
--- a/sys/dev/ral/rt2560.c
+++ b/sys/dev/ral/rt2560.c
@@ -2711,13 +2711,11 @@ rt2560_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
if (!(sc->sc_flags & RT2560_F_RUNNING)) {
RAL_UNLOCK(sc);
m_freem(m);
- ieee80211_free_node(ni);
return ENETDOWN;
}
if (sc->prioq.queued >= RT2560_PRIO_RING_COUNT) {
RAL_UNLOCK(sc);
m_freem(m);
- ieee80211_free_node(ni);
return ENOBUFS; /* XXX */
}
@@ -2742,7 +2740,6 @@ rt2560_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
return 0;
bad:
- ieee80211_free_node(ni);
RAL_UNLOCK(sc);
return EIO; /* XXX */
}
diff --git a/sys/dev/ral/rt2560var.h b/sys/dev/ral/rt2560var.h
index 12601d8..9d7ed53 100644
--- a/sys/dev/ral/rt2560var.h
+++ b/sys/dev/ral/rt2560var.h
@@ -146,10 +146,8 @@ struct rt2560_softc {
int nb_ant;
struct rt2560_rx_radiotap_header sc_rxtap;
- int sc_rxtap_len;
-
struct rt2560_tx_radiotap_header sc_txtap;
- int sc_txtap_len;
+
#define RT2560_F_INPUT_RUNNING 0x1
#define RT2560_F_RUNNING 0x2
int sc_flags;
diff --git a/sys/dev/ral/rt2661.c b/sys/dev/ral/rt2661.c
index 100b5d6..cff64b1 100644
--- a/sys/dev/ral/rt2661.c
+++ b/sys/dev/ral/rt2661.c
@@ -1636,13 +1636,11 @@ rt2661_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
if (!(sc->sc_flags & RAL_RUNNING)) {
RAL_UNLOCK(sc);
m_freem(m);
- ieee80211_free_node(ni);
return ENETDOWN;
}
if (sc->mgtq.queued >= RT2661_MGT_RING_COUNT) {
RAL_UNLOCK(sc);
m_freem(m);
- ieee80211_free_node(ni);
return ENOBUFS; /* XXX */
}
@@ -1659,7 +1657,6 @@ rt2661_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
return 0;
bad:
- ieee80211_free_node(ni);
RAL_UNLOCK(sc);
return EIO; /* XXX */
}
diff --git a/sys/dev/ral/rt2661var.h b/sys/dev/ral/rt2661var.h
index 7ea16f6..93810a6 100644
--- a/sys/dev/ral/rt2661var.h
+++ b/sys/dev/ral/rt2661var.h
@@ -157,9 +157,7 @@ struct rt2661_softc {
int dwelltime;
struct rt2661_rx_radiotap_header sc_rxtap;
- int sc_rxtap_len;
struct rt2661_tx_radiotap_header sc_txtap;
- int sc_txtap_len;
};
int rt2661_attach(device_t, int);
diff --git a/sys/dev/ral/rt2860.c b/sys/dev/ral/rt2860.c
index 9c7fa53..d233315 100644
--- a/sys/dev/ral/rt2860.c
+++ b/sys/dev/ral/rt2860.c
@@ -1702,7 +1702,6 @@ rt2860_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
if (!(sc->sc_flags & RT2860_RUNNNING)) {
RAL_UNLOCK(sc);
m_freem(m);
- ieee80211_free_node(ni);
return ENETDOWN;
}
if (params == NULL) {
@@ -1718,10 +1717,6 @@ rt2860_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
*/
error = rt2860_tx_raw(sc, m, ni, params);
}
- if (error != 0) {
- /* NB: m is reclaimed on tx failure */
- ieee80211_free_node(ni);
- }
sc->sc_tx_timer = 5;
RAL_UNLOCK(sc);
return error;
diff --git a/sys/dev/ral/rt2860var.h b/sys/dev/ral/rt2860var.h
index 3779e5b..f7fd218 100644
--- a/sys/dev/ral/rt2860var.h
+++ b/sys/dev/ral/rt2860var.h
@@ -194,9 +194,7 @@ struct rt2860_softc {
uint32_t txpow40mhz_5ghz[5];
struct rt2860_rx_radiotap_header sc_rxtap;
- int sc_rxtap_len;
struct rt2860_tx_radiotap_header sc_txtap;
- int sc_txtap_len;
};
int rt2860_attach(device_t, int);
diff --git a/sys/dev/usb/wlan/if_rsu.c b/sys/dev/usb/wlan/if_rsu.c
index 4fb9d85..6558c93 100644
--- a/sys/dev/usb/wlan/if_rsu.c
+++ b/sys/dev/usb/wlan/if_rsu.c
@@ -2793,19 +2793,16 @@ rsu_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
/* prevent management frames from being sent if we're not ready */
if (!sc->sc_running) {
m_freem(m);
- ieee80211_free_node(ni);
return (ENETDOWN);
}
RSU_LOCK(sc);
bf = rsu_getbuf(sc);
if (bf == NULL) {
- ieee80211_free_node(ni);
m_freem(m);
RSU_UNLOCK(sc);
return (ENOBUFS);
}
if (rsu_tx_start(sc, ni, m, bf) != 0) {
- ieee80211_free_node(ni);
m_freem(m);
rsu_freebuf(sc, bf);
RSU_UNLOCK(sc);
diff --git a/sys/dev/usb/wlan/if_rsureg.h b/sys/dev/usb/wlan/if_rsureg.h
index ddb29a3..c40f28d 100644
--- a/sys/dev/usb/wlan/if_rsureg.h
+++ b/sys/dev/usb/wlan/if_rsureg.h
@@ -793,12 +793,10 @@ struct rsu_softc {
uint8_t pad[64];
} sc_rxtapu;
#define sc_rxtap sc_rxtapu.th
- int sc_rxtap_len;
union {
struct rsu_tx_radiotap_header th;
uint8_t pad[64];
} sc_txtapu;
#define sc_txtap sc_txtapu.th
- int sc_txtap_len;
};
diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c
index f1c9cdf..de7b880 100644
--- a/sys/dev/usb/wlan/if_rum.c
+++ b/sys/dev/usb/wlan/if_rum.c
@@ -2850,7 +2850,6 @@ rum_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
bad:
RUM_UNLOCK(sc);
m_freem(m);
- ieee80211_free_node(ni);
return ret;
}
diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c
index be43755..3a8c020 100644
--- a/sys/dev/usb/wlan/if_run.c
+++ b/sys/dev/usb/wlan/if_run.c
@@ -3707,7 +3707,6 @@ done:
if (error != 0) {
if(m != NULL)
m_freem(m);
- ieee80211_free_node(ni);
}
return (error);
diff --git a/sys/dev/usb/wlan/if_runvar.h b/sys/dev/usb/wlan/if_runvar.h
index 3af5b22..aabdaf1 100644
--- a/sys/dev/usb/wlan/if_runvar.h
+++ b/sys/dev/usb/wlan/if_runvar.h
@@ -253,14 +253,12 @@ struct run_softc {
uint8_t pad[64];
} sc_rxtapu;
#define sc_rxtap sc_rxtapu.th
- int sc_rxtap_len;
union {
struct run_tx_radiotap_header th;
uint8_t pad[64];
} sc_txtapu;
#define sc_txtap sc_txtapu.th
- int sc_txtap_len;
};
#define RUN_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
diff --git a/sys/dev/usb/wlan/if_uath.c b/sys/dev/usb/wlan/if_uath.c
index 39fa71b..ec5b54c 100644
--- a/sys/dev/usb/wlan/if_uath.c
+++ b/sys/dev/usb/wlan/if_uath.c
@@ -1663,22 +1663,6 @@ uath_txfrag_setup(struct uath_softc *sc, uath_datahead *frags,
return !STAILQ_EMPTY(frags);
}
-/*
- * Reclaim mbuf resources. For fragmented frames we need to claim each frag
- * chained with m_nextpkt.
- */
-static void
-uath_freetx(struct mbuf *m)
-{
- struct mbuf *next;
-
- do {
- next = m->m_nextpkt;
- m->m_nextpkt = NULL;
- m_freem(m);
- } while ((m = next) != NULL);
-}
-
static int
uath_transmit(struct ieee80211com *ic, struct mbuf *m)
{
@@ -1735,7 +1719,7 @@ uath_start(struct uath_softc *sc)
!uath_txfrag_setup(sc, &frags, m, ni)) {
DPRINTF(sc, UATH_DEBUG_XMIT,
"%s: out of txfrag buffers\n", __func__);
- uath_freetx(m);
+ ieee80211_free_mbuf(m);
goto bad;
}
sc->sc_seqnum = 0;
@@ -1770,7 +1754,7 @@ uath_start(struct uath_softc *sc)
"%s: flush fragmented packet, state %s\n",
__func__,
ieee80211_state_name[ni->ni_vap->iv_state]);
- uath_freetx(next);
+ ieee80211_free_mbuf(next);
goto reclaim;
}
m = next;
@@ -1797,7 +1781,6 @@ uath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
if ((sc->sc_flags & UATH_FLAG_INVALID) ||
!(sc->sc_flags & UATH_FLAG_INITDONE)) {
m_freem(m);
- ieee80211_free_node(ni);
UATH_UNLOCK(sc);
return (ENETDOWN);
}
@@ -1805,7 +1788,6 @@ uath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
/* grab a TX buffer */
bf = uath_getbuf(sc);
if (bf == NULL) {
- ieee80211_free_node(ni);
m_freem(m);
UATH_UNLOCK(sc);
return (ENOBUFS);
@@ -1813,7 +1795,6 @@ uath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
sc->sc_seqnum = 0;
if (uath_tx_start(sc, m, ni, bf) != 0) {
- ieee80211_free_node(ni);
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
UATH_STAT_INC(sc, st_tx_inactive);
UATH_UNLOCK(sc);
diff --git a/sys/dev/usb/wlan/if_uathvar.h b/sys/dev/usb/wlan/if_uathvar.h
index 4b4d9fc..a38f54f 100644
--- a/sys/dev/usb/wlan/if_uathvar.h
+++ b/sys/dev/usb/wlan/if_uathvar.h
@@ -230,9 +230,7 @@ struct uath_softc {
#define UATH_FLAG_INITDONE (1 << 2)
struct uath_rx_radiotap_header sc_rxtap;
- int sc_rxtap_len;
struct uath_tx_radiotap_header sc_txtap;
- int sc_txtap_len;
};
#define UATH_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
diff --git a/sys/dev/usb/wlan/if_upgt.c b/sys/dev/usb/wlan/if_upgt.c
index 516caf0..2689ae0 100644
--- a/sys/dev/usb/wlan/if_upgt.c
+++ b/sys/dev/usb/wlan/if_upgt.c
@@ -798,14 +798,12 @@ upgt_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
/* prevent management frames from being sent if we're not ready */
if (!(sc->sc_flags & UPGT_FLAG_INITDONE)) {
m_freem(m);
- ieee80211_free_node(ni);
UPGT_UNLOCK(sc);
return ENETDOWN;
}
data_tx = upgt_gettxbuf(sc);
if (data_tx == NULL) {
- ieee80211_free_node(ni);
m_freem(m);
UPGT_UNLOCK(sc);
return (ENOBUFS);
@@ -814,7 +812,6 @@ upgt_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
if (upgt_tx_start(sc, m, ni, data_tx) != 0) {
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, data_tx, next);
UPGT_STAT_INC(sc, st_tx_inactive);
- ieee80211_free_node(ni);
UPGT_UNLOCK(sc);
return (EIO);
}
diff --git a/sys/dev/usb/wlan/if_upgtvar.h b/sys/dev/usb/wlan/if_upgtvar.h
index 3dcd335..ce996f6 100644
--- a/sys/dev/usb/wlan/if_upgtvar.h
+++ b/sys/dev/usb/wlan/if_upgtvar.h
@@ -472,9 +472,7 @@ struct upgt_softc {
/* BPF */
struct upgt_rx_radiotap_header sc_rxtap;
- int sc_rxtap_len;
struct upgt_tx_radiotap_header sc_txtap;
- int sc_txtap_len;
};
#define UPGT_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
diff --git a/sys/dev/usb/wlan/if_ural.c b/sys/dev/usb/wlan/if_ural.c
index 6f6686f..3fb03bd 100644
--- a/sys/dev/usb/wlan/if_ural.c
+++ b/sys/dev/usb/wlan/if_ural.c
@@ -2123,13 +2123,11 @@ ural_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
if (!sc->sc_running) {
RAL_UNLOCK(sc);
m_freem(m);
- ieee80211_free_node(ni);
return ENETDOWN;
}
if (sc->tx_nfree < RAL_TX_MINFREE) {
RAL_UNLOCK(sc);
m_freem(m);
- ieee80211_free_node(ni);
return EIO;
}
@@ -2152,7 +2150,6 @@ ural_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
return 0;
bad:
RAL_UNLOCK(sc);
- ieee80211_free_node(ni);
return EIO; /* XXX */
}
diff --git a/sys/dev/usb/wlan/if_uralvar.h b/sys/dev/usb/wlan/if_uralvar.h
index 5461e87..208a969 100644
--- a/sys/dev/usb/wlan/if_uralvar.h
+++ b/sys/dev/usb/wlan/if_uralvar.h
@@ -125,10 +125,7 @@ struct ural_softc {
int nb_ant;
struct ural_rx_radiotap_header sc_rxtap;
- int sc_rxtap_len;
-
struct ural_tx_radiotap_header sc_txtap;
- int sc_txtap_len;
};
#define RAL_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
diff --git a/sys/dev/usb/wlan/if_urtw.c b/sys/dev/usb/wlan/if_urtw.c
index 040ba86..a9aac3a 100644
--- a/sys/dev/usb/wlan/if_urtw.c
+++ b/sys/dev/usb/wlan/if_urtw.c
@@ -1527,20 +1527,17 @@ urtw_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
/* prevent management frames from being sent if we're not ready */
if (!(sc->sc_flags & URTW_RUNNING)) {
m_freem(m);
- ieee80211_free_node(ni);
return ENETDOWN;
}
URTW_LOCK(sc);
bf = urtw_getbuf(sc);
if (bf == NULL) {
- ieee80211_free_node(ni);
m_freem(m);
URTW_UNLOCK(sc);
return (ENOBUFS); /* XXX */
}
if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_LOW) != 0) {
- ieee80211_free_node(ni);
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
URTW_UNLOCK(sc);
return (EIO);
diff --git a/sys/dev/usb/wlan/if_urtwn.c b/sys/dev/usb/wlan/if_urtwn.c
index f680edc..5aca1a4 100644
--- a/sys/dev/usb/wlan/if_urtwn.c
+++ b/sys/dev/usb/wlan/if_urtwn.c
@@ -76,6 +76,7 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/usb_debug.h>
#include <dev/usb/wlan/if_urtwnreg.h>
+#include <dev/usb/wlan/if_urtwnvar.h>
#ifdef USB_DEBUG
static int urtwn_debug = 0;
@@ -1631,6 +1632,19 @@ urtwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
/* Enable Rx of data frames. */
urtwn_write_2(sc, R92C_RXFLTMAP2, 0xffff);
+ /* Enable Rx of ctrl frames. */
+ urtwn_write_2(sc, R92C_RXFLTMAP1, 0xffff);
+
+ /*
+ * Accept data/control/management frames
+ * from any BSSID.
+ */
+ urtwn_write_4(sc, R92C_RCR,
+ (urtwn_read_4(sc, R92C_RCR) & ~(R92C_RCR_APM |
+ R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN)) |
+ R92C_RCR_ADF | R92C_RCR_ACF | R92C_RCR_AMF |
+ R92C_RCR_AAP);
+
/* Turn link LED on. */
urtwn_set_led(sc, URTWN_LED_LINK, 1);
break;
@@ -3460,13 +3474,11 @@ urtwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
/* prevent management frames from being sent if we're not ready */
if (!(sc->sc_flags & URTWN_RUNNING)) {
m_freem(m);
- ieee80211_free_node(ni);
return (ENETDOWN);
}
URTWN_LOCK(sc);
bf = urtwn_getbuf(sc);
if (bf == NULL) {
- ieee80211_free_node(ni);
m_freem(m);
URTWN_UNLOCK(sc);
return (ENOBUFS);
@@ -3474,7 +3486,6 @@ urtwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
if (urtwn_tx_start(sc, ni, m, bf) != 0) {
m_freem(m);
- ieee80211_free_node(ni);
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
URTWN_UNLOCK(sc);
return (EIO);
diff --git a/sys/dev/usb/wlan/if_urtwnreg.h b/sys/dev/usb/wlan/if_urtwnreg.h
index ece356d..628b50e 100644
--- a/sys/dev/usb/wlan/if_urtwnreg.h
+++ b/sys/dev/usb/wlan/if_urtwnreg.h
@@ -1061,197 +1061,6 @@ struct r92c_tx_desc {
/*
- * Driver definitions.
- */
-#define URTWN_RX_LIST_COUNT 1
-#define URTWN_TX_LIST_COUNT 8
-#define URTWN_HOST_CMD_RING_COUNT 32
-
-#define URTWN_RXBUFSZ (16 * 1024)
-#define URTWN_TXBUFSZ (sizeof(struct r92c_tx_desc) + IEEE80211_MAX_LEN)
-#define URTWN_RX_DESC_SIZE (sizeof(struct r92c_rx_stat))
-#define URTWN_TX_DESC_SIZE (sizeof(struct r92c_tx_desc))
-
-#define URTWN_RIDX_COUNT 28
-
-#define URTWN_TX_TIMEOUT 5000 /* ms */
-
-#define URTWN_LED_LINK 0
-#define URTWN_LED_DATA 1
-
-struct urtwn_rx_radiotap_header {
- struct ieee80211_radiotap_header wr_ihdr;
- uint8_t wr_flags;
- uint8_t wr_rate;
- uint16_t wr_chan_freq;
- uint16_t wr_chan_flags;
- uint8_t wr_dbm_antsignal;
-} __packed __aligned(8);
-
-#define URTWN_RX_RADIOTAP_PRESENT \
- (1 << IEEE80211_RADIOTAP_FLAGS | \
- 1 << IEEE80211_RADIOTAP_RATE | \
- 1 << IEEE80211_RADIOTAP_CHANNEL | \
- 1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL)
-
-struct urtwn_tx_radiotap_header {
- struct ieee80211_radiotap_header wt_ihdr;
- uint8_t wt_flags;
- uint16_t wt_chan_freq;
- uint16_t wt_chan_flags;
-} __packed __aligned(8);
-
-#define URTWN_TX_RADIOTAP_PRESENT \
- (1 << IEEE80211_RADIOTAP_FLAGS | \
- 1 << IEEE80211_RADIOTAP_CHANNEL)
-
-struct urtwn_softc;
-
-struct urtwn_data {
- struct urtwn_softc *sc;
- uint8_t *buf;
- uint16_t buflen;
- struct mbuf *m;
- struct ieee80211_node *ni;
- STAILQ_ENTRY(urtwn_data) next;
-};
-typedef STAILQ_HEAD(, urtwn_data) urtwn_datahead;
-
-struct urtwn_cmdq {
- void *arg0;
- void *arg1;
- void (*func)(void *);
- struct ieee80211_key *k;
- struct ieee80211_key key;
- uint8_t mac[IEEE80211_ADDR_LEN];
- uint8_t wcid;
-};
-
-struct urtwn_fw_info {
- const uint8_t *data;
- size_t size;
-};
-
-struct urtwn_vap {
- struct ieee80211vap vap;
-
- int (*newstate)(struct ieee80211vap *,
- enum ieee80211_state, int);
-};
-#define URTWN_VAP(vap) ((struct urtwn_vap *)(vap))
-
-struct urtwn_host_cmd {
- void (*cb)(struct urtwn_softc *, void *);
- uint8_t data[256];
-};
-
-struct urtwn_cmd_newstate {
- enum ieee80211_state state;
- int arg;
-};
-
-struct urtwn_cmd_key {
- struct ieee80211_key key;
- uint16_t associd;
-};
-
-enum {
- URTWN_BULK_RX,
- URTWN_BULK_TX_BE, /* = WME_AC_BE */
- URTWN_BULK_TX_BK, /* = WME_AC_BK */
- URTWN_BULK_TX_VI, /* = WME_AC_VI */
- URTWN_BULK_TX_VO, /* = WME_AC_VI */
- URTWN_N_TRANSFER = 5,
-};
-
-#define URTWN_EP_QUEUES URTWN_BULK_RX
-
-struct urtwn_softc {
- struct ieee80211com sc_ic;
- struct mbufq sc_snd;
- device_t sc_dev;
- struct usb_device *sc_udev;
-
- int ac2idx[WME_NUM_AC];
- u_int sc_flags;
-#define URTWN_FLAG_CCK_HIPWR 0x01
-#define URTWN_DETACHED 0x02
-#define URTWN_RUNNING 0x04
-
- u_int chip;
-#define URTWN_CHIP_92C 0x01
-#define URTWN_CHIP_92C_1T2R 0x02
-#define URTWN_CHIP_UMC 0x04
-#define URTWN_CHIP_UMC_A_CUT 0x08
-#define URTWN_CHIP_88E 0x10
-
- void (*sc_rf_write)(struct urtwn_softc *,
- int, uint8_t, uint32_t);
- int (*sc_power_on)(struct urtwn_softc *);
- int (*sc_dma_init)(struct urtwn_softc *);
-
- uint8_t board_type;
- uint8_t regulatory;
- uint8_t pa_setting;
- int avg_pwdb;
- int thcal_state;
- int thcal_lctemp;
- int ntxchains;
- int nrxchains;
- int ledlink;
- int sc_txtimer;
-
- int fwcur;
- struct urtwn_data sc_rx[URTWN_RX_LIST_COUNT];
- urtwn_datahead sc_rx_active;
- urtwn_datahead sc_rx_inactive;
- struct urtwn_data sc_tx[URTWN_TX_LIST_COUNT];
- urtwn_datahead sc_tx_active;
- urtwn_datahead sc_tx_inactive;
- urtwn_datahead sc_tx_pending;
-
- const char *fwname;
- const struct firmware *fw_fp;
- struct urtwn_fw_info fw;
- void *fw_virtaddr;
-
- struct r92c_rom rom;
- uint8_t r88e_rom[512];
- uint8_t cck_tx_pwr[6];
- uint8_t ht40_tx_pwr[5];
- int8_t bw20_tx_pwr_diff;
- int8_t ofdm_tx_pwr_diff;
-
- struct callout sc_watchdog_ch;
- struct mtx sc_mtx;
-
-/* need to be power of 2, otherwise URTWN_CMDQ_GET fails */
-#define URTWN_CMDQ_MAX 16
-#define URTWN_CMDQ_MASQ (URTWN_CMDQ_MAX - 1)
- struct urtwn_cmdq cmdq[URTWN_CMDQ_MAX];
- struct task cmdq_task;
- uint32_t cmdq_store;
- uint8_t cmdq_exec;
- uint8_t cmdq_run;
- uint8_t cmdq_key_set;
-#define URTWN_CMDQ_ABORT 0
-#define URTWN_CMDQ_GO 1
-
- uint32_t rf_chnlbw[R92C_MAX_CHAINS];
- struct usb_xfer *sc_xfer[URTWN_N_TRANSFER];
-
- struct urtwn_rx_radiotap_header sc_rxtap;
- int sc_rxtap_len;
-
- struct urtwn_tx_radiotap_header sc_txtap;
- int sc_txtap_len;
-};
-
-#define URTWN_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
-#define URTWN_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
-#define URTWN_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED)
-
-/*
* MAC initialization values.
*/
static const struct {
diff --git a/sys/dev/usb/wlan/if_urtwnvar.h b/sys/dev/usb/wlan/if_urtwnvar.h
new file mode 100644
index 0000000..5186b38
--- /dev/null
+++ b/sys/dev/usb/wlan/if_urtwnvar.h
@@ -0,0 +1,203 @@
+/*-
+ * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $
+ * $FreeBSD$
+ */
+
+#define URTWN_RX_LIST_COUNT 1
+#define URTWN_TX_LIST_COUNT 8
+#define URTWN_HOST_CMD_RING_COUNT 32
+
+#define URTWN_RXBUFSZ (16 * 1024)
+#define URTWN_TXBUFSZ (sizeof(struct r92c_tx_desc) + IEEE80211_MAX_LEN)
+#define URTWN_RX_DESC_SIZE (sizeof(struct r92c_rx_stat))
+#define URTWN_TX_DESC_SIZE (sizeof(struct r92c_tx_desc))
+
+#define URTWN_RIDX_COUNT 28
+
+#define URTWN_TX_TIMEOUT 5000 /* ms */
+
+#define URTWN_LED_LINK 0
+#define URTWN_LED_DATA 1
+
+struct urtwn_rx_radiotap_header {
+ struct ieee80211_radiotap_header wr_ihdr;
+ uint8_t wr_flags;
+ uint8_t wr_rate;
+ uint16_t wr_chan_freq;
+ uint16_t wr_chan_flags;
+ uint8_t wr_dbm_antsignal;
+} __packed __aligned(8);
+
+#define URTWN_RX_RADIOTAP_PRESENT \
+ (1 << IEEE80211_RADIOTAP_FLAGS | \
+ 1 << IEEE80211_RADIOTAP_RATE | \
+ 1 << IEEE80211_RADIOTAP_CHANNEL | \
+ 1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL)
+
+struct urtwn_tx_radiotap_header {
+ struct ieee80211_radiotap_header wt_ihdr;
+ uint8_t wt_flags;
+ uint16_t wt_chan_freq;
+ uint16_t wt_chan_flags;
+} __packed __aligned(8);
+
+#define URTWN_TX_RADIOTAP_PRESENT \
+ (1 << IEEE80211_RADIOTAP_FLAGS | \
+ 1 << IEEE80211_RADIOTAP_CHANNEL)
+
+struct urtwn_softc;
+
+struct urtwn_data {
+ struct urtwn_softc *sc;
+ uint8_t *buf;
+ uint16_t buflen;
+ struct mbuf *m;
+ struct ieee80211_node *ni;
+ STAILQ_ENTRY(urtwn_data) next;
+};
+typedef STAILQ_HEAD(, urtwn_data) urtwn_datahead;
+
+struct urtwn_cmdq {
+ void *arg0;
+ void *arg1;
+ void (*func)(void *);
+ struct ieee80211_key *k;
+ struct ieee80211_key key;
+ uint8_t mac[IEEE80211_ADDR_LEN];
+ uint8_t wcid;
+};
+
+struct urtwn_fw_info {
+ const uint8_t *data;
+ size_t size;
+};
+
+struct urtwn_vap {
+ struct ieee80211vap vap;
+
+ int (*newstate)(struct ieee80211vap *,
+ enum ieee80211_state, int);
+};
+#define URTWN_VAP(vap) ((struct urtwn_vap *)(vap))
+
+struct urtwn_host_cmd {
+ void (*cb)(struct urtwn_softc *, void *);
+ uint8_t data[256];
+};
+
+struct urtwn_cmd_newstate {
+ enum ieee80211_state state;
+ int arg;
+};
+
+struct urtwn_cmd_key {
+ struct ieee80211_key key;
+ uint16_t associd;
+};
+
+enum {
+ URTWN_BULK_RX,
+ URTWN_BULK_TX_BE, /* = WME_AC_BE */
+ URTWN_BULK_TX_BK, /* = WME_AC_BK */
+ URTWN_BULK_TX_VI, /* = WME_AC_VI */
+ URTWN_BULK_TX_VO, /* = WME_AC_VI */
+ URTWN_N_TRANSFER = 5,
+};
+
+#define URTWN_EP_QUEUES URTWN_BULK_RX
+
+struct urtwn_softc {
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
+ device_t sc_dev;
+ struct usb_device *sc_udev;
+
+ int ac2idx[WME_NUM_AC];
+ u_int sc_flags;
+#define URTWN_FLAG_CCK_HIPWR 0x01
+#define URTWN_DETACHED 0x02
+#define URTWN_RUNNING 0x04
+
+ u_int chip;
+#define URTWN_CHIP_92C 0x01
+#define URTWN_CHIP_92C_1T2R 0x02
+#define URTWN_CHIP_UMC 0x04
+#define URTWN_CHIP_UMC_A_CUT 0x08
+#define URTWN_CHIP_88E 0x10
+
+ void (*sc_rf_write)(struct urtwn_softc *,
+ int, uint8_t, uint32_t);
+ int (*sc_power_on)(struct urtwn_softc *);
+ int (*sc_dma_init)(struct urtwn_softc *);
+
+ uint8_t board_type;
+ uint8_t regulatory;
+ uint8_t pa_setting;
+ int avg_pwdb;
+ int thcal_state;
+ int thcal_lctemp;
+ int ntxchains;
+ int nrxchains;
+ int ledlink;
+ int sc_txtimer;
+
+ int fwcur;
+ struct urtwn_data sc_rx[URTWN_RX_LIST_COUNT];
+ urtwn_datahead sc_rx_active;
+ urtwn_datahead sc_rx_inactive;
+ struct urtwn_data sc_tx[URTWN_TX_LIST_COUNT];
+ urtwn_datahead sc_tx_active;
+ urtwn_datahead sc_tx_inactive;
+ urtwn_datahead sc_tx_pending;
+
+ const char *fwname;
+ const struct firmware *fw_fp;
+ struct urtwn_fw_info fw;
+ void *fw_virtaddr;
+
+ struct r92c_rom rom;
+ uint8_t r88e_rom[512];
+ uint8_t cck_tx_pwr[6];
+ uint8_t ht40_tx_pwr[5];
+ int8_t bw20_tx_pwr_diff;
+ int8_t ofdm_tx_pwr_diff;
+
+ struct callout sc_watchdog_ch;
+ struct mtx sc_mtx;
+
+/* need to be power of 2, otherwise URTWN_CMDQ_GET fails */
+#define URTWN_CMDQ_MAX 16
+#define URTWN_CMDQ_MASQ (URTWN_CMDQ_MAX - 1)
+ struct urtwn_cmdq cmdq[URTWN_CMDQ_MAX];
+ struct task cmdq_task;
+ uint32_t cmdq_store;
+ uint8_t cmdq_exec;
+ uint8_t cmdq_run;
+ uint8_t cmdq_key_set;
+#define URTWN_CMDQ_ABORT 0
+#define URTWN_CMDQ_GO 1
+
+ uint32_t rf_chnlbw[R92C_MAX_CHAINS];
+ struct usb_xfer *sc_xfer[URTWN_N_TRANSFER];
+
+ struct urtwn_rx_radiotap_header sc_rxtap;
+ struct urtwn_tx_radiotap_header sc_txtap;
+};
+
+#define URTWN_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
+#define URTWN_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
+#define URTWN_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED)
diff --git a/sys/dev/usb/wlan/if_urtwvar.h b/sys/dev/usb/wlan/if_urtwvar.h
index a423214..08ffc8f 100644
--- a/sys/dev/usb/wlan/if_urtwvar.h
+++ b/sys/dev/usb/wlan/if_urtwvar.h
@@ -178,9 +178,7 @@ struct urtw_softc {
struct urtw_stats sc_stats;
struct urtw_rx_radiotap_header sc_rxtap;
- int sc_rxtap_len;
struct urtw_tx_radiotap_header sc_txtap;
- int sc_txtap_len;
};
#define URTW_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c
index ed70d19..dc7a87f 100644
--- a/sys/dev/usb/wlan/if_zyd.c
+++ b/sys/dev/usb/wlan/if_zyd.c
@@ -2590,13 +2590,11 @@ zyd_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
if (!(sc->sc_flags & ZYD_FLAG_RUNNING)) {
ZYD_UNLOCK(sc);
m_freem(m);
- ieee80211_free_node(ni);
return (ENETDOWN);
}
if (sc->tx_nfree == 0) {
ZYD_UNLOCK(sc);
m_freem(m);
- ieee80211_free_node(ni);
return (ENOBUFS); /* XXX */
}
@@ -2607,7 +2605,6 @@ zyd_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
*/
if (zyd_tx_start(sc, m, ni) != 0) {
ZYD_UNLOCK(sc);
- ieee80211_free_node(ni);
m_freem(m);
return (EIO);
}
diff --git a/sys/dev/usb/wlan/if_zydreg.h b/sys/dev/usb/wlan/if_zydreg.h
index ec61d06..86c7ff3 100644
--- a/sys/dev/usb/wlan/if_zydreg.h
+++ b/sys/dev/usb/wlan/if_zydreg.h
@@ -1304,9 +1304,7 @@ struct zyd_softc {
struct zyd_cmd sc_ibuf;
struct zyd_rx_radiotap_header sc_rxtap;
- int sc_rxtap_len;
struct zyd_tx_radiotap_header sc_txtap;
- int sc_txtap_len;
};
#define ZYD_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c
index f8af231..832e6aa 100644
--- a/sys/dev/wi/if_wi.c
+++ b/sys/dev/wi/if_wi.c
@@ -1077,6 +1077,7 @@ wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0,
goto out;
}
m0 = NULL;
+ ieee80211_free_node(ni);
sc->sc_txnext = cur = (cur + 1) % sc->sc_ntxbuf;
out:
@@ -1084,7 +1085,6 @@ out:
if (m0 != NULL)
m_freem(m0);
- ieee80211_free_node(ni);
return rc;
}
diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c
index dfd6424..7932bce 100644
--- a/sys/dev/wpi/if_wpi.c
+++ b/sys/dev/wpi/if_wpi.c
@@ -196,6 +196,7 @@ static void wpi_debug_registers(struct wpi_softc *);
#endif
static void wpi_fatal_intr(struct wpi_softc *);
static void wpi_intr(void *);
+static void wpi_free_txfrags(struct wpi_softc *, uint16_t);
static int wpi_cmd2(struct wpi_softc *, struct wpi_buf *);
static int wpi_tx_data(struct wpi_softc *, struct mbuf *,
struct ieee80211_node *);
@@ -458,6 +459,7 @@ wpi_attach(device_t dev)
| IEEE80211_C_MONITOR /* monitor mode supported */
| IEEE80211_C_AHDEMO /* adhoc demo mode */
| IEEE80211_C_BGSCAN /* capable of bg scanning */
+ | IEEE80211_C_TXFRAG /* handle tx frags */
| IEEE80211_C_TXPMGT /* tx power management */
| IEEE80211_C_SHSLOT /* short slot time supported */
| IEEE80211_C_WPA /* 802.11i */
@@ -1168,6 +1170,7 @@ wpi_alloc_tx_ring(struct wpi_softc *sc, struct wpi_tx_ring *ring, uint8_t qid)
ring->qid = qid;
ring->queued = 0;
ring->cur = 0;
+ ring->pending = 0;
ring->update = 0;
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_BEGIN, __func__);
@@ -1288,6 +1291,7 @@ wpi_reset_tx_ring(struct wpi_softc *sc, struct wpi_tx_ring *ring)
BUS_DMASYNC_PREWRITE);
ring->queued = 0;
ring->cur = 0;
+ ring->pending = 0;
ring->update = 0;
}
@@ -2572,6 +2576,34 @@ done:
end: WPI_UNLOCK(sc);
}
+static void
+wpi_free_txfrags(struct wpi_softc *sc, uint16_t ac)
+{
+ struct wpi_tx_ring *ring;
+ struct wpi_tx_data *data;
+ uint8_t cur;
+
+ WPI_TXQ_LOCK(sc);
+ ring = &sc->txq[ac];
+
+ while (ring->pending != 0) {
+ ring->pending--;
+ cur = (ring->cur + ring->pending) % WPI_TX_RING_COUNT;
+ data = &ring->data[cur];
+
+ bus_dmamap_sync(ring->data_dmat, data->map,
+ BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(ring->data_dmat, data->map);
+ m_freem(data->m);
+ data->m = NULL;
+
+ ieee80211_node_decref(data->ni);
+ data->ni = NULL;
+ }
+
+ WPI_TXQ_UNLOCK(sc);
+}
+
static int
wpi_cmd2(struct wpi_softc *sc, struct wpi_buf *buf)
{
@@ -2582,9 +2614,9 @@ wpi_cmd2(struct wpi_softc *sc, struct wpi_buf *buf)
struct wpi_tx_ring *ring;
struct mbuf *m1;
bus_dma_segment_t *seg, segs[WPI_MAX_SCATTER];
- uint8_t pad;
+ uint8_t cur, pad;
uint16_t hdrlen;
- int error, i, nsegs, totlen;
+ int error, i, nsegs, totlen, frag;
WPI_TXQ_LOCK(sc);
@@ -2601,6 +2633,7 @@ wpi_cmd2(struct wpi_softc *sc, struct wpi_buf *buf)
wh = mtod(buf->m, struct ieee80211_frame *);
hdrlen = ieee80211_anyhdrsize(wh);
totlen = buf->m->m_pkthdr.len;
+ frag = ((buf->m->m_flags & (M_FRAG | M_LASTFRAG)) == M_FRAG);
if (__predict_false(totlen < sizeof(struct ieee80211_frame_min))) {
error = EINVAL;
@@ -2614,15 +2647,16 @@ wpi_cmd2(struct wpi_softc *sc, struct wpi_buf *buf)
pad = 0;
ring = &sc->txq[buf->ac];
- desc = &ring->desc[ring->cur];
- data = &ring->data[ring->cur];
+ cur = (ring->cur + ring->pending) % WPI_TX_RING_COUNT;
+ desc = &ring->desc[cur];
+ data = &ring->data[cur];
/* Prepare TX firmware command. */
- cmd = &ring->cmd[ring->cur];
+ cmd = &ring->cmd[cur];
cmd->code = buf->code;
cmd->flags = 0;
cmd->qid = ring->qid;
- cmd->idx = ring->cur;
+ cmd->idx = cur;
memcpy(cmd->data, buf->data, buf->size);
@@ -2662,7 +2696,8 @@ wpi_cmd2(struct wpi_softc *sc, struct wpi_buf *buf)
if (ring->qid < WPI_CMD_QUEUE_NUM) {
if_inc_counter(buf->ni->ni_vap->iv_ifp,
IFCOUNTER_OERRORS, 1);
- ieee80211_free_node(buf->ni);
+ if (!frag)
+ ieee80211_free_node(buf->ni);
}
m_freem(buf->m);
error = 0;
@@ -2678,7 +2713,7 @@ wpi_cmd2(struct wpi_softc *sc, struct wpi_buf *buf)
data->ni = buf->ni;
DPRINTF(sc, WPI_DEBUG_XMIT, "%s: qid %d idx %d len %d nsegs %d\n",
- __func__, ring->qid, ring->cur, totlen, nsegs);
+ __func__, ring->qid, cur, totlen, nsegs);
/* Fill TX descriptor. */
desc->nsegs = WPI_PAD32(totlen + pad) << 4 | (1 + nsegs);
@@ -2699,16 +2734,23 @@ wpi_cmd2(struct wpi_softc *sc, struct wpi_buf *buf)
bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
BUS_DMASYNC_PREWRITE);
- /* Kick TX ring. */
- ring->cur = (ring->cur + 1) % WPI_TX_RING_COUNT;
- sc->sc_update_tx_ring(sc, ring);
+ ring->pending += 1;
- if (ring->qid < WPI_CMD_QUEUE_NUM) {
- WPI_TXQ_STATE_LOCK(sc);
- ring->queued++;
- callout_reset(&sc->tx_timeout, 5*hz, wpi_tx_timeout, sc);
- WPI_TXQ_STATE_UNLOCK(sc);
- }
+ if (!frag) {
+ if (ring->qid < WPI_CMD_QUEUE_NUM) {
+ WPI_TXQ_STATE_LOCK(sc);
+ ring->queued += ring->pending;
+ callout_reset(&sc->tx_timeout, 5*hz, wpi_tx_timeout,
+ sc);
+ WPI_TXQ_STATE_UNLOCK(sc);
+ }
+
+ /* Kick TX ring. */
+ ring->cur = (ring->cur + ring->pending) % WPI_TX_RING_COUNT;
+ ring->pending = 0;
+ sc->sc_update_tx_ring(sc, ring);
+ } else
+ ieee80211_node_incref(data->ni);
end: DPRINTF(sc, WPI_DEBUG_TRACE, error ? TRACE_STR_END_ERR : TRACE_STR_END,
__func__);
@@ -2793,6 +2835,8 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
tap->wt_rate = rate;
if (k != NULL)
tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
+ if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
+ tap->wt_flags |= IEEE80211_RADIOTAP_F_FRAG;
ieee80211_radiotap_tx(vap, m);
}
@@ -2808,7 +2852,7 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
if (!IEEE80211_QOS_HAS_SEQ(wh))
flags |= WPI_TX_AUTO_SEQ;
if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG)
- flags |= WPI_TX_MORE_FRAG; /* Cannot happen yet. */
+ flags |= WPI_TX_MORE_FRAG;
/* Check if frame must be protected using RTS/CTS or CTS-to-self. */
if (!ismcast) {
@@ -2866,6 +2910,15 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
memcpy(tx->key, k->wk_key, k->wk_keylen);
}
+ if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG) {
+ struct mbuf *next = m->m_nextpkt;
+
+ tx->lnext = htole16(next->m_pkthdr.len);
+ tx->fnext = htole32(tx->security |
+ (flags & WPI_TX_NEED_ACK) |
+ WPI_NEXT_STA_ID(tx->id));
+ }
+
tx->len = htole16(totlen);
tx->flags = htole32(flags);
tx->plcp = rate2plcp(rate);
@@ -2989,13 +3042,13 @@ wpi_tx_data_raw(struct wpi_softc *sc, struct mbuf *m,
}
static __inline int
-wpi_tx_ring_is_full(struct wpi_softc *sc, uint16_t ac)
+wpi_tx_ring_free_space(struct wpi_softc *sc, uint16_t ac)
{
struct wpi_tx_ring *ring = &sc->txq[ac];
int retval;
WPI_TXQ_STATE_LOCK(sc);
- retval = (ring->queued > WPI_TX_RING_HIMARK);
+ retval = WPI_TX_RING_HIMARK - ring->queued;
WPI_TXQ_STATE_UNLOCK(sc);
return retval;
@@ -3016,7 +3069,8 @@ wpi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
WPI_TX_LOCK(sc);
- if (sc->sc_running == 0 || wpi_tx_ring_is_full(sc, ac)) {
+ /* NB: no fragments here */
+ if (sc->sc_running == 0 || wpi_tx_ring_free_space(sc, ac) < 1) {
error = sc->sc_running ? ENOBUFS : ENETDOWN;
goto unlock;
}
@@ -3039,7 +3093,6 @@ unlock: WPI_TX_UNLOCK(sc);
if (error != 0) {
m_freem(m);
- ieee80211_free_node(ni);
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END_ERR, __func__);
return error;
@@ -3055,8 +3108,9 @@ wpi_transmit(struct ieee80211com *ic, struct mbuf *m)
{
struct wpi_softc *sc = ic->ic_softc;
struct ieee80211_node *ni;
+ struct mbuf *mnext;
uint16_t ac;
- int error;
+ int error, nmbufs;
WPI_TX_LOCK(sc);
DPRINTF(sc, WPI_DEBUG_XMIT, "%s: called\n", __func__);
@@ -3067,20 +3121,30 @@ wpi_transmit(struct ieee80211com *ic, struct mbuf *m)
goto unlock;
}
+ nmbufs = 1;
+ for (mnext = m->m_nextpkt; mnext != NULL; mnext = mnext->m_nextpkt)
+ nmbufs++;
+
/* Check for available space. */
ac = M_WME_GETAC(m);
- if (wpi_tx_ring_is_full(sc, ac)) {
+ if (wpi_tx_ring_free_space(sc, ac) < nmbufs) {
error = ENOBUFS;
goto unlock;
}
error = 0;
ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
- if (wpi_tx_data(sc, m, ni) != 0) {
- if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1);
- ieee80211_free_node(ni);
- m_freem(m);
- }
+ do {
+ mnext = m->m_nextpkt;
+ if (wpi_tx_data(sc, m, ni) != 0) {
+ if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS,
+ nmbufs);
+ wpi_free_txfrags(sc, ac);
+ ieee80211_free_mbuf(m);
+ ieee80211_free_node(ni);
+ break;
+ }
+ } while((m = mnext) != NULL);
DPRINTF(sc, WPI_DEBUG_XMIT, "%s: done\n", __func__);
diff --git a/sys/dev/wpi/if_wpireg.h b/sys/dev/wpi/if_wpireg.h
index f36dd25..b0154f2 100644
--- a/sys/dev/wpi/if_wpireg.h
+++ b/sys/dev/wpi/if_wpireg.h
@@ -520,6 +520,8 @@ struct wpi_cmd_data {
uint8_t key[IEEE80211_KEYBUF_SIZE];
uint8_t tkip[IEEE80211_WEP_MICLEN];
uint32_t fnext;
+#define WPI_NEXT_STA_ID(id) ((id) << 8)
+
uint32_t lifetime;
#define WPI_LIFETIME_INFINITE 0xffffffff
diff --git a/sys/dev/wpi/if_wpivar.h b/sys/dev/wpi/if_wpivar.h
index fb566b5..1957740 100644
--- a/sys/dev/wpi/if_wpivar.h
+++ b/sys/dev/wpi/if_wpivar.h
@@ -74,6 +74,7 @@ struct wpi_tx_ring {
bus_dma_tag_t data_dmat;
uint8_t qid;
uint8_t cur;
+ uint8_t pending;
int16_t queued;
int update:1;
};
diff --git a/sys/modules/usb/urtwn/Makefile b/sys/modules/usb/urtwn/Makefile
index d965294..656fab9 100644
--- a/sys/modules/usb/urtwn/Makefile
+++ b/sys/modules/usb/urtwn/Makefile
@@ -3,7 +3,7 @@
.PATH: ${.CURDIR}/../../../dev/usb/wlan
KMOD = if_urtwn
-SRCS = if_urtwn.c if_urtwnreg.h \
+SRCS = if_urtwn.c if_urtwnreg.h if_urtwnvar.h \
bus_if.h device_if.h \
opt_bus.h opt_usb.h opt_wlan.h usb_if.h usbdevs.h
diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c
index 6fdfb5c..7f2eae5 100644
--- a/sys/net80211/ieee80211_freebsd.c
+++ b/sys/net80211/ieee80211_freebsd.c
@@ -529,9 +529,6 @@ ieee80211_get_rx_params(struct mbuf *m, struct ieee80211_rx_stats *rxs)
/*
* Transmit a frame to the parent interface.
- *
- * TODO: if the transmission fails, make sure the parent node is freed
- * (the callers will first need modifying.)
*/
int
ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m)
@@ -544,8 +541,16 @@ ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m)
*/
IEEE80211_TX_LOCK_ASSERT(ic);
error = ic->ic_transmit(ic, m);
- if (error)
- m_freem(m);
+ if (error) {
+ struct ieee80211_node *ni;
+
+ ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
+
+ /* XXX number of fragments */
+ if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1);
+ ieee80211_free_node(ni);
+ ieee80211_free_mbuf(m);
+ }
return (error);
}
diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c
index ccb31ab..34d1b4e 100644
--- a/sys/net80211/ieee80211_hostap.c
+++ b/sys/net80211/ieee80211_hostap.c
@@ -2327,12 +2327,11 @@ ieee80211_recv_pspoll(struct ieee80211_node *ni, struct mbuf *m0)
/*
* Do the right thing; if it's an encap'ed frame then
- * call ieee80211_parent_xmitpkt() (and free the ref) else
+ * call ieee80211_parent_xmitpkt() else
* call ieee80211_vap_xmitpkt().
*/
if (m->m_flags & M_ENCAP) {
- if (ieee80211_parent_xmitpkt(ic, m) != 0)
- ieee80211_free_node(ni);
+ (void) ieee80211_parent_xmitpkt(ic, m);
} else {
(void) ieee80211_vap_xmitpkt(vap, m);
}
diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c
index cb6ab81..1778c09 100644
--- a/sys/net80211/ieee80211_mesh.c
+++ b/sys/net80211/ieee80211_mesh.c
@@ -1239,12 +1239,8 @@ mesh_forward(struct ieee80211vap *vap, struct mbuf *m,
IEEE80211_TX_LOCK(ic);
err = ieee80211_parent_xmitpkt(ic, mcopy);
IEEE80211_TX_UNLOCK(ic);
- if (err != 0) {
- /* NB: IFQ_HANDOFF reclaims mbuf */
- ieee80211_free_node(ni);
- } else {
+ if (!err)
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- }
}
static struct mbuf *
diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c
index 19af613..322491d 100644
--- a/sys/net80211/ieee80211_output.c
+++ b/sys/net80211/ieee80211_output.c
@@ -132,7 +132,7 @@ ieee80211_vap_pkt_send_dest(struct ieee80211vap *vap, struct mbuf *m,
{
struct ieee80211com *ic = vap->iv_ic;
struct ifnet *ifp = vap->iv_ifp;
- int error, len, mcast;
+ int len, mcast;
if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) &&
(m->m_flags & M_PWR_SAV) == 0) {
@@ -264,18 +264,13 @@ ieee80211_vap_pkt_send_dest(struct ieee80211vap *vap, struct mbuf *m,
return (ENOBUFS);
}
}
- error = ieee80211_parent_xmitpkt(ic, m);
+ (void) ieee80211_parent_xmitpkt(ic, m);
/*
* Unlock at this point - no need to hold it across
* ieee80211_free_node() (ie, the comlock)
*/
IEEE80211_TX_UNLOCK(ic);
- if (error != 0) {
- /* NB: IFQ_HANDOFF reclaims mbuf */
- ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
- }
ic->ic_lastdata = ticks;
return (0);
@@ -536,8 +531,10 @@ ieee80211_raw_output(struct ieee80211vap *vap, struct ieee80211_node *ni,
(void) ieee80211_add_xmit_params(m, params);
error = ic->ic_raw_xmit(ni, m, params);
- if (error)
+ if (error) {
if_inc_counter(vap->iv_ifp, IFCOUNTER_OERRORS, 1);
+ ieee80211_free_node(ni);
+ }
return (error);
}
@@ -1583,6 +1580,21 @@ bad:
#undef MC01
}
+void
+ieee80211_free_mbuf(struct mbuf *m)
+{
+ struct mbuf *next;
+
+ if (m == NULL)
+ return;
+
+ do {
+ next = m->m_nextpkt;
+ m->m_nextpkt = NULL;
+ m_freem(m);
+ } while ((m = next) != NULL);
+}
+
/*
* Fragment the frame according to the specified mtu.
* The size of the 802.11 header (w/o padding) is provided
@@ -1597,7 +1609,7 @@ ieee80211_fragment(struct ieee80211vap *vap, struct mbuf *m0,
{
struct ieee80211com *ic = vap->iv_ic;
struct ieee80211_frame *wh, *whf;
- struct mbuf *m, *prev, *next;
+ struct mbuf *m, *prev;
u_int totalhdrsize, fragno, fragsize, off, remainder, payload;
u_int hdrspace;
@@ -1692,11 +1704,7 @@ ieee80211_fragment(struct ieee80211vap *vap, struct mbuf *m0,
return 1;
bad:
/* reclaim fragments but leave original frame for caller to free */
- for (m = m0->m_nextpkt; m != NULL; m = next) {
- next = m->m_nextpkt;
- m->m_nextpkt = NULL; /* XXX paranoid */
- m_freem(m);
- }
+ ieee80211_free_mbuf(m0->m_nextpkt);
m0->m_nextpkt = NULL;
return 0;
}
diff --git a/sys/net80211/ieee80211_power.c b/sys/net80211/ieee80211_power.c
index 2d216c2..73c1382 100644
--- a/sys/net80211/ieee80211_power.c
+++ b/sys/net80211/ieee80211_power.c
@@ -457,12 +457,7 @@ pwrsave_flushq(struct ieee80211_node *ni)
KASSERT((m->m_flags & M_ENCAP),
("%s: parentq with non-M_ENCAP frame!\n",
__func__));
- /*
- * For encaped frames, we need to free the node
- * reference upon failure.
- */
- if (ieee80211_parent_xmitpkt(ic, m) != 0)
- ieee80211_free_node(ni);
+ (void) ieee80211_parent_xmitpkt(ic, m);
}
/* VAP frames, aren't encapsulated */
diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h
index 4305863..38bd3d6 100644
--- a/sys/net80211/ieee80211_proto.h
+++ b/sys/net80211/ieee80211_proto.h
@@ -93,6 +93,7 @@ struct mbuf *ieee80211_mbuf_adjust(struct ieee80211vap *, int,
struct ieee80211_key *, struct mbuf *);
struct mbuf *ieee80211_encap(struct ieee80211vap *, struct ieee80211_node *,
struct mbuf *);
+void ieee80211_free_mbuf(struct mbuf *);
int ieee80211_send_mgmt(struct ieee80211_node *, int, int);
struct ieee80211_appie;
int ieee80211_send_probereq(struct ieee80211_node *ni,
diff --git a/sys/net80211/ieee80211_superg.c b/sys/net80211/ieee80211_superg.c
index e91da01..8be098a 100644
--- a/sys/net80211/ieee80211_superg.c
+++ b/sys/net80211/ieee80211_superg.c
@@ -475,13 +475,9 @@ ff_transmit(struct ieee80211_node *ni, struct mbuf *m)
if (m != NULL) {
struct ifnet *ifp = vap->iv_ifp;
- error = ieee80211_parent_xmitpkt(ic, m);;
- if (error != 0) {
- /* NB: IFQ_HANDOFF reclaims mbuf */
- ieee80211_free_node(ni);
- } else {
+ error = ieee80211_parent_xmitpkt(ic, m);
+ if (!error)
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- }
} else
ieee80211_free_node(ni);
}
diff --git a/sys/net80211/ieee80211_wds.c b/sys/net80211/ieee80211_wds.c
index 1d3f30a..a444b79 100644
--- a/sys/net80211/ieee80211_wds.c
+++ b/sys/net80211/ieee80211_wds.c
@@ -298,11 +298,7 @@ ieee80211_dwds_mcast(struct ieee80211vap *vap0, struct mbuf *m)
mcopy->m_pkthdr.rcvif = (void *) ni;
err = ieee80211_parent_xmitpkt(ic, mcopy);
- if (err) {
- /* NB: IFQ_HANDOFF reclaims mbuf */
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
- ieee80211_free_node(ni);
- } else {
+ if (!err) {
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1);
if_inc_counter(ifp, IFCOUNTER_OBYTES,
OpenPOWER on IntegriCloud