mirror of
http://git.openwrt.org/packages.git
synced 2025-01-09 04:19:54 +08:00
move a few unmaintained packages from trunk to /packages
git-svn-id: svn://svn.openwrt.org/openwrt/packages@33634 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
parent
c4e7d12cfc
commit
27d674c623
47
libs/libipfix/Makefile
Normal file
47
libs/libipfix/Makefile
Normal file
@ -0,0 +1,47 @@
|
||||
#
|
||||
# Copyright (C) 2006 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=libipfix
|
||||
PKG_VERSION:=r51
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME).$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
|
||||
PKG_MD5SUM:=0e5b2871ea20ac48eda3f6006c5dba28
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME).$(PKG_VERSION)
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/libipfix
|
||||
SECTION:=libs
|
||||
CATEGORY:=Libraries
|
||||
TITLE:=IP Flow Information Export Library
|
||||
URL:=http://www.fokus.fraunhofer.de/de/net/more_about/download/ipfixlib.html
|
||||
BUILDONLY:=1
|
||||
endef
|
||||
|
||||
TARGET_CFLAGS += \
|
||||
-ffunction-sections -fdata-sections
|
||||
|
||||
define Build/Compile
|
||||
$(MAKE) -C $(PKG_BUILD_DIR) \
|
||||
CCOPT="$(TARGET_CFLAGS) -I$(BUILD_DIR)/linux/include" \
|
||||
prefix="$(PKG_INSTALL_DIR)/usr" \
|
||||
exec_prefix="$(PKG_INSTALL_DIR)/usr" \
|
||||
all install
|
||||
$(TARGET_CROSS)ranlib $(PKG_INSTALL_DIR)/usr/lib/libipfix.a
|
||||
$(TARGET_CROSS)ranlib $(PKG_INSTALL_DIR)/usr/lib/libipfixmisc.a
|
||||
endef
|
||||
|
||||
define Build/InstallDev
|
||||
$(INSTALL_DIR) $(1)
|
||||
$(CP) $(PKG_INSTALL_DIR)/* $(1)/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,libipfix))
|
38
libs/libipfix/extra/append-wprobe-ie.pl
Normal file
38
libs/libipfix/extra/append-wprobe-ie.pl
Normal file
@ -0,0 +1,38 @@
|
||||
use strict;
|
||||
|
||||
my @fields = (
|
||||
[ "_n", "UINT", " - Number of samples", 4 ],
|
||||
[ "_s", "UINT", " - Sum of samples", 8 ],
|
||||
[ "_ss", "UINT", " - Sum of squared samples", 8 ],
|
||||
);
|
||||
|
||||
my $file = $ARGV[0] or die "Syntax: $0 <file> <start>\n";
|
||||
-f $file or die "File not found\n";
|
||||
my $start = $ARGV[1];
|
||||
$start =~ /^\d+$/ or die "Invalid start number";
|
||||
open FILE, "<$file" or die "Can't open file";
|
||||
while (<FILE>) {
|
||||
/^(%?)(\w+),\s*(\w+),\s*(.+)$/ and do {
|
||||
my $counter = $1;
|
||||
my $rfield = $2;
|
||||
my $nfield = $3;
|
||||
my $descr = $4;
|
||||
my @f;
|
||||
if ($counter) {
|
||||
@f = [ "", "UINT", "", 4];
|
||||
} else {
|
||||
@f = @fields;
|
||||
}
|
||||
foreach my $f (@f) {
|
||||
my $nr = $start++;
|
||||
my $n = $f->[0];
|
||||
my $N = uc $n;
|
||||
my $ftype = $f->[1];
|
||||
my $fdesc = $f->[2];
|
||||
my $size = $f->[3];
|
||||
print "$nr, IPFIX_FT_WPROBE_$rfield$N, $size, IPFIX_CODING_$ftype, \"$nfield$n\", \"$descr$fdesc\"\n";
|
||||
}
|
||||
};
|
||||
}
|
||||
close FILE;
|
||||
|
14
libs/libipfix/extra/wprobe-ie.txt
Normal file
14
libs/libipfix/extra/wprobe-ie.txt
Normal file
@ -0,0 +1,14 @@
|
||||
NOISE, global_noise, wprobe global noice floor
|
||||
PHY_BUSY, global_phy_busy, wprobe global airtime total
|
||||
PHY_RX, global_phy_rx, wprobe global airtime total from rx-frame
|
||||
PHY_TX, global_phy_tx, wprobe global airtime total from tx-frame
|
||||
RSSI, link_rssi, wprobe link received signal strength indication
|
||||
SIGNAL, link_signal, wprobe link signal strength in dB
|
||||
IEEE_RX_RATE, link_ieee_rx_rate, wprobe link IEEE 802.11 RX data rate
|
||||
IEEE_TX_RATE, link_ieee_tx_rate, wprobe link IEEE 802.11 TX data rate
|
||||
RETRANSMIT_200, link_retransmit_200, wprobe link total retransmissions per packet - <200 bytes
|
||||
RETRANSMIT_400, link_retransmit_400, wprobe link total retransmissions per packet - <400 bytes
|
||||
RETRANSMIT_800, link_retransmit_800, wprobe link total retransmissions per packet - <800 bytes
|
||||
RETRANSMIT_1600, link_retransmit_1600, wprobe link total retransmissions per packet - >800 bytes
|
||||
%FRAMES, global_frames, wprobe global number of 802.11 frames seen
|
||||
%PROBEREQ, global_probereq, wprobe global number of 802.11 probe requests seen
|
474
libs/libipfix/patches/100-openimp_sync.patch
Normal file
474
libs/libipfix/patches/100-openimp_sync.patch
Normal file
@ -0,0 +1,474 @@
|
||||
--- a/lib/ipfix.c
|
||||
+++ b/lib/ipfix.c
|
||||
@@ -37,6 +37,9 @@ $$LIC$$
|
||||
#ifdef SCTPSUPPORT
|
||||
#include <netinet/sctp.h>
|
||||
#endif
|
||||
+#ifndef NOTHREADS
|
||||
+#include <pthread.h>
|
||||
+#endif
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
|
||||
@@ -123,6 +126,18 @@ static uint16_t g_lasttid;
|
||||
static ipfix_datarecord_t g_data = { NULL, NULL, 0 }; /* ipfix_export */
|
||||
|
||||
static ipfix_field_t *g_ipfix_fields;
|
||||
+#ifndef NOTHREADS
|
||||
+static pthread_mutex_t g_mutex;
|
||||
+#define mod_lock() { \
|
||||
+ if ( pthread_mutex_lock( &g_mutex ) !=0 ) \
|
||||
+ mlogf( 0, "[ipfix] mutex_lock() failed: %s\n", \
|
||||
+ strerror( errno ) ); \
|
||||
+ }
|
||||
+#define mod_unlock() { pthread_mutex_unlock( &g_mutex ); }
|
||||
+#else
|
||||
+#define mod_lock()
|
||||
+#define mod_unlock()
|
||||
+#endif
|
||||
|
||||
/*----- prototypes -------------------------------------------------------*/
|
||||
|
||||
@@ -133,6 +148,7 @@ int _ipfix_send_message( ipfix_t *ifh,
|
||||
ipfix_message_t *message );
|
||||
int _ipfix_write_msghdr( ipfix_t *ifh, ipfix_message_t *msg, iobuf_t *buf );
|
||||
void _ipfix_disconnect( ipfix_collector_t *col );
|
||||
+int _ipfix_export_flush( ipfix_t *ifh );
|
||||
|
||||
|
||||
/* name : do_writeselect
|
||||
@@ -576,16 +592,18 @@ int ipfix_decode_float( void *in, void *
|
||||
|
||||
int ipfix_snprint_float( char *str, size_t size, void *data, size_t len )
|
||||
{
|
||||
- float tmp32;
|
||||
- double tmp64;
|
||||
+ uint32_t tmp32;
|
||||
+ uint64_t tmp64;
|
||||
|
||||
switch ( len ) {
|
||||
case 4:
|
||||
- ipfix_decode_float( data, &tmp32, 4);
|
||||
- return snprintf( str, size, "%f", tmp32 );
|
||||
+ memcpy( &tmp32, data, len );
|
||||
+ tmp32 = htonl( tmp32 );
|
||||
+ return snprintf( str, size, "%f", (float)tmp32 );
|
||||
case 8:
|
||||
- ipfix_decode_float( data, &tmp64, 8);
|
||||
- return snprintf( str, size, "%lf", tmp64);
|
||||
+ memcpy( &tmp64, data, len );
|
||||
+ tmp64 = HTONLL( tmp64 );
|
||||
+ return snprintf( str, size, "%lf", (double)tmp64 );
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -682,12 +700,19 @@ int ipfix_get_eno_ieid( char *field, int
|
||||
* parameters:
|
||||
* remarks: init module, read field type info.
|
||||
*/
|
||||
-int ipfix_init ( void )
|
||||
+int ipfix_init( void )
|
||||
{
|
||||
if ( g_tstart ) {
|
||||
ipfix_cleanup();
|
||||
}
|
||||
|
||||
+#ifndef NOTHREADS
|
||||
+ if ( pthread_mutex_init( &g_mutex, NULL ) !=0 ) {
|
||||
+ mlogf( 0, "[ipfix] pthread_mutex_init() failed: %s\n",
|
||||
+ strerror(errno) );
|
||||
+ return -1;
|
||||
+ }
|
||||
+#endif
|
||||
g_tstart = time(NULL);
|
||||
signal( SIGPIPE, SIG_IGN );
|
||||
g_lasttid = 255;
|
||||
@@ -806,6 +831,9 @@ void ipfix_cleanup ( void )
|
||||
g_data.maxfields = 0;
|
||||
g_data.lens = NULL;
|
||||
g_data.addrs = NULL;
|
||||
+#ifndef NOTHREADS
|
||||
+ (void)pthread_mutex_destroy( &g_mutex );
|
||||
+#endif
|
||||
}
|
||||
|
||||
int _ipfix_connect ( ipfix_collector_t *col )
|
||||
@@ -1465,7 +1493,7 @@ int _ipfix_write_template( ipfix_t
|
||||
default:
|
||||
/* check space */
|
||||
if ( tsize+ifh->offset > IPFIX_DEFAULT_BUFLEN ) {
|
||||
- if ( ipfix_export_flush( ifh ) < 0 )
|
||||
+ if ( _ipfix_export_flush( ifh ) < 0 )
|
||||
return -1;
|
||||
if ( tsize+ifh->offset > IPFIX_DEFAULT_BUFLEN )
|
||||
return -1;
|
||||
@@ -1474,6 +1502,8 @@ int _ipfix_write_template( ipfix_t
|
||||
/* write template prior to data */
|
||||
if ( ifh->offset > 0 ) {
|
||||
memmove( ifh->buffer + tsize, ifh->buffer, ifh->offset );
|
||||
+ if ( ifh->cs_tid )
|
||||
+ ifh->cs_header += tsize;
|
||||
}
|
||||
|
||||
buf = ifh->buffer;
|
||||
@@ -1615,8 +1645,11 @@ int ipfix_open( ipfix_t **ipfixh, int so
|
||||
return -1;
|
||||
}
|
||||
node->ifh = i;
|
||||
+
|
||||
+ mod_lock();
|
||||
node->next = g_ipfixlist;
|
||||
g_ipfixlist = node;
|
||||
+ mod_unlock();
|
||||
|
||||
*ipfixh = i;
|
||||
return 0;
|
||||
@@ -1633,7 +1666,8 @@ void ipfix_close( ipfix_t *h )
|
||||
{
|
||||
ipfix_node_t *l, *n;
|
||||
|
||||
- ipfix_export_flush( h );
|
||||
+ mod_lock();
|
||||
+ _ipfix_export_flush( h );
|
||||
|
||||
while( h->collectors )
|
||||
_ipfix_drop_collector( (ipfix_collector_t**)&h->collectors );
|
||||
@@ -1659,6 +1693,7 @@ void ipfix_close( ipfix_t *h )
|
||||
#endif
|
||||
free(h->buffer);
|
||||
free(h);
|
||||
+ mod_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2156,6 +2191,22 @@ void ipfix_release_template( ipfix_t *if
|
||||
ipfix_delete_template( ifh, templ );
|
||||
}
|
||||
|
||||
+static void _finish_cs( ipfix_t *ifh )
|
||||
+{
|
||||
+ size_t buflen;
|
||||
+ uint8_t *buf;
|
||||
+
|
||||
+ /* finish current dataset */
|
||||
+ if ( (buf=ifh->cs_header) ==NULL )
|
||||
+ return;
|
||||
+ buflen = 0;
|
||||
+ INSERTU16( buf+buflen, buflen, ifh->cs_tid );
|
||||
+ INSERTU16( buf+buflen, buflen, ifh->cs_bytes );
|
||||
+ ifh->cs_bytes = 0;
|
||||
+ ifh->cs_header = NULL;
|
||||
+ ifh->cs_tid = 0;
|
||||
+}
|
||||
+
|
||||
int ipfix_export( ipfix_t *ifh, ipfix_template_t *templ, ... )
|
||||
{
|
||||
int i;
|
||||
@@ -2199,13 +2250,14 @@ int ipfix_export( ipfix_t *ifh, ipfix_te
|
||||
g_data.addrs, g_data.lens );
|
||||
}
|
||||
|
||||
-int ipfix_export_array( ipfix_t *ifh,
|
||||
- ipfix_template_t *templ,
|
||||
- int nfields,
|
||||
- void **fields,
|
||||
- uint16_t *lengths )
|
||||
+static int
|
||||
+_ipfix_export_array( ipfix_t *ifh,
|
||||
+ ipfix_template_t *templ,
|
||||
+ int nfields,
|
||||
+ void **fields,
|
||||
+ uint16_t *lengths )
|
||||
{
|
||||
- int i;
|
||||
+ int i, newset_f=0;
|
||||
size_t buflen, datasetlen;
|
||||
uint8_t *p, *buf;
|
||||
|
||||
@@ -2249,7 +2301,19 @@ int ipfix_export_array( ipfix_t
|
||||
|
||||
/** get size of data set, check space
|
||||
*/
|
||||
- for ( i=0, datasetlen=4; i<nfields; i++ ) {
|
||||
+ if ( templ->tid == ifh->cs_tid ) {
|
||||
+ newset_f = 0;
|
||||
+ datasetlen = 0;
|
||||
+ }
|
||||
+ else {
|
||||
+ if ( ifh->cs_tid > 0 ) {
|
||||
+ _finish_cs( ifh );
|
||||
+ }
|
||||
+ newset_f = 1;
|
||||
+ datasetlen = 4;
|
||||
+ }
|
||||
+
|
||||
+ for ( i=0; i<nfields; i++ ) {
|
||||
if ( templ->fields[i].flength == IPFIX_FT_VARLEN ) {
|
||||
if ( lengths[i]>254 )
|
||||
datasetlen += 3;
|
||||
@@ -2263,21 +2327,29 @@ int ipfix_export_array( ipfix_t
|
||||
}
|
||||
datasetlen += lengths[i];
|
||||
}
|
||||
- if ( ((ifh->offset + datasetlen) > IPFIX_DEFAULT_BUFLEN )
|
||||
- && (ipfix_export_flush( ifh ) <0) ) {
|
||||
- return -1;
|
||||
+
|
||||
+ if ( (ifh->offset + datasetlen) > IPFIX_DEFAULT_BUFLEN ) {
|
||||
+ if ( ifh->cs_tid )
|
||||
+ _finish_cs( ifh );
|
||||
+ newset_f = 1;
|
||||
+
|
||||
+ if ( _ipfix_export_flush( ifh ) <0 )
|
||||
+ return -1;
|
||||
}
|
||||
|
||||
- /* fill buffer
|
||||
- */
|
||||
+ /* fill buffer */
|
||||
buf = (uint8_t*)(ifh->buffer) + ifh->offset;
|
||||
buflen = 0;
|
||||
|
||||
- /* insert data set
|
||||
- */
|
||||
- ifh->nrecords ++;
|
||||
- INSERTU16( buf+buflen, buflen, templ->tid );
|
||||
- INSERTU16( buf+buflen, buflen, datasetlen );
|
||||
+ if ( newset_f ) {
|
||||
+ /* insert data set
|
||||
+ */
|
||||
+ ifh->cs_bytes = 0;
|
||||
+ ifh->cs_header = buf;
|
||||
+ ifh->cs_tid = templ->tid;
|
||||
+ INSERTU16( buf+buflen, buflen, templ->tid );
|
||||
+ INSERTU16( buf+buflen, buflen, 4 );
|
||||
+ }
|
||||
|
||||
/* insert data record
|
||||
*/
|
||||
@@ -2303,7 +2375,9 @@ int ipfix_export_array( ipfix_t
|
||||
buflen += lengths[i];
|
||||
}
|
||||
|
||||
+ ifh->nrecords ++;
|
||||
ifh->offset += buflen;
|
||||
+ ifh->cs_bytes += buflen;
|
||||
if ( ifh->version == IPFIX_VERSION )
|
||||
ifh->seqno ++;
|
||||
return 0;
|
||||
@@ -2313,7 +2387,7 @@ int ipfix_export_array( ipfix_t
|
||||
* parameters:
|
||||
* remarks: rewrite this func!
|
||||
*/
|
||||
-int ipfix_export_flush( ipfix_t *ifh )
|
||||
+int _ipfix_export_flush( ipfix_t *ifh )
|
||||
{
|
||||
iobuf_t *buf;
|
||||
ipfix_collector_t *col;
|
||||
@@ -2322,8 +2396,14 @@ int ipfix_export_flush( ipfix_t *ifh )
|
||||
if ( (ifh==NULL) || (ifh->offset==0) )
|
||||
return 0;
|
||||
|
||||
- if ( (buf=_ipfix_getbuf()) ==NULL )
|
||||
+ if ( ifh->cs_tid > 0 ) {
|
||||
+ /* finish current dataset */
|
||||
+ _finish_cs( ifh );
|
||||
+ }
|
||||
+
|
||||
+ if ( (buf=_ipfix_getbuf()) ==NULL ) {
|
||||
return -1;
|
||||
+ }
|
||||
|
||||
#ifdef DEBUG
|
||||
mlogf( 0, "[ipfix_export_flush] msg has %d records, %d bytes\n",
|
||||
@@ -2350,3 +2430,30 @@ int ipfix_export_flush( ipfix_t *ifh )
|
||||
_ipfix_freebuf( buf );
|
||||
return ret;
|
||||
}
|
||||
+
|
||||
+int ipfix_export_array( ipfix_t *ifh,
|
||||
+ ipfix_template_t *templ,
|
||||
+ int nfields,
|
||||
+ void **fields,
|
||||
+ uint16_t *lengths )
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ mod_lock();
|
||||
+ ret = _ipfix_export_array( ifh, templ, nfields, fields, lengths );
|
||||
+ mod_unlock();
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int ipfix_export_flush( ipfix_t *ifh )
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ mod_lock();
|
||||
+ ret = _ipfix_export_flush( ifh );
|
||||
+ mod_unlock();
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
--- a/lib/ipfix.h
|
||||
+++ b/lib/ipfix.h
|
||||
@@ -142,6 +142,12 @@ typedef struct
|
||||
int nrecords; /* no. of records in buffer */
|
||||
size_t offset; /* output buffer fill level */
|
||||
uint32_t seqno; /* sequence no. of next message */
|
||||
+
|
||||
+ /* experimental */
|
||||
+ int cs_tid; /* template id of current dataset */
|
||||
+ int cs_bytes; /* size of current set */
|
||||
+ uint8_t *cs_header; /* start of current set */
|
||||
+
|
||||
} ipfix_t;
|
||||
|
||||
/** exporter funcs
|
||||
--- a/lib/ipfix_col.c
|
||||
+++ b/lib/ipfix_col.c
|
||||
@@ -897,6 +897,8 @@ int ipfix_decode_datarecord( ipfixt_node
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ n->ipfixt->fields[i].elem->decode(p,p,len);
|
||||
+
|
||||
data->lens[i] = len;
|
||||
data->addrs[i] = p;
|
||||
|
||||
@@ -907,7 +909,7 @@ int ipfix_decode_datarecord( ipfixt_node
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void do_free_datarecord( ipfix_datarecord_t *data )
|
||||
+void ipfix_free_datarecord( ipfix_datarecord_t *data )
|
||||
{
|
||||
if ( data ) {
|
||||
if ( data->addrs )
|
||||
@@ -925,6 +927,7 @@ int ipfix_parse_msg( ipfix_input_t *inpu
|
||||
ipfix_hdr_t hdr; /* ipfix packet header */
|
||||
ipfixs_node_t *s;
|
||||
ipfix_datarecord_t data = { NULL, NULL, 0 };
|
||||
+ ipfixe_node_t *e;
|
||||
uint8_t *buf; /* ipfix payload */
|
||||
uint16_t setid, setlen; /* set id, set lenght */
|
||||
int i, nread, offset; /* counter */
|
||||
@@ -1042,6 +1045,12 @@ int ipfix_parse_msg( ipfix_input_t *inpu
|
||||
err_flag = 1;
|
||||
}
|
||||
else {
|
||||
+ for ( e=g_exporter; e!=NULL; e=e->next ) {
|
||||
+ if ( e->elem->export_dset )
|
||||
+ (void) e->elem->export_dset( t, buf+nread, setlen,
|
||||
+ e->elem->data );
|
||||
+ }
|
||||
+
|
||||
/** read data records
|
||||
*/
|
||||
for ( offset=nread, bytesleft=setlen; bytesleft>4; ) {
|
||||
@@ -1076,11 +1085,11 @@ int ipfix_parse_msg( ipfix_input_t *inpu
|
||||
goto errend;
|
||||
|
||||
end:
|
||||
- do_free_datarecord( &data );
|
||||
+ ipfix_free_datarecord( &data );
|
||||
return nread;
|
||||
|
||||
errend:
|
||||
- do_free_datarecord( &data );
|
||||
+ ipfix_free_datarecord( &data );
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1093,7 +1102,7 @@ void process_client_tcp( int fd, int mas
|
||||
tcp_conn_t *tcon = (tcp_conn_t*)data;
|
||||
char *func = "process_client_tcp";
|
||||
|
||||
- mlogf( 3, "[%s] fd %d mask %d called.\n", func, fd, mask );
|
||||
+ mlogf( 4, "[%s] fd %d mask %d called.\n", func, fd, mask );
|
||||
|
||||
/** read ipfix header
|
||||
*/
|
||||
--- a/lib/ipfix_col.h
|
||||
+++ b/lib/ipfix_col.h
|
||||
@@ -88,6 +88,7 @@ typedef struct ipfix_col_info
|
||||
int (*export_newsource)(ipfixs_node_t*,void*);
|
||||
int (*export_newmsg)(ipfixs_node_t*,ipfix_hdr_t*,void*);
|
||||
int (*export_trecord)(ipfixs_node_t*,ipfixt_node_t*,void*);
|
||||
+ int (*export_dset)(ipfixt_node_t*,uint8_t*,size_t,void*);
|
||||
int (*export_drecord)(ipfixs_node_t*,ipfixt_node_t*,
|
||||
ipfix_datarecord_t*,void*);
|
||||
void (*export_cleanup)(void*);
|
||||
--- a/lib/ipfix_col_files.c
|
||||
+++ b/lib/ipfix_col_files.c
|
||||
@@ -68,7 +68,7 @@ static int export_newsource_file( ipfixs
|
||||
return -1;
|
||||
}
|
||||
snprintf( s->fname+strlen(s->fname), PATH_MAX-strlen(s->fname),
|
||||
- "/%u", s->odid );
|
||||
+ "/%u", (unsigned int)s->odid );
|
||||
if ( (access( s->fname, R_OK ) <0 )
|
||||
&& (mkdir( s->fname, S_IRWXU ) <0) ) {
|
||||
mlogf( 0, "[%s] cannot access dir '%s': %s\n",
|
||||
--- a/lib/ipfix_FOKUS_IEs.txt
|
||||
+++ b/lib/ipfix_FOKUS_IEs.txt
|
||||
@@ -24,6 +24,8 @@
|
||||
196, IPFIX_FT_PKTID, 4, IPFIX_CODING_UINT, "pktId", "FOKUS packet id"
|
||||
197, IPFIX_FT_STARTTIME, 4, IPFIX_CODING_INT, "startTime", "FOKUS interval start"
|
||||
198, IPFIX_FT_ENDTIME, 4, IPFIX_CODING_INT, "endTime", "FOKUS interval end"
|
||||
+199, IPFIX_FT_RTT_USEC, 8, IPFIX_CODING_UINT, "rtt_usec", "FOKUS rtt in us"
|
||||
+
|
||||
300, IPFIX_FT_FLOWCREATIONTIMEUSEC, 4, IPFIX_CODING_INT, "flowCreationTimeUsec", "FOKUS flow start usec fraction"
|
||||
301, IPFIX_FT_FLOWENDTIMEUSEC, 4, IPFIX_CODING_INT, "flowEndTimeUsec", "FOKUS flow end usec fraction"
|
||||
303, IPFIX_FT_TC_PACKETS, 4, IPFIX_CODING_UINT, "tcPackets", "DAIDALOS Packets seen"
|
||||
@@ -39,3 +41,48 @@
|
||||
313, IPFIX_FT_OWDVARMIN_NSEC, 4, IPFIX_CODING_INT, "owdvarmin_nsec", "FOKUS minimum owd variance in ns"
|
||||
314, IPFIX_FT_OWDVARMAX_NSEC, 4, IPFIX_CODING_INT, "owdvarmax_nsec", "FOKUS maximum ow variance in ns"
|
||||
|
||||
+# Project INTERSECTION
|
||||
+315, IPFIX_FT_SOURCEIPV4FANOUT, 4, IPFIX_CODING_UINT,"sourceIPv4FanOut", "FOKUS IPv4 fanout"
|
||||
+316, IPFIX_FT_DESTINATIONIPV4FANIN, 4, IPFIX_CODING_UINT,"destinationIPv4FanIn", "FOKUS IPv4 fanin"
|
||||
+
|
||||
+# Project PRISM
|
||||
+
|
||||
+330, IPFIX_FT_PR_SESSIONID, 4, IPFIX_CODING_UINT, "sessionId", "PRISM Session ID"
|
||||
+331, IPFIX_FT_PR_TRANSACTIONID, 4, IPFIX_CODING_UINT, "transactionId", "PRISM Transaction ID"
|
||||
+332, IPFIX_FT_PR_ENCRYPTEDDATA, 65535, IPFIX_CODING_STRING, "encryptedData", "PRISM encrypted data"
|
||||
+333, IPFIX_FT_PR_DECRYPTIONKEY, 65535, IPFIX_CODING_STRING, "decryptionKey", "PRISM decryption key"
|
||||
+334, IPFIX_FT_PR_KEYSHARE, 65535, IPFIX_CODING_STRING, "keyShare", "PRISM key share"
|
||||
+335, IPFIX_FT_PR_KEYSHAREADP, 65535, IPFIX_CODING_STRING, "keyShareAdp", "PRISM key share ADP"
|
||||
+336, IPFIX_FT_PR_INITVECTOR, 65535, IPFIX_CODING_STRING, "cryptoInitVector", "PRISM crypto init vector"
|
||||
+
|
||||
+
|
||||
+# these information elements have been defined by FOKUS for the Oracle project
|
||||
+
|
||||
+402, IPFIX_FT_ORsignalBandwidth, 4, IPFIX_CODING_UINT, "ORsignalBandwidth", "signal bandwidth"
|
||||
+403, IPFIX_FT_ORsignalPower, 2, IPFIX_CODING_UINT, "ORsignalPower", "ERIP"
|
||||
+404, IPFIX_FT_ORmodulationType, 2, IPFIX_CODING_UINT, "ORmodulationType", "AM/FM,.."
|
||||
+405, IPFIX_FT_ORsymbolRate, 2, IPFIX_CODING_UINT, "ORsymbolRate", "symbol rate"
|
||||
+406, IPFIX_FT_ORmodulationOrder, 1, IPFIX_CODING_UINT, "ORmodulationOrder", "number of levels"
|
||||
+407, IPFIX_FT_ORrolloffFactor, 2, IPFIX_CODING_UINT, "ORrolloffFactor", "roll of factor"
|
||||
+408, IPFIX_FT_ORgeopositionLon, 4, IPFIX_CODING_UINT, "ORgeopositionLon", "GPS coordinate, resolution 1 cm"
|
||||
+409, IPFIX_FT_ORgeopositionLat, 4, IPFIX_CODING_UINT, "ORgeopositionLat", "GPS coordinate, resolution 1 cm"
|
||||
+410, IPFIX_FT_ORgeopositionElev, 4, IPFIX_CODING_UINT, "ORgeopositionElev", "GPS coordinate, resolution 1 cm"
|
||||
+411, IPFIX_FT_ORpolicyRecord, 65535, IPFIX_CODING_STRING, "ORpolicyRecord", "policy record has variable length, First 8 bits in data describe the length (in bytes) of the field"
|
||||
+420, IPFIX_FT_channel_status, 1, IPFIX_CODING_UINT, "channel_status", vacancy of the scanned channel (1: channel busy, 0: channel idle)"
|
||||
+421, IPFIX_FT_sensing_value, 2, IPFIX_CODING_UINT, "sensing_value", "Cost function output"
|
||||
+422, IPFIX_FT_sensing_threshold, 2, IPFIX_CODING_UINT, "sensing_threshold", "Decision threshold"
|
||||
+423, IPFIX_FT_OR_terminal_id, 1, IPFIX_CODING_UINT, "OR_terminal_id", "terminal identifier"
|
||||
+424, IPFIX_FT_OR_terminal_id_list, 65535, IPFIX_CODING_STRING, "OR_terminal_id_list", "terminal identifier list"
|
||||
+425, IPFIX_FT_Infrastructure_network_id, 1, IPFIX_CODING_UINT, "Infrastructure_network_id", "network identifier"
|
||||
+426, IPFIX_FT_Infrastructure_network_type, 1, IPFIX_CODING_UINT, "Infrastructure_network_type", "network type (GSM - 1, UMTS - 2, WiMAX - 3, WiFi - 4)"
|
||||
+427, IPFIX_FT_Battery_lifetime_min, 1, IPFIX_CODING_UINT, "Battery_lifetime_min", "expected battery lifetime to provide requested services or functionalities, in minutes"
|
||||
+428, IPFIX_FT_Battery_lifetime_h, 1, IPFIX_CODING_UINT, "Battery_lifetime_h", "expected battery lifetime to provide requested services or functionalities, in hours"
|
||||
+429, IPFIX_FT_Battery_status, 1, IPFIX_CODING_UINT, "Battery_status", "expected battery lifetime to provide requested services or functionalities, 1 bit status flag, values 1 or 0"
|
||||
+430, IPFIX_FT_Cell_id_number, 4, IPFIX_CODING_UINT, "Cell_id_number", "16-32 bit cell id number, identifier"
|
||||
+431, IPFIX_FT_Spectral_allocation_vector, 1, IPFIX_CODING_UINT, "Spectral_allocation_vector", "binary vector to indicate whether a band is free 1 bit 0 or not 1 bit 1"
|
||||
+432, IPFIX_FT_Spectral_allocation_profile, 2, IPFIX_CODING_UINT, "Spectral_allocation_profile", "received power spectral density vs. frequency to indicate spectral activity in the band of interest (8-16 bits per discrete frequency value)"
|
||||
+433, IPFIX_FT_Center_frequency, 2, IPFIX_CODING_UINT, "Center_frequency", "Center frequency of the sensed band"
|
||||
+434, IPFIX_FT_Bandwidth_of_CAP, 2, IPFIX_CODING_UINT, "Bandwidth_of_CAP", "Bandwidth of the spectral allocation profile"
|
||||
+435, IPFIX_FT_ORmodulation, 1, IPFIX_CODING_UINT, "ORmodulation", "CREST factor"
|
||||
+436, IPFIX_FT_ORprofileRecord, 65535, IPFIX_CODING_STRING, "ORprofileRecord", "profile record has variable length, First 8 bits in data describe the length (in bytes) of the field"
|
||||
+
|
44
libs/libipfix/patches/110-wprobe_ie.patch
Normal file
44
libs/libipfix/patches/110-wprobe_ie.patch
Normal file
@ -0,0 +1,44 @@
|
||||
--- a/lib/ipfix_FOKUS_IEs.txt
|
||||
+++ b/lib/ipfix_FOKUS_IEs.txt
|
||||
@@ -86,3 +86,41 @@
|
||||
435, IPFIX_FT_ORmodulation, 1, IPFIX_CODING_UINT, "ORmodulation", "CREST factor"
|
||||
436, IPFIX_FT_ORprofileRecord, 65535, IPFIX_CODING_STRING, "ORprofileRecord", "profile record has variable length, First 8 bits in data describe the length (in bytes) of the field"
|
||||
|
||||
+500, IPFIX_FT_WPROBE_NOISE_N, 4, IPFIX_CODING_UINT, "global_noise_n", "wprobe global noice floor - Number of samples"
|
||||
+501, IPFIX_FT_WPROBE_NOISE_S, 8, IPFIX_CODING_UINT, "global_noise_s", "wprobe global noice floor - Sum of samples"
|
||||
+502, IPFIX_FT_WPROBE_NOISE_SS, 8, IPFIX_CODING_UINT, "global_noise_ss", "wprobe global noice floor - Sum of squared samples"
|
||||
+503, IPFIX_FT_WPROBE_PHY_BUSY_N, 4, IPFIX_CODING_UINT, "global_phy_busy_n", "wprobe global airtime total - Number of samples"
|
||||
+504, IPFIX_FT_WPROBE_PHY_BUSY_S, 8, IPFIX_CODING_UINT, "global_phy_busy_s", "wprobe global airtime total - Sum of samples"
|
||||
+505, IPFIX_FT_WPROBE_PHY_BUSY_SS, 8, IPFIX_CODING_UINT, "global_phy_busy_ss", "wprobe global airtime total - Sum of squared samples"
|
||||
+506, IPFIX_FT_WPROBE_PHY_RX_N, 4, IPFIX_CODING_UINT, "global_phy_rx_n", "wprobe global airtime total from rx-frame - Number of samples"
|
||||
+507, IPFIX_FT_WPROBE_PHY_RX_S, 8, IPFIX_CODING_UINT, "global_phy_rx_s", "wprobe global airtime total from rx-frame - Sum of samples"
|
||||
+508, IPFIX_FT_WPROBE_PHY_RX_SS, 8, IPFIX_CODING_UINT, "global_phy_rx_ss", "wprobe global airtime total from rx-frame - Sum of squared samples"
|
||||
+509, IPFIX_FT_WPROBE_PHY_TX_N, 4, IPFIX_CODING_UINT, "global_phy_tx_n", "wprobe global airtime total from tx-frame - Number of samples"
|
||||
+510, IPFIX_FT_WPROBE_PHY_TX_S, 8, IPFIX_CODING_UINT, "global_phy_tx_s", "wprobe global airtime total from tx-frame - Sum of samples"
|
||||
+511, IPFIX_FT_WPROBE_PHY_TX_SS, 8, IPFIX_CODING_UINT, "global_phy_tx_ss", "wprobe global airtime total from tx-frame - Sum of squared samples"
|
||||
+512, IPFIX_FT_WPROBE_RSSI_N, 4, IPFIX_CODING_UINT, "link_rssi_n", "wprobe link received signal strength indication - Number of samples"
|
||||
+513, IPFIX_FT_WPROBE_RSSI_S, 8, IPFIX_CODING_UINT, "link_rssi_s", "wprobe link received signal strength indication - Sum of samples"
|
||||
+514, IPFIX_FT_WPROBE_RSSI_SS, 8, IPFIX_CODING_UINT, "link_rssi_ss", "wprobe link received signal strength indication - Sum of squared samples"
|
||||
+515, IPFIX_FT_WPROBE_SIGNAL_N, 4, IPFIX_CODING_UINT, "link_signal_n", "wprobe link signal strength in dB - Number of samples"
|
||||
+516, IPFIX_FT_WPROBE_SIGNAL_S, 8, IPFIX_CODING_UINT, "link_signal_s", "wprobe link signal strength in dB - Sum of samples"
|
||||
+517, IPFIX_FT_WPROBE_SIGNAL_SS, 8, IPFIX_CODING_UINT, "link_signal_ss", "wprobe link signal strength in dB - Sum of squared samples"
|
||||
+518, IPFIX_FT_WPROBE_IEEE_RX_RATE_N, 4, IPFIX_CODING_UINT, "link_ieee_rx_rate_n", "wprobe link IEEE 802.11 RX data rate - Number of samples"
|
||||
+519, IPFIX_FT_WPROBE_IEEE_RX_RATE_S, 8, IPFIX_CODING_UINT, "link_ieee_rx_rate_s", "wprobe link IEEE 802.11 RX data rate - Sum of samples"
|
||||
+520, IPFIX_FT_WPROBE_IEEE_RX_RATE_SS, 8, IPFIX_CODING_UINT, "link_ieee_rx_rate_ss", "wprobe link IEEE 802.11 RX data rate - Sum of squared samples"
|
||||
+521, IPFIX_FT_WPROBE_IEEE_TX_RATE_N, 4, IPFIX_CODING_UINT, "link_ieee_tx_rate_n", "wprobe link IEEE 802.11 TX data rate - Number of samples"
|
||||
+522, IPFIX_FT_WPROBE_IEEE_TX_RATE_S, 8, IPFIX_CODING_UINT, "link_ieee_tx_rate_s", "wprobe link IEEE 802.11 TX data rate - Sum of samples"
|
||||
+523, IPFIX_FT_WPROBE_IEEE_TX_RATE_SS, 8, IPFIX_CODING_UINT, "link_ieee_tx_rate_ss", "wprobe link IEEE 802.11 TX data rate - Sum of squared samples"
|
||||
+524, IPFIX_FT_WPROBE_RETRANSMIT_200_N, 4, IPFIX_CODING_UINT, "link_retransmit_200_n", "wprobe link total retransmissions per packet - <200 bytes - Number of samples"
|
||||
+525, IPFIX_FT_WPROBE_RETRANSMIT_200_S, 8, IPFIX_CODING_UINT, "link_retransmit_200_s", "wprobe link total retransmissions per packet - <200 bytes - Sum of samples"
|
||||
+526, IPFIX_FT_WPROBE_RETRANSMIT_200_SS, 8, IPFIX_CODING_UINT, "link_retransmit_200_ss", "wprobe link total retransmissions per packet - <200 bytes - Sum of squared samples"
|
||||
+527, IPFIX_FT_WPROBE_RETRANSMIT_400_N, 4, IPFIX_CODING_UINT, "link_retransmit_400_n", "wprobe link total retransmissions per packet - <400 bytes - Number of samples"
|
||||
+528, IPFIX_FT_WPROBE_RETRANSMIT_400_S, 8, IPFIX_CODING_UINT, "link_retransmit_400_s", "wprobe link total retransmissions per packet - <400 bytes - Sum of samples"
|
||||
+529, IPFIX_FT_WPROBE_RETRANSMIT_400_SS, 8, IPFIX_CODING_UINT, "link_retransmit_400_ss", "wprobe link total retransmissions per packet - <400 bytes - Sum of squared samples"
|
||||
+530, IPFIX_FT_WPROBE_RETRANSMIT_800_N, 4, IPFIX_CODING_UINT, "link_retransmit_800_n", "wprobe link total retransmissions per packet - <800 bytes - Number of samples"
|
||||
+531, IPFIX_FT_WPROBE_RETRANSMIT_800_S, 8, IPFIX_CODING_UINT, "link_retransmit_800_s", "wprobe link total retransmissions per packet - <800 bytes - Sum of samples"
|
||||
+532, IPFIX_FT_WPROBE_RETRANSMIT_800_SS, 8, IPFIX_CODING_UINT, "link_retransmit_800_ss", "wprobe link total retransmissions per packet - <800 bytes - Sum of squared samples"
|
||||
+533, IPFIX_FT_WPROBE_RETRANSMIT_1600_N, 4, IPFIX_CODING_UINT, "link_retransmit_1600_n", "wprobe link total retransmissions per packet - >800 bytes - Number of samples"
|
||||
+534, IPFIX_FT_WPROBE_RETRANSMIT_1600_S, 8, IPFIX_CODING_UINT, "link_retransmit_1600_s", "wprobe link total retransmissions per packet - >800 bytes - Sum of samples"
|
||||
+535, IPFIX_FT_WPROBE_RETRANSMIT_1600_SS, 8, IPFIX_CODING_UINT, "link_retransmit_1600_ss", "wprobe link total retransmissions per packet - >800 bytes - Sum of squared samples"
|
||||
+536, IPFIX_FT_WPROBE_FRAMES, 4, IPFIX_CODING_UINT, "global_frames", "wprobe global number of 802.11 frames seen"
|
||||
+537, IPFIX_FT_WPROBE_PROBEREQ, 4, IPFIX_CODING_UINT, "global_probereq", "wprobe global number of 802.11 probe requests seen"
|
27
libs/libipfix/patches/120-ipfixmisc.patch
Normal file
27
libs/libipfix/patches/120-ipfixmisc.patch
Normal file
@ -0,0 +1,27 @@
|
||||
Index: libipfix.r51/lib/Makefile.in
|
||||
===================================================================
|
||||
--- libipfix.r51.orig/lib/Makefile.in 2008-08-05 15:15:23.000000000 +0200
|
||||
+++ libipfix.r51/lib/Makefile.in 2012-06-05 19:26:34.061692890 +0200
|
||||
@@ -41,7 +41,7 @@
|
||||
INCLS = -I. -I..
|
||||
CFLAGS = $(CCOPT) $(INCLS) $(DEFS)
|
||||
|
||||
-TARGETS = libmisc.a libipfix.a
|
||||
+TARGETS = libipfixmisc.a libipfix.a
|
||||
OBJS = ipfix.o ipfix_col.o ipfix_print.o \
|
||||
ipfix_col_files.o ipfix_col_db.o @IPFIX_DB_OBJ@ @IPFIX_SSL_OBJ@
|
||||
DEPHDR = ipfix.h ipfix_def.h ipfix_fields.h ipfix_def_fokus.h ipfix_fields_fokus.h
|
||||
@@ -60,11 +60,11 @@
|
||||
install:
|
||||
@[ -d ${libdir} ] || (mkdir -p ${libdir}; chmod 755 ${libdir})
|
||||
$(INSTALL_DATA) libipfix.a ${libdir}/
|
||||
- $(INSTALL_DATA) libmisc.a ${libdir}/
|
||||
+ $(INSTALL_DATA) libipfixmisc.a ${libdir}/
|
||||
@[ -d ${includedir} ] || (mkdir -p ${includedir}; chmod 755 ${includedir})
|
||||
$(INSTALL_HEADER) ipfix*.h mlog.h mpoll.h ${includedir}/
|
||||
|
||||
-libmisc.a: $(MISCOBJS) Makefile
|
||||
+libipfixmisc.a: $(MISCOBJS) Makefile
|
||||
@rm -f $@
|
||||
$(AR) rc $@ $(MISCOBJS)
|
||||
|
51
net/bridge-utils/Makefile
Normal file
51
net/bridge-utils/Makefile
Normal file
@ -0,0 +1,51 @@
|
||||
#
|
||||
# Copyright (C) 2006-2012 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=bridge-utils
|
||||
PKG_RELEASE:=1
|
||||
PKG_SOURCE_URL:=@SF/bridge
|
||||
PKG_VERSION:=1.5
|
||||
PKG_MD5SUM:=ec7b381160b340648dede58c31bb2238
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/bridge
|
||||
SECTION:=net
|
||||
CATEGORY:=Base system
|
||||
TITLE:=Ethernet bridging configuration utility
|
||||
URL:=http://bridge.sourceforge.net/
|
||||
endef
|
||||
|
||||
define Package/bridge/description
|
||||
Manage ethernet bridging: a way to connect networks together to
|
||||
form a larger network.
|
||||
endef
|
||||
|
||||
CONFIGURE_ARGS += \
|
||||
--with-linux-headers="$(LINUX_DIR)" \
|
||||
|
||||
define Build/Prepare
|
||||
$(call Build/Prepare/Default)
|
||||
( cd $(PKG_BUILD_DIR) ; \
|
||||
[ -f ./configure ] || { \
|
||||
ln -sf configure.in configure.ac ; \
|
||||
autoconf ; \
|
||||
} \
|
||||
)
|
||||
endef
|
||||
|
||||
define Package/bridge/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/brctl/brctl $(1)/usr/sbin
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,bridge))
|
11
net/bridge-utils/patches/001-libbridge_cflags.patch
Normal file
11
net/bridge-utils/patches/001-libbridge_cflags.patch
Normal file
@ -0,0 +1,11 @@
|
||||
--- a/libbridge/Makefile.in
|
||||
+++ b/libbridge/Makefile.in
|
||||
@@ -5,7 +5,7 @@ AR=ar
|
||||
RANLIB=@RANLIB@
|
||||
|
||||
CC=@CC@
|
||||
-CFLAGS = -Wall -g $(KERNEL_HEADERS)
|
||||
+CFLAGS = -Wall -g @CFLAGS@ $(KERNEL_HEADERS)
|
||||
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
74
net/crda/Makefile
Normal file
74
net/crda/Makefile
Normal file
@ -0,0 +1,74 @@
|
||||
#
|
||||
# Copyright (C) 2009-2012 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=crda
|
||||
PKG_RELEASE:=1
|
||||
PKG_VERSION:=1.1.2
|
||||
PKG_SOURCE_URL:=http://wireless.kernel.org/download/crda
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
|
||||
PKG_MD5SUM:=5226f65aebacf94baaf820f8b4e06df4
|
||||
|
||||
PKG_REGULATORY_NAME:=regulatory
|
||||
PKG_REGULATORY_VERSION:=2011.04.28
|
||||
PKG_REGULATORY_SOURCE_URL:=http://wireless.kernel.org/download/wireless-regdb/regulatory.bins
|
||||
PKG_REGULATORY_SOURCE:=$(PKG_REGULATORY_VERSION)-$(PKG_REGULATORY_NAME).bin
|
||||
PKG_REGULATORY_MD5SUM:=1535e98bcaba732e2f8e8f62dac6f369
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/crda
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
TITLE:=Central Regulatory Domain Agent (CRDA)
|
||||
DEPENDS:=+libnl-tiny
|
||||
URL:=http://wireless.kernel.org/en/developers/Regulatory/CRDA
|
||||
endef
|
||||
|
||||
define Download/wireless-regdb
|
||||
FILE:=$(PKG_REGULATORY_SOURCE)
|
||||
URL:=$(PKG_REGULATORY_SOURCE_URL)
|
||||
VERSION:=$(PKG_REGULATORY_VERSION)
|
||||
MD5SUM:=$(PKG_REGULATORY_MD5SUM)
|
||||
endef
|
||||
$(eval $(call Download,wireless-regdb))
|
||||
|
||||
define Package/crda/description
|
||||
This is the Central Regulatory Domain Agent for Linux. It serves one
|
||||
purpose: tell Linux kernel what to enforce. In essence it is a udev
|
||||
helper for communication between the kernel and userspace. You only
|
||||
need to run this manually for debugging purposes. For manual changing
|
||||
of regulatory domains use iw (iw reg set) or wpa_supplicant (feature
|
||||
yet to be added).
|
||||
endef
|
||||
|
||||
TARGET_CPPFLAGS := \
|
||||
-I$(STAGING_DIR)/usr/include/libnl-tiny \
|
||||
-D_GNU_SOURCE \
|
||||
$(TARGET_CPPFLAGS)
|
||||
|
||||
MAKE_FLAGS += \
|
||||
NL1FOUND="" NL2FOUND=Y \
|
||||
NLLIBNAME="libnl-tiny" \
|
||||
NLLIBS="-lnl-tiny -lm" \
|
||||
REG_BIN="$(DL_DIR)/$(PKG_REGULATORY_SOURCE)" \
|
||||
crda
|
||||
|
||||
define Package/crda/install
|
||||
$(INSTALL_DIR) $(1)/sbin
|
||||
$(INSTALL_DIR) $(1)/etc/hotplug.d
|
||||
$(INSTALL_DIR) $(1)/etc/hotplug.d/platform
|
||||
$(INSTALL_DIR) $(1)/usr/lib/crda
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/crda $(1)/sbin/
|
||||
$(INSTALL_DATA) ./files/hotplug.rule $(1)/etc/hotplug.d/platform/10-regulatory
|
||||
$(INSTALL_DATA) $(DL_DIR)/$(PKG_REGULATORY_SOURCE) $(1)/usr/lib/crda/regulatory.bin
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,crda))
|
||||
|
6
net/crda/files/hotplug.rule
Normal file
6
net/crda/files/hotplug.rule
Normal file
@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2009 OpenWrt.org
|
||||
|
||||
[ change = "$ACTION" -a regulatory.0 = "$DEVICENAME" ] && {
|
||||
/sbin/crda
|
||||
}
|
13
net/crda/patches/101-make_crypto_use_optional.patch
Normal file
13
net/crda/patches/101-make_crypto_use_optional.patch
Normal file
@ -0,0 +1,13 @@
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -35,7 +35,9 @@ LDLIBS += `pkg-config --libs openssl`
|
||||
|
||||
reglib.o: keys-ssl.c
|
||||
|
||||
-else
|
||||
+endif
|
||||
+
|
||||
+ifeq ($(USE_GCRYPT),1)
|
||||
CFLAGS += -DUSE_GCRYPT
|
||||
LDLIBS += -lgcrypt
|
||||
|
55
net/madwifi/Config.in
Normal file
55
net/madwifi/Config.in
Normal file
@ -0,0 +1,55 @@
|
||||
menu "Configuration"
|
||||
depends on PACKAGE_kmod-madwifi
|
||||
|
||||
config MADWIFI_DEBUG
|
||||
bool "Enable compilation of debugging features"
|
||||
depends on DEVEL
|
||||
default n
|
||||
|
||||
config MADWIFI_COMPRESSION
|
||||
bool "Enable Atheros Super A/G Compression"
|
||||
depends !TARGET_ar71xx
|
||||
default n
|
||||
help
|
||||
Enables Atheros Super A/G Hardware Compression Engine.
|
||||
|
||||
config MADWIFI_SINGLE_MODULE
|
||||
bool "Combine driver and net80211 into a single module"
|
||||
default y
|
||||
help
|
||||
This option combines all driver and stack related code (except for HAL)
|
||||
into a single module, thus saving space and removing unnecessary kernel
|
||||
exports
|
||||
|
||||
choice
|
||||
prompt "Rate control algorithm selection"
|
||||
default MADWIFI_RCA_MINSTREL
|
||||
help
|
||||
This option controls how MadWifi chooses its bitrate.
|
||||
|
||||
config MADWIFI_RCA_MINSTREL
|
||||
bool "Use the Minstrel rate control algorithm"
|
||||
help
|
||||
This code is takes a wandering minstrel approach. Wander around the
|
||||
different rates, singing wherever you can. And then, look at the
|
||||
performance, and make a choice. Note that the wandering minstrel will
|
||||
always wander in directions where he/she feels he/she will get paid
|
||||
the best for his/her work.
|
||||
|
||||
config MADWIFI_RCA_SAMPLERATE
|
||||
bool "Use the SampleRate rate control algorithm"
|
||||
help
|
||||
SampleRate decides on the transmission bit-rate based on the past
|
||||
history of performance; it keeps a record of the number of successive
|
||||
failures, the number of successful transmits and the total transmission
|
||||
time along with the destination for that bit-rate. Stale samples are
|
||||
removed based on a EWMA windowing mechanism. If in the sampling
|
||||
process, no successful acknowledgment is received or the number of
|
||||
packets sent is multiple of 10 on a specific link, it transmits the
|
||||
packet with the highest rate which has not failed 4 successive times.
|
||||
Other than that it transmits packets at the rate which has the lowest
|
||||
average transmission time.
|
||||
|
||||
endchoice
|
||||
|
||||
endmenu
|
266
net/madwifi/Makefile
Normal file
266
net/madwifi/Makefile
Normal file
@ -0,0 +1,266 @@
|
||||
#
|
||||
# Copyright (C) 2006-2009 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=madwifi
|
||||
|
||||
PKG_REV:=3314
|
||||
PKG_VERSION:=r$(PKG_REV)
|
||||
PKG_RELEASE:=6
|
||||
|
||||
PKG_SOURCE_PROTO:=svn
|
||||
PKG_SOURCE_VERSION:=$(PKG_REV)
|
||||
PKG_SOURCE_SUBDIR:=$(if $(PKG_BRANCH),$(PKG_BRANCH),madwifi-trunk)-$(PKG_VERSION)
|
||||
PKG_SOURCE_URL:=http://madwifi-project.org/svn/madwifi/$(if $(PKG_BRANCH),branches/$(PKG_BRANCH),trunk)
|
||||
PKG_SOURCE:=$(PKG_SOURCE_SUBDIR).tar.gz
|
||||
PKG_MIRROR_MD5SUM:=086b026d1c1561be8a949b79b0931404
|
||||
|
||||
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(if $(PKG_BRANCH),$(PKG_BRANCH),madwifi-trunk)-$(PKG_VERSION)
|
||||
|
||||
HAL_VERSION:=20090508
|
||||
HAL_FILE:=ath_hal-$(HAL_VERSION).tgz
|
||||
HAL_MD5SUM:=4ab7ae8bdb96c0be388c98bf8f92d5ca
|
||||
|
||||
PKG_BUILD_DEPENDS:=wprobe
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
ifdef CONFIG_MADWIFI_COMPRESSION
|
||||
COMPRESSION:=1
|
||||
else
|
||||
COMPRESSION:=0
|
||||
endif
|
||||
|
||||
define Download/hal
|
||||
FILE:=$(HAL_FILE)
|
||||
URL:=http://mirror2.openwrt.org/sources
|
||||
MD5SUM:=$(HAL_MD5SUM)
|
||||
endef
|
||||
$(eval $(call Download,hal))
|
||||
|
||||
|
||||
ifneq ($(CONFIG_TARGET_atheros),)
|
||||
BUS:=AHB
|
||||
else
|
||||
ifneq ($(CONFIG_PCI_SUPPORT),)
|
||||
BUS:=PCI
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_CPU_MIPS32_R2),)
|
||||
ifeq ($(ARCH),mips)
|
||||
HAL_TARGET:=mips32r2-be-elf
|
||||
endif
|
||||
ifeq ($(ARCH),mipsel)
|
||||
HAL_TARGET:=mips32r2-le-elf
|
||||
endif
|
||||
else
|
||||
ifeq ($(ARCH),mips)
|
||||
HAL_TARGET:=mips32-be-elf
|
||||
endif
|
||||
ifeq ($(ARCH),mipsel)
|
||||
HAL_TARGET:=mips32-le-elf
|
||||
endif
|
||||
endif
|
||||
ifeq ($(ARCH),i386)
|
||||
HAL_TARGET:=i386-elf
|
||||
endif
|
||||
ifeq ($(ARCH),i686)
|
||||
HAL_TARGET:=i386-elf
|
||||
endif
|
||||
ifeq ($(ARCH),armeb)
|
||||
HAL_TARGET:=xscale-be-elfgnueabi
|
||||
endif
|
||||
ifeq ($(ARCH),arm)
|
||||
HAL_TARGET:=xscale-le-elfgnueabi
|
||||
ifeq ($(BOARD),cns21xx)
|
||||
HAL_TARGET:=armv4-le-elfgnueabi
|
||||
endif
|
||||
ifeq ($(BOARD),cns3xxx)
|
||||
HAL_TARGET:=arm11-le-elfgnueabi
|
||||
endif
|
||||
ifeq ($(BOARD),gemini)
|
||||
HAL_TARGET:=armv4-le-elfgnueabi
|
||||
endif
|
||||
endif
|
||||
ifeq ($(ARCH),powerpc)
|
||||
HAL_TARGET:=powerpc-be-elf
|
||||
endif
|
||||
ifneq ($(CONFIG_TARGET_atheros),)
|
||||
HAL_TARGET:=wisoc
|
||||
endif
|
||||
|
||||
ifdef CONFIG_MADWIFI_RCA_MINSTREL
|
||||
RATE_CONTROL:=minstrel
|
||||
endif
|
||||
|
||||
ifdef CONFIG_MADWIFI_RCA_ONOE
|
||||
RATE_CONTROL:=onoe
|
||||
endif
|
||||
|
||||
ifdef CONFIG_MADWIFI_RCA_AMRR
|
||||
RATE_CONTROL:=amrr
|
||||
endif
|
||||
|
||||
ifdef CONFIG_MADWIFI_RCA_SAMPLERATE
|
||||
RATE_CONTROL:=sample
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_MADWIFI_SINGLE_MODULE),)
|
||||
MADWIFI_FILES:= $(PKG_BUILD_DIR)/ath_hal/ath_hal.ko
|
||||
else
|
||||
MADWIFI_FILES:= \
|
||||
$(PKG_BUILD_DIR)/net80211/wlan.ko \
|
||||
$(PKG_BUILD_DIR)/net80211/wlan_scan_ap.ko \
|
||||
$(PKG_BUILD_DIR)/net80211/wlan_scan_sta.ko \
|
||||
$(PKG_BUILD_DIR)/ath_hal/ath_hal.ko \
|
||||
$(PKG_BUILD_DIR)/ath_rate/$(RATE_CONTROL)/ath_rate_$(RATE_CONTROL).ko \
|
||||
$(PKG_BUILD_DIR)/net80211/wlan_acl.ko \
|
||||
$(PKG_BUILD_DIR)/net80211/wlan_ccmp.ko \
|
||||
$(PKG_BUILD_DIR)/net80211/wlan_tkip.ko \
|
||||
$(PKG_BUILD_DIR)/net80211/wlan_wep.ko \
|
||||
$(PKG_BUILD_DIR)/net80211/wlan_xauth.ko
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_MADWIFI_SINGLE_MODULE),)
|
||||
MADWIFI_AUTOLOAD:= ath_hal
|
||||
else
|
||||
MADWIFI_AUTOLOAD:= \
|
||||
wlan \
|
||||
wlan_scan_ap \
|
||||
wlan_scan_sta \
|
||||
ath_hal \
|
||||
ath_rate_$(RATE_CONTROL) \
|
||||
wlan_acl \
|
||||
wlan_ccmp \
|
||||
wlan_tkip \
|
||||
wlan_wep \
|
||||
wlan_xauth
|
||||
endif
|
||||
|
||||
ifeq ($(findstring AHB,$(BUS)),AHB)
|
||||
MADWIFI_FILES+= $(PKG_BUILD_DIR)/ath/ath_ahb.ko
|
||||
MADWIFI_AUTOLOAD+= ath_ahb
|
||||
endif
|
||||
ifeq ($(findstring PCI,$(BUS)),PCI)
|
||||
MADWIFI_FILES+= $(PKG_BUILD_DIR)/ath/ath_pci.ko
|
||||
MADWIFI_AUTOLOAD+= ath_pci
|
||||
endif
|
||||
|
||||
MADWIFI_APPLETS:=80211stats athchans athkey athstats wlanconfig ath_info madwifi_multi
|
||||
ifdef CONFIG_MADWIFI_DEBUG
|
||||
MADWIFI_APPLETS += athdebug 80211debug
|
||||
endif
|
||||
|
||||
define KernelPackage/madwifi
|
||||
SUBMENU:=Wireless Drivers
|
||||
TITLE:=Driver for Atheros wireless chipsets
|
||||
URL:=http://madwifi-project.org/
|
||||
DEPENDS:=+wireless-tools @PCI_SUPPORT @(!(TARGET_avr32||TARGET_cobalt||TARGET_ep93xx||TARGET_etrax||TARGET_octeon||TARGET_pxcab||TARGET_sibyte)||BROKEN) +@DRIVER_WEXT_SUPPORT
|
||||
FILES:=$(MADWIFI_FILES)
|
||||
AUTOLOAD:=$(call AutoLoad,50,$(MADWIFI_AUTOLOAD))
|
||||
MENU:=1
|
||||
endef
|
||||
|
||||
define KernelPackage/madwifi/description
|
||||
This package contains a driver for Atheros 802.11a/b/g chipsets.
|
||||
endef
|
||||
|
||||
define KernelPackage/madwifi/config
|
||||
source "$(SOURCE)/Config.in"
|
||||
endef
|
||||
|
||||
MADWIFI_INC = \
|
||||
-I$(PKG_BUILD_DIR) \
|
||||
-I$(PKG_BUILD_DIR)/include \
|
||||
-I$(PKG_BUILD_DIR)/hal \
|
||||
-I$(PKG_BUILD_DIR)/ath \
|
||||
-I$(PKG_BUILD_DIR)/ath_hal \
|
||||
-I$(PKG_BUILD_DIR)/net80211 \
|
||||
-I$(STAGING_DIR)/usr/include/wprobe \
|
||||
-include $(PKG_BUILD_DIR)/include/compat.h
|
||||
|
||||
MAKE_ARGS:= \
|
||||
PATH="$(TARGET_PATH)" \
|
||||
ARCH="$(LINUX_KARCH)" \
|
||||
ARCH-y="$(LINUX_KARCH)" \
|
||||
CROSS_COMPILE="$(TARGET_CROSS)" \
|
||||
TARGET="$(HAL_TARGET)" \
|
||||
TOOLPREFIX="$(KERNEL_CROSS)" \
|
||||
TOOLPATH="$(KERNEL_CROSS)" \
|
||||
KERNELPATH="$(LINUX_DIR)" \
|
||||
LDOPTS="--no-warn-mismatch " \
|
||||
ATH_RATE="$(RATE_CONTROL)" \
|
||||
ATH_CAP_SUPERG_COMP="$(COMPRESSION)" \
|
||||
DO_MULTI=1 \
|
||||
SINGLE_MODULE=$(if $(CONFIG_MADWIFI_SINGLE_MODULE),1) \
|
||||
INCS="$(MADWIFI_INC)" \
|
||||
$(if $(CONFIG_MADWIFI_DEBUG),,DEBUG=) WARNINGS="-Wno-unused"
|
||||
|
||||
MAKE_VARS:= \
|
||||
COPTS="-DATH_REVERSE_ENGINEERING=1" \
|
||||
|
||||
define Build/Prepare/HAL
|
||||
rm -rf $(PKG_BUILD_DIR)/tmp
|
||||
mkdir -p $(PKG_BUILD_DIR)/tmp
|
||||
tar xvzf $(DL_DIR)/$(HAL_FILE) -C $(PKG_BUILD_DIR)/tmp
|
||||
$(CP) $(PKG_BUILD_DIR)/tmp/ath_hal*/* $(PKG_BUILD_DIR)/hal/
|
||||
rm -rf $(PKG_BUILD_DIR)/tmp
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
$(call Build/Prepare/Default)
|
||||
$(call Build/Prepare/HAL)
|
||||
# patch cflags
|
||||
$(SED) 's, -E[LB],,' \
|
||||
-e 's, -mips2,,' \
|
||||
-e 's, -mapcs-32,,' \
|
||||
-e 's, -mlong-calls,,' \
|
||||
$(PKG_BUILD_DIR)/hal/public/*.inc
|
||||
$(SED) 's,march=armv4,march=armv5te,' \
|
||||
$(PKG_BUILD_DIR)/hal/public/xscale*.inc
|
||||
endef
|
||||
|
||||
ifeq ($(findstring AHB,$(BUS)),AHB)
|
||||
define Build/Compile/ahb
|
||||
$(MAKE_VARS) $(MAKE) -C $(PKG_BUILD_DIR) $(MAKE_ARGS) BUS="AHB" modules
|
||||
$(MAKE) -C $(PKG_BUILD_DIR) $(MAKE_ARGS) CFLAGS="$(TARGET_CFLAGS)" tools
|
||||
endef
|
||||
endif
|
||||
|
||||
ifeq ($(findstring PCI,$(BUS)),PCI)
|
||||
define Build/Compile/pci
|
||||
$(MAKE_VARS) $(MAKE) -C $(PKG_BUILD_DIR) $(MAKE_ARGS) BUS="PCI" modules
|
||||
$(MAKE) -C $(PKG_BUILD_DIR) $(MAKE_ARGS) CFLAGS="$(TARGET_CFLAGS)" tools
|
||||
endef
|
||||
endif
|
||||
|
||||
define Build/Configure
|
||||
$(SED) 's,-E[LB] ,,g' $(PKG_BUILD_DIR)/hal/public/*.inc
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
$(call Build/Compile/ahb)
|
||||
$(call Build/Compile/pci)
|
||||
endef
|
||||
|
||||
define Build/InstallDev
|
||||
mkdir -p $(1)/usr/include/madwifi
|
||||
$(CP) $(PKG_BUILD_DIR)/include $(1)/usr/include/madwifi/
|
||||
mkdir -p $(1)/usr/include/madwifi/net80211
|
||||
$(CP) $(PKG_BUILD_DIR)/net80211/*.h $(1)/usr/include/madwifi/net80211/
|
||||
endef
|
||||
|
||||
define KernelPackage/madwifi/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(CP) ./files/* $(1)/
|
||||
$(CP) $(foreach applet,$(MADWIFI_APPLETS),$(PKG_BUILD_DIR)/tools/$(applet)) $(1)/usr/sbin/
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,madwifi))
|
12
net/madwifi/files/etc/hotplug.d/net/10-madwifi
Normal file
12
net/madwifi/files/etc/hotplug.d/net/10-madwifi
Normal file
@ -0,0 +1,12 @@
|
||||
if [ "$ACTION" = "add" -o "$ACTION" = "register" ]; then
|
||||
case "$INTERFACE" in
|
||||
ath*.sta*)
|
||||
local BASEIF="${INTERFACE%%\.*}"
|
||||
|
||||
include /lib/network
|
||||
scan_interfaces
|
||||
local CONFIG="$(find_config "$BASEIF")"
|
||||
[ -n "$CONFIG" ] && setup_interface "$INTERFACE" "$CONFIG"
|
||||
;;
|
||||
esac
|
||||
fi
|
498
net/madwifi/files/lib/wifi/madwifi.sh
Executable file
498
net/madwifi/files/lib/wifi/madwifi.sh
Executable file
@ -0,0 +1,498 @@
|
||||
#!/bin/sh
|
||||
append DRIVERS "atheros"
|
||||
|
||||
find_atheros_phy() {
|
||||
local device="$1"
|
||||
|
||||
local macaddr="$(config_get "$device" macaddr | tr 'A-Z' 'a-z')"
|
||||
config_get phy "$device" phy
|
||||
[ -z "$phy" -a -n "$macaddr" ] && {
|
||||
cd /proc/sys/dev
|
||||
for phy in $(ls -d wifi* 2>&-); do
|
||||
[ "$macaddr" = "$(cat /sys/class/net/${phy}/address)" ] || continue
|
||||
config_set "$device" phy "$phy"
|
||||
break
|
||||
done
|
||||
config_get phy "$device" phy
|
||||
}
|
||||
[ -n "$phy" -a -d "/proc/sys/dev/$phy" ] || {
|
||||
echo "phy for wifi device $1 not found"
|
||||
return 1
|
||||
}
|
||||
[ -z "$macaddr" ] && {
|
||||
config_set "$device" macaddr "$(cat /sys/class/net/${phy}/address)"
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
scan_atheros() {
|
||||
local device="$1"
|
||||
local wds
|
||||
local adhoc ahdemo sta ap monitor disabled
|
||||
|
||||
[ ${device%[0-9]} = "wifi" ] && config_set "$device" phy "$device"
|
||||
|
||||
local ifidx=0
|
||||
|
||||
config_get vifs "$device" vifs
|
||||
for vif in $vifs; do
|
||||
config_get_bool disabled "$vif" disabled 0
|
||||
[ $disabled = 0 ] || continue
|
||||
|
||||
local vifname
|
||||
[ $ifidx -gt 0 ] && vifname="ath${device#radio}-$ifidx" || vifname="ath${device#radio}"
|
||||
|
||||
config_get ifname "$vif" ifname
|
||||
config_set "$vif" ifname "${ifname:-$vifname}"
|
||||
|
||||
config_get mode "$vif" mode
|
||||
case "$mode" in
|
||||
adhoc|ahdemo|sta|ap|monitor)
|
||||
append $mode "$vif"
|
||||
;;
|
||||
wds)
|
||||
config_get ssid "$vif" ssid
|
||||
[ -z "$ssid" ] && continue
|
||||
|
||||
config_set "$vif" wds 1
|
||||
config_set "$vif" mode sta
|
||||
mode="sta"
|
||||
addr="$ssid"
|
||||
${addr:+append $mode "$vif"}
|
||||
;;
|
||||
*) echo "$device($vif): Invalid mode, ignored."; continue;;
|
||||
esac
|
||||
|
||||
ifidx=$(($ifidx + 1))
|
||||
done
|
||||
|
||||
case "${adhoc:+1}:${sta:+1}:${ap:+1}" in
|
||||
# valid mode combinations
|
||||
1::) wds="";;
|
||||
1::1);;
|
||||
:1:1)config_set "$device" nosbeacon 1;; # AP+STA, can't use beacon timers for STA
|
||||
:1:);;
|
||||
::1);;
|
||||
::);;
|
||||
*) echo "$device: Invalid mode combination in config"; return 1;;
|
||||
esac
|
||||
|
||||
config_set "$device" vifs "${sta:+$sta }${ap:+$ap }${adhoc:+$adhoc }${ahdemo:+$ahdemo }${wds:+$wds }${monitor:+$monitor}"
|
||||
}
|
||||
|
||||
|
||||
disable_atheros() (
|
||||
local device="$1"
|
||||
|
||||
find_atheros_phy "$device" || return 0
|
||||
config_get phy "$device" phy
|
||||
|
||||
set_wifi_down "$device"
|
||||
|
||||
include /lib/network
|
||||
cd /proc/sys/net
|
||||
for dev in *; do
|
||||
grep "$phy" "$dev/%parent" >/dev/null 2>/dev/null && {
|
||||
[ -f "/var/run/wifi-${dev}.pid" ] &&
|
||||
kill "$(cat "/var/run/wifi-${dev}.pid")"
|
||||
ifconfig "$dev" down
|
||||
unbridge "$dev"
|
||||
wlanconfig "$dev" destroy
|
||||
}
|
||||
done
|
||||
return 0
|
||||
)
|
||||
|
||||
enable_atheros() {
|
||||
local device="$1"
|
||||
|
||||
find_atheros_phy "$device" || return 0
|
||||
config_get phy "$device" phy
|
||||
|
||||
config_get regdomain "$device" regdomain
|
||||
[ -n "$regdomain" ] && echo "$regdomain" > /proc/sys/dev/$phy/regdomain
|
||||
|
||||
config_get country "$device" country
|
||||
case "$country" in
|
||||
[A-Za-z]*) country=`grep -i "$country" /lib/wifi/madwifi_countrycodes.txt |cut -d " " -f 2`;;
|
||||
[0-9]*) ;;
|
||||
*) country="" ;;
|
||||
esac
|
||||
[ -n "$country" ] && echo "$country" > /proc/sys/dev/$phy/countrycode
|
||||
|
||||
config_get_bool outdoor "$device" outdoor "0"
|
||||
echo "$outdoor" > /proc/sys/dev/$phy/outdoor
|
||||
|
||||
config_get channel "$device" channel
|
||||
config_get vifs "$device" vifs
|
||||
config_get txpower "$device" txpower
|
||||
|
||||
[ auto = "$channel" ] && channel=0
|
||||
|
||||
config_get_bool antdiv "$device" diversity
|
||||
config_get antrx "$device" rxantenna
|
||||
config_get anttx "$device" txantenna
|
||||
config_get_bool softled "$device" softled
|
||||
config_get antenna "$device" antenna
|
||||
|
||||
devname="$(cat /proc/sys/dev/$phy/dev_name)"
|
||||
local antgpio=
|
||||
local invert=
|
||||
case "$devname" in
|
||||
NanoStation2) antgpio=7; invert=1;;
|
||||
NanoStation5) antgpio=1; invert=1;;
|
||||
"NanoStation Loco2") antgpio=2;;
|
||||
"NanoStation Loco5")
|
||||
case "$antenna" in
|
||||
horizontal) antdiv=0; anttx=1; antrx=1;;
|
||||
vertical) antdiv=0; anttx=2; antrx=2;;
|
||||
*) antdiv=1; anttx=0; antrx=0;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
if [ -n "$invert" ]; then
|
||||
_set="clear"
|
||||
_clear="set"
|
||||
else
|
||||
_set="set"
|
||||
_clear="clear"
|
||||
fi
|
||||
if [ -n "$antgpio" ]; then
|
||||
softled=0
|
||||
case "$devname" in
|
||||
"NanoStation Loco2")
|
||||
antdiv=0
|
||||
antrx=1
|
||||
anttx=1
|
||||
case "$antenna" in
|
||||
horizontal) gpioval=0;;
|
||||
*) gpioval=1;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
case "$antenna" in
|
||||
external) antdiv=0; antrx=1; anttx=1; gpioval=1;;
|
||||
horizontal) antdiv=0; antrx=1; anttx=1; gpioval=0;;
|
||||
vertical) antdiv=0; antrx=2; anttx=2; gpioval=0;;
|
||||
auto) antdiv=1; antrx=0; anttx=0; gpioval=0;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
[ -x "$(which gpioctl 2>/dev/null)" ] || antenna=
|
||||
gpioctl "dirout" "$antgpio" >/dev/null 2>&1
|
||||
case "$gpioval" in
|
||||
0)
|
||||
gpioctl "$_clear" "$antgpio" >/dev/null 2>&1
|
||||
;;
|
||||
1)
|
||||
gpioctl "$_set" "$antgpio" >/dev/null 2>&1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
[ -n "$antdiv" ] && sysctl -w dev."$phy".diversity="$antdiv" >&-
|
||||
[ -n "$antrx" ] && sysctl -w dev."$phy".rxantenna="$antrx" >&-
|
||||
[ -n "$anttx" ] && sysctl -w dev."$phy".txantenna="$anttx" >&-
|
||||
[ -n "$softled" ] && sysctl -w dev."$phy".softled="$softled" >&-
|
||||
|
||||
config_get distance "$device" distance
|
||||
[ -n "$distance" ] && sysctl -w dev."$phy".distance="$distance" >&-
|
||||
|
||||
for vif in $vifs; do
|
||||
local start_hostapd= vif_txpower= nosbeacon=
|
||||
config_get ifname "$vif" ifname
|
||||
config_get enc "$vif" encryption
|
||||
config_get eap_type "$vif" eap_type
|
||||
config_get mode "$vif" mode
|
||||
|
||||
case "$mode" in
|
||||
sta) config_get_bool nosbeacon "$device" nosbeacon;;
|
||||
adhoc) config_get_bool nosbeacon "$vif" sw_merge 1;;
|
||||
esac
|
||||
|
||||
[ "$nosbeacon" = 1 ] || nosbeacon=""
|
||||
ifname=$(wlanconfig "$ifname" create nounit wlandev "$phy" wlanmode "$mode" ${nosbeacon:+nosbeacon})
|
||||
[ $? -ne 0 ] && {
|
||||
echo "enable_atheros($device): Failed to set up $mode vif $ifname" >&2
|
||||
continue
|
||||
}
|
||||
config_set "$vif" ifname "$ifname"
|
||||
|
||||
config_get hwmode "$device" hwmode
|
||||
[ -z "$hwmode" ] && config_get hwmode "$device" mode
|
||||
|
||||
pureg=0
|
||||
case "$hwmode" in
|
||||
*b) hwmode=11b;;
|
||||
*bg) hwmode=11g;;
|
||||
*g) hwmode=11g; pureg=1;;
|
||||
*gdt) hwmode=11gdt;;
|
||||
*a) hwmode=11a;;
|
||||
*adt) hwmode=11adt;;
|
||||
*ast) hwmode=11ast;;
|
||||
*fh) hwmode=fh;;
|
||||
*) hwmode=auto;;
|
||||
esac
|
||||
iwpriv "$ifname" mode "$hwmode"
|
||||
iwpriv "$ifname" pureg "$pureg"
|
||||
|
||||
iwconfig "$ifname" channel "$channel" >/dev/null 2>/dev/null
|
||||
|
||||
config_get_bool hidden "$vif" hidden 0
|
||||
iwpriv "$ifname" hide_ssid "$hidden"
|
||||
|
||||
config_get ff "$vif" ff
|
||||
if [ -n "$ff" ]; then
|
||||
iwpriv "$ifname" ff "$ff"
|
||||
fi
|
||||
|
||||
config_get wds "$vif" wds
|
||||
case "$wds" in
|
||||
1|on|enabled) wds=1;;
|
||||
*) wds=0;;
|
||||
esac
|
||||
iwpriv "$ifname" wds "$wds" >/dev/null 2>&1
|
||||
|
||||
[ "$mode" = ap -a "$wds" = 1 ] && {
|
||||
config_get_bool wdssep "$vif" wdssep 1
|
||||
[ -n "$wdssep" ] && iwpriv "$ifname" wdssep "$wdssep"
|
||||
}
|
||||
|
||||
case "$enc" in
|
||||
wep*)
|
||||
case "$enc" in
|
||||
*shared*) iwpriv "$ifname" authmode 2;;
|
||||
*) iwpriv "$ifname" authmode 1;;
|
||||
esac
|
||||
for idx in 1 2 3 4; do
|
||||
config_get key "$vif" "key${idx}"
|
||||
iwconfig "$ifname" enc "[$idx]" "${key:-off}"
|
||||
done
|
||||
config_get key "$vif" key
|
||||
key="${key:-1}"
|
||||
case "$key" in
|
||||
[1234]) iwconfig "$ifname" enc "[$key]";;
|
||||
*) iwconfig "$ifname" enc "$key";;
|
||||
esac
|
||||
;;
|
||||
psk*|wpa*)
|
||||
start_hostapd=1
|
||||
config_get key "$vif" key
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$mode" in
|
||||
sta|adhoc|ahdemo)
|
||||
config_get addr "$vif" bssid
|
||||
[ -z "$addr" ] || {
|
||||
iwconfig "$ifname" ap "$addr"
|
||||
}
|
||||
;;
|
||||
esac
|
||||
|
||||
config_get_bool uapsd "$vif" uapsd 0
|
||||
iwpriv "$ifname" uapsd "$uapsd"
|
||||
|
||||
config_get_bool bgscan "$vif" bgscan
|
||||
[ -n "$bgscan" ] && iwpriv "$ifname" bgscan "$bgscan"
|
||||
|
||||
config_get rate "$vif" rate
|
||||
[ -n "$rate" ] && iwconfig "$ifname" rate "${rate%%.*}"
|
||||
|
||||
config_get mcast_rate "$vif" mcast_rate
|
||||
[ -n "$mcast_rate" ] && iwpriv "$ifname" mcast_rate "${mcast_rate%%.*}"
|
||||
|
||||
config_get frag "$vif" frag
|
||||
[ -n "$frag" ] && iwconfig "$ifname" frag "${frag%%.*}"
|
||||
|
||||
config_get rts "$vif" rts
|
||||
[ -n "$rts" ] && iwconfig "$ifname" rts "${rts%%.*}"
|
||||
|
||||
config_get_bool comp "$vif" compression 0
|
||||
iwpriv "$ifname" compression "$comp" >/dev/null 2>&1
|
||||
|
||||
config_get minrate "$vif" minrate
|
||||
[ -n "$minrate" ] && iwpriv "$ifname" minrate "$minrate"
|
||||
|
||||
config_get maxrate "$vif" maxrate
|
||||
[ -n "$maxrate" ] && iwpriv "$ifname" maxrate "$maxrate"
|
||||
|
||||
config_get_bool burst "$vif" bursting
|
||||
[ -n "$burst" ] && iwpriv "$ifname" burst "$burst"
|
||||
|
||||
config_get_bool wmm "$vif" wmm
|
||||
[ -n "$wmm" ] && iwpriv "$ifname" wmm "$wmm"
|
||||
|
||||
config_get_bool xr "$vif" xr
|
||||
[ -n "$xr" ] && iwpriv "$ifname" xr "$xr"
|
||||
|
||||
config_get_bool ar "$vif" ar
|
||||
[ -n "$ar" ] && iwpriv "$ifname" ar "$ar"
|
||||
|
||||
config_get_bool beacon_power "$vif" beacon_power
|
||||
[ -n "$beacon_power" ] && iwpriv "$ifname" beacon_pwr "$beacon_power"
|
||||
|
||||
config_get_bool doth "$vif" doth 0
|
||||
[ -n "$doth" ] && iwpriv "$ifname" doth "$doth"
|
||||
|
||||
config_get_bool probereq "$vif" probereq
|
||||
[ -n "$probereq" ] && iwpriv "$ifname" probereq "$probereq"
|
||||
|
||||
config_get maclist "$vif" maclist
|
||||
[ -n "$maclist" ] && {
|
||||
# flush MAC list
|
||||
iwpriv "$ifname" maccmd 3
|
||||
for mac in $maclist; do
|
||||
iwpriv "$ifname" addmac "$mac"
|
||||
done
|
||||
}
|
||||
|
||||
config_get macpolicy "$vif" macpolicy
|
||||
case "$macpolicy" in
|
||||
allow)
|
||||
iwpriv "$ifname" maccmd 1
|
||||
;;
|
||||
deny)
|
||||
iwpriv "$ifname" maccmd 2
|
||||
;;
|
||||
*)
|
||||
# default deny policy if mac list exists
|
||||
[ -n "$maclist" ] && iwpriv "$ifname" maccmd 2
|
||||
;;
|
||||
esac
|
||||
|
||||
ifconfig "$ifname" up
|
||||
|
||||
local net_cfg bridge
|
||||
net_cfg="$(find_net_config "$vif")"
|
||||
[ -z "$net_cfg" ] || {
|
||||
bridge="$(bridge_interface "$net_cfg")"
|
||||
config_set "$vif" bridge "$bridge"
|
||||
start_net "$ifname" "$net_cfg"
|
||||
}
|
||||
|
||||
config_get ssid "$vif" ssid
|
||||
[ -n "$ssid" ] && {
|
||||
iwconfig "$ifname" essid on
|
||||
iwconfig "$ifname" essid ${ssid:+-- }"$ssid"
|
||||
}
|
||||
|
||||
set_wifi_up "$vif" "$ifname"
|
||||
|
||||
# TXPower settings only work if device is up already
|
||||
# while atheros hardware theoretically is capable of per-vif (even per-packet) txpower
|
||||
# adjustment it does not work with the current atheros hal/madwifi driver
|
||||
|
||||
config_get vif_txpower "$vif" txpower
|
||||
# use vif_txpower (from wifi-iface) instead of txpower (from wifi-device) if
|
||||
# the latter doesn't exist
|
||||
txpower="${txpower:-$vif_txpower}"
|
||||
[ -z "$txpower" ] || iwconfig "$ifname" txpower "${txpower%%.*}"
|
||||
|
||||
case "$mode" in
|
||||
ap)
|
||||
config_get_bool isolate "$vif" isolate 0
|
||||
iwpriv "$ifname" ap_bridge "$((isolate^1))"
|
||||
|
||||
if [ -n "$start_hostapd" ] && eval "type hostapd_setup_vif" 2>/dev/null >/dev/null; then
|
||||
hostapd_setup_vif "$vif" madwifi || {
|
||||
echo "enable_atheros($device): Failed to set up hostapd for interface $ifname" >&2
|
||||
# make sure this wifi interface won't accidentally stay open without encryption
|
||||
ifconfig "$ifname" down
|
||||
wlanconfig "$ifname" destroy
|
||||
continue
|
||||
}
|
||||
fi
|
||||
;;
|
||||
wds|sta)
|
||||
if eval "type wpa_supplicant_setup_vif" 2>/dev/null >/dev/null; then
|
||||
wpa_supplicant_setup_vif "$vif" wext || {
|
||||
echo "enable_atheros($device): Failed to set up wpa_supplicant for interface $ifname" >&2
|
||||
ifconfig "$ifname" down
|
||||
wlanconfig "$ifname" destroy
|
||||
continue
|
||||
}
|
||||
fi
|
||||
;;
|
||||
adhoc)
|
||||
if eval "type wpa_supplicant_setup_vif" 2>/dev/null >/dev/null; then
|
||||
wpa_supplicant_setup_vif "$vif" madwifi || {
|
||||
echo "enable_atheros($device): Failed to set up wpa"
|
||||
ifconfig "$ifname" down
|
||||
wlanconfig "$ifname" destroy
|
||||
continue
|
||||
}
|
||||
fi
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
check_atheros_device() {
|
||||
[ ${1%[0-9]} = "wifi" ] && config_set "$1" phy "$1"
|
||||
config_get phy "$1" phy
|
||||
[ -z "$phy" ] && {
|
||||
find_atheros_phy "$1" >/dev/null || return 0
|
||||
config_get phy "$1" phy
|
||||
}
|
||||
[ "$phy" = "$dev" ] && found=1
|
||||
}
|
||||
|
||||
|
||||
detect_atheros() {
|
||||
devidx=0
|
||||
config_load wireless
|
||||
while :; do
|
||||
config_get type "radio$devidx" type
|
||||
[ -n "$type" ] || break
|
||||
devidx=$(($devidx + 1))
|
||||
done
|
||||
cd /proc/sys/dev
|
||||
[ -d ath ] || return
|
||||
for dev in $(ls -d wifi* 2>&-); do
|
||||
found=0
|
||||
config_foreach check_atheros_device wifi-device
|
||||
[ "$found" -gt 0 ] && continue
|
||||
|
||||
devname="$(cat /proc/sys/dev/$dev/dev_name)"
|
||||
case "$devname" in
|
||||
"NanoStation Loco2")
|
||||
EXTRA_DEV="
|
||||
# Ubiquiti NanoStation Loco2 features
|
||||
option antenna vertical # (horizontal|vertical)
|
||||
"
|
||||
;;
|
||||
"NanoStation Loco5")
|
||||
EXTRA_DEV="
|
||||
# Ubiquiti NanoStation Loco5 features
|
||||
option antenna auto # (auto|horizontal|vertical)
|
||||
"
|
||||
;;
|
||||
NanoStation*)
|
||||
EXTRA_DEV="
|
||||
# Ubiquiti NanoStation features
|
||||
option antenna auto # (auto|horizontal|vertical|external)
|
||||
"
|
||||
;;
|
||||
esac
|
||||
|
||||
cat <<EOF
|
||||
config wifi-device radio$devidx
|
||||
option type atheros
|
||||
option channel auto
|
||||
option macaddr $(cat /sys/class/net/${dev}/address)
|
||||
$EXTRA_DEV
|
||||
# REMOVE THIS LINE TO ENABLE WIFI:
|
||||
option disabled 1
|
||||
|
||||
config wifi-iface
|
||||
option device radio$devidx
|
||||
option network lan
|
||||
option mode ap
|
||||
option ssid OpenWrt
|
||||
option encryption none
|
||||
|
||||
EOF
|
||||
devidx=$(($devidx + 1))
|
||||
done
|
||||
}
|
239
net/madwifi/files/lib/wifi/madwifi_countrycodes.txt
Normal file
239
net/madwifi/files/lib/wifi/madwifi_countrycodes.txt
Normal file
@ -0,0 +1,239 @@
|
||||
AF 4
|
||||
AL 8
|
||||
DZ 12
|
||||
AS 16
|
||||
AD 20
|
||||
AO 24
|
||||
AI 660
|
||||
AQ 10
|
||||
AG 28
|
||||
AR 32
|
||||
AM 51
|
||||
AW 533
|
||||
AU 36
|
||||
AT 40
|
||||
AZ 31
|
||||
BS 44
|
||||
BH 48
|
||||
BD 50
|
||||
BB 52
|
||||
BY 112
|
||||
BE 56
|
||||
BZ 84
|
||||
BJ 204
|
||||
BM 60
|
||||
BT 64
|
||||
BO 68
|
||||
BA 70
|
||||
BW 72
|
||||
BV 74
|
||||
BR 76
|
||||
IO 86
|
||||
VG 92
|
||||
BN 96
|
||||
BG 100
|
||||
BF 854
|
||||
BI 108
|
||||
KH 116
|
||||
CM 120
|
||||
CA 124
|
||||
CV 132
|
||||
KY 136
|
||||
CF 140
|
||||
TD 148
|
||||
CL 152
|
||||
CN 156
|
||||
CX 162
|
||||
CC 166
|
||||
CO 170
|
||||
KM 174
|
||||
CD 180
|
||||
CG 178
|
||||
CK 184
|
||||
CR 188
|
||||
CI 384
|
||||
CU 192
|
||||
CY 196
|
||||
CZ 203
|
||||
DK 208
|
||||
DJ 262
|
||||
DM 212
|
||||
DO 214
|
||||
EC 218
|
||||
EG 818
|
||||
SV 222
|
||||
GQ 226
|
||||
ER 232
|
||||
EE 233
|
||||
ET 231
|
||||
FO 234
|
||||
FK 238
|
||||
FJ 242
|
||||
FI 246
|
||||
FR 250
|
||||
GF 254
|
||||
PF 258
|
||||
TF 260
|
||||
GA 266
|
||||
GM 270
|
||||
GE 268
|
||||
DE 276
|
||||
GH 288
|
||||
GI 292
|
||||
GR 300
|
||||
GL 304
|
||||
GD 308
|
||||
GP 312
|
||||
GU 316
|
||||
GT 320
|
||||
GN 324
|
||||
GW 624
|
||||
GY 328
|
||||
HT 332
|
||||
HM 334
|
||||
VA 336
|
||||
HN 340
|
||||
HK 344
|
||||
HR 191
|
||||
HU 348
|
||||
IS 352
|
||||
IN 356
|
||||
ID 360
|
||||
IR 364
|
||||
IQ 368
|
||||
IE 372
|
||||
IL 376
|
||||
IT 380
|
||||
JM 388
|
||||
JP 392
|
||||
JO 400
|
||||
KZ 398
|
||||
KE 404
|
||||
KI 296
|
||||
KP 408
|
||||
KR 410
|
||||
KW 414
|
||||
KG 417
|
||||
LA 418
|
||||
LV 428
|
||||
LB 422
|
||||
LS 426
|
||||
LR 430
|
||||
LY 434
|
||||
LI 438
|
||||
LT 440
|
||||
LU 442
|
||||
MO 446
|
||||
MK 807
|
||||
MG 450
|
||||
MW 454
|
||||
MY 458
|
||||
MV 462
|
||||
ML 466
|
||||
MT 470
|
||||
MH 584
|
||||
MQ 474
|
||||
MR 478
|
||||
MU 480
|
||||
YT 175
|
||||
MX 484
|
||||
FM 583
|
||||
MD 498
|
||||
MC 492
|
||||
MN 496
|
||||
MS 500
|
||||
MA 504
|
||||
MZ 508
|
||||
MM 104
|
||||
NA 516
|
||||
NR 520
|
||||
NP 524
|
||||
AN 530
|
||||
NL 528
|
||||
NC 540
|
||||
NZ 554
|
||||
NI 558
|
||||
NE 562
|
||||
NG 566
|
||||
NU 570
|
||||
NF 574
|
||||
MP 580
|
||||
NO 578
|
||||
OM 512
|
||||
PK 586
|
||||
PW 585
|
||||
PS 275
|
||||
PA 591
|
||||
PG 598
|
||||
PY 600
|
||||
PE 604
|
||||
PH 608
|
||||
PN 612
|
||||
PL 616
|
||||
PT 620
|
||||
PR 630
|
||||
QA 634
|
||||
RE 638
|
||||
RO 642
|
||||
RU 643
|
||||
RW 646
|
||||
SH 654
|
||||
KN 659
|
||||
LC 662
|
||||
PM 666
|
||||
VC 670
|
||||
WS 882
|
||||
SM 674
|
||||
ST 678
|
||||
SA 682
|
||||
SN 686
|
||||
CS 891
|
||||
SC 690
|
||||
SL 694
|
||||
SG 702
|
||||
SK 703
|
||||
SI 705
|
||||
SB 90
|
||||
SO 706
|
||||
ZA 710
|
||||
GS 239
|
||||
ES 724
|
||||
LK 144
|
||||
SD 736
|
||||
SR 740
|
||||
SJ 744
|
||||
SZ 748
|
||||
SE 752
|
||||
CH 756
|
||||
SY 760
|
||||
TW 158
|
||||
TJ 762
|
||||
TZ 834
|
||||
TH 764
|
||||
TL 626
|
||||
TG 768
|
||||
TK 772
|
||||
TO 776
|
||||
TT 780
|
||||
TN 788
|
||||
TR 792
|
||||
TM 795
|
||||
TC 796
|
||||
TV 798
|
||||
VI 850
|
||||
UG 800
|
||||
UA 804
|
||||
AE 784
|
||||
GB 826
|
||||
UM 581
|
||||
US 840
|
||||
UY 858
|
||||
UZ 860
|
||||
VU 548
|
||||
VE 862
|
||||
VN 704
|
||||
WF 876
|
||||
EH 732
|
||||
YE 887
|
||||
ZM 894
|
||||
ZW 716
|
315
net/madwifi/patches/102-multicall_binary.patch
Normal file
315
net/madwifi/patches/102-multicall_binary.patch
Normal file
@ -0,0 +1,315 @@
|
||||
--- a/tools/80211debug.c
|
||||
+++ b/tools/80211debug.c
|
||||
@@ -48,6 +48,7 @@
|
||||
#include <ctype.h>
|
||||
#include <getopt.h>
|
||||
#include <err.h>
|
||||
+#include "do_multi.h"
|
||||
|
||||
#undef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
@@ -185,7 +186,7 @@ sysctlbyname(const char *oid0, void *old
|
||||
#endif /* __linux__ */
|
||||
|
||||
int
|
||||
-main(int argc, char *argv[])
|
||||
+CMD(a80211debug)(int argc, char *argv[])
|
||||
{
|
||||
const char *ifname = "ath0";
|
||||
const char *cp, *tp;
|
||||
--- a/tools/80211stats.c
|
||||
+++ b/tools/80211stats.c
|
||||
@@ -59,6 +59,7 @@
|
||||
#include "net80211/ieee80211.h"
|
||||
#include "net80211/ieee80211_crypto.h"
|
||||
#include "net80211/ieee80211_ioctl.h"
|
||||
+#include "do_multi.h"
|
||||
|
||||
#ifndef SIOCG80211STATS
|
||||
#define SIOCG80211STATS (SIOCDEVPRIVATE + 2)
|
||||
@@ -240,7 +241,7 @@ print_sta_stats(FILE *fd, const u_int8_t
|
||||
}
|
||||
|
||||
int
|
||||
-main(int argc, char *argv[])
|
||||
+CMD(a80211stats)(int argc, char *argv[])
|
||||
{
|
||||
int c, len;
|
||||
struct ieee80211req_sta_info *si;
|
||||
--- a/tools/athchans.c
|
||||
+++ b/tools/athchans.c
|
||||
@@ -58,6 +58,7 @@
|
||||
#include "net80211/ieee80211.h"
|
||||
#include "net80211/ieee80211_crypto.h"
|
||||
#include "net80211/ieee80211_ioctl.h"
|
||||
+#include "do_multi.h"
|
||||
|
||||
static int s = -1;
|
||||
static const char *progname;
|
||||
@@ -140,8 +141,9 @@ usage(void)
|
||||
}
|
||||
|
||||
#define MAXCHAN ((int)(sizeof(struct ieee80211req_chanlist) * NBBY))
|
||||
+
|
||||
int
|
||||
-main(int argc, char *argv[])
|
||||
+CMD(athchans)(int argc, char *argv[])
|
||||
{
|
||||
const char *ifname = "wifi0";
|
||||
struct ieee80211req_chanlist chanlist;
|
||||
--- a/tools/athctrl.c
|
||||
+++ b/tools/athctrl.c
|
||||
@@ -52,6 +52,7 @@
|
||||
#include <err.h>
|
||||
|
||||
#include <net/if.h>
|
||||
+#include "do_multi.h"
|
||||
|
||||
static int
|
||||
setsysctrl(const char *dev, const char *control , u_long value)
|
||||
@@ -88,7 +89,7 @@ static void usage(void)
|
||||
}
|
||||
|
||||
int
|
||||
-main(int argc, char *argv[])
|
||||
+CMD(athctrl)(int argc, char *argv[])
|
||||
{
|
||||
char device[IFNAMSIZ + 1];
|
||||
int distance = -1;
|
||||
--- a/tools/athdebug.c
|
||||
+++ b/tools/athdebug.c
|
||||
@@ -51,6 +51,7 @@
|
||||
#include <ctype.h>
|
||||
#include <getopt.h>
|
||||
#include <err.h>
|
||||
+#include "do_multi.h"
|
||||
|
||||
#undef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
@@ -194,7 +195,7 @@ sysctlbyname(const char *oid0, void *old
|
||||
#endif /* __linux__ */
|
||||
|
||||
int
|
||||
-main(int argc, char *argv[])
|
||||
+CMD(athdebug)(int argc, char *argv[])
|
||||
{
|
||||
#ifdef __linux__
|
||||
const char *ifname = "wifi0";
|
||||
--- a/tools/athkey.c
|
||||
+++ b/tools/athkey.c
|
||||
@@ -58,6 +58,7 @@
|
||||
#include "net80211/ieee80211.h"
|
||||
#include "net80211/ieee80211_crypto.h"
|
||||
#include "net80211/ieee80211_ioctl.h"
|
||||
+#include "do_multi.h"
|
||||
|
||||
static int s = -1;
|
||||
static const char *progname;
|
||||
@@ -213,8 +214,7 @@ usage(void)
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
-int
|
||||
-main(int argc, char *argv[])
|
||||
+int CMD(athkey)(int argc, char *argv[])
|
||||
{
|
||||
const char *ifname = "wifi0";
|
||||
struct ieee80211req_key setkey;
|
||||
--- a/tools/athstats.c
|
||||
+++ b/tools/athstats.c
|
||||
@@ -65,6 +65,7 @@
|
||||
|
||||
#undef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
+#include "do_multi.h"
|
||||
|
||||
static const struct {
|
||||
u_int phyerr;
|
||||
@@ -228,7 +229,7 @@ catchalarm(int signo)
|
||||
}
|
||||
|
||||
int
|
||||
-main(int argc, char *argv[])
|
||||
+CMD(athstats)(int argc, char *argv[])
|
||||
{
|
||||
#ifdef __linux__
|
||||
const char *ifname = "wifi0";
|
||||
--- /dev/null
|
||||
+++ b/tools/do_multi.c
|
||||
@@ -0,0 +1,33 @@
|
||||
+#include <string.h>
|
||||
+#include <libgen.h>
|
||||
+#include "do_multi.h"
|
||||
+
|
||||
+int
|
||||
+main(int argc, char *argv[])
|
||||
+{
|
||||
+ char *progname;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ progname = basename(argv[0]);
|
||||
+
|
||||
+ if(strcmp(progname, "80211debug") == 0)
|
||||
+ ret = a80211debug_init(argc, argv);
|
||||
+ if(strcmp(progname, "80211stats") == 0)
|
||||
+ ret = a80211stats_init(argc, argv);
|
||||
+ if(strcmp(progname, "athchans") == 0)
|
||||
+ ret = athchans_init(argc, argv);
|
||||
+ if(strcmp(progname, "athctrl") == 0)
|
||||
+ ret = athctrl_init(argc, argv);
|
||||
+ if(strcmp(progname, "athdebug") == 0)
|
||||
+ ret = athdebug_init(argc, argv);
|
||||
+ if(strcmp(progname, "athkey") == 0)
|
||||
+ ret = athkey_init(argc, argv);
|
||||
+ if(strcmp(progname, "athstats") == 0)
|
||||
+ ret = athstats_init(argc, argv);
|
||||
+ if(strcmp(progname, "wlanconfig") == 0)
|
||||
+ ret = wlanconfig_init(argc, argv);
|
||||
+ if(strcmp(progname, "ath_info") == 0)
|
||||
+ ret = athinfo_init(argc, argv);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/tools/do_multi.h
|
||||
@@ -0,0 +1,15 @@
|
||||
+#ifdef DO_MULTI
|
||||
+int a80211debug_init(int argc, char *argv[]);
|
||||
+int a80211stats_init(int argc, char *argv[]);
|
||||
+int athchans_init(int argc, char *argv[]);
|
||||
+int athctrl_init(int argc, char *argv[]);
|
||||
+int athdebug_init(int argc, char *argv[]);
|
||||
+int athkey_init(int argc, char *argv[]);
|
||||
+int athstats_init(int argc, char *argv[]);
|
||||
+int wlanconfig_init(int argc, char *argv[]);
|
||||
+int athinfo_init(int argc, char *argv[]);
|
||||
+
|
||||
+#define CMD(name) name##_init
|
||||
+#else
|
||||
+#define CMD(name) main
|
||||
+#endif
|
||||
--- a/tools/Makefile
|
||||
+++ b/tools/Makefile
|
||||
@@ -46,56 +46,55 @@ ifeq ($(HAL),)
|
||||
HAL= $(TOP)/hal
|
||||
endif
|
||||
|
||||
+all: compile
|
||||
|
||||
-ALL= athstats 80211stats athkey athchans athctrl \
|
||||
+ALLPROGS= athstats 80211stats athkey athchans athctrl \
|
||||
athdebug 80211debug wlanconfig ath_info
|
||||
|
||||
-all: $(ALL)
|
||||
+OBJS= $(patsubst %,%.o,$(ALLPROGS))
|
||||
|
||||
-INCS= -I. -I$(HAL) -I$(TOP) -I$(ATH_HAL)
|
||||
+INCS= -I. -I../ath -I$(HAL) -I$(TOP) -I$(ATH_HAL)
|
||||
CFLAGS= -g -O2 -Wall
|
||||
ALL_CFLAGS= $(CFLAGS) $(INCS)
|
||||
LDFLAGS=
|
||||
|
||||
-all: $(ALL)
|
||||
|
||||
-athstats: athstats.c
|
||||
- $(CC) -o athstats $(ALL_CFLAGS) -I$(TOP)/ath $(LDFLAGS) athstats.c
|
||||
-80211stats: 80211stats.c
|
||||
- $(CC) -o 80211stats $(ALL_CFLAGS) $(LDFLAGS) 80211stats.c
|
||||
-athkey: athkey.c
|
||||
- $(CC) -o athkey $(ALL_CFLAGS) $(LDFLAGS) athkey.c
|
||||
-athchans: athchans.c
|
||||
- $(CC) -o athchans $(ALL_CFLAGS) $(LDFLAGS) athchans.c
|
||||
-athctrl: athctrl.c
|
||||
- $(CC) -o athctrl $(ALL_CFLAGS) $(LDFLAGS) athctrl.c
|
||||
-athdebug: athdebug.c
|
||||
- $(CC) -o athdebug $(ALL_CFLAGS) $(LDFLAGS) athdebug.c
|
||||
-wlanconfig: wlanconfig.c
|
||||
- $(CC) -o wlanconfig $(ALL_CFLAGS) $(LDFLAGS) wlanconfig.c
|
||||
-80211debug: 80211debug.c
|
||||
- $(CC) -o 80211debug $(ALL_CFLAGS) $(LDFLAGS) 80211debug.c
|
||||
-ath_info: ath_info.c
|
||||
- $(CC) -o ath_info $(CFLAGS) ath_info.c
|
||||
+ifneq ($(DO_MULTI),)
|
||||
+ALL_CFLAGS += -DDO_MULTI=1
|
||||
+%.o: %.c
|
||||
+ ${CC} $(ALL_CFLAGS) -c -o $@ $<
|
||||
+
|
||||
+madwifi_multi: $(OBJS) do_multi.o
|
||||
+ $(CC) -o $@ $^
|
||||
+
|
||||
+compile: madwifi_multi
|
||||
+ for i in $(ALLPROGS); do \
|
||||
+ ln -s -f madwifi_multi $$i; \
|
||||
+ done
|
||||
+else
|
||||
+$(ALLPROGS):
|
||||
+ $(CC) $(ALL_CFLAGS) -o $@ $@.c
|
||||
+
|
||||
+compile: $(ALLPROGS)
|
||||
+endif
|
||||
|
||||
|
||||
install: $(ALL)
|
||||
install -d $(DESTDIR)$(BINDIR)
|
||||
- for i in $(ALL); do \
|
||||
+ for i in $(ALLPROGS) $(if $(DO_MULTI),madwifi_multi); do \
|
||||
install $$i $(DESTDIR)$(BINDIR)/$$i; \
|
||||
- $(STRIP) $(DESTDIR)$(BINDIR)/$$i; \
|
||||
done
|
||||
install -d $(DESTDIR)$(MANDIR)/man8
|
||||
install -m 0644 man/*.8 $(DESTDIR)$(MANDIR)/man8
|
||||
install $(TOP)/scripts/madwifi-unload $(DESTDIR)$(BINDIR)/madwifi-unload
|
||||
|
||||
uninstall:
|
||||
- for i in $(ALL); do \
|
||||
+ for i in $(ALLPROGS) $(if $(DO_MULTI),madwifi_multi); do \
|
||||
rm -f $(DESTDIR)$(BINDIR)/$$i; \
|
||||
done
|
||||
- for i in $(ALL:=.8); do \
|
||||
- rm -f $(DESTDIR)$(MANDIR)/man8/$$i; \
|
||||
+ for i in $(ALLPROGS); do \
|
||||
+ rm -f $(DESTDIR)$(MANDIR)/man8/$$i.8; \
|
||||
done
|
||||
|
||||
clean:
|
||||
- rm -f $(ALL) core a.out
|
||||
+ rm -f $(ALLPROGS) madwifi_multi *.o core a.out
|
||||
--- a/tools/wlanconfig.c
|
||||
+++ b/tools/wlanconfig.c
|
||||
@@ -61,6 +61,7 @@
|
||||
#include "net80211/ieee80211.h"
|
||||
#include "net80211/ieee80211_crypto.h"
|
||||
#include "net80211/ieee80211_ioctl.h"
|
||||
+#include "do_multi.h"
|
||||
|
||||
/*
|
||||
* These are taken from ieee80211_node.h
|
||||
@@ -100,7 +101,7 @@ size_t strlcat(char *, const char *, siz
|
||||
static int verbose = 0;
|
||||
|
||||
int
|
||||
-main(int argc, char *argv[])
|
||||
+CMD(wlanconfig)(int argc, char *argv[])
|
||||
{
|
||||
const char *ifname, *cmd;
|
||||
unsigned char bnounit = 0;
|
||||
--- a/tools/ath_info.c
|
||||
+++ b/tools/ath_info.c
|
||||
@@ -98,6 +98,7 @@
|
||||
#include <sys/mman.h>
|
||||
#include <endian.h>
|
||||
#include <byteswap.h>
|
||||
+#include "do_multi.h"
|
||||
|
||||
#undef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
@@ -738,7 +739,8 @@ static void usage(const char *n)
|
||||
"unlawful radio transmissions!\n\n");
|
||||
}
|
||||
|
||||
-int main(int argc, char *argv[])
|
||||
+int
|
||||
+CMD(athinfo)(int argc, char *argv[])
|
||||
{
|
||||
u_int32_t dev_addr;
|
||||
u_int16_t eeprom_header, srev, phy_rev_5ghz, phy_rev_2ghz;
|
11
net/madwifi/patches/104-autocreate_none.patch
Normal file
11
net/madwifi/patches/104-autocreate_none.patch
Normal file
@ -0,0 +1,11 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -516,7 +516,7 @@ ath_attach(u_int16_t devid, struct net_d
|
||||
HAL_STATUS status;
|
||||
int error = 0;
|
||||
unsigned int i;
|
||||
- int autocreatemode = IEEE80211_M_STA;
|
||||
+ int autocreatemode = -1;
|
||||
u_int8_t csz;
|
||||
|
||||
sc->devid = devid;
|
23
net/madwifi/patches/105-ratectl_attach.patch
Normal file
23
net/madwifi/patches/105-ratectl_attach.patch
Normal file
@ -0,0 +1,23 @@
|
||||
--- a/net80211/ieee80211_rate.c
|
||||
+++ b/net80211/ieee80211_rate.c
|
||||
@@ -100,8 +100,18 @@ struct ath_ratectrl *ieee80211_rate_atta
|
||||
ieee80211_load_module(buf);
|
||||
|
||||
if (!ratectls[id].attach) {
|
||||
- printk(KERN_ERR "Error loading module \"%s\"\n", buf);
|
||||
- return NULL;
|
||||
+ /* pick the first available rate control module */
|
||||
+ printk(KERN_INFO "Rate control module \"%s\" not available\n", buf);
|
||||
+ for (id = 0; id < IEEE80211_RATE_MAX - 1; id++) {
|
||||
+ if (ratectls[id].attach)
|
||||
+ break;
|
||||
+ }
|
||||
+ if (!ratectls[id].attach) {
|
||||
+ printk(KERN_ERR "No rate control module available");
|
||||
+ return NULL;
|
||||
+ } else {
|
||||
+ printk(KERN_INFO "Using \"%s\" instead.\n", module_names[id]);
|
||||
+ }
|
||||
}
|
||||
|
||||
ctl = ratectls[id].attach(sc);
|
21
net/madwifi/patches/106-get_arch.patch
Normal file
21
net/madwifi/patches/106-get_arch.patch
Normal file
@ -0,0 +1,21 @@
|
||||
--- a/scripts/get_arch.mk
|
||||
+++ b/scripts/get_arch.mk
|
||||
@@ -36,11 +36,14 @@ ifeq (,$(ARCH-y))
|
||||
$(Cannot determine ARCH)
|
||||
endif
|
||||
|
||||
+# Allow ARCH to be x86
|
||||
+ifneq (,$(CONFIG_X86))
|
||||
+ifeq (x86,$(ARCH))
|
||||
+ARCH-y = $(ARCH)
|
||||
+endif
|
||||
+endif
|
||||
+
|
||||
# Don't allow ARCH to be overridden by a different value.
|
||||
ifeq (,$(ARCH))
|
||||
ARCH = $(ARCH-y)
|
||||
-else
|
||||
-ifneq ($(ARCH),$(ARCH-y))
|
||||
-$(error ARCH mismatch: supplied "$(ARCH)", determined "$(ARCH-y)")
|
||||
-endif
|
||||
endif
|
12
net/madwifi/patches/111-minstrel_crash.patch
Normal file
12
net/madwifi/patches/111-minstrel_crash.patch
Normal file
@ -0,0 +1,12 @@
|
||||
--- a/ath_rate/minstrel/minstrel.c
|
||||
+++ b/ath_rate/minstrel/minstrel.c
|
||||
@@ -393,6 +393,9 @@ ath_rate_get_mrr(struct ath_softc *sc, s
|
||||
struct minstrel_node *sn = ATH_NODE_MINSTREL(an);
|
||||
int rc1, rc2, rc3; /* Index into the rate table, so for example, it is 0..11 */
|
||||
|
||||
+ if (sn->num_rates <= 0)
|
||||
+ return;
|
||||
+
|
||||
if (sn->is_sampling) {
|
||||
sn->is_sampling = 0;
|
||||
if (sn->rs_sample_rate_slower)
|
12
net/madwifi/patches/113-no_ibss_pwrsave.patch
Normal file
12
net/madwifi/patches/113-no_ibss_pwrsave.patch
Normal file
@ -0,0 +1,12 @@
|
||||
--- a/net80211/ieee80211_scan.c
|
||||
+++ b/net80211/ieee80211_scan.c
|
||||
@@ -291,7 +291,8 @@ scan_restart_pwrsav(unsigned long arg)
|
||||
struct ieee80211com *ic = vap->iv_ic;
|
||||
int delay;
|
||||
|
||||
- ieee80211_sta_pwrsave(vap, 1);
|
||||
+ if (vap->iv_opmode != IEEE80211_M_IBSS)
|
||||
+ ieee80211_sta_pwrsave(vap, 1);
|
||||
/*
|
||||
* Use an initial 1ms delay to ensure the null
|
||||
* data frame has a chance to go out.
|
12
net/madwifi/patches/122-replayfail_workaround.patch
Normal file
12
net/madwifi/patches/122-replayfail_workaround.patch
Normal file
@ -0,0 +1,12 @@
|
||||
--- a/net80211/ieee80211_linux.c
|
||||
+++ b/net80211/ieee80211_linux.c
|
||||
@@ -331,6 +331,9 @@ ieee80211_notify_replay_failure(struct i
|
||||
k->wk_cipher->ic_name, k->wk_keyix,
|
||||
(unsigned long long)rsc);
|
||||
|
||||
+ /* disabled for now due to bogus events for unknown reasons */
|
||||
+ return;
|
||||
+
|
||||
/* TODO: needed parameters: count, keyid, key type, src address, TSC */
|
||||
snprintf(buf, sizeof(buf), "%s(keyid=%d %scast addr=" MAC_FMT ")", tag,
|
||||
k->wk_keyix,
|
95
net/madwifi/patches/123-ccmp_checks.patch
Normal file
95
net/madwifi/patches/123-ccmp_checks.patch
Normal file
@ -0,0 +1,95 @@
|
||||
--- a/net80211/ieee80211_crypto_ccmp.c
|
||||
+++ b/net80211/ieee80211_crypto_ccmp.c
|
||||
@@ -115,6 +115,7 @@ ccmp_attach(struct ieee80211vap *vap, st
|
||||
/* This function (crypto_alloc_foo might sleep. Therefore:
|
||||
* Context: process
|
||||
*/
|
||||
+#ifdef CONFIG_CRYPTO
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
|
||||
ctx->cc_tfm = crypto_alloc_tfm("aes", 0);
|
||||
#else
|
||||
@@ -123,7 +124,8 @@ ccmp_attach(struct ieee80211vap *vap, st
|
||||
if (IS_ERR(ctx->cc_tfm))
|
||||
ctx->cc_tfm = NULL;
|
||||
#endif
|
||||
-
|
||||
+#endif
|
||||
+
|
||||
if (ctx->cc_tfm == NULL) {
|
||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO,
|
||||
"%s: unable to load kernel AES crypto support\n",
|
||||
@@ -138,12 +140,14 @@ ccmp_detach(struct ieee80211_key *k)
|
||||
{
|
||||
struct ccmp_ctx *ctx = k->wk_private;
|
||||
|
||||
+#ifdef CONFIG_CRYPTO
|
||||
if (ctx->cc_tfm != NULL)
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
|
||||
crypto_free_tfm(ctx->cc_tfm);
|
||||
#else
|
||||
crypto_free_cipher(ctx->cc_tfm);
|
||||
#endif
|
||||
+#endif
|
||||
FREE(ctx, M_DEVBUF);
|
||||
|
||||
_MOD_DEC_USE(THIS_MODULE);
|
||||
@@ -169,7 +173,9 @@ ccmp_setkey(struct ieee80211_key *k)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_CRYPTO
|
||||
crypto_cipher_setkey(ctx->cc_tfm, k->wk_key, k->wk_keylen);
|
||||
+#endif
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -324,6 +330,7 @@ xor_block(u8 *b, const u8 *a, size_t len
|
||||
static void
|
||||
rijndael_encrypt(struct crypto_cipher *tfm, const void *src, void *dst)
|
||||
{
|
||||
+#ifdef CONFIG_CRYPTO
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
|
||||
crypto_cipher_encrypt_one(tfm, dst, src);
|
||||
#else
|
||||
@@ -339,6 +346,7 @@ rijndael_encrypt(struct crypto_cipher *t
|
||||
sg_dst.length = AES_BLOCK_LEN;
|
||||
crypto_cipher_encrypt(tfm, &sg_dst, &sg_src, AES_BLOCK_LEN);
|
||||
#endif
|
||||
+#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -475,6 +483,9 @@ ccmp_encrypt(struct ieee80211_key *key,
|
||||
uint8_t *mic, *pos;
|
||||
u_int space;
|
||||
|
||||
+ if (ctx->cc_tfm == NULL)
|
||||
+ return 0;
|
||||
+
|
||||
ctx->cc_vap->iv_stats.is_crypto_ccmp++;
|
||||
|
||||
skb = skb0;
|
||||
@@ -589,6 +600,9 @@ ccmp_decrypt(struct ieee80211_key *key,
|
||||
uint8_t *pos, *mic;
|
||||
u_int space;
|
||||
|
||||
+ if (ctx->cc_tfm == NULL)
|
||||
+ return 0;
|
||||
+
|
||||
ctx->cc_vap->iv_stats.is_crypto_ccmp++;
|
||||
|
||||
skb = skb0;
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -192,11 +192,4 @@ endif
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
- @# check crypto support is enabled
|
||||
- @if [ -z "$(CONFIG_CRYPTO)" ]; then \
|
||||
- echo "FAILED"; \
|
||||
- echo "Please enable crypto API."; \
|
||||
- exit 1; \
|
||||
- fi
|
||||
-
|
||||
@echo "ok."
|
202
net/madwifi/patches/124-linux24_compat.patch
Normal file
202
net/madwifi/patches/124-linux24_compat.patch
Normal file
@ -0,0 +1,202 @@
|
||||
--- a/ath/if_athvar.h
|
||||
+++ b/ath/if_athvar.h
|
||||
@@ -126,6 +126,11 @@ typedef void irqreturn_t;
|
||||
#define ATH_GET_NETDEV_DEV(ndev) ((ndev)->class_dev.dev)
|
||||
#endif
|
||||
|
||||
+#ifndef NETDEV_TX_OK
|
||||
+#define NETDEV_TX_OK 0
|
||||
+#define NETDEV_TX_BUSY 1
|
||||
+#endif
|
||||
+
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23)
|
||||
static inline struct net_device *_alloc_netdev(int sizeof_priv, const char *mask,
|
||||
void (*setup)(struct net_device *))
|
||||
--- a/ath/if_ath_radar.c
|
||||
+++ b/ath/if_ath_radar.c
|
||||
@@ -92,6 +92,13 @@
|
||||
#define nofloat_pct(_value, _pct) \
|
||||
( (_value * (1000 + _pct)) / 1000 )
|
||||
|
||||
+#ifndef list_for_each_entry_reverse
|
||||
+#define list_for_each_entry_reverse(pos, head, member) \
|
||||
+ for (pos = list_entry((head)->prev, typeof(*pos), member); \
|
||||
+ prefetch(pos->member.prev), &pos->member != (head); \
|
||||
+ pos = list_entry(pos->member.prev, typeof(*pos), member))
|
||||
+#endif
|
||||
+
|
||||
struct radar_pattern_specification {
|
||||
/* The name of the rule/specification (i.e. what did we detect) */
|
||||
const char *name;
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -4705,6 +4705,46 @@ ath_beacon_setup(struct ath_softc *sc, s
|
||||
#undef USE_SHPREAMBLE
|
||||
}
|
||||
|
||||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
|
||||
+static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
|
||||
+{
|
||||
+ int ret;
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ local_irq_save(flags);
|
||||
+ ret = v->counter;
|
||||
+ if (likely(ret == old))
|
||||
+ v->counter = new;
|
||||
+ local_irq_restore(flags);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * atomic_add_unless - add unless the number is a given value
|
||||
+ * @v: pointer of type atomic_t
|
||||
+ * @a: the amount to add to v...
|
||||
+ * @u: ...unless v is equal to u.
|
||||
+ *
|
||||
+ * Atomically adds @a to @v, so long as it was not @u.
|
||||
+ * Returns non-zero if @v was not @u, and zero otherwise.
|
||||
+ */
|
||||
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
|
||||
+{
|
||||
+ int c, old;
|
||||
+ c = atomic_read(v);
|
||||
+ for (;;) {
|
||||
+ if (unlikely(c == (u)))
|
||||
+ break;
|
||||
+ old = atomic_cmpxchg((v), c, c + (a));
|
||||
+ if (likely(old == c))
|
||||
+ break;
|
||||
+ c = old;
|
||||
+ }
|
||||
+ return c != (u);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* Generate beacon frame and queue cab data for a VAP.
|
||||
*/
|
||||
--- /dev/null
|
||||
+++ b/net80211/sort.c
|
||||
@@ -0,0 +1,120 @@
|
||||
+/*
|
||||
+ * A fast, small, non-recursive O(nlog n) sort for the Linux kernel
|
||||
+ *
|
||||
+ * Jan 23 2005 Matt Mackall <mpm@selenic.com>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/slab.h>
|
||||
+
|
||||
+static void u32_swap(void *a, void *b, int size)
|
||||
+{
|
||||
+ u32 t = *(u32 *)a;
|
||||
+ *(u32 *)a = *(u32 *)b;
|
||||
+ *(u32 *)b = t;
|
||||
+}
|
||||
+
|
||||
+static void generic_swap(void *a, void *b, int size)
|
||||
+{
|
||||
+ char t;
|
||||
+
|
||||
+ do {
|
||||
+ t = *(char *)a;
|
||||
+ *(char *)a++ = *(char *)b;
|
||||
+ *(char *)b++ = t;
|
||||
+ } while (--size > 0);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * sort - sort an array of elements
|
||||
+ * @base: pointer to data to sort
|
||||
+ * @num: number of elements
|
||||
+ * @size: size of each element
|
||||
+ * @cmp: pointer to comparison function
|
||||
+ * @swap: pointer to swap function or NULL
|
||||
+ *
|
||||
+ * This function does a heapsort on the given array. You may provide a
|
||||
+ * swap function optimized to your element type.
|
||||
+ *
|
||||
+ * Sorting time is O(n log n) both on average and worst-case. While
|
||||
+ * qsort is about 20% faster on average, it suffers from exploitable
|
||||
+ * O(n*n) worst-case behavior and extra memory requirements that make
|
||||
+ * it less suitable for kernel use.
|
||||
+ */
|
||||
+
|
||||
+static void sort(void *base, size_t num, size_t size,
|
||||
+ int (*cmp)(const void *, const void *),
|
||||
+ void (*swap)(void *, void *, int size))
|
||||
+{
|
||||
+ /* pre-scale counters for performance */
|
||||
+ int i = (num/2 - 1) * size, n = num * size, c, r;
|
||||
+
|
||||
+ if (!swap)
|
||||
+ swap = (size == 4 ? u32_swap : generic_swap);
|
||||
+
|
||||
+ /* heapify */
|
||||
+ for ( ; i >= 0; i -= size) {
|
||||
+ for (r = i; r * 2 + size < n; r = c) {
|
||||
+ c = r * 2 + size;
|
||||
+ if (c < n - size && cmp(base + c, base + c + size) < 0)
|
||||
+ c += size;
|
||||
+ if (cmp(base + r, base + c) >= 0)
|
||||
+ break;
|
||||
+ swap(base + r, base + c, size);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* sort */
|
||||
+ for (i = n - size; i >= 0; i -= size) {
|
||||
+ swap(base, base + i, size);
|
||||
+ for (r = 0; r * 2 + size < i; r = c) {
|
||||
+ c = r * 2 + size;
|
||||
+ if (c < i - size && cmp(base + c, base + c + size) < 0)
|
||||
+ c += size;
|
||||
+ if (cmp(base + r, base + c) >= 0)
|
||||
+ break;
|
||||
+ swap(base + r, base + c, size);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+EXPORT_SYMBOL(sort);
|
||||
+
|
||||
+#if 0
|
||||
+/* a simple boot-time regression test */
|
||||
+
|
||||
+int cmpint(const void *a, const void *b)
|
||||
+{
|
||||
+ return *(int *)a - *(int *)b;
|
||||
+}
|
||||
+
|
||||
+static int sort_test(void)
|
||||
+{
|
||||
+ int *a, i, r = 1;
|
||||
+
|
||||
+ a = kmalloc(1000 * sizeof(int), GFP_KERNEL);
|
||||
+ BUG_ON(!a);
|
||||
+
|
||||
+ printk("testing sort()\n");
|
||||
+
|
||||
+ for (i = 0; i < 1000; i++) {
|
||||
+ r = (r * 725861) % 6599;
|
||||
+ a[i] = r;
|
||||
+ }
|
||||
+
|
||||
+ sort(a, 1000, sizeof(int), cmpint, NULL);
|
||||
+
|
||||
+ for (i = 0; i < 999; i++)
|
||||
+ if (a[i] > a[i+1]) {
|
||||
+ printk("sort() failed!\n");
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ kfree(a);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+module_init(sort_test);
|
||||
+#endif
|
13
net/madwifi/patches/126-rxerr_frames.patch
Normal file
13
net/madwifi/patches/126-rxerr_frames.patch
Normal file
@ -0,0 +1,13 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -6474,8 +6474,9 @@ ath_rx_tasklet(TQUEUE_ARG data)
|
||||
/*
|
||||
* Reject error frames if we have no vaps that
|
||||
* are operating in monitor mode.
|
||||
+ * Reject empty frames as well
|
||||
*/
|
||||
- if (sc->sc_nmonvaps == 0)
|
||||
+ if ((sc->sc_nmonvaps == 0) || (rs->rs_datalen == 0))
|
||||
goto rx_next;
|
||||
}
|
||||
rx_accept:
|
408
net/madwifi/patches/200-no_debug.patch
Normal file
408
net/madwifi/patches/200-no_debug.patch
Normal file
@ -0,0 +1,408 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -42,7 +42,6 @@
|
||||
* This software is derived from work of Atsushi Onoe; his contribution
|
||||
* is greatly appreciated.
|
||||
*/
|
||||
-#define AR_DEBUG
|
||||
#include "if_ath_debug.h"
|
||||
#include "opt_ah.h"
|
||||
|
||||
@@ -368,8 +367,10 @@ static unsigned int ath_get_dfs_cac_time
|
||||
static void ath_set_dfs_cac_time(struct ieee80211com *, unsigned int seconds);
|
||||
|
||||
static unsigned int ath_test_radar(struct ieee80211com *);
|
||||
-static unsigned int ath_dump_hal_map(struct ieee80211com *ic);
|
||||
+#ifdef AR_DEBUG
|
||||
|
||||
+static unsigned int ath_dump_hal_map(struct ieee80211com *ic);
|
||||
+#endif
|
||||
static u_int32_t ath_get_clamped_maxtxpower(struct ath_softc *sc);
|
||||
static u_int32_t ath_set_clamped_maxtxpower(struct ath_softc *sc,
|
||||
u_int32_t new_clamped_maxtxpower);
|
||||
@@ -520,9 +521,11 @@ ath_attach(u_int16_t devid, struct net_d
|
||||
u_int8_t csz;
|
||||
|
||||
sc->devid = devid;
|
||||
+#ifdef AR_DEBUG
|
||||
ath_debug_global = (ath_debug & ATH_DEBUG_GLOBAL);
|
||||
sc->sc_debug = (ath_debug & ~ATH_DEBUG_GLOBAL);
|
||||
DPRINTF(sc, ATH_DEBUG_ANY, "%s: devid 0x%x\n", __func__, devid);
|
||||
+#endif
|
||||
|
||||
/* Allocate space for dynamically determined maximum VAP count */
|
||||
sc->sc_bslot =
|
||||
@@ -1038,8 +1041,9 @@ ath_attach(u_int16_t devid, struct net_d
|
||||
ic->ic_vap_delete = ath_vap_delete;
|
||||
|
||||
ic->ic_test_radar = ath_test_radar;
|
||||
+#ifdef AR_DEBUG
|
||||
ic->ic_dump_hal_map = ath_dump_hal_map;
|
||||
-
|
||||
+#endif
|
||||
ic->ic_set_dfs_testmode = ath_set_dfs_testmode;
|
||||
ic->ic_get_dfs_testmode = ath_get_dfs_testmode;
|
||||
|
||||
@@ -1297,12 +1301,14 @@ ath_vap_create(struct ieee80211com *ic,
|
||||
/* If no default VAP debug flags are passed, allow a few to
|
||||
* transfer down from the driver to new VAPs so we can have load
|
||||
* time debugging for VAPs too. */
|
||||
+#ifdef AR_DEBUG
|
||||
vap->iv_debug = 0 |
|
||||
((sc->sc_debug & ATH_DEBUG_RATE) ? IEEE80211_MSG_XRATE : 0) |
|
||||
((sc->sc_debug & ATH_DEBUG_XMIT) ? IEEE80211_MSG_OUTPUT : 0) |
|
||||
((sc->sc_debug & ATH_DEBUG_RECV) ? IEEE80211_MSG_INPUT : 0) |
|
||||
0
|
||||
;
|
||||
+#endif
|
||||
}
|
||||
ic->ic_debug = (sc->sc_default_ieee80211_debug & IEEE80211_MSG_IC);
|
||||
|
||||
@@ -10496,9 +10502,11 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
|
||||
/* XXX validate? */
|
||||
sc->sc_ledpin = val;
|
||||
break;
|
||||
+#ifdef AR_DEBUG
|
||||
case ATH_DEBUG:
|
||||
sc->sc_debug = (val & ~ATH_DEBUG_GLOBAL);
|
||||
ath_debug_global = (val & ATH_DEBUG_GLOBAL);
|
||||
+#endif
|
||||
break;
|
||||
case ATH_TXANTENNA:
|
||||
/*
|
||||
@@ -10918,9 +10926,11 @@ ath_dynamic_sysctl_register(struct ath_s
|
||||
}
|
||||
|
||||
/* initialize values */
|
||||
+#ifdef AR_DEBUG
|
||||
ath_debug_global = (ath_debug & ATH_DEBUG_GLOBAL);
|
||||
sc->sc_debug = (ath_debug & ~ATH_DEBUG_GLOBAL);
|
||||
sc->sc_default_ieee80211_debug = ieee80211_debug;
|
||||
+#endif
|
||||
sc->sc_txantenna = 0; /* default to auto-selection */
|
||||
sc->sc_txintrperiod = ATH_TXQ_INTR_PERIOD;
|
||||
}
|
||||
@@ -11762,6 +11772,7 @@ ath_test_radar(struct ieee80211com *ic)
|
||||
}
|
||||
|
||||
/* This is called by a private ioctl (iwpriv) to dump the HAL obfuscation table */
|
||||
+#ifdef AR_DEBUG
|
||||
static unsigned int
|
||||
ath_dump_hal_map(struct ieee80211com *ic)
|
||||
{
|
||||
@@ -11770,7 +11781,7 @@ ath_dump_hal_map(struct ieee80211com *ic
|
||||
ath_hal_dump_map(sc->sc_ah);
|
||||
return 0;
|
||||
}
|
||||
-
|
||||
+#endif
|
||||
/* If we are shutting down or blowing off the DFS channel availability check
|
||||
* then we call this to stop the behavior before we take the rest of the
|
||||
* necessary actions (such as a DFS reaction to radar). */
|
||||
--- a/ath_rate/amrr/amrr.c
|
||||
+++ b/ath_rate/amrr/amrr.c
|
||||
@@ -70,7 +70,9 @@
|
||||
|
||||
#include "amrr.h"
|
||||
|
||||
+#ifdef AR_DEBUG
|
||||
#define AMRR_DEBUG
|
||||
+#endif
|
||||
#ifdef AMRR_DEBUG
|
||||
#define DPRINTF(sc, _fmt, ...) do { \
|
||||
if (sc->sc_debug & 0x10) \
|
||||
--- a/ath_rate/minstrel/minstrel.c
|
||||
+++ b/ath_rate/minstrel/minstrel.c
|
||||
@@ -117,7 +117,9 @@
|
||||
|
||||
#include "minstrel.h"
|
||||
|
||||
+#ifdef AR_DEBUG
|
||||
#define MINSTREL_DEBUG
|
||||
+#endif
|
||||
#ifdef MINSTREL_DEBUG
|
||||
enum {
|
||||
ATH_DEBUG_RATE = 0x00000010 /* rate control */
|
||||
--- a/ath_rate/onoe/onoe.c
|
||||
+++ b/ath_rate/onoe/onoe.c
|
||||
@@ -66,7 +66,9 @@
|
||||
|
||||
#include "onoe.h"
|
||||
|
||||
+#ifdef AR_DEBUG
|
||||
#define ONOE_DEBUG
|
||||
+#endif
|
||||
#ifdef ONOE_DEBUG
|
||||
enum {
|
||||
ATH_DEBUG_RATE = 0x00000010, /* rate control */
|
||||
--- a/ath_rate/sample/sample.c
|
||||
+++ b/ath_rate/sample/sample.c
|
||||
@@ -68,7 +68,9 @@
|
||||
|
||||
#include "sample.h"
|
||||
|
||||
-#define SAMPLE_DEBUG
|
||||
+#ifdef AR_DEBUG
|
||||
+#define SAMPLE_DEBUG
|
||||
+#endif
|
||||
#ifdef SAMPLE_DEBUG
|
||||
enum {
|
||||
ATH_DEBUG_RATE = 0x00000010, /* rate control */
|
||||
--- a/tools/do_multi.c
|
||||
+++ b/tools/do_multi.c
|
||||
@@ -10,16 +10,20 @@ main(int argc, char *argv[])
|
||||
|
||||
progname = basename(argv[0]);
|
||||
|
||||
+#ifdef AR_DEBUG
|
||||
if(strcmp(progname, "80211debug") == 0)
|
||||
ret = a80211debug_init(argc, argv);
|
||||
+#endif
|
||||
if(strcmp(progname, "80211stats") == 0)
|
||||
ret = a80211stats_init(argc, argv);
|
||||
if(strcmp(progname, "athchans") == 0)
|
||||
ret = athchans_init(argc, argv);
|
||||
if(strcmp(progname, "athctrl") == 0)
|
||||
ret = athctrl_init(argc, argv);
|
||||
+#ifdef AR_DEBUG
|
||||
if(strcmp(progname, "athdebug") == 0)
|
||||
ret = athdebug_init(argc, argv);
|
||||
+#endif
|
||||
if(strcmp(progname, "athkey") == 0)
|
||||
ret = athkey_init(argc, argv);
|
||||
if(strcmp(progname, "athstats") == 0)
|
||||
--- a/tools/Makefile
|
||||
+++ b/tools/Makefile
|
||||
@@ -48,14 +48,16 @@ endif
|
||||
|
||||
all: compile
|
||||
|
||||
+DEBUG = -DAR_DEBUG
|
||||
+
|
||||
ALLPROGS= athstats 80211stats athkey athchans athctrl \
|
||||
- athdebug 80211debug wlanconfig ath_info
|
||||
+ $(if $(DEBUG),athdebug 80211debug) wlanconfig ath_info
|
||||
|
||||
OBJS= $(patsubst %,%.o,$(ALLPROGS))
|
||||
|
||||
INCS= -I. -I../ath -I$(HAL) -I$(TOP) -I$(ATH_HAL)
|
||||
CFLAGS= -g -O2 -Wall
|
||||
-ALL_CFLAGS= $(CFLAGS) $(INCS)
|
||||
+ALL_CFLAGS= $(CFLAGS) $(INCS) $(DEBUG)
|
||||
LDFLAGS=
|
||||
|
||||
|
||||
--- a/net80211/ieee80211_linux.h
|
||||
+++ b/net80211/ieee80211_linux.h
|
||||
@@ -29,8 +29,6 @@
|
||||
#ifndef _NET80211_IEEE80211_LINUX_H_
|
||||
#define _NET80211_IEEE80211_LINUX_H_
|
||||
|
||||
-#define IEEE80211_DEBUG
|
||||
-#define IEEE80211_DEBUG_REFCNT /* Node reference count debugging */
|
||||
/* #define ATH_DEBUG_SPINLOCKS */ /* announce before spinlocking */
|
||||
|
||||
#include <linux/wireless.h>
|
||||
--- a/Makefile.inc
|
||||
+++ b/Makefile.inc
|
||||
@@ -147,8 +147,9 @@ ATH_RATE= $(TOP)/ath_rate
|
||||
#
|
||||
TOOLS= $(TOP)/tools
|
||||
|
||||
-WARNINGS = -Werror
|
||||
-COPTS+= $(WARNINGS)
|
||||
+WARNINGS = -Wno-unused
|
||||
+# DEBUG = -DAR_DEBUG -DIEEE80211_DEBUG
|
||||
+COPTS+= $(WARNINGS) $(DEBUG)
|
||||
INCS= -include $(TOP)/include/compat.h -I$(TOP)/include
|
||||
|
||||
# TARGET defines the target platform architecture. It must match one of
|
||||
--- a/ath/if_ath_radar.c
|
||||
+++ b/ath/if_ath_radar.c
|
||||
@@ -19,8 +19,6 @@
|
||||
* $Id: if_ath_radar.c 2464 2007-06-15 22:51:56Z mtaylor $
|
||||
*/
|
||||
#include "opt_ah.h"
|
||||
-
|
||||
-#define AR_DEBUG
|
||||
#include "if_ath_debug.h"
|
||||
|
||||
#ifndef AUTOCONF_INCLUDED
|
||||
@@ -56,8 +54,6 @@
|
||||
#include <net80211/if_llc.h>
|
||||
#endif
|
||||
|
||||
-#define AR_DEBUG
|
||||
-
|
||||
#include "net80211/if_athproto.h"
|
||||
#include "if_athvar.h"
|
||||
|
||||
--- a/ath/if_ath_hal.h
|
||||
+++ b/ath/if_ath_hal.h
|
||||
@@ -1081,6 +1081,7 @@ static inline HAL_BOOL ath_hal_disable(s
|
||||
|
||||
tail -f /var/log/messages | sed -f hal_unmangle.sed
|
||||
*/
|
||||
+#ifdef AR_DEBUG
|
||||
static inline void ath_hal_dump_map(struct ath_hal *ah)
|
||||
{
|
||||
#ifdef CONFIG_KALLSYMS
|
||||
@@ -1345,7 +1346,7 @@ static inline void ath_hal_dump_map(stru
|
||||
#endif /* #ifndef CONFIG_KALLSYMS */
|
||||
|
||||
}
|
||||
-
|
||||
+#endif
|
||||
#include "if_ath_hal_wrappers.h"
|
||||
|
||||
#endif /* #ifndef _IF_ATH_HAL_H_ */
|
||||
--- a/net80211/ieee80211_var.h
|
||||
+++ b/net80211/ieee80211_var.h
|
||||
@@ -492,9 +492,10 @@ struct ieee80211com {
|
||||
/* inject a fake radar signal -- used while on a 802.11h DFS channels */
|
||||
unsigned int (*ic_test_radar)(struct ieee80211com *);
|
||||
|
||||
+#ifdef AR_DEBUG
|
||||
/* dump HAL */
|
||||
unsigned int (*ic_dump_hal_map)(struct ieee80211com *);
|
||||
-
|
||||
+#endif
|
||||
/* DFS channel availability check time (in seconds) */
|
||||
void (*ic_set_dfs_cac_time)(struct ieee80211com *, unsigned int);
|
||||
unsigned int (*ic_get_dfs_cac_time)(struct ieee80211com *);
|
||||
--- a/net80211/ieee80211_wireless.c
|
||||
+++ b/net80211/ieee80211_wireless.c
|
||||
@@ -1548,6 +1548,7 @@ ieee80211_get_txcont_power(struct net_de
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#ifdef AR_DEBUG
|
||||
static int
|
||||
ieee80211_ioctl_hal_map(struct net_device *dev, struct iw_request_info *info,
|
||||
void *w, char *extra)
|
||||
@@ -1558,7 +1559,7 @@ ieee80211_ioctl_hal_map(struct net_devic
|
||||
params[0] = ic->ic_dump_hal_map(ic);
|
||||
return 0;
|
||||
}
|
||||
-
|
||||
+#endif
|
||||
|
||||
static int
|
||||
ieee80211_ioctl_radar(struct net_device *dev, struct iw_request_info *info,
|
||||
@@ -5258,8 +5259,10 @@ static const struct iw_priv_args ieee802
|
||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwmmparams" },
|
||||
{ IEEE80211_IOCTL_RADAR,
|
||||
0, 0, "doth_radar" },
|
||||
+#ifdef AR_DEBUG
|
||||
{ IEEE80211_IOCTL_HALMAP,
|
||||
0, 0, "dump_hal_map" },
|
||||
+#endif
|
||||
/*
|
||||
* These depends on sub-ioctl support which added in version 12.
|
||||
*/
|
||||
@@ -5695,7 +5698,9 @@ static const iw_handler ieee80211_priv_h
|
||||
set_priv(IEEE80211_IOCTL_SETMLME, ieee80211_ioctl_setmlme),
|
||||
set_priv(IEEE80211_IOCTL_SETKEY, ieee80211_ioctl_setkey),
|
||||
set_priv(IEEE80211_IOCTL_DELKEY, ieee80211_ioctl_delkey),
|
||||
+#ifdef AR_DEBUG
|
||||
set_priv(IEEE80211_IOCTL_HALMAP, ieee80211_ioctl_hal_map),
|
||||
+#endif
|
||||
set_priv(IEEE80211_IOCTL_ADDMAC, ieee80211_ioctl_addmac),
|
||||
set_priv(IEEE80211_IOCTL_DELMAC, ieee80211_ioctl_delmac),
|
||||
set_priv(IEEE80211_IOCTL_WDSADDMAC, ieee80211_ioctl_wdsmac),
|
||||
--- a/ath/if_ath_debug.h
|
||||
+++ b/ath/if_ath_debug.h
|
||||
@@ -54,6 +54,10 @@ enum {
|
||||
ATH_DEBUG_GLOBAL = (ATH_DEBUG_SKB|ATH_DEBUG_SKB_REF)
|
||||
};
|
||||
|
||||
+#define EPRINTF(_sc, _fmt, ...) \
|
||||
+ printk(KERN_ERR "%s: %s: " _fmt, \
|
||||
+ SC_DEV_NAME(_sc), __func__, ## __VA_ARGS__)
|
||||
+
|
||||
#ifdef AR_DEBUG
|
||||
|
||||
/* DEBUG-ONLY DEFINITIONS */
|
||||
@@ -68,20 +72,9 @@ enum {
|
||||
ath_keyprint((_sc), __func__, _ix, _hk, _mac); \
|
||||
} while (0)
|
||||
|
||||
-#else /* #ifdef AR_DEBUG */
|
||||
-
|
||||
-#define DFLAG_ISSET(sc, _m) 0
|
||||
-#define DPRINTF(sc, _m, _fmt, ...)
|
||||
-#define KEYPRINTF(sc, k, ix, mac)
|
||||
-
|
||||
-#endif /* #ifdef AR_DEBUG */
|
||||
|
||||
#define IFF_DUMPPKTS(_sc, _m) DFLAG_ISSET((_sc), (_m))
|
||||
|
||||
-#define EPRINTF(_sc, _fmt, ...) \
|
||||
- printk(KERN_ERR "%s: %s: " _fmt, \
|
||||
- SC_DEV_NAME(_sc), __func__, ## __VA_ARGS__)
|
||||
-
|
||||
#define WPRINTF(_sc, _fmt, ...) \
|
||||
printk(KERN_WARNING "%s: %s: " _fmt, \
|
||||
SC_DEV_NAME(_sc), __func__, ## __VA_ARGS__)
|
||||
@@ -89,5 +82,14 @@ enum {
|
||||
#define IPRINTF(_sc, _fmt, ...) \
|
||||
printk(KERN_INFO "%s: %s: " _fmt, \
|
||||
SC_DEV_NAME(_sc), __func__, ## __VA_ARGS__)
|
||||
+#else
|
||||
+#define DFLAG_ISSET(sc, _m) 0
|
||||
+#define DPRINTF(sc, _m, _fmt, ...)
|
||||
+#define KEYPRINTF(sc, k, ix, mac)
|
||||
+#define WPRINTF(...)
|
||||
+#define IPRINTF(...)
|
||||
+#define IFF_DUMPPKTS(...) 0
|
||||
+
|
||||
+#endif
|
||||
|
||||
#endif /* #ifndef _IF_ATH_DEBUG_H_ */
|
||||
--- a/net80211/ieee80211_node.c
|
||||
+++ b/net80211/ieee80211_node.c
|
||||
@@ -920,6 +920,9 @@ node_cleanup(struct ieee80211_node *ni)
|
||||
ni->ni_rxkeyoff = 0;
|
||||
}
|
||||
|
||||
+#ifndef IEEE80211_DEBUG
|
||||
+#define node_print_message(...) do {} while(0)
|
||||
+#else
|
||||
static void node_print_message(
|
||||
u_int32_t flags,
|
||||
int show_counter,
|
||||
@@ -972,7 +975,7 @@ static void node_print_message(
|
||||
adjusted_refcount);
|
||||
va_end(args);
|
||||
}
|
||||
-EXPORT_SYMBOL(node_print_message);
|
||||
+#endif
|
||||
|
||||
static void
|
||||
#ifdef IEEE80211_DEBUG_REFCNT
|
||||
--- a/ath/if_ath_pci.c
|
||||
+++ b/ath/if_ath_pci.c
|
||||
@@ -134,8 +134,10 @@ ath_pci_probe(struct pci_dev *pdev, cons
|
||||
u16 vdevice;
|
||||
int i;
|
||||
|
||||
- if (pci_enable_device(pdev))
|
||||
+ if (pci_enable_device(pdev)) {
|
||||
+ printk(KERN_ERR "%s: failed to enable PCI device\n", dev_info);
|
||||
return -EIO;
|
||||
+ }
|
||||
|
||||
/* XXX 32-bit addressing only */
|
||||
if (pci_set_dma_mask(pdev, 0xffffffff)) {
|
||||
@@ -244,8 +246,10 @@ ath_pci_probe(struct pci_dev *pdev, cons
|
||||
sc->aps_sc.sc_ledpin = 1;
|
||||
}
|
||||
|
||||
- if (ath_attach(vdevice, dev, NULL) != 0)
|
||||
+ if ((i = ath_attach(vdevice, dev, NULL)) != 0) {
|
||||
+ printk(KERN_ERR "%s: ath_attach failed: %d\n", dev_info, i);
|
||||
goto bad4;
|
||||
+ }
|
||||
|
||||
athname = ath_hal_probe(id->vendor, vdevice);
|
||||
printk(KERN_INFO "%s: %s: %s: mem=0x%lx, irq=%d\n",
|
20
net/madwifi/patches/201-debug_fix.patch
Normal file
20
net/madwifi/patches/201-debug_fix.patch
Normal file
@ -0,0 +1,20 @@
|
||||
--- a/ath_hal/ah_os.c
|
||||
+++ b/ath_hal/ah_os.c
|
||||
@@ -65,7 +65,7 @@
|
||||
#include <ah_os.h>
|
||||
|
||||
#ifdef AH_DEBUG
|
||||
-static int ath_hal_debug = 0;
|
||||
+static int ath_hal_debug = 99;
|
||||
#endif
|
||||
|
||||
int ath_hal_dma_beacon_response_time = 2; /* in TUs */
|
||||
@@ -327,6 +327,8 @@ EXPORT_SYMBOL(OS_MARK);
|
||||
* useful for debugging and figuring out, which hal function sets which
|
||||
* registers */
|
||||
char *ath_hal_func = NULL;
|
||||
+EXPORT_SYMBOL(ath_hal_func);
|
||||
+
|
||||
#endif
|
||||
|
||||
/*
|
204
net/madwifi/patches/202-debug_variables.patch
Normal file
204
net/madwifi/patches/202-debug_variables.patch
Normal file
@ -0,0 +1,204 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -453,8 +453,8 @@ MODULE_PARM_DESC(autocreate, "Create ath
|
||||
MODULE_PARM_DESC(ratectl, "Rate control algorithm [amrr|minstrel|onoe|sample], "
|
||||
"defaults to '" DEF_RATE_CTL "'");
|
||||
|
||||
-static int ath_debug = 0;
|
||||
#ifdef AR_DEBUG
|
||||
+static int ath_debug = 0;
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,52))
|
||||
MODULE_PARM(ath_debug, "i");
|
||||
#else
|
||||
@@ -465,8 +465,8 @@ static void ath_printrxbuf(const struct
|
||||
static void ath_printtxbuf(const struct ath_buf *, int);
|
||||
#endif /* defined(AR_DEBUG) */
|
||||
|
||||
-static int ieee80211_debug = 0;
|
||||
#ifdef AR_DEBUG
|
||||
+static int ieee80211_debug = 0;
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,52))
|
||||
MODULE_PARM(ieee80211_debug, "i");
|
||||
#else
|
||||
@@ -1565,7 +1565,9 @@ ath_vap_delete(struct ieee80211vap *vap)
|
||||
void
|
||||
ath_suspend(struct net_device *dev)
|
||||
{
|
||||
+#ifdef AR_DEBUG
|
||||
struct ath_softc *sc = dev->priv;
|
||||
+#endif
|
||||
|
||||
DPRINTF(sc, ATH_DEBUG_ANY, "flags=%x\n", dev->flags);
|
||||
ath_stop(dev);
|
||||
@@ -1574,7 +1576,9 @@ ath_suspend(struct net_device *dev)
|
||||
void
|
||||
ath_resume(struct net_device *dev)
|
||||
{
|
||||
+#ifdef AR_DEBUG
|
||||
struct ath_softc *sc = dev->priv;
|
||||
+#endif
|
||||
|
||||
DPRINTF(sc, ATH_DEBUG_ANY, "flags=%x\n", dev->flags);
|
||||
ath_init(dev);
|
||||
@@ -4019,7 +4023,9 @@ static void
|
||||
ath_key_update_begin(struct ieee80211vap *vap)
|
||||
{
|
||||
struct net_device *dev = vap->iv_ic->ic_dev;
|
||||
+#ifdef AR_DEBUG
|
||||
struct ath_softc *sc = dev->priv;
|
||||
+#endif
|
||||
|
||||
DPRINTF(sc, ATH_DEBUG_KEYCACHE, "Begin\n");
|
||||
/*
|
||||
@@ -4040,7 +4046,9 @@ static void
|
||||
ath_key_update_end(struct ieee80211vap *vap)
|
||||
{
|
||||
struct net_device *dev = vap->iv_ic->ic_dev;
|
||||
+#ifdef AR_DEBUG
|
||||
struct ath_softc *sc = dev->priv;
|
||||
+#endif
|
||||
|
||||
DPRINTF(sc, ATH_DEBUG_KEYCACHE, "End\n");
|
||||
netif_wake_queue(dev);
|
||||
@@ -6218,7 +6226,9 @@ ath_recv_mgmt(struct ieee80211vap * vap,
|
||||
struct sk_buff *skb, int subtype, int rssi, u_int64_t rtsf)
|
||||
{
|
||||
struct ath_softc *sc = vap->iv_ic->ic_dev->priv;
|
||||
+#ifdef AR_DEBUG
|
||||
struct ieee80211_frame *wh = (struct ieee80211_frame *)skb->data;
|
||||
+#endif
|
||||
struct ieee80211_node * ni = ni_or_null;
|
||||
u_int64_t hw_tsf, beacon_tsf;
|
||||
u_int32_t hw_tu, beacon_tu, intval;
|
||||
@@ -8382,7 +8392,9 @@ ath_tx_timeout(struct net_device *dev)
|
||||
static void
|
||||
ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq)
|
||||
{
|
||||
+#ifdef AR_DEBUG
|
||||
struct ath_hal *ah = sc->sc_ah;
|
||||
+#endif
|
||||
struct ath_buf *bf;
|
||||
/*
|
||||
* NB: this assumes output has been stopped and
|
||||
@@ -11002,6 +11014,7 @@ ath_announce(struct net_device *dev)
|
||||
strncat(m, b, MLEN);
|
||||
}
|
||||
strncat(m, "\n", MLEN);
|
||||
+#ifdef AR_DEBUG
|
||||
if (1 /* bootverbose */) {
|
||||
unsigned int i;
|
||||
for (i = 0; i <= WME_AC_VO; i++) {
|
||||
@@ -11014,6 +11027,7 @@ ath_announce(struct net_device *dev)
|
||||
sc->sc_cabq->axq_qnum);
|
||||
IPRINTF(sc, "Use hw queue %u for beacons\n", sc->sc_bhalq);
|
||||
}
|
||||
+#endif
|
||||
#undef HAL_MODE_DUALBAND
|
||||
}
|
||||
|
||||
--- a/ath/if_ath_radar.c
|
||||
+++ b/ath/if_ath_radar.c
|
||||
@@ -156,7 +156,9 @@ static struct radar_pattern_specificatio
|
||||
#endif
|
||||
};
|
||||
|
||||
+#ifdef AR_DEBUG
|
||||
static u_int32_t interval_to_frequency(u_int32_t pri);
|
||||
+#endif
|
||||
|
||||
/* Returns true if radar detection is enabled. */
|
||||
int ath_radar_is_enabled(struct ath_softc *sc)
|
||||
@@ -229,7 +231,9 @@ int ath_radar_update(struct ath_softc *s
|
||||
{
|
||||
|
||||
struct ath_hal *ah = sc->sc_ah;
|
||||
+#ifdef AR_DEBUG
|
||||
struct net_device *dev = sc->sc_dev;
|
||||
+#endif
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
int required = 0;
|
||||
|
||||
@@ -366,6 +370,7 @@ static struct ath_rp *pulse_prev(struct
|
||||
#define MR_FAIL_MIN_PERIOD 4
|
||||
#define MR_FAIL_MAX_PERIOD 5
|
||||
|
||||
+#ifdef AR_DEBUG
|
||||
static const char* get_match_result_desc(u_int32_t code) {
|
||||
switch (code) {
|
||||
case MR_MATCH:
|
||||
@@ -384,6 +389,7 @@ static const char* get_match_result_desc
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
+#endif
|
||||
|
||||
static int32_t match_radar(
|
||||
u_int32_t matched,
|
||||
@@ -775,7 +781,10 @@ static HAL_BOOL rp_analyse_short_pulse(
|
||||
struct ath_softc *sc, struct ath_rp *last_pulse,
|
||||
u_int32_t *index, u_int32_t *pri, u_int32_t *matching_pulses,
|
||||
u_int32_t *missed_pulses, u_int32_t *noise_pulses)
|
||||
-{ struct net_device *dev = sc->sc_dev;
|
||||
+{
|
||||
+#ifdef AR_DEBUG
|
||||
+ struct net_device *dev = sc->sc_dev;
|
||||
+#endif
|
||||
int i;
|
||||
int best_index = -1;
|
||||
unsigned int best_matched = 0;
|
||||
@@ -1217,6 +1226,7 @@ static HAL_BOOL rp_analyse_short_pulse(
|
||||
return (-1 != best_index) ? AH_TRUE : AH_FALSE;
|
||||
}
|
||||
|
||||
+#ifdef AR_DEBUG
|
||||
static u_int32_t interval_to_frequency(u_int32_t interval)
|
||||
{
|
||||
/* Calculate BRI from PRI */
|
||||
@@ -1224,6 +1234,7 @@ static u_int32_t interval_to_frequency(u
|
||||
/* Round to nearest multiple of 50 */
|
||||
return frequency + ((frequency % 50) >= 25 ? 50 : 0) - (frequency % 50);
|
||||
}
|
||||
+#endif
|
||||
|
||||
#ifdef ATH_RADAR_LONG_PULSE
|
||||
static const char* get_longpulse_desc(int lp) {
|
||||
@@ -1580,7 +1591,9 @@ void ath_rp_done(struct ath_softc *sc)
|
||||
void ath_rp_record(struct ath_softc *sc, u_int64_t tsf, u_int8_t rssi,
|
||||
u_int8_t width, HAL_BOOL is_simulated)
|
||||
{
|
||||
+#ifdef AR_DEBUG
|
||||
struct net_device *dev = sc->sc_dev;
|
||||
+#endif
|
||||
struct ath_rp *pulse;
|
||||
|
||||
DPRINTF(sc, ATH_DEBUG_DOTHPULSES, "%s: ath_rp_record: "
|
||||
--- a/ath_rate/minstrel/minstrel.c
|
||||
+++ b/ath_rate/minstrel/minstrel.c
|
||||
@@ -931,7 +931,9 @@ ath_proc_read_nodes(struct ieee80211vap
|
||||
(struct ieee80211_node_table *) &vap->iv_ic->ic_sta;
|
||||
unsigned int x = 0;
|
||||
unsigned int this_tp, this_prob, this_eprob;
|
||||
+#ifdef AR_DEBUG
|
||||
struct ath_softc *sc = vap->iv_ic->ic_dev->priv;;
|
||||
+#endif
|
||||
|
||||
IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
|
||||
TAILQ_FOREACH(ni, &nt->nt_node, ni_list) {
|
||||
--- a/net80211/ieee80211_scan_ap.c
|
||||
+++ b/net80211/ieee80211_scan_ap.c
|
||||
@@ -731,6 +731,7 @@ pick_channel(struct ieee80211_scan_state
|
||||
|
||||
sort(chans, ss_last, sizeof(*chans), pc_cmp, pc_swap);
|
||||
|
||||
+#ifdef IEEE80211_DEBUG
|
||||
for (i = 0; i < ss_last; i++) {
|
||||
int chan = ieee80211_chan2ieee(ic, chans[i].chan);
|
||||
|
||||
@@ -742,6 +743,7 @@ pick_channel(struct ieee80211_scan_state
|
||||
!!IEEE80211_ARE_CHANS_SAME_MODE(chans[i].chan,
|
||||
ic->ic_bsschan));
|
||||
}
|
||||
+#endif
|
||||
|
||||
best = NULL;
|
||||
best_rssi = 0xff; /* If signal is bigger than 0xff, we'd be melting. */
|
536
net/madwifi/patches/300-napi_polling.patch
Normal file
536
net/madwifi/patches/300-napi_polling.patch
Normal file
@ -0,0 +1,536 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -184,7 +184,11 @@ static void ath_recv_mgmt(struct ieee802
|
||||
struct sk_buff *, int, int, u_int64_t);
|
||||
static void ath_setdefantenna(struct ath_softc *, u_int);
|
||||
static struct ath_txq *ath_txq_setup(struct ath_softc *, int, int);
|
||||
-static void ath_rx_tasklet(TQUEUE_ARG);
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
|
||||
+static int ath_rx_poll(struct napi_struct *napi, int budget);
|
||||
+#else
|
||||
+static int ath_rx_poll(struct net_device *dev, int *budget);
|
||||
+#endif
|
||||
static int ath_hardstart(struct sk_buff *, struct net_device *);
|
||||
static int ath_mgtstart(struct ieee80211com *, struct sk_buff *);
|
||||
#ifdef ATH_SUPERG_COMP
|
||||
@@ -376,6 +380,9 @@ static u_int32_t ath_set_clamped_maxtxpo
|
||||
u_int32_t new_clamped_maxtxpower);
|
||||
static u_int32_t ath_get_real_maxtxpower(struct ath_softc *sc);
|
||||
|
||||
+static void ath_poll_disable(struct net_device *dev);
|
||||
+static void ath_poll_enable(struct net_device *dev);
|
||||
+
|
||||
/* calibrate every 30 secs in steady state but check every second at first. */
|
||||
static int ath_calinterval = ATH_SHORT_CALINTERVAL;
|
||||
static int ath_countrycode = CTRY_DEFAULT; /* country code */
|
||||
@@ -547,7 +554,6 @@ ath_attach(u_int16_t devid, struct net_d
|
||||
|
||||
atomic_set(&sc->sc_txbuf_counter, 0);
|
||||
|
||||
- ATH_INIT_TQUEUE(&sc->sc_rxtq, ath_rx_tasklet, dev);
|
||||
ATH_INIT_TQUEUE(&sc->sc_txtq, ath_tx_tasklet, dev);
|
||||
ATH_INIT_TQUEUE(&sc->sc_bmisstq, ath_bmiss_tasklet, dev);
|
||||
ATH_INIT_TQUEUE(&sc->sc_bstucktq, ath_bstuck_tasklet, dev);
|
||||
@@ -821,6 +827,12 @@ ath_attach(u_int16_t devid, struct net_d
|
||||
dev->set_mac_address = ath_set_mac_address;
|
||||
dev->change_mtu = ath_change_mtu;
|
||||
dev->tx_queue_len = ATH_TXBUF - ATH_TXBUF_MGT_RESERVED;
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
|
||||
+ netif_napi_add(dev, &sc->sc_napi, ath_rx_poll, 64);
|
||||
+#else
|
||||
+ dev->poll = ath_rx_poll;
|
||||
+ dev->weight = 64;
|
||||
+#endif
|
||||
#ifdef USE_HEADERLEN_RESV
|
||||
dev->hard_header_len += sizeof(struct ieee80211_qosframe) +
|
||||
sizeof(struct llc) +
|
||||
@@ -2220,6 +2232,7 @@ ath_intr(int irq, void *dev_id, struct p
|
||||
(status & HAL_INT_GLOBAL) ? " HAL_INT_GLOBAL" : ""
|
||||
);
|
||||
|
||||
+ sc->sc_isr = status;
|
||||
status &= sc->sc_imask; /* discard unasked for bits */
|
||||
/* As soon as we know we have a real interrupt we intend to service,
|
||||
* we will check to see if we need an initial hardware TSF reading.
|
||||
@@ -2277,7 +2290,21 @@ ath_intr(int irq, void *dev_id, struct p
|
||||
}
|
||||
if (status & (HAL_INT_RX | HAL_INT_RXPHY)) {
|
||||
ath_uapsd_processtriggers(sc, hw_tsf);
|
||||
- ATH_SCHEDULE_TQUEUE(&sc->sc_rxtq, &needmark);
|
||||
+ sc->sc_isr &= ~HAL_INT_RX;
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
|
||||
+ if (netif_rx_schedule_prep(dev, &sc->sc_napi))
|
||||
+#else
|
||||
+ if (netif_rx_schedule_prep(dev))
|
||||
+#endif
|
||||
+ {
|
||||
+ sc->sc_imask &= ~HAL_INT_RX;
|
||||
+ ath_hal_intrset(ah, sc->sc_imask);
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
|
||||
+ __netif_rx_schedule(dev, &sc->sc_napi);
|
||||
+#else
|
||||
+ __netif_rx_schedule(dev);
|
||||
+#endif
|
||||
+ }
|
||||
}
|
||||
if (status & HAL_INT_TX) {
|
||||
#ifdef ATH_SUPERG_DYNTURBO
|
||||
@@ -2303,6 +2330,11 @@ ath_intr(int irq, void *dev_id, struct p
|
||||
}
|
||||
}
|
||||
#endif
|
||||
+ /* disable transmit interrupt */
|
||||
+ sc->sc_isr &= ~HAL_INT_TX;
|
||||
+ ath_hal_intrset(ah, sc->sc_imask & ~HAL_INT_TX);
|
||||
+ sc->sc_imask &= ~HAL_INT_TX;
|
||||
+
|
||||
ATH_SCHEDULE_TQUEUE(&sc->sc_txtq, &needmark);
|
||||
}
|
||||
if (status & HAL_INT_BMISS) {
|
||||
@@ -2515,6 +2547,7 @@ ath_init(struct net_device *dev)
|
||||
if (sc->sc_tx99 != NULL)
|
||||
sc->sc_tx99->start(sc->sc_tx99);
|
||||
#endif
|
||||
+ ath_poll_enable(dev);
|
||||
|
||||
done:
|
||||
ATH_UNLOCK(sc);
|
||||
@@ -2555,6 +2588,9 @@ ath_stop_locked(struct net_device *dev)
|
||||
if (sc->sc_tx99 != NULL)
|
||||
sc->sc_tx99->stop(sc->sc_tx99);
|
||||
#endif
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
|
||||
+ ath_poll_disable(dev);
|
||||
+#endif
|
||||
netif_stop_queue(dev); /* XXX re-enabled by ath_newstate */
|
||||
dev->flags &= ~IFF_RUNNING; /* NB: avoid recursion */
|
||||
ieee80211_stop_running(ic); /* stop all VAPs */
|
||||
@@ -4013,12 +4049,47 @@ ath_key_set(struct ieee80211vap *vap, co
|
||||
return ath_keyset(sc, k, mac, vap->iv_bss);
|
||||
}
|
||||
|
||||
+static void ath_poll_disable(struct net_device *dev)
|
||||
+{
|
||||
+ struct ath_softc *sc = dev->priv;
|
||||
+
|
||||
+ /*
|
||||
+ * XXX Using in_softirq is not right since we might
|
||||
+ * be called from other soft irq contexts than
|
||||
+ * ath_rx_poll
|
||||
+ */
|
||||
+ if (!in_softirq()) {
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
|
||||
+ napi_disable(&sc->sc_napi);
|
||||
+#else
|
||||
+ netif_poll_disable(dev);
|
||||
+#endif
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void ath_poll_enable(struct net_device *dev)
|
||||
+{
|
||||
+ struct ath_softc *sc = dev->priv;
|
||||
+
|
||||
+ /* NB: see above */
|
||||
+ if (!in_softirq()) {
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
|
||||
+ napi_enable(&sc->sc_napi);
|
||||
+#else
|
||||
+ netif_poll_enable(dev);
|
||||
+#endif
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
/*
|
||||
* Block/unblock tx+rx processing while a key change is done.
|
||||
* We assume the caller serializes key management operations
|
||||
* so we only need to worry about synchronization with other
|
||||
* uses that originate in the driver.
|
||||
*/
|
||||
+#define IS_UP(_dev) \
|
||||
+ (((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))
|
||||
static void
|
||||
ath_key_update_begin(struct ieee80211vap *vap)
|
||||
{
|
||||
@@ -4032,14 +4103,9 @@ ath_key_update_begin(struct ieee80211vap
|
||||
* When called from the rx tasklet we cannot use
|
||||
* tasklet_disable because it will block waiting
|
||||
* for us to complete execution.
|
||||
- *
|
||||
- * XXX Using in_softirq is not right since we might
|
||||
- * be called from other soft irq contexts than
|
||||
- * ath_rx_tasklet.
|
||||
*/
|
||||
- if (!in_softirq())
|
||||
- tasklet_disable(&sc->sc_rxtq);
|
||||
- netif_stop_queue(dev);
|
||||
+ if (IS_UP(vap->iv_dev))
|
||||
+ netif_stop_queue(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4051,9 +4117,9 @@ ath_key_update_end(struct ieee80211vap *
|
||||
#endif
|
||||
|
||||
DPRINTF(sc, ATH_DEBUG_KEYCACHE, "End\n");
|
||||
- netif_wake_queue(dev);
|
||||
- if (!in_softirq()) /* NB: see above */
|
||||
- tasklet_enable(&sc->sc_rxtq);
|
||||
+
|
||||
+ if (IS_UP(vap->iv_dev))
|
||||
+ netif_wake_queue(dev);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -6360,15 +6426,25 @@ ath_setdefantenna(struct ath_softc *sc,
|
||||
sc->sc_rxotherant = 0;
|
||||
}
|
||||
|
||||
-static void
|
||||
-ath_rx_tasklet(TQUEUE_ARG data)
|
||||
+static int
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
|
||||
+ath_rx_poll(struct napi_struct *napi, int budget)
|
||||
+#else
|
||||
+ath_rx_poll(struct net_device *dev, int *budget)
|
||||
+#endif
|
||||
{
|
||||
#define PA2DESC(_sc, _pa) \
|
||||
((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \
|
||||
((_pa) - (_sc)->sc_rxdma.dd_desc_paddr)))
|
||||
- struct net_device *dev = (struct net_device *)data;
|
||||
- struct ath_buf *bf;
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
|
||||
+ struct ath_softc *sc = container_of(napi, struct ath_softc, sc_napi);
|
||||
+ struct net_device *dev = sc->sc_dev;
|
||||
+ u_int rx_limit = budget;
|
||||
+#else
|
||||
struct ath_softc *sc = dev->priv;
|
||||
+ u_int rx_limit = min(dev->quota, *budget);
|
||||
+#endif
|
||||
+ struct ath_buf *bf;
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
struct ath_hal *ah = sc ? sc->sc_ah : NULL;
|
||||
struct ath_desc *ds;
|
||||
@@ -6378,8 +6454,10 @@ ath_rx_tasklet(TQUEUE_ARG data)
|
||||
unsigned int len;
|
||||
int type;
|
||||
u_int phyerr;
|
||||
+ u_int processed = 0, early_stop = 0;
|
||||
|
||||
DPRINTF(sc, ATH_DEBUG_RX_PROC, "invoked\n");
|
||||
+process_rx_again:
|
||||
do {
|
||||
bf = STAILQ_FIRST(&sc->sc_rxbuf);
|
||||
if (bf == NULL) { /* XXX ??? can this happen */
|
||||
@@ -6403,6 +6481,15 @@ ath_rx_tasklet(TQUEUE_ARG data)
|
||||
/* NB: never process the self-linked entry at the end */
|
||||
break;
|
||||
}
|
||||
+
|
||||
+ if (rx_limit-- < 2) {
|
||||
+ early_stop = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
|
||||
+ processed++;
|
||||
+#endif
|
||||
+
|
||||
skb = bf->bf_skb;
|
||||
if (skb == NULL) {
|
||||
EPRINTF(sc, "Dropping; buffer contains NULL skbuff.\n");
|
||||
@@ -6450,6 +6537,7 @@ ath_rx_tasklet(TQUEUE_ARG data)
|
||||
sc->sc_stats.ast_rx_phyerr++;
|
||||
phyerr = rs->rs_phyerr & 0x1f;
|
||||
sc->sc_stats.ast_rx_phy[phyerr]++;
|
||||
+ goto rx_next;
|
||||
}
|
||||
if (rs->rs_status & HAL_RXERR_DECRYPT) {
|
||||
/*
|
||||
@@ -6645,9 +6733,39 @@ rx_next:
|
||||
STAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
|
||||
ATH_RXBUF_UNLOCK_IRQ(sc);
|
||||
} while (ath_rxbuf_init(sc, bf) == 0);
|
||||
+ if (!early_stop) {
|
||||
+ unsigned long flags;
|
||||
+ /* Check if more data is received while we were
|
||||
+ * processing the descriptor chain.
|
||||
+ */
|
||||
+ local_irq_save(flags);
|
||||
+ if (sc->sc_isr & HAL_INT_RX) {
|
||||
+ u_int64_t hw_tsf = ath_hal_gettsf64(ah);
|
||||
+ sc->sc_isr &= ~HAL_INT_RX;
|
||||
+ local_irq_restore(flags);
|
||||
+ ath_uapsd_processtriggers(sc, hw_tsf);
|
||||
+ goto process_rx_again;
|
||||
+ }
|
||||
+ local_irq_restore(flags);
|
||||
+ }
|
||||
+
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
|
||||
+ netif_rx_complete(dev, napi);
|
||||
+#else
|
||||
+ netif_rx_complete(dev);
|
||||
+ *budget -= processed;
|
||||
+ dev->quota -= processed;
|
||||
+#endif
|
||||
+ sc->sc_imask |= HAL_INT_RX;
|
||||
+ ath_hal_intrset(ah, sc->sc_imask);
|
||||
|
||||
/* rx signal state monitoring */
|
||||
ath_hal_rxmonitor(ah, &sc->sc_halstats, &sc->sc_curchan);
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
|
||||
+ return processed;
|
||||
+#else
|
||||
+ return early_stop;
|
||||
+#endif
|
||||
#undef PA2DESC
|
||||
}
|
||||
|
||||
@@ -8298,12 +8416,24 @@ ath_tx_tasklet_q0(TQUEUE_ARG data)
|
||||
{
|
||||
struct net_device *dev = (struct net_device *)data;
|
||||
struct ath_softc *sc = dev->priv;
|
||||
+ unsigned long flags;
|
||||
|
||||
+process_tx_again:
|
||||
if (txqactive(sc->sc_ah, 0))
|
||||
ath_tx_processq(sc, &sc->sc_txq[0]);
|
||||
if (txqactive(sc->sc_ah, sc->sc_cabq->axq_qnum))
|
||||
ath_tx_processq(sc, sc->sc_cabq);
|
||||
|
||||
+ local_irq_save(flags);
|
||||
+ if (sc->sc_isr & HAL_INT_TX) {
|
||||
+ sc->sc_isr &= ~HAL_INT_TX;
|
||||
+ local_irq_restore(flags);
|
||||
+ goto process_tx_again;
|
||||
+ }
|
||||
+ sc->sc_imask |= HAL_INT_TX;
|
||||
+ ath_hal_intrset(sc->sc_ah, sc->sc_imask);
|
||||
+ local_irq_restore(flags);
|
||||
+
|
||||
netif_wake_queue(dev);
|
||||
|
||||
if (sc->sc_softled)
|
||||
@@ -8319,7 +8449,9 @@ ath_tx_tasklet_q0123(TQUEUE_ARG data)
|
||||
{
|
||||
struct net_device *dev = (struct net_device *)data;
|
||||
struct ath_softc *sc = dev->priv;
|
||||
+ unsigned long flags;
|
||||
|
||||
+process_tx_again:
|
||||
/*
|
||||
* Process each active queue.
|
||||
*/
|
||||
@@ -8340,6 +8472,16 @@ ath_tx_tasklet_q0123(TQUEUE_ARG data)
|
||||
if (sc->sc_uapsdq && txqactive(sc->sc_ah, sc->sc_uapsdq->axq_qnum))
|
||||
ath_tx_processq(sc, sc->sc_uapsdq);
|
||||
|
||||
+ local_irq_save(flags);
|
||||
+ if (sc->sc_isr & HAL_INT_TX) {
|
||||
+ sc->sc_isr &= ~HAL_INT_TX;
|
||||
+ local_irq_restore(flags);
|
||||
+ goto process_tx_again;
|
||||
+ }
|
||||
+ sc->sc_imask |= HAL_INT_TX;
|
||||
+ ath_hal_intrset(sc->sc_ah, sc->sc_imask);
|
||||
+ local_irq_restore(flags);
|
||||
+
|
||||
netif_wake_queue(dev);
|
||||
|
||||
if (sc->sc_softled)
|
||||
@@ -8355,13 +8497,25 @@ ath_tx_tasklet(TQUEUE_ARG data)
|
||||
struct net_device *dev = (struct net_device *)data;
|
||||
struct ath_softc *sc = dev->priv;
|
||||
unsigned int i;
|
||||
+ unsigned long flags;
|
||||
|
||||
/* Process each active queue. This includes sc_cabq, sc_xrtq and
|
||||
* sc_uapsdq */
|
||||
+process_tx_again:
|
||||
for (i = 0; i < HAL_NUM_TX_QUEUES; i++)
|
||||
if (ATH_TXQ_SETUP(sc, i) && txqactive(sc->sc_ah, i))
|
||||
ath_tx_processq(sc, &sc->sc_txq[i]);
|
||||
|
||||
+ local_irq_save(flags);
|
||||
+ if (sc->sc_isr & HAL_INT_TX) {
|
||||
+ sc->sc_isr &= ~HAL_INT_TX;
|
||||
+ local_irq_restore(flags);
|
||||
+ goto process_tx_again;
|
||||
+ }
|
||||
+ sc->sc_imask |= HAL_INT_TX;
|
||||
+ ath_hal_intrset(sc->sc_ah, sc->sc_imask);
|
||||
+ local_irq_restore(flags);
|
||||
+
|
||||
netif_wake_queue(dev);
|
||||
|
||||
if (sc->sc_softled)
|
||||
@@ -10296,9 +10450,9 @@ ath_change_mtu(struct net_device *dev, i
|
||||
dev->mtu = mtu;
|
||||
if ((dev->flags & IFF_RUNNING) && !sc->sc_invalid) {
|
||||
/* NB: the rx buffers may need to be reallocated */
|
||||
- tasklet_disable(&sc->sc_rxtq);
|
||||
+ ath_poll_disable(dev);
|
||||
error = ath_reset(dev);
|
||||
- tasklet_enable(&sc->sc_rxtq);
|
||||
+ ath_poll_enable(dev);
|
||||
}
|
||||
ATH_UNLOCK(sc);
|
||||
|
||||
--- a/ath/if_athvar.h
|
||||
+++ b/ath/if_athvar.h
|
||||
@@ -53,6 +53,10 @@
|
||||
# include <asm/bitops.h>
|
||||
#endif
|
||||
|
||||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
|
||||
+#define irqs_disabled() 0
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* Deduce if tasklets are available. If not then
|
||||
* fall back to using the immediate work queue.
|
||||
@@ -616,6 +620,9 @@ struct ath_rp {
|
||||
struct ath_softc {
|
||||
struct ieee80211com sc_ic; /* NB: must be first */
|
||||
struct net_device *sc_dev;
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
|
||||
+ struct napi_struct sc_napi;
|
||||
+#endif
|
||||
void __iomem *sc_iobase; /* address of the device */
|
||||
struct semaphore sc_lock; /* dev-level lock */
|
||||
struct net_device_stats sc_devstats; /* device statistics */
|
||||
@@ -730,7 +737,6 @@ struct ath_softc {
|
||||
struct ath_buf *sc_rxbufcur; /* current rx buffer */
|
||||
u_int32_t *sc_rxlink; /* link ptr in last RX desc */
|
||||
spinlock_t sc_rxbuflock;
|
||||
- struct ATH_TQ_STRUCT sc_rxtq; /* rx intr tasklet */
|
||||
struct ATH_TQ_STRUCT sc_rxorntq; /* rxorn intr tasklet */
|
||||
u_int8_t sc_defant; /* current default antenna */
|
||||
u_int8_t sc_rxotherant; /* RXs on non-default antenna */
|
||||
@@ -745,6 +751,7 @@ struct ath_softc {
|
||||
u_int sc_txintrperiod; /* tx interrupt batching */
|
||||
struct ath_txq sc_txq[HAL_NUM_TX_QUEUES];
|
||||
struct ath_txq *sc_ac2q[WME_NUM_AC]; /* WME AC -> h/w qnum */
|
||||
+ HAL_INT sc_isr; /* unmasked ISR state */
|
||||
struct ATH_TQ_STRUCT sc_txtq; /* tx intr tasklet */
|
||||
u_int8_t sc_grppoll_str[GRPPOLL_RATE_STR_LEN];
|
||||
struct ath_descdma sc_bdma; /* beacon descriptors */
|
||||
@@ -858,6 +865,8 @@ typedef void (*ath_callback) (struct ath
|
||||
#define ATH_TXBUF_LOCK_CHECK(_sc)
|
||||
#endif
|
||||
|
||||
+#define ATH_DISABLE_INTR local_irq_disable
|
||||
+#define ATH_ENABLE_INTR local_irq_enable
|
||||
|
||||
#define ATH_RXBUF_LOCK_INIT(_sc) spin_lock_init(&(_sc)->sc_rxbuflock)
|
||||
#define ATH_RXBUF_LOCK_DESTROY(_sc)
|
||||
--- a/net80211/ieee80211_input.c
|
||||
+++ b/net80211/ieee80211_input.c
|
||||
@@ -1198,7 +1198,7 @@ ieee80211_deliver_data(struct ieee80211_
|
||||
/* attach vlan tag */
|
||||
struct ieee80211_node *ni_tmp = SKB_CB(skb)->ni;
|
||||
if (vlan_hwaccel_receive_skb(skb, vap->iv_vlgrp, ni->ni_vlan) == NET_RX_DROP) {
|
||||
- /* If netif_rx dropped the packet because
|
||||
+ /* If netif_receive_skb dropped the packet because
|
||||
* device was too busy */
|
||||
if (ni_tmp != NULL) {
|
||||
/* node reference was leaked */
|
||||
@@ -1209,8 +1209,8 @@ ieee80211_deliver_data(struct ieee80211_
|
||||
skb = NULL; /* SKB is no longer ours */
|
||||
} else {
|
||||
struct ieee80211_node *ni_tmp = SKB_CB(skb)->ni;
|
||||
- if (netif_rx(skb) == NET_RX_DROP) {
|
||||
- /* If netif_rx dropped the packet because
|
||||
+ if (netif_receive_skb(skb) == NET_RX_DROP) {
|
||||
+ /* If netif_receive_skb dropped the packet because
|
||||
* device was too busy */
|
||||
if (ni_tmp != NULL) {
|
||||
/* node reference was leaked */
|
||||
@@ -2322,8 +2322,8 @@ forward_mgmt_to_app(struct ieee80211vap
|
||||
skb1->protocol = __constant_htons(0x0019); /* ETH_P_80211_RAW */
|
||||
|
||||
ni_tmp = SKB_CB(skb1)->ni;
|
||||
- if (netif_rx(skb1) == NET_RX_DROP) {
|
||||
- /* If netif_rx dropped the packet because
|
||||
+ if (netif_receive_skb(skb1) == NET_RX_DROP) {
|
||||
+ /* If netif_receive_skb dropped the packet because
|
||||
* device was too busy */
|
||||
if (ni_tmp != NULL) {
|
||||
/* node reference was leaked */
|
||||
--- a/net80211/ieee80211_monitor.c
|
||||
+++ b/net80211/ieee80211_monitor.c
|
||||
@@ -584,8 +584,8 @@ ieee80211_input_monitor(struct ieee80211
|
||||
skb1->protocol =
|
||||
__constant_htons(0x0019); /* ETH_P_80211_RAW */
|
||||
|
||||
- if (netif_rx(skb1) == NET_RX_DROP) {
|
||||
- /* If netif_rx dropped the packet because
|
||||
+ if (netif_receive_skb(skb1) == NET_RX_DROP) {
|
||||
+ /* If netif_receive_skb dropped the packet because
|
||||
* device was too busy, reclaim the ref. in
|
||||
* the skb. */
|
||||
if (SKB_CB(skb1)->ni != NULL)
|
||||
--- a/net80211/ieee80211_skb.c
|
||||
+++ b/net80211/ieee80211_skb.c
|
||||
@@ -73,7 +73,7 @@
|
||||
#undef dev_queue_xmit
|
||||
#undef kfree_skb
|
||||
#undef kfree_skb_fast
|
||||
-#undef netif_rx
|
||||
+#undef netif_receive_skb
|
||||
#undef pskb_copy
|
||||
#undef skb_clone
|
||||
#undef skb_copy
|
||||
@@ -638,8 +638,8 @@ int vlan_hwaccel_receive_skb_debug(stru
|
||||
grp, vlan_tag);
|
||||
}
|
||||
|
||||
-int netif_rx_debug(struct sk_buff *skb, const char* func, int line) {
|
||||
- return netif_rx(untrack_skb(skb, 0, func, line, __func__, __LINE__));
|
||||
+int netif_receive_skb_debug(struct sk_buff *skb, const char* func, int line) {
|
||||
+ return netif_receive_skb(untrack_skb(skb, 0, func, line, __func__, __LINE__));
|
||||
}
|
||||
|
||||
struct sk_buff * alloc_skb_debug(unsigned int length, gfp_t gfp_mask,
|
||||
@@ -760,7 +760,7 @@ struct sk_buff * skb_copy_expand_debug(c
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(vlan_hwaccel_receive_skb_debug);
|
||||
-EXPORT_SYMBOL(netif_rx_debug);
|
||||
+EXPORT_SYMBOL(netif_receive_skb_debug);
|
||||
EXPORT_SYMBOL(alloc_skb_debug);
|
||||
EXPORT_SYMBOL(dev_alloc_skb_debug);
|
||||
EXPORT_SYMBOL(skb_clone_debug);
|
||||
--- a/net80211/ieee80211_skb.h
|
||||
+++ b/net80211/ieee80211_skb.h
|
||||
@@ -116,7 +116,7 @@ int ieee80211_skb_references(void);
|
||||
int vlan_hwaccel_receive_skb_debug(struct sk_buff *skb,
|
||||
struct vlan_group *grp, unsigned short vlan_tag,
|
||||
const char* func, int line);
|
||||
-int netif_rx_debug(struct sk_buff *skb, const char* func, int line);
|
||||
+int netif_receive_skb_debug(struct sk_buff *skb, const char* func, int line);
|
||||
struct sk_buff * alloc_skb_debug(unsigned int length, gfp_t gfp_mask,
|
||||
const char *func, int line);
|
||||
struct sk_buff * dev_alloc_skb_debug(unsigned int length,
|
||||
@@ -151,7 +151,7 @@ struct sk_buff * skb_copy_expand_debug(c
|
||||
#undef dev_queue_xmit
|
||||
#undef kfree_skb
|
||||
#undef kfree_skb_fast
|
||||
-#undef netif_rx
|
||||
+#undef netif_receive_skb
|
||||
#undef pskb_copy
|
||||
#undef skb_clone
|
||||
#undef skb_copy
|
||||
@@ -168,8 +168,8 @@ struct sk_buff * skb_copy_expand_debug(c
|
||||
skb_copy_expand_debug(_skb, _newheadroom, _newtailroom, _gfp_mask, __func__, __LINE__)
|
||||
#define vlan_hwaccel_receive_skb(_skb, _grp, _tag) \
|
||||
vlan_hwaccel_receive_skb_debug(_skb, _grp, _tag, __func__, __LINE__)
|
||||
-#define netif_rx(_skb) \
|
||||
- netif_rx_debug(_skb, __func__, __LINE__)
|
||||
+#define netif_receive_skb(_skb) \
|
||||
+ netif_receive_skb_debug(_skb, __func__, __LINE__)
|
||||
#define alloc_skb(_length, _gfp_mask) \
|
||||
alloc_skb_debug(_length, _gfp_mask, __func__, __LINE__)
|
||||
#define dev_alloc_skb(_length) \
|
168
net/madwifi/patches/305-pureg_fix.patch
Normal file
168
net/madwifi/patches/305-pureg_fix.patch
Normal file
@ -0,0 +1,168 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -4158,7 +4158,9 @@ ath_calcrxfilter(struct ath_softc *sc)
|
||||
rfilt |= HAL_RX_FILTER_PROM;
|
||||
if (ic->ic_opmode == IEEE80211_M_STA ||
|
||||
sc->sc_opmode == HAL_M_IBSS || /* NB: AHDEMO too */
|
||||
- (sc->sc_nostabeacons) || sc->sc_scanning)
|
||||
+ (sc->sc_nostabeacons) || sc->sc_scanning ||
|
||||
+ ((ic->ic_opmode == IEEE80211_M_HOSTAP) &&
|
||||
+ (ic->ic_protmode != IEEE80211_PROT_NONE)))
|
||||
rfilt |= HAL_RX_FILTER_BEACON;
|
||||
if (sc->sc_nmonvaps > 0)
|
||||
rfilt |= (HAL_RX_FILTER_CONTROL | HAL_RX_FILTER_BEACON |
|
||||
--- a/net80211/ieee80211_input.c
|
||||
+++ b/net80211/ieee80211_input.c
|
||||
@@ -346,11 +346,12 @@ ieee80211_input(struct ieee80211vap * va
|
||||
bssid = wh->i_addr3;
|
||||
}
|
||||
/*
|
||||
- * Validate the bssid.
|
||||
+ * Validate the bssid. Let beacons get through though for 11g protection mode.
|
||||
*/
|
||||
-#ifdef ATH_SUPERG_XR
|
||||
if (!IEEE80211_ADDR_EQ(bssid, vap->iv_bssid) &&
|
||||
- !IEEE80211_ADDR_EQ(bssid, dev->broadcast)) {
|
||||
+ !IEEE80211_ADDR_EQ(bssid, dev->broadcast) &&
|
||||
+ (subtype != IEEE80211_FC0_SUBTYPE_BEACON)) {
|
||||
+#ifdef ATH_SUPERG_XR
|
||||
/*
|
||||
* allow MGT frames to vap->iv_xrvap.
|
||||
* this will allow roaming between XR and normal vaps
|
||||
@@ -366,18 +367,14 @@ ieee80211_input(struct ieee80211vap * va
|
||||
vap->iv_stats.is_rx_wrongbss++;
|
||||
goto out;
|
||||
}
|
||||
- }
|
||||
#else
|
||||
- if (!IEEE80211_ADDR_EQ(bssid, vap->iv_bssid) &&
|
||||
- !IEEE80211_ADDR_EQ(bssid, dev->broadcast)) {
|
||||
/* not interested in */
|
||||
IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
|
||||
bssid, NULL, "%s", "not to bss");
|
||||
vap->iv_stats.is_rx_wrongbss++;
|
||||
goto out;
|
||||
- }
|
||||
-
|
||||
#endif
|
||||
+ }
|
||||
break;
|
||||
case IEEE80211_M_WDS:
|
||||
if (skb->len < sizeof(struct ieee80211_frame_addr4)) {
|
||||
@@ -3066,7 +3063,7 @@ ieee80211_recv_mgmt(struct ieee80211vap
|
||||
u_int8_t *frm, *efrm;
|
||||
u_int8_t *ssid, *rates, *xrates, *suppchan, *wpa, *rsn, *wme, *ath;
|
||||
u_int8_t rate;
|
||||
- int reassoc, resp, allocbs = 0;
|
||||
+ int reassoc, resp, allocbs = 0, has_erp = 0;
|
||||
u_int8_t qosinfo;
|
||||
|
||||
if (ni_or_null == NULL)
|
||||
@@ -3096,11 +3093,15 @@ ieee80211_recv_mgmt(struct ieee80211vap
|
||||
* o station mode when associated (to collect state
|
||||
* updates such as 802.11g slot time), or
|
||||
* o adhoc mode (to discover neighbors)
|
||||
+ * o ap mode in protection mode (beacons only)
|
||||
* Frames otherwise received are discarded.
|
||||
*/
|
||||
if (!((ic->ic_flags & IEEE80211_F_SCAN) ||
|
||||
(vap->iv_opmode == IEEE80211_M_STA && ni->ni_associd) ||
|
||||
- vap->iv_opmode == IEEE80211_M_IBSS)) {
|
||||
+ (vap->iv_opmode == IEEE80211_M_IBSS) ||
|
||||
+ ((subtype == IEEE80211_FC0_SUBTYPE_BEACON) &&
|
||||
+ (vap->iv_opmode == IEEE80211_M_HOSTAP) &&
|
||||
+ (ic->ic_protmode != IEEE80211_PROT_NONE)))) {
|
||||
vap->iv_stats.is_rx_mgtdiscard++;
|
||||
return;
|
||||
}
|
||||
@@ -3184,6 +3185,7 @@ ieee80211_recv_mgmt(struct ieee80211vap
|
||||
break;
|
||||
}
|
||||
scan.erp = frm[2];
|
||||
+ has_erp = 1;
|
||||
break;
|
||||
case IEEE80211_ELEMID_RSN:
|
||||
scan.rsn = frm;
|
||||
@@ -3421,6 +3423,20 @@ ieee80211_recv_mgmt(struct ieee80211vap
|
||||
ieee80211_bg_scan(vap);
|
||||
return;
|
||||
}
|
||||
+
|
||||
+ /* Update AP protection mode when in 11G mode */
|
||||
+ if ((vap->iv_opmode == IEEE80211_M_HOSTAP) &&
|
||||
+ IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) {
|
||||
+
|
||||
+ /* Assume no ERP IE == 11b AP */
|
||||
+ if ((!has_erp || (has_erp && (scan.erp & IEEE80211_ERP_NON_ERP_PRESENT))) &&
|
||||
+ !(ic->ic_flags & IEEE80211_F_USEPROT)) {
|
||||
+
|
||||
+ ic->ic_flags |= IEEE80211_F_USEPROT;
|
||||
+ ic->ic_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* If scanning, just pass information to the scan module.
|
||||
*/
|
||||
--- a/net80211/ieee80211_node.c
|
||||
+++ b/net80211/ieee80211_node.c
|
||||
@@ -383,10 +383,16 @@ ieee80211_create_ibss(struct ieee80211va
|
||||
/* Update country ie information */
|
||||
ieee80211_build_countryie(ic);
|
||||
|
||||
- if (IEEE80211_IS_CHAN_HALF(chan))
|
||||
+ if (IEEE80211_IS_CHAN_HALF(chan)) {
|
||||
ni->ni_rates = ic->ic_sup_half_rates;
|
||||
- else if (IEEE80211_IS_CHAN_QUARTER(chan))
|
||||
+ } else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
|
||||
ni->ni_rates = ic->ic_sup_quarter_rates;
|
||||
+ }
|
||||
+
|
||||
+ if ((vap->iv_flags & IEEE80211_F_PUREG) &&
|
||||
+ IEEE80211_IS_CHAN_ANYG(chan)) {
|
||||
+ ieee80211_setpuregbasicrates(&ni->ni_rates);
|
||||
+ }
|
||||
|
||||
(void) ieee80211_sta_join1(PASS_NODE(ni));
|
||||
}
|
||||
--- a/net80211/ieee80211_proto.c
|
||||
+++ b/net80211/ieee80211_proto.c
|
||||
@@ -595,6 +595,28 @@ static const struct ieee80211_rateset ba
|
||||
{ 4, { 2, 4, 11, 22 } }, /* IEEE80211_MODE_TURBO_G (mixed b/g) */
|
||||
};
|
||||
|
||||
+static const struct ieee80211_rateset basicpureg[] = {
|
||||
+ { 7, {2, 4, 11, 22, 12, 24, 48 } },
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * Mark basic rates for the 11g rate table based on the pureg setting
|
||||
+ */
|
||||
+void
|
||||
+ieee80211_setpuregbasicrates(struct ieee80211_rateset *rs)
|
||||
+{
|
||||
+ int i, j;
|
||||
+
|
||||
+ for (i = 0; i < rs->rs_nrates; i++) {
|
||||
+ rs->rs_rates[i] &= IEEE80211_RATE_VAL;
|
||||
+ for (j = 0; j < basicpureg[0].rs_nrates; j++)
|
||||
+ if (basicpureg[0].rs_rates[j] == rs->rs_rates[i]) {
|
||||
+ rs->rs_rates[i] |= IEEE80211_RATE_BASIC;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Mark the basic rates for the 11g rate table based on the
|
||||
* specified mode. For 11b compatibility we mark only 11b
|
||||
--- a/net80211/ieee80211_var.h
|
||||
+++ b/net80211/ieee80211_var.h
|
||||
@@ -708,6 +708,7 @@ int ieee80211_media_setup(struct ieee802
|
||||
void ieee80211_build_sc_ie(struct ieee80211com *);
|
||||
void ieee80211_dfs_action(struct ieee80211com *);
|
||||
void ieee80211_expire_channel_excl_restrictions(struct ieee80211com *);
|
||||
+void ieee80211_setpuregbasicrates(struct ieee80211_rateset *rs);
|
||||
|
||||
/*
|
||||
* Iterate through ic_channels to enumerate all distinct ic_ieee channel numbers.
|
321
net/madwifi/patches/309-micfail_detect.patch
Normal file
321
net/madwifi/patches/309-micfail_detect.patch
Normal file
@ -0,0 +1,321 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -6457,6 +6457,7 @@ ath_rx_poll(struct net_device *dev, int
|
||||
int type;
|
||||
u_int phyerr;
|
||||
u_int processed = 0, early_stop = 0;
|
||||
+ u_int mic_fail = 0;
|
||||
|
||||
DPRINTF(sc, ATH_DEBUG_RX_PROC, "invoked\n");
|
||||
process_rx_again:
|
||||
@@ -6558,24 +6559,8 @@ process_rx_again:
|
||||
}
|
||||
if (rs->rs_status & HAL_RXERR_MIC) {
|
||||
sc->sc_stats.ast_rx_badmic++;
|
||||
- /*
|
||||
- * Do minimal work required to hand off
|
||||
- * the 802.11 header for notification.
|
||||
- */
|
||||
- /* XXX frag's and QoS frames */
|
||||
- if (len >= sizeof (struct ieee80211_frame)) {
|
||||
- bus_dma_sync_single(sc->sc_bdev,
|
||||
- bf->bf_skbaddr, len,
|
||||
- BUS_DMA_FROMDEVICE);
|
||||
-#if 0
|
||||
-/* XXX revalidate MIC, lookup ni to find VAP */
|
||||
- ieee80211_notify_michael_failure(ic,
|
||||
- (struct ieee80211_frame *)skb->data,
|
||||
- sc->sc_splitmic ?
|
||||
- rs->rs_keyix - 32 : rs->rs_keyix
|
||||
- );
|
||||
-#endif
|
||||
- }
|
||||
+ mic_fail = 1;
|
||||
+ goto rx_accept;
|
||||
}
|
||||
/*
|
||||
* Reject error frames if we have no vaps that
|
||||
@@ -6614,8 +6599,9 @@ rx_accept:
|
||||
/*
|
||||
* Finished monitor mode handling, now reject
|
||||
* error frames before passing to other vaps
|
||||
+ * Ignore MIC failures here, as we need to recheck them
|
||||
*/
|
||||
- if (rs->rs_status != 0) {
|
||||
+ if (rs->rs_status & ~(HAL_RXERR_MIC | HAL_RXERR_DECRYPT)) {
|
||||
ieee80211_dev_kfree_skb(&skb);
|
||||
goto rx_next;
|
||||
}
|
||||
@@ -6623,6 +6609,26 @@ rx_accept:
|
||||
/* remove the CRC */
|
||||
skb_trim(skb, skb->len - IEEE80211_CRC_LEN);
|
||||
|
||||
+ if (mic_fail) {
|
||||
+ /* Ignore control frames which are reported with mic error */
|
||||
+ if ((((struct ieee80211_frame *)skb->data)->i_fc[0] &
|
||||
+ IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
|
||||
+ goto drop_micfail;
|
||||
+
|
||||
+ ni = ieee80211_find_rxnode(ic, (const struct ieee80211_frame_min *) skb->data);
|
||||
+
|
||||
+ if (ni && ni->ni_table) {
|
||||
+ ieee80211_check_mic(ni, skb);
|
||||
+ ieee80211_unref_node(&ni);
|
||||
+ }
|
||||
+
|
||||
+drop_micfail:
|
||||
+ dev_kfree_skb_any(skb);
|
||||
+ skb = NULL;
|
||||
+ mic_fail = 0;
|
||||
+ goto rx_next;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* From this point on we assume the frame is at least
|
||||
* as large as ieee80211_frame_min; verify that.
|
||||
@@ -6635,6 +6641,7 @@ rx_accept:
|
||||
goto rx_next;
|
||||
}
|
||||
|
||||
+ /* MIC failure. Drop the packet in any case */
|
||||
/*
|
||||
* Normal receive.
|
||||
*/
|
||||
--- a/net80211/ieee80211_crypto_ccmp.c
|
||||
+++ b/net80211/ieee80211_crypto_ccmp.c
|
||||
@@ -73,7 +73,7 @@ static int ccmp_setkey(struct ieee80211_
|
||||
static int ccmp_encap(struct ieee80211_key *, struct sk_buff *, u_int8_t);
|
||||
static int ccmp_decap(struct ieee80211_key *, struct sk_buff *, int);
|
||||
static int ccmp_enmic(struct ieee80211_key *, struct sk_buff *, int);
|
||||
-static int ccmp_demic(struct ieee80211_key *, struct sk_buff *, int);
|
||||
+static int ccmp_demic(struct ieee80211_key *, struct sk_buff *, int, int);
|
||||
|
||||
static const struct ieee80211_cipher ccmp = {
|
||||
.ic_name = "AES-CCM",
|
||||
@@ -314,7 +314,7 @@ ccmp_decap(struct ieee80211_key *k, stru
|
||||
* Verify and strip MIC from the frame.
|
||||
*/
|
||||
static int
|
||||
-ccmp_demic(struct ieee80211_key *k, struct sk_buff *skb, int hdrlen)
|
||||
+ccmp_demic(struct ieee80211_key *k, struct sk_buff *skb, int hdrlen, int force)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
--- a/net80211/ieee80211_crypto.h
|
||||
+++ b/net80211/ieee80211_crypto.h
|
||||
@@ -145,7 +145,7 @@ struct ieee80211_cipher {
|
||||
int (*ic_encap)(struct ieee80211_key *, struct sk_buff *, u_int8_t);
|
||||
int (*ic_decap)(struct ieee80211_key *, struct sk_buff *, int);
|
||||
int (*ic_enmic)(struct ieee80211_key *, struct sk_buff *, int);
|
||||
- int (*ic_demic)(struct ieee80211_key *, struct sk_buff *, int);
|
||||
+ int (*ic_demic)(struct ieee80211_key *, struct sk_buff *, int, int);
|
||||
};
|
||||
extern const struct ieee80211_cipher ieee80211_cipher_none;
|
||||
|
||||
@@ -163,10 +163,10 @@ struct ieee80211_key *ieee80211_crypto_d
|
||||
*/
|
||||
static __inline int
|
||||
ieee80211_crypto_demic(struct ieee80211vap *vap, struct ieee80211_key *k,
|
||||
- struct sk_buff *skb, int hdrlen)
|
||||
+ struct sk_buff *skb, int hdrlen, int force)
|
||||
{
|
||||
const struct ieee80211_cipher *cip = k->wk_cipher;
|
||||
- return (cip->ic_miclen > 0 ? cip->ic_demic(k, skb, hdrlen) : 1);
|
||||
+ return (cip->ic_miclen > 0 ? cip->ic_demic(k, skb, hdrlen, force) : 1);
|
||||
}
|
||||
|
||||
/*
|
||||
--- a/net80211/ieee80211_crypto_none.c
|
||||
+++ b/net80211/ieee80211_crypto_none.c
|
||||
@@ -52,7 +52,7 @@ static int none_setkey(struct ieee80211_
|
||||
static int none_encap(struct ieee80211_key *, struct sk_buff *, u_int8_t);
|
||||
static int none_decap(struct ieee80211_key *, struct sk_buff *, int);
|
||||
static int none_enmic(struct ieee80211_key *, struct sk_buff *, int);
|
||||
-static int none_demic(struct ieee80211_key *, struct sk_buff *, int);
|
||||
+static int none_demic(struct ieee80211_key *, struct sk_buff *, int, int);
|
||||
|
||||
const struct ieee80211_cipher ieee80211_cipher_none = {
|
||||
.ic_name = "NONE",
|
||||
@@ -137,7 +137,7 @@ none_enmic(struct ieee80211_key *k, stru
|
||||
}
|
||||
|
||||
static int
|
||||
-none_demic(struct ieee80211_key *k, struct sk_buff *skb, int hdrlen)
|
||||
+none_demic(struct ieee80211_key *k, struct sk_buff *skb, int hdrlen, int force)
|
||||
{
|
||||
struct ieee80211vap *vap = k->wk_private;
|
||||
|
||||
--- a/net80211/ieee80211_crypto_tkip.c
|
||||
+++ b/net80211/ieee80211_crypto_tkip.c
|
||||
@@ -57,7 +57,7 @@ static int tkip_setkey(struct ieee80211_
|
||||
static int tkip_encap(struct ieee80211_key *, struct sk_buff *, u_int8_t);
|
||||
static int tkip_enmic(struct ieee80211_key *, struct sk_buff *, int);
|
||||
static int tkip_decap(struct ieee80211_key *, struct sk_buff *, int);
|
||||
-static int tkip_demic(struct ieee80211_key *, struct sk_buff *, int);
|
||||
+static int tkip_demic(struct ieee80211_key *, struct sk_buff *, int, int);
|
||||
|
||||
static const struct ieee80211_cipher tkip = {
|
||||
.ic_name = "TKIP",
|
||||
@@ -339,7 +339,7 @@ tkip_decap(struct ieee80211_key *k, stru
|
||||
* Verify and strip MIC from the frame.
|
||||
*/
|
||||
static int
|
||||
-tkip_demic(struct ieee80211_key *k, struct sk_buff *skb0, int hdrlen)
|
||||
+tkip_demic(struct ieee80211_key *k, struct sk_buff *skb0, int hdrlen, int force)
|
||||
{
|
||||
struct tkip_ctx *ctx = k->wk_private;
|
||||
struct sk_buff *skb;
|
||||
@@ -355,7 +355,7 @@ tkip_demic(struct ieee80211_key *k, stru
|
||||
}
|
||||
wh = (struct ieee80211_frame *) skb0->data;
|
||||
/* NB: skb left pointing at last in chain */
|
||||
- if (k->wk_flags & IEEE80211_KEY_SWMIC) {
|
||||
+ if ((k->wk_flags & IEEE80211_KEY_SWMIC) || force) {
|
||||
struct ieee80211vap *vap = ctx->tc_vap;
|
||||
u8 mic[IEEE80211_WEP_MICLEN];
|
||||
u8 mic0[IEEE80211_WEP_MICLEN];
|
||||
--- a/net80211/ieee80211_crypto_wep.c
|
||||
+++ b/net80211/ieee80211_crypto_wep.c
|
||||
@@ -54,7 +54,7 @@ static int wep_setkey(struct ieee80211_k
|
||||
static int wep_encap(struct ieee80211_key *, struct sk_buff *, u_int8_t);
|
||||
static int wep_decap(struct ieee80211_key *, struct sk_buff *, int);
|
||||
static int wep_enmic(struct ieee80211_key *, struct sk_buff *, int);
|
||||
-static int wep_demic(struct ieee80211_key *, struct sk_buff *, int);
|
||||
+static int wep_demic(struct ieee80211_key *, struct sk_buff *, int, int);
|
||||
|
||||
static const struct ieee80211_cipher wep = {
|
||||
.ic_name = "WEP",
|
||||
@@ -244,7 +244,7 @@ wep_decap(struct ieee80211_key *k, struc
|
||||
* Verify and strip MIC from the frame.
|
||||
*/
|
||||
static int
|
||||
-wep_demic(struct ieee80211_key *k, struct sk_buff *skb, int hdrlen)
|
||||
+wep_demic(struct ieee80211_key *k, struct sk_buff *skb, int hdrlen, int force)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
--- a/net80211/ieee80211_input.c
|
||||
+++ b/net80211/ieee80211_input.c
|
||||
@@ -669,7 +669,7 @@ ieee80211_input(struct ieee80211vap * va
|
||||
* Next strip any MSDU crypto bits.
|
||||
*/
|
||||
if (key != NULL &&
|
||||
- !ieee80211_crypto_demic(vap, key, skb, hdrspace)) {
|
||||
+ !ieee80211_crypto_demic(vap, key, skb, hdrspace, 0)) {
|
||||
IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
|
||||
ni->ni_macaddr, "data", "%s", "demic error");
|
||||
IEEE80211_NODE_STAT(ni, rx_demicfail);
|
||||
@@ -4293,6 +4293,47 @@ ath_eth_type_trans(struct sk_buff *skb,
|
||||
}
|
||||
#endif
|
||||
|
||||
+/*
|
||||
+ * Process a frame w/ hw detected MIC failure.
|
||||
+ * The frame will be dropped in any case.
|
||||
+ */
|
||||
+void
|
||||
+ieee80211_check_mic(struct ieee80211_node *ni, struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211vap *vap = ni->ni_vap;
|
||||
+
|
||||
+ struct ieee80211_frame *wh;
|
||||
+ struct ieee80211_key *key;
|
||||
+ int hdrspace;
|
||||
+ struct ieee80211com *ic = vap->iv_ic;
|
||||
+
|
||||
+ if (skb->len < sizeof(struct ieee80211_frame_min)) {
|
||||
+ IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
|
||||
+ ni->ni_macaddr, NULL,
|
||||
+ "too short (1): len %u", skb->len);
|
||||
+ vap->iv_stats.is_rx_tooshort++;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ wh = (struct ieee80211_frame *)skb->data;
|
||||
+
|
||||
+ hdrspace = ieee80211_hdrspace(ic, wh);
|
||||
+ key = ieee80211_crypto_decap(ni, skb, hdrspace);
|
||||
+ if (key == NULL) {
|
||||
+ /* NB: stats+msgs handled in crypto_decap */
|
||||
+ IEEE80211_NODE_STAT(ni, rx_wepfail);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!ieee80211_crypto_demic(vap, key, skb, hdrspace, 1)) {
|
||||
+ IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
|
||||
+ ni->ni_macaddr, "data", "%s", "demic error");
|
||||
+ IEEE80211_NODE_STAT(ni, rx_demicfail);
|
||||
+ }
|
||||
+ return;
|
||||
+}
|
||||
+EXPORT_SYMBOL(ieee80211_check_mic);
|
||||
+
|
||||
#ifdef IEEE80211_DEBUG
|
||||
/*
|
||||
* Debugging support.
|
||||
--- a/net80211/ieee80211_proto.h
|
||||
+++ b/net80211/ieee80211_proto.h
|
||||
@@ -90,6 +90,7 @@ int ieee80211_iserp_rateset(struct ieee8
|
||||
void ieee80211_set11gbasicrates(struct ieee80211_rateset *, enum ieee80211_phymode);
|
||||
enum ieee80211_phymode ieee80211_get11gbasicrates(struct ieee80211_rateset *);
|
||||
void ieee80211_send_pspoll(struct ieee80211_node *);
|
||||
+void ieee80211_check_mic(struct ieee80211_node *, struct sk_buff *);
|
||||
|
||||
/*
|
||||
* Return the size of the 802.11 header for a management or data frame.
|
||||
--- a/net80211/ieee80211_linux.c
|
||||
+++ b/net80211/ieee80211_linux.c
|
||||
@@ -337,8 +337,8 @@ ieee80211_notify_replay_failure(struct i
|
||||
/* TODO: needed parameters: count, keyid, key type, src address, TSC */
|
||||
snprintf(buf, sizeof(buf), "%s(keyid=%d %scast addr=" MAC_FMT ")", tag,
|
||||
k->wk_keyix,
|
||||
- IEEE80211_IS_MULTICAST(wh->i_addr1) ? "broad" : "uni",
|
||||
- MAC_ADDR(wh->i_addr1));
|
||||
+ IEEE80211_IS_MULTICAST(wh->i_addr2) ? "broad" : "uni",
|
||||
+ MAC_ADDR(wh->i_addr2));
|
||||
memset(&wrqu, 0, sizeof(wrqu));
|
||||
wrqu.data.length = strlen(buf);
|
||||
wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
|
||||
--- a/net80211/ieee80211_output.c
|
||||
+++ b/net80211/ieee80211_output.c
|
||||
@@ -1074,13 +1074,16 @@ ieee80211_encap(struct ieee80211_node *n
|
||||
cip = (struct ieee80211_cipher *) key->wk_cipher;
|
||||
ciphdrsize = cip->ic_header;
|
||||
tailsize += (cip->ic_trailer + cip->ic_miclen);
|
||||
+
|
||||
+ /* add the 8 bytes MIC length */
|
||||
+ if (cip->ic_cipher == IEEE80211_CIPHER_TKIP)
|
||||
+ pktlen += IEEE80211_WEP_MICLEN;
|
||||
}
|
||||
|
||||
pdusize = vap->iv_fragthreshold - (hdrsize_nopad + ciphdrsize);
|
||||
fragcnt = *framecnt =
|
||||
- ((pktlen - (hdrsize_nopad + ciphdrsize)) / pdusize) +
|
||||
- (((pktlen - (hdrsize_nopad + ciphdrsize)) %
|
||||
- pdusize == 0) ? 0 : 1);
|
||||
+ ((pktlen - hdrsize_nopad) / pdusize) +
|
||||
+ (((pktlen - hdrsize_nopad) % pdusize == 0) ? 0 : 1);
|
||||
|
||||
/*
|
||||
* Allocate sk_buff for each subsequent fragment; First fragment
|
||||
--- a/net80211/ieee80211_node.c
|
||||
+++ b/net80211/ieee80211_node.c
|
||||
@@ -2264,11 +2264,13 @@ ieee80211_node_leave(struct ieee80211_no
|
||||
/* From this point onwards we can no longer find the node,
|
||||
* so no more references are generated
|
||||
*/
|
||||
- ieee80211_remove_wds_addr(nt, ni->ni_macaddr);
|
||||
- ieee80211_del_wds_node(nt, ni);
|
||||
- IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
|
||||
- node_table_leave_locked(nt, ni);
|
||||
- IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
|
||||
+ if (nt) {
|
||||
+ ieee80211_remove_wds_addr(nt, ni->ni_macaddr);
|
||||
+ ieee80211_del_wds_node(nt, ni);
|
||||
+ IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
|
||||
+ node_table_leave_locked(nt, ni);
|
||||
+ IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
|
||||
+ }
|
||||
|
||||
/*
|
||||
* If node wasn't previously associated all
|
55
net/madwifi/patches/310-noise_get.patch
Normal file
55
net/madwifi/patches/310-noise_get.patch
Normal file
@ -0,0 +1,55 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -1699,8 +1699,6 @@ ath_uapsd_processtriggers(struct ath_sof
|
||||
* get to reality. This value is used in monitor mode and by tools like
|
||||
* Wireshark and Kismet.
|
||||
*/
|
||||
- ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
|
||||
-
|
||||
ATH_RXBUF_LOCK_IRQ(sc);
|
||||
if (sc->sc_rxbufcur == NULL)
|
||||
sc->sc_rxbufcur = STAILQ_FIRST(&sc->sc_rxbuf);
|
||||
@@ -8975,6 +8973,7 @@ ath_calibrate(unsigned long arg)
|
||||
sc->sc_curchan.channel);
|
||||
sc->sc_stats.ast_per_calfail++;
|
||||
}
|
||||
+ ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
|
||||
|
||||
ath_hal_process_noisefloor(ah);
|
||||
if (isIQdone == AH_TRUE) {
|
||||
@@ -9043,6 +9042,7 @@ ath_set_channel(struct ieee80211com *ic)
|
||||
struct ath_softc *sc = dev->priv;
|
||||
|
||||
(void) ath_chan_set(sc, ic->ic_curchan);
|
||||
+ ic->ic_channoise = ath_hal_get_channel_noise(sc->sc_ah, &(sc->sc_curchan));
|
||||
/*
|
||||
* If we are returning to our bss channel then mark state
|
||||
* so the next recv'd beacon's TSF will be used to sync the
|
||||
@@ -9311,6 +9311,7 @@ ath_newstate(struct ieee80211vap *vap, e
|
||||
}
|
||||
|
||||
ath_hal_process_noisefloor(ah);
|
||||
+ ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
|
||||
/*
|
||||
* Reset rssi stats; maybe not the best place...
|
||||
*/
|
||||
--- a/net80211/ieee80211_wireless.c
|
||||
+++ b/net80211/ieee80211_wireless.c
|
||||
@@ -4358,6 +4358,7 @@ get_sta_info(void *arg, struct ieee80211
|
||||
si->isi_state = ni->ni_flags;
|
||||
si->isi_authmode = ni->ni_authmode;
|
||||
si->isi_rssi = ic->ic_node_getrssi(ni);
|
||||
+ si->isi_noise = ic->ic_channoise;
|
||||
si->isi_capinfo = ni->ni_capinfo;
|
||||
si->isi_athflags = ni->ni_ath_flags;
|
||||
si->isi_erp = ni->ni_erp;
|
||||
--- a/net80211/ieee80211_ioctl.h
|
||||
+++ b/net80211/ieee80211_ioctl.h
|
||||
@@ -311,6 +311,7 @@ struct ieee80211req_sta_info {
|
||||
u_int16_t isi_state; /* state flags */
|
||||
u_int8_t isi_authmode; /* authentication algorithm */
|
||||
u_int8_t isi_rssi;
|
||||
+ int8_t isi_noise;
|
||||
u_int16_t isi_capinfo; /* capabilities */
|
||||
u_int8_t isi_athflags; /* Atheros capabilities */
|
||||
u_int8_t isi_erp; /* ERP element */
|
11
net/madwifi/patches/311-bssid_alloc.patch
Normal file
11
net/madwifi/patches/311-bssid_alloc.patch
Normal file
@ -0,0 +1,11 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -1354,7 +1354,7 @@ ath_vap_create(struct ieee80211com *ic,
|
||||
TAILQ_FOREACH(v, &ic->ic_vaps, iv_next)
|
||||
id_mask |= (1 << ATH_GET_VAP_ID(v->iv_myaddr));
|
||||
|
||||
- for (id = 1; id < ath_maxvaps; id++) {
|
||||
+ for (id = 0; id < ath_maxvaps; id++) {
|
||||
/* get the first available slot */
|
||||
if ((id_mask & (1 << id)) == 0) {
|
||||
ATH_SET_VAP_BSSID(vap->iv_myaddr, id);
|
68
net/madwifi/patches/312-erpupdate.patch
Normal file
68
net/madwifi/patches/312-erpupdate.patch
Normal file
@ -0,0 +1,68 @@
|
||||
--- a/net80211/ieee80211_beacon.c
|
||||
+++ b/net80211/ieee80211_beacon.c
|
||||
@@ -542,10 +542,10 @@ ieee80211_beacon_update(struct ieee80211
|
||||
vap->iv_flags &= ~IEEE80211_F_XRUPDATE;
|
||||
}
|
||||
#endif
|
||||
- if ((ic->ic_flags_ext & IEEE80211_FEXT_ERPUPDATE) &&
|
||||
+ if ((vap->iv_flags_ext & IEEE80211_FEXT_ERPUPDATE) &&
|
||||
(bo->bo_erp != NULL)) {
|
||||
(void)ieee80211_add_erp(bo->bo_erp, ic);
|
||||
- ic->ic_flags_ext &= ~IEEE80211_FEXT_ERPUPDATE;
|
||||
+ vap->iv_flags_ext &= ~IEEE80211_FEXT_ERPUPDATE;
|
||||
}
|
||||
}
|
||||
/* if it is a mode change beacon for dynamic turbo case */
|
||||
--- a/net80211/ieee80211_input.c
|
||||
+++ b/net80211/ieee80211_input.c
|
||||
@@ -3431,9 +3431,12 @@ ieee80211_recv_mgmt(struct ieee80211vap
|
||||
/* Assume no ERP IE == 11b AP */
|
||||
if ((!has_erp || (has_erp && (scan.erp & IEEE80211_ERP_NON_ERP_PRESENT))) &&
|
||||
!(ic->ic_flags & IEEE80211_F_USEPROT)) {
|
||||
+ struct ieee80211vap *tmpvap;
|
||||
|
||||
ic->ic_flags |= IEEE80211_F_USEPROT;
|
||||
- ic->ic_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
|
||||
+ TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) {
|
||||
+ tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
--- a/net80211/ieee80211_node.c
|
||||
+++ b/net80211/ieee80211_node.c
|
||||
@@ -2025,8 +2025,12 @@ ieee80211_node_join_11g(struct ieee80211
|
||||
}
|
||||
|
||||
/* Update ERP element if this is first non ERP station */
|
||||
- if (ic->ic_nonerpsta == 1)
|
||||
- ic->ic_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
|
||||
+ if (ic->ic_nonerpsta == 1) {
|
||||
+ struct ieee80211vap *tmpvap;
|
||||
+ TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) {
|
||||
+ tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
|
||||
+ }
|
||||
+ }
|
||||
} else
|
||||
ni->ni_flags |= IEEE80211_NODE_ERP;
|
||||
}
|
||||
@@ -2229,6 +2233,8 @@ ieee80211_node_leave_11g(struct ieee8021
|
||||
IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,
|
||||
"non-ERP station leaves, count now %d", ic->ic_nonerpsta);
|
||||
if (ic->ic_nonerpsta == 0) {
|
||||
+ struct ieee80211vap *tmpvap;
|
||||
+
|
||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC,
|
||||
"%s: disable use of protection\n", __func__);
|
||||
ic->ic_flags &= ~IEEE80211_F_USEPROT;
|
||||
@@ -2240,7 +2246,9 @@ ieee80211_node_leave_11g(struct ieee8021
|
||||
ic->ic_flags |= IEEE80211_F_SHPREAMBLE;
|
||||
ic->ic_flags &= ~IEEE80211_F_USEBARKER;
|
||||
}
|
||||
- ic->ic_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
|
||||
+ TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) {
|
||||
+ tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
13
net/madwifi/patches/317-bmask.patch
Normal file
13
net/madwifi/patches/317-bmask.patch
Normal file
@ -0,0 +1,13 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -8689,6 +8689,10 @@ ath_startrecv(struct ath_softc *sc)
|
||||
|
||||
sc->sc_rxbufcur = NULL;
|
||||
|
||||
+ /* configure bssid mask */
|
||||
+ if (sc->sc_hasbmask)
|
||||
+ ath_hal_setbssidmask(ah, sc->sc_bssidmask);
|
||||
+
|
||||
bf = STAILQ_FIRST(&sc->sc_rxbuf);
|
||||
ath_hal_putrxbuf(ah, bf->bf_daddr);
|
||||
ath_hal_rxena(ah); /* enable recv descriptors */
|
38
net/madwifi/patches/323-dfs_optional.patch
Normal file
38
net/madwifi/patches/323-dfs_optional.patch
Normal file
@ -0,0 +1,38 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -1778,17 +1778,14 @@ ath_uapsd_processtriggers(struct ath_sof
|
||||
* may have occurred in the intervening timeframe. */
|
||||
bf->bf_channoise = ic->ic_channoise;
|
||||
|
||||
- if (rs->rs_status) {
|
||||
- if ((HAL_RXERR_PHY == rs->rs_status) &&
|
||||
- (HAL_PHYERR_RADAR ==
|
||||
- (rs->rs_phyerr & 0x1f)) &&
|
||||
- (0 == (bf->bf_status &
|
||||
- ATH_BUFSTATUS_RADAR_DONE))) {
|
||||
- check_for_radar = 1;
|
||||
- }
|
||||
- /* Skip past the error now */
|
||||
+ if ((HAL_RXERR_PHY == rs->rs_status) &&
|
||||
+ (HAL_PHYERR_RADAR == (rs->rs_phyerr & 0x1f)) &&
|
||||
+ (0 == (bf->bf_status & ATH_BUFSTATUS_RADAR_DONE)) &&
|
||||
+ (ic->ic_flags & IEEE80211_F_DOTH))
|
||||
+ check_for_radar = 1;
|
||||
+
|
||||
+ if (rs->rs_status) /* Skip past the error now */
|
||||
continue;
|
||||
- }
|
||||
|
||||
/* Prepare wireless header for examination */
|
||||
bus_dma_sync_single(sc->sc_bdev, bf->bf_skbaddr,
|
||||
--- a/ath/if_ath_radar.c
|
||||
+++ b/ath/if_ath_radar.c
|
||||
@@ -265,7 +265,7 @@ int ath_radar_update(struct ath_softc *s
|
||||
unsigned int new_rxfilt = old_rxfilt;
|
||||
|
||||
ath_hal_intrset(ah, old_ier & ~HAL_INT_GLOBAL);
|
||||
- if (required) {
|
||||
+ if ((required) && (ic->ic_flags & IEEE80211_F_DOTH)) {
|
||||
new_radar |= AR5K_PHY_RADAR_ENABLE;
|
||||
new_filter |= AR5K_AR5212_PHY_ERR_FIL_RADAR;
|
||||
new_rxfilt |= (HAL_RX_FILTER_PHYERR |
|
19
net/madwifi/patches/324-alignment.patch
Normal file
19
net/madwifi/patches/324-alignment.patch
Normal file
@ -0,0 +1,19 @@
|
||||
--- a/net80211/ieee80211_input.c
|
||||
+++ b/net80211/ieee80211_input.c
|
||||
@@ -1275,14 +1275,8 @@ ieee80211_decap(struct ieee80211vap *vap
|
||||
eh->ether_type = ether_type;
|
||||
|
||||
if (!ALIGNED_POINTER(skb->data + sizeof(*eh), u_int32_t)) {
|
||||
- struct sk_buff *tskb;
|
||||
-
|
||||
- /* XXX: does this always work? */
|
||||
- tskb = skb_copy(skb, GFP_ATOMIC);
|
||||
- if (tskb)
|
||||
- ieee80211_skb_copy_noderef(skb, tskb);
|
||||
- ieee80211_dev_kfree_skb(&skb);
|
||||
- skb = tskb;
|
||||
+ memmove(skb->data - 2, skb->data, skb->len);
|
||||
+ skb->data -= 2;
|
||||
}
|
||||
return skb;
|
||||
}
|
28
net/madwifi/patches/325-channel_spam.patch
Normal file
28
net/madwifi/patches/325-channel_spam.patch
Normal file
@ -0,0 +1,28 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -9792,7 +9792,9 @@ ath_getchannels(struct net_device *dev,
|
||||
/*
|
||||
* Convert HAL channels to ieee80211 ones.
|
||||
*/
|
||||
+#ifdef AR_DEBUG
|
||||
IPRINTF(sc, "HAL returned %d channels.\n", nchan);
|
||||
+#endif
|
||||
for (i = 0; i < nchan; i++) {
|
||||
HAL_CHANNEL *c = &chans[i];
|
||||
struct ieee80211_channel *ichan = &ic->ic_channels[i];
|
||||
@@ -9819,6 +9821,7 @@ ath_getchannels(struct net_device *dev,
|
||||
ic->ic_chan_non_occupy[i].tv_sec = 0;
|
||||
ic->ic_chan_non_occupy[i].tv_usec = 0;
|
||||
|
||||
+#ifdef AR_DEBUG
|
||||
IPRINTF(sc, "Channel %3d (%4d MHz) Max Tx Power %d dBm%s "
|
||||
"[%d hw %d reg] Flags%s%s%s%s%s%s%s%s%s%s%s%s%"
|
||||
"s%s%s%s%s%s%s%s%s%s%s%s\n",
|
||||
@@ -9907,6 +9910,7 @@ ath_getchannels(struct net_device *dev,
|
||||
(c->privFlags & 0x0080 ?
|
||||
" PF & (1 << 7)" : "")
|
||||
);
|
||||
+#endif
|
||||
}
|
||||
ic->ic_nchans = nchan;
|
||||
kfree(chans);
|
40
net/madwifi/patches/327-queue.patch
Normal file
40
net/madwifi/patches/327-queue.patch
Normal file
@ -0,0 +1,40 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -8438,8 +8438,6 @@ process_tx_again:
|
||||
ath_hal_intrset(sc->sc_ah, sc->sc_imask);
|
||||
local_irq_restore(flags);
|
||||
|
||||
- netif_wake_queue(dev);
|
||||
-
|
||||
if (sc->sc_softled)
|
||||
ath_led_event(sc, ATH_LED_TX);
|
||||
}
|
||||
@@ -8486,8 +8484,6 @@ process_tx_again:
|
||||
ath_hal_intrset(sc->sc_ah, sc->sc_imask);
|
||||
local_irq_restore(flags);
|
||||
|
||||
- netif_wake_queue(dev);
|
||||
-
|
||||
if (sc->sc_softled)
|
||||
ath_led_event(sc, ATH_LED_TX);
|
||||
}
|
||||
@@ -8520,8 +8516,6 @@ process_tx_again:
|
||||
ath_hal_intrset(sc->sc_ah, sc->sc_imask);
|
||||
local_irq_restore(flags);
|
||||
|
||||
- netif_wake_queue(dev);
|
||||
-
|
||||
if (sc->sc_softled)
|
||||
ath_led_event(sc, ATH_LED_TX);
|
||||
}
|
||||
--- a/net80211/ieee80211_input.c
|
||||
+++ b/net80211/ieee80211_input.c
|
||||
@@ -1132,7 +1132,7 @@ ieee80211_deliver_data(struct ieee80211_
|
||||
(vap->iv_flags & IEEE80211_F_NOBRIDGE) == 0) {
|
||||
struct sk_buff *skb1 = NULL;
|
||||
|
||||
- if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
|
||||
+ if (ETHER_IS_MULTICAST(eh->ether_dhost) && !netif_queue_stopped(dev)) {
|
||||
/* Create a SKB for the BSS to send out. */
|
||||
skb1 = skb_copy(skb, GFP_ATOMIC);
|
||||
if (skb1)
|
166
net/madwifi/patches/330-beaconcal.patch
Normal file
166
net/madwifi/patches/330-beaconcal.patch
Normal file
@ -0,0 +1,166 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -397,6 +397,7 @@ static int countrycode = -1;
|
||||
static int maxvaps = -1;
|
||||
static int outdoor = -1;
|
||||
static int xchanmode = -1;
|
||||
+static int beacon_cal = 1;
|
||||
|
||||
static const char *hal_status_desc[] = {
|
||||
"No error",
|
||||
@@ -422,6 +423,7 @@ static struct notifier_block ath_event_b
|
||||
};
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,52))
|
||||
+MODULE_PARM(beacon_cal, "i");
|
||||
MODULE_PARM(countrycode, "i");
|
||||
MODULE_PARM(maxvaps, "i");
|
||||
MODULE_PARM(outdoor, "i");
|
||||
@@ -434,6 +436,7 @@ MODULE_PARM(autocreate, "s");
|
||||
MODULE_PARM(ratectl, "s");
|
||||
#else
|
||||
#include <linux/moduleparam.h>
|
||||
+module_param(beacon_cal, int, 0600);
|
||||
module_param(countrycode, int, 0600);
|
||||
module_param(maxvaps, int, 0600);
|
||||
module_param(outdoor, int, 0600);
|
||||
@@ -2600,7 +2603,8 @@ ath_stop_locked(struct net_device *dev)
|
||||
}
|
||||
if (!sc->sc_invalid) {
|
||||
del_timer_sync(&sc->sc_dfs_cac_timer);
|
||||
- del_timer_sync(&sc->sc_cal_ch);
|
||||
+ if (!sc->sc_beacon_cal)
|
||||
+ del_timer_sync(&sc->sc_cal_ch);
|
||||
}
|
||||
ath_draintxq(sc);
|
||||
if (!sc->sc_invalid) {
|
||||
@@ -2617,6 +2621,20 @@ ath_stop_locked(struct net_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void ath_set_beacon_cal(struct ath_softc *sc, int val)
|
||||
+{
|
||||
+ if (sc->sc_beacon_cal == !!val)
|
||||
+ return;
|
||||
+
|
||||
+ if (val) {
|
||||
+ del_timer_sync(&sc->sc_cal_ch);
|
||||
+ } else {
|
||||
+ sc->sc_cal_ch.expires = jiffies + (ath_calinterval * HZ);
|
||||
+ add_timer(&sc->sc_cal_ch);
|
||||
+ }
|
||||
+ sc->sc_beacon_cal = !!val && beacon_cal;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Stop the device, grabbing the top-level lock to protect
|
||||
* against concurrent entry through ath_init (which can happen
|
||||
@@ -2742,6 +2760,12 @@ ath_reset(struct net_device *dev)
|
||||
HAL_STATUS status;
|
||||
|
||||
/*
|
||||
+ * XXX: starting the calibration too early seems to lead to
|
||||
+ * problems with the beacons.
|
||||
+ */
|
||||
+ sc->sc_lastcal = jiffies;
|
||||
+
|
||||
+ /*
|
||||
* Convert to a HAL channel description with the flags
|
||||
* constrained to reflect the current operating mode.
|
||||
*/
|
||||
@@ -5154,6 +5178,10 @@ ath_beacon_send(struct ath_softc *sc, in
|
||||
"Invoking ath_hal_txstart with sc_bhalq: %d\n",
|
||||
sc->sc_bhalq);
|
||||
ath_hal_txstart(ah, sc->sc_bhalq);
|
||||
+ if (sc->sc_beacon_cal && (jiffies > sc->sc_lastcal + (ath_calinterval * HZ))) {
|
||||
+ sc->sc_cal_ch.expires = jiffies + msecs_to_jiffies(10);
|
||||
+ add_timer(&sc->sc_cal_ch);
|
||||
+ }
|
||||
|
||||
sc->sc_stats.ast_be_xmit++; /* XXX per-VAP? */
|
||||
}
|
||||
@@ -5403,6 +5431,7 @@ ath_beacon_config(struct ath_softc *sc,
|
||||
ath_hal_beacontimers(ah, &bs);
|
||||
sc->sc_imask |= HAL_INT_BMISS;
|
||||
ath_hal_intrset(ah, sc->sc_imask);
|
||||
+ ath_set_beacon_cal(sc, 0);
|
||||
} else {
|
||||
ath_hal_intrset(ah, 0);
|
||||
if (reset_tsf)
|
||||
@@ -5414,8 +5443,11 @@ ath_beacon_config(struct ath_softc *sc,
|
||||
*/
|
||||
intval |= HAL_BEACON_ENA;
|
||||
sc->sc_imask |= HAL_INT_SWBA;
|
||||
+ ath_set_beacon_cal(sc, 1);
|
||||
ath_beaconq_config(sc);
|
||||
- }
|
||||
+ } else
|
||||
+ ath_set_beacon_cal(sc, 0);
|
||||
+
|
||||
#ifdef ATH_SUPERG_DYNTURBO
|
||||
ath_beacon_dturbo_config(vap, intval &
|
||||
~(HAL_BEACON_RESET_TSF | HAL_BEACON_ENA));
|
||||
@@ -8879,6 +8911,9 @@ ath_chan_set(struct ath_softc *sc, struc
|
||||
/* Enter DFS wait period */
|
||||
mod_timer(&sc->sc_dfs_cac_timer,
|
||||
jiffies + (sc->sc_dfs_cac_period * HZ));
|
||||
+
|
||||
+ /* This is a good time to start a calibration */
|
||||
+ ath_set_beacon_cal(sc, 1);
|
||||
}
|
||||
/*
|
||||
* re configure beacons when it is a turbo mode switch.
|
||||
@@ -8988,8 +9023,11 @@ ath_calibrate(unsigned long arg)
|
||||
sc->sc_curchan.channel, sc->sc_curchan.channelFlags,
|
||||
isIQdone ? "done" : "not done");
|
||||
|
||||
- sc->sc_cal_ch.expires = jiffies + (ath_calinterval * HZ);
|
||||
- add_timer(&sc->sc_cal_ch);
|
||||
+ sc->sc_lastcal = jiffies;
|
||||
+ if (!sc->sc_beacon_cal) {
|
||||
+ sc->sc_cal_ch.expires = jiffies + (ath_calinterval * HZ);
|
||||
+ add_timer(&sc->sc_cal_ch);
|
||||
+ }
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -9096,7 +9134,8 @@ ath_newstate(struct ieee80211vap *vap, e
|
||||
ieee80211_state_name[vap->iv_state],
|
||||
ieee80211_state_name[nstate]);
|
||||
|
||||
- del_timer(&sc->sc_cal_ch); /* periodic calibration timer */
|
||||
+ if (!sc->sc_beacon_cal)
|
||||
+ del_timer(&sc->sc_cal_ch); /* periodic calibration timer */
|
||||
|
||||
ath_hal_setledstate(ah, leds[nstate]); /* set LED */
|
||||
netif_stop_queue(dev); /* before we do anything else */
|
||||
@@ -9321,7 +9360,8 @@ ath_newstate(struct ieee80211vap *vap, e
|
||||
"VAP -> DFSWAIT_PENDING \n");
|
||||
/* start calibration timer with a really small value
|
||||
* 1/10 sec */
|
||||
- mod_timer(&sc->sc_cal_ch, jiffies + (HZ/10));
|
||||
+ if (!sc->sc_beacon_cal)
|
||||
+ mod_timer(&sc->sc_cal_ch, jiffies + (HZ/10));
|
||||
/* wake the receiver */
|
||||
netif_wake_queue(dev);
|
||||
/* don't do the other usual stuff... */
|
||||
@@ -9364,7 +9404,7 @@ done:
|
||||
error = avp->av_newstate(vap, nstate, arg);
|
||||
|
||||
/* Finally, start any timers. */
|
||||
- if (nstate == IEEE80211_S_RUN) {
|
||||
+ if (nstate == IEEE80211_S_RUN && !sc->sc_beacon_cal) {
|
||||
/* start periodic recalibration timer */
|
||||
mod_timer(&sc->sc_cal_ch, jiffies + (ath_calinterval * HZ));
|
||||
}
|
||||
--- a/ath/if_athvar.h
|
||||
+++ b/ath/if_athvar.h
|
||||
@@ -778,6 +778,8 @@ struct ath_softc {
|
||||
struct ieee80211vap **sc_bslot; /* beacon xmit slots */
|
||||
int sc_bnext; /* next slot for beacon xmit */
|
||||
|
||||
+ int sc_beacon_cal; /* use beacon timer for calibration */
|
||||
+ u_int64_t sc_lastcal; /* last time the calibration was performed */
|
||||
struct timer_list sc_cal_ch; /* calibration timer */
|
||||
HAL_NODE_STATS sc_halstats; /* station-mode rssi stats */
|
||||
|
36
net/madwifi/patches/331-memory_alloc.patch
Normal file
36
net/madwifi/patches/331-memory_alloc.patch
Normal file
@ -0,0 +1,36 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -3320,17 +3320,18 @@ ath_hardstart(struct sk_buff *skb, struc
|
||||
* without affecting any other bridge ports. */
|
||||
if (skb_cloned(skb)) {
|
||||
/* Remember the original SKB so we can free up our references */
|
||||
- struct sk_buff *skb_orig = skb;
|
||||
- skb = skb_copy(skb, GFP_ATOMIC);
|
||||
- if (skb == NULL) {
|
||||
+ struct sk_buff *skb_new;
|
||||
+ skb_new = skb_copy(skb, GFP_ATOMIC);
|
||||
+ if (skb_new == NULL) {
|
||||
DPRINTF(sc, ATH_DEBUG_XMIT,
|
||||
"Dropping; skb_copy failure.\n");
|
||||
/* No free RAM, do not requeue! */
|
||||
goto hardstart_fail;
|
||||
}
|
||||
- ieee80211_skb_copy_noderef(skb_orig, skb);
|
||||
- ieee80211_dev_kfree_skb(&skb_orig);
|
||||
- }
|
||||
+ ieee80211_skb_copy_noderef(skb, skb_new);
|
||||
+ ieee80211_dev_kfree_skb(&skb);
|
||||
+ skb = skb_new;
|
||||
+ }
|
||||
eh = (struct ether_header *)skb->data;
|
||||
|
||||
#ifdef ATH_SUPERG_FF
|
||||
@@ -3601,6 +3602,8 @@ ath_mgtstart(struct ieee80211com *ic, st
|
||||
sc->sc_stats.ast_tx_mgmt++;
|
||||
return 0;
|
||||
bad:
|
||||
+ if (skb)
|
||||
+ ieee80211_dev_kfree_skb(&skb);
|
||||
ath_return_txbuf(sc, &bf);
|
||||
return error;
|
||||
}
|
11
net/madwifi/patches/332-reset_beacons.patch
Normal file
11
net/madwifi/patches/332-reset_beacons.patch
Normal file
@ -0,0 +1,11 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -8922,7 +8922,7 @@ ath_chan_set(struct ath_softc *sc, struc
|
||||
* re configure beacons when it is a turbo mode switch.
|
||||
* HW seems to turn off beacons during turbo mode switch.
|
||||
*/
|
||||
- if (sc->sc_beacons && tswitch && !sc->sc_dfs_cac)
|
||||
+ if (sc->sc_beacons && !sc->sc_dfs_cac)
|
||||
ath_beacon_config(sc, NULL);
|
||||
/*
|
||||
* Re-enable interrupts.
|
15
net/madwifi/patches/333-apscan_mode.patch
Normal file
15
net/madwifi/patches/333-apscan_mode.patch
Normal file
@ -0,0 +1,15 @@
|
||||
--- a/net80211/ieee80211_scan_ap.c
|
||||
+++ b/net80211/ieee80211_scan_ap.c
|
||||
@@ -783,12 +783,6 @@ pick_channel(struct ieee80211_scan_state
|
||||
/* break the loop as the subsequent chans won't be
|
||||
* better */
|
||||
break;
|
||||
-
|
||||
- if (!IEEE80211_ARE_CHANS_SAME_MODE(c->chan,
|
||||
- ic->ic_bsschan))
|
||||
- /* break the loop as the subsequent chans won't be
|
||||
- * better */
|
||||
- break;
|
||||
}
|
||||
|
||||
if (sta_assoc != 0) {
|
12
net/madwifi/patches/334-input.patch
Normal file
12
net/madwifi/patches/334-input.patch
Normal file
@ -0,0 +1,12 @@
|
||||
--- a/net80211/ieee80211_input.c
|
||||
+++ b/net80211/ieee80211_input.c
|
||||
@@ -950,6 +950,9 @@ ieee80211_input_all(struct ieee80211com
|
||||
TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
|
||||
struct sk_buff *skb1;
|
||||
|
||||
+ if ((vap->iv_dev->flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
|
||||
+ continue;
|
||||
+
|
||||
if (TAILQ_NEXT(vap, iv_next) != NULL) {
|
||||
skb1 = skb_copy(skb, GFP_ATOMIC);
|
||||
if (skb1 == NULL) {
|
98
net/madwifi/patches/340-maxrate.patch
Normal file
98
net/madwifi/patches/340-maxrate.patch
Normal file
@ -0,0 +1,98 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -1307,6 +1307,7 @@ ath_vap_create(struct ieee80211com *ic,
|
||||
vap->iv_key_set = ath_key_set;
|
||||
vap->iv_key_update_begin = ath_key_update_begin;
|
||||
vap->iv_key_update_end = ath_key_update_end;
|
||||
+ vap->iv_maxrateindex = 0;
|
||||
if (sc->sc_default_ieee80211_debug) {
|
||||
/* User specified defaults for new VAPs were provided, so
|
||||
* use those (only). */
|
||||
--- a/ath_rate/minstrel/minstrel.c
|
||||
+++ b/ath_rate/minstrel/minstrel.c
|
||||
@@ -622,8 +622,12 @@ ath_rate_ctl_reset(struct ath_softc *sc,
|
||||
return;
|
||||
}
|
||||
sn->static_rate_ndx = -1;
|
||||
+ if (vap->iv_maxrateindex == 0 || ni->ni_rates.rs_nrates <= 0
|
||||
+ || vap->iv_maxrateindex > ni->ni_rates.rs_nrates)
|
||||
+ sn->num_rates = ni->ni_rates.rs_nrates;
|
||||
+ else
|
||||
+ sn->num_rates = vap->iv_maxrateindex;
|
||||
|
||||
- sn->num_rates = ni->ni_rates.rs_nrates;
|
||||
for (x = 0; x < ni->ni_rates.rs_nrates; x++) {
|
||||
sn->rs_rateattempts [x] = 0;
|
||||
sn->rs_thisprob [x] = 0;
|
||||
--- a/ath_rate/sample/sample.c
|
||||
+++ b/ath_rate/sample/sample.c
|
||||
@@ -835,7 +835,12 @@ ath_rate_ctl_reset(struct ath_softc *sc,
|
||||
}
|
||||
sn->static_rate_ndx = -1;
|
||||
|
||||
- sn->num_rates = ni->ni_rates.rs_nrates;
|
||||
+ if (vap->iv_maxrateindex == 0 || ni->ni_rates.rs_nrates <= 0
|
||||
+ || vap->iv_maxrateindex > ni->ni_rates.rs_nrates)
|
||||
+ sn->num_rates = ni->ni_rates.rs_nrates;
|
||||
+ else
|
||||
+ sn->num_rates = vap->iv_maxrateindex;
|
||||
+
|
||||
for (x = 0; x < ni->ni_rates.rs_nrates; x++) {
|
||||
sn->rates[x].rate = ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL;
|
||||
sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate];
|
||||
--- a/net80211/ieee80211_ioctl.h
|
||||
+++ b/net80211/ieee80211_ioctl.h
|
||||
@@ -641,6 +641,7 @@ enum {
|
||||
FCC requires 30m, so that is the default. */
|
||||
IEEE80211_PARAM_BEACON_MISS_THRESH = 73, /* Beacon miss threshold (in beacons) */
|
||||
IEEE80211_PARAM_BEACON_MISS_THRESH_MS = 74, /* Beacon miss threshold (in ms) */
|
||||
+ IEEE80211_PARAM_MAXRATE = 75, /* Maximum rate (by table index) */
|
||||
};
|
||||
|
||||
#define SIOCG80211STATS (SIOCDEVPRIVATE+2)
|
||||
--- a/net80211/ieee80211_var.h
|
||||
+++ b/net80211/ieee80211_var.h
|
||||
@@ -281,6 +281,7 @@ struct ieee80211vap {
|
||||
struct ieee80211_spy iv_spy; /* IWSPY support */
|
||||
struct ieee80211_app_ie app_ie[IEEE80211_APPIE_NUM_OF_FRAME]; /* app-specified IEs by frame type */
|
||||
u_int32_t app_filter; /* filters which management frames are forwarded to app */
|
||||
+ u_int iv_maxrateindex;
|
||||
};
|
||||
|
||||
/* Debug functions need the defintion of struct ieee80211vap because iv_debug
|
||||
--- a/net80211/ieee80211_wireless.c
|
||||
+++ b/net80211/ieee80211_wireless.c
|
||||
@@ -2839,6 +2839,12 @@ ieee80211_ioctl_setparam(struct net_devi
|
||||
else
|
||||
ic->ic_flags_ext &= ~IEEE80211_FEXT_MARKDFS;
|
||||
break;
|
||||
+ case IEEE80211_PARAM_MAXRATE:
|
||||
+ if (value > 0)
|
||||
+ vap->iv_maxrateindex = value;
|
||||
+ else
|
||||
+ vap->iv_maxrateindex = 0;
|
||||
+ break;
|
||||
#ifdef ATH_REVERSE_ENGINEERING
|
||||
case IEEE80211_PARAM_DUMPREGS:
|
||||
ieee80211_dump_registers(dev, info, w, extra);
|
||||
@@ -3174,6 +3180,9 @@ ieee80211_ioctl_getparam(struct net_devi
|
||||
else
|
||||
param[0] = 0;
|
||||
break;
|
||||
+ case IEEE80211_PARAM_MAXRATE:
|
||||
+ param[0] = vap->iv_maxrateindex;
|
||||
+ break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@@ -5610,6 +5619,10 @@ static const struct iw_priv_args ieee802
|
||||
0, IW_PRIV_TYPE_APPIEBUF, "getiebuf" },
|
||||
{ IEEE80211_IOCTL_FILTERFRAME,
|
||||
IW_PRIV_TYPE_FILTER , 0, "setfilter" },
|
||||
+ {IEEE80211_PARAM_MAXRATE,
|
||||
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "maxrate"},
|
||||
+ {IEEE80211_PARAM_MAXRATE,
|
||||
+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_maxrate"},
|
||||
|
||||
#ifdef ATH_REVERSE_ENGINEERING
|
||||
/*
|
114
net/madwifi/patches/341-minrate.patch
Normal file
114
net/madwifi/patches/341-minrate.patch
Normal file
@ -0,0 +1,114 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -1308,6 +1308,7 @@ ath_vap_create(struct ieee80211com *ic,
|
||||
vap->iv_key_update_begin = ath_key_update_begin;
|
||||
vap->iv_key_update_end = ath_key_update_end;
|
||||
vap->iv_maxrateindex = 0;
|
||||
+ vap->iv_minrateindex = 0;
|
||||
if (sc->sc_default_ieee80211_debug) {
|
||||
/* User specified defaults for new VAPs were provided, so
|
||||
* use those (only). */
|
||||
--- a/ath_rate/minstrel/minstrel.c
|
||||
+++ b/ath_rate/minstrel/minstrel.c
|
||||
@@ -638,9 +638,15 @@ ath_rate_ctl_reset(struct ath_softc *sc,
|
||||
sn->rs_succ_hist [x] = 0;
|
||||
sn->rs_att_hist [x] = 0;
|
||||
sn->rs_this_tp [x] = 0;
|
||||
-
|
||||
+ if (vap->iv_minrateindex && vap->iv_minrateindex<ni->ni_rates.rs_nrates)
|
||||
+ {
|
||||
+ int idx = vap->iv_minrateindex;
|
||||
+ sn->rates[x].rate = ni->ni_rates.rs_rates[idx] & IEEE80211_RATE_VAL;
|
||||
+ sn->rates[x].rix = sc->sc_rixmap[sn->rates[idx].rate];
|
||||
+ }else{
|
||||
sn->rates[x].rate = ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL;
|
||||
sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate];
|
||||
+ }
|
||||
if (sn->rates[x].rix == 0xff) {
|
||||
DPRINTF(sc, "%s: %s ignore bogus rix at %d\n",
|
||||
dev_info, __func__, x);
|
||||
@@ -649,7 +655,7 @@ ath_rate_ctl_reset(struct ath_softc *sc,
|
||||
sn->rates[x].rateCode = rt->info[sn->rates[x].rix].rateCode;
|
||||
sn->rates[x].shortPreambleRateCode =
|
||||
rt->info[sn->rates[x].rix].rateCode |
|
||||
- rt->info[sn->rates[x].rix].shortPreamble;
|
||||
+ rt->info[sn->rates[x].rix].shortPreamble;
|
||||
}
|
||||
|
||||
ath_fill_sample_table(sn);
|
||||
--- a/ath_rate/sample/sample.c
|
||||
+++ b/ath_rate/sample/sample.c
|
||||
@@ -842,8 +842,15 @@ ath_rate_ctl_reset(struct ath_softc *sc,
|
||||
sn->num_rates = vap->iv_maxrateindex;
|
||||
|
||||
for (x = 0; x < ni->ni_rates.rs_nrates; x++) {
|
||||
- sn->rates[x].rate = ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL;
|
||||
- sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate];
|
||||
+ if (vap->iv_minrateindex && vap->iv_minrateindex<ni->ni_rates.rs_nrates)
|
||||
+ {
|
||||
+ int idx = vap->iv_minrateindex;
|
||||
+ sn->rates[x].rate = ni->ni_rates.rs_rates[idx] & IEEE80211_RATE_VAL;
|
||||
+ sn->rates[x].rix = sc->sc_rixmap[sn->rates[idx].rate];
|
||||
+ }else{
|
||||
+ sn->rates[x].rate = ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL;
|
||||
+ sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate];
|
||||
+ }
|
||||
if (sn->rates[x].rix == 0xff) {
|
||||
DPRINTF(sc, ATH_DEBUG_RATE, "%s: %s ignore bogus rix at %u\n",
|
||||
dev_info, __func__, x);
|
||||
--- a/net80211/ieee80211_ioctl.h
|
||||
+++ b/net80211/ieee80211_ioctl.h
|
||||
@@ -642,6 +642,7 @@ enum {
|
||||
IEEE80211_PARAM_BEACON_MISS_THRESH = 73, /* Beacon miss threshold (in beacons) */
|
||||
IEEE80211_PARAM_BEACON_MISS_THRESH_MS = 74, /* Beacon miss threshold (in ms) */
|
||||
IEEE80211_PARAM_MAXRATE = 75, /* Maximum rate (by table index) */
|
||||
+ IEEE80211_PARAM_MINRATE = 76, /* Minimum rate (by table index) */
|
||||
};
|
||||
|
||||
#define SIOCG80211STATS (SIOCDEVPRIVATE+2)
|
||||
--- a/net80211/ieee80211_var.h
|
||||
+++ b/net80211/ieee80211_var.h
|
||||
@@ -282,6 +282,7 @@ struct ieee80211vap {
|
||||
struct ieee80211_app_ie app_ie[IEEE80211_APPIE_NUM_OF_FRAME]; /* app-specified IEs by frame type */
|
||||
u_int32_t app_filter; /* filters which management frames are forwarded to app */
|
||||
u_int iv_maxrateindex;
|
||||
+ u_int iv_minrateindex;
|
||||
};
|
||||
|
||||
/* Debug functions need the defintion of struct ieee80211vap because iv_debug
|
||||
--- a/net80211/ieee80211_wireless.c
|
||||
+++ b/net80211/ieee80211_wireless.c
|
||||
@@ -2845,6 +2845,12 @@ ieee80211_ioctl_setparam(struct net_devi
|
||||
else
|
||||
vap->iv_maxrateindex = 0;
|
||||
break;
|
||||
+ case IEEE80211_PARAM_MINRATE:
|
||||
+ if (value > 0)
|
||||
+ vap->iv_minrateindex = value;
|
||||
+ else
|
||||
+ vap->iv_minrateindex = 0;
|
||||
+ break;
|
||||
#ifdef ATH_REVERSE_ENGINEERING
|
||||
case IEEE80211_PARAM_DUMPREGS:
|
||||
ieee80211_dump_registers(dev, info, w, extra);
|
||||
@@ -3183,6 +3189,9 @@ ieee80211_ioctl_getparam(struct net_devi
|
||||
case IEEE80211_PARAM_MAXRATE:
|
||||
param[0] = vap->iv_maxrateindex;
|
||||
break;
|
||||
+ case IEEE80211_PARAM_MINRATE:
|
||||
+ param[0] = vap->iv_minrateindex;
|
||||
+ break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@@ -5623,6 +5632,10 @@ static const struct iw_priv_args ieee802
|
||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "maxrate"},
|
||||
{IEEE80211_PARAM_MAXRATE,
|
||||
0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_maxrate"},
|
||||
+ {IEEE80211_PARAM_MINRATE,
|
||||
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "minrate"},
|
||||
+ {IEEE80211_PARAM_MINRATE,
|
||||
+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_minrate"},
|
||||
|
||||
#ifdef ATH_REVERSE_ENGINEERING
|
||||
/*
|
263
net/madwifi/patches/342-performance.patch
Normal file
263
net/madwifi/patches/342-performance.patch
Normal file
@ -0,0 +1,263 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -3239,7 +3239,6 @@ ath_hardstart(struct sk_buff *skb, struc
|
||||
struct ath_softc *sc = dev->priv;
|
||||
struct ieee80211_node *ni = NULL;
|
||||
struct ath_buf *bf = NULL;
|
||||
- struct ether_header *eh;
|
||||
ath_bufhead bf_head;
|
||||
struct ath_buf *tbf, *tempbf;
|
||||
struct sk_buff *tskb;
|
||||
@@ -3251,6 +3250,7 @@ ath_hardstart(struct sk_buff *skb, struc
|
||||
*/
|
||||
int requeue = 0;
|
||||
#ifdef ATH_SUPERG_FF
|
||||
+ struct ether_header *eh;
|
||||
unsigned int pktlen;
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
struct ath_node *an;
|
||||
@@ -3316,27 +3316,9 @@ ath_hardstart(struct sk_buff *skb, struc
|
||||
requeue = 1;
|
||||
goto hardstart_fail;
|
||||
}
|
||||
-#endif
|
||||
|
||||
- /* If the skb data is shared, we will copy it so we can strip padding
|
||||
- * without affecting any other bridge ports. */
|
||||
- if (skb_cloned(skb)) {
|
||||
- /* Remember the original SKB so we can free up our references */
|
||||
- struct sk_buff *skb_new;
|
||||
- skb_new = skb_copy(skb, GFP_ATOMIC);
|
||||
- if (skb_new == NULL) {
|
||||
- DPRINTF(sc, ATH_DEBUG_XMIT,
|
||||
- "Dropping; skb_copy failure.\n");
|
||||
- /* No free RAM, do not requeue! */
|
||||
- goto hardstart_fail;
|
||||
- }
|
||||
- ieee80211_skb_copy_noderef(skb, skb_new);
|
||||
- ieee80211_dev_kfree_skb(&skb);
|
||||
- skb = skb_new;
|
||||
- }
|
||||
eh = (struct ether_header *)skb->data;
|
||||
|
||||
-#ifdef ATH_SUPERG_FF
|
||||
/* NB: use this lock to protect an->an_tx_ffbuf (and txq->axq_stageq)
|
||||
* in athff_can_aggregate() call too. */
|
||||
ATH_TXQ_LOCK_IRQ(txq);
|
||||
--- a/net80211/ieee80211_output.c
|
||||
+++ b/net80211/ieee80211_output.c
|
||||
@@ -283,7 +283,7 @@ ieee80211_hardstart(struct sk_buff *skb,
|
||||
* normal vap. */
|
||||
if (vap->iv_xrvap && (ni == vap->iv_bss) &&
|
||||
vap->iv_xrvap->iv_sta_assoc) {
|
||||
- struct sk_buff *skb1 = skb_copy(skb, GFP_ATOMIC);
|
||||
+ struct sk_buff *skb1 = skb_clone(skb, GFP_ATOMIC);
|
||||
if (skb1) {
|
||||
memset(SKB_CB(skb1), 0, sizeof(struct ieee80211_cb));
|
||||
#ifdef IEEE80211_DEBUG_REFCNT
|
||||
@@ -566,7 +566,7 @@ ieee80211_skbhdr_adjust(struct ieee80211
|
||||
struct ieee80211_key *key, struct sk_buff *skb, int ismulticast)
|
||||
{
|
||||
/* XXX pre-calculate per node? */
|
||||
- int need_headroom = LLC_SNAPFRAMELEN + hdrsize + IEEE80211_ADDR_LEN;
|
||||
+ int need_headroom = LLC_SNAPFRAMELEN + hdrsize;
|
||||
int need_tailroom = 0;
|
||||
#ifdef ATH_SUPERG_FF
|
||||
int isff = ATH_FF_MAGIC_PRESENT(skb);
|
||||
@@ -608,109 +608,56 @@ ieee80211_skbhdr_adjust(struct ieee80211
|
||||
need_tailroom += cip->ic_miclen;
|
||||
}
|
||||
|
||||
- if (skb_shared(skb)) {
|
||||
- /* Take our own reference to the node in the clone */
|
||||
- ieee80211_ref_node(SKB_CB(skb)->ni);
|
||||
- /* Unshare the node, decrementing users in the old skb */
|
||||
- skb = skb_unshare(skb, GFP_ATOMIC);
|
||||
- }
|
||||
+ need_headroom -= skb_headroom(skb);
|
||||
+ if (isff)
|
||||
+ need_tailroom -= skb_tailroom(skb2);
|
||||
+ else
|
||||
+ need_tailroom -= skb_tailroom(skb);
|
||||
+
|
||||
+ if (need_headroom < 0)
|
||||
+ need_headroom = 0;
|
||||
+ if (need_tailroom < 0)
|
||||
+ need_tailroom = 0;
|
||||
|
||||
-#ifdef ATH_SUPERG_FF
|
||||
- if (isff) {
|
||||
- if (skb == NULL) {
|
||||
- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
|
||||
- "%s: cannot unshare for encapsulation\n",
|
||||
- __func__);
|
||||
- vap->iv_stats.is_tx_nobuf++;
|
||||
- ieee80211_dev_kfree_skb(&skb2);
|
||||
+ if (skb_cloned(skb) || (need_headroom > 0) ||
|
||||
+ (!isff && (need_tailroom > 0))) {
|
||||
|
||||
- return NULL;
|
||||
+ if (pskb_expand_head(skb, need_headroom, need_tailroom, GFP_ATOMIC)) {
|
||||
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
|
||||
+ "%s: cannot expand storage (tail)\n", __func__);
|
||||
+ goto error;
|
||||
}
|
||||
+ }
|
||||
|
||||
- /* first skb header */
|
||||
- if (skb_headroom(skb) < need_headroom) {
|
||||
- struct sk_buff *tmp = skb;
|
||||
- skb = skb_realloc_headroom(skb, need_headroom);
|
||||
- if (skb == NULL) {
|
||||
- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
|
||||
- "%s: cannot expand storage (head1)\n",
|
||||
- __func__);
|
||||
- vap->iv_stats.is_tx_nobuf++;
|
||||
- ieee80211_dev_kfree_skb(&skb2);
|
||||
- return NULL;
|
||||
- } else
|
||||
- ieee80211_skb_copy_noderef(tmp, skb);
|
||||
- ieee80211_dev_kfree_skb(&tmp);
|
||||
- /* NB: cb[] area was copied, but not next ptr. must do that
|
||||
- * prior to return on success. */
|
||||
- }
|
||||
+#ifdef ATH_SUPERG_FF
|
||||
+ if (isff) {
|
||||
+ inter_headroom -= skb_headroom(skb2);
|
||||
+ if (inter_headroom < 0)
|
||||
+ inter_headroom = 0;
|
||||
+ if ((skb_cloned(skb2) ||
|
||||
+ (inter_headroom > 0) || (need_tailroom > 0))) {
|
||||
|
||||
- /* second skb with header and tail adjustments possible */
|
||||
- if (skb_tailroom(skb2) < need_tailroom) {
|
||||
- int n = 0;
|
||||
- if (inter_headroom > skb_headroom(skb2))
|
||||
- n = inter_headroom - skb_headroom(skb2);
|
||||
- if (pskb_expand_head(skb2, n,
|
||||
- need_tailroom - skb_tailroom(skb2), GFP_ATOMIC)) {
|
||||
- ieee80211_dev_kfree_skb(&skb2);
|
||||
+ if (pskb_expand_head(skb2, inter_headroom,
|
||||
+ need_tailroom, GFP_ATOMIC)) {
|
||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
|
||||
- "%s: cannot expand storage (tail2)\n",
|
||||
- __func__);
|
||||
- vap->iv_stats.is_tx_nobuf++;
|
||||
- /* this shouldn't happen, but don't send first ff either */
|
||||
- ieee80211_dev_kfree_skb(&skb);
|
||||
+ "%s: cannot expand storage (tail)\n", __func__);
|
||||
+ goto error;
|
||||
}
|
||||
- } else if (skb_headroom(skb2) < inter_headroom) {
|
||||
- struct sk_buff *tmp = skb2;
|
||||
-
|
||||
- skb2 = skb_realloc_headroom(skb2, inter_headroom);
|
||||
- if (skb2 == NULL) {
|
||||
- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
|
||||
- "%s: cannot expand storage (head2)\n",
|
||||
- __func__);
|
||||
- vap->iv_stats.is_tx_nobuf++;
|
||||
- /* this shouldn't happen, but don't send first ff either */
|
||||
- ieee80211_dev_kfree_skb(&skb);
|
||||
- skb = NULL;
|
||||
- } else
|
||||
- ieee80211_skb_copy_noderef(tmp, skb);
|
||||
- ieee80211_dev_kfree_skb(&tmp);
|
||||
- }
|
||||
- if (skb) {
|
||||
- skb->next = skb2;
|
||||
}
|
||||
- return skb;
|
||||
+ skb->next = skb2;
|
||||
}
|
||||
#endif /* ATH_SUPERG_FF */
|
||||
- if (skb == NULL) {
|
||||
- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
|
||||
- "%s: cannot unshare for encapsulation\n", __func__);
|
||||
- vap->iv_stats.is_tx_nobuf++;
|
||||
- } else if (skb_tailroom(skb) < need_tailroom) {
|
||||
- int n = 0;
|
||||
- if (need_headroom > skb_headroom(skb))
|
||||
- n = need_headroom - skb_headroom(skb);
|
||||
- if (pskb_expand_head(skb, n, need_tailroom -
|
||||
- skb_tailroom(skb), GFP_ATOMIC)) {
|
||||
- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
|
||||
- "%s: cannot expand storage (tail)\n", __func__);
|
||||
- vap->iv_stats.is_tx_nobuf++;
|
||||
- ieee80211_dev_kfree_skb(&skb);
|
||||
- }
|
||||
- } else if (skb_headroom(skb) < need_headroom) {
|
||||
- struct sk_buff *tmp = skb;
|
||||
- skb = skb_realloc_headroom(skb, need_headroom);
|
||||
- /* Increment reference count after copy */
|
||||
- if (skb == NULL) {
|
||||
- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
|
||||
- "%s: cannot expand storage (head)\n", __func__);
|
||||
- vap->iv_stats.is_tx_nobuf++;
|
||||
- } else
|
||||
- ieee80211_skb_copy_noderef(tmp, skb);
|
||||
- ieee80211_dev_kfree_skb(&tmp);
|
||||
- }
|
||||
|
||||
return skb;
|
||||
+
|
||||
+error:
|
||||
+ vap->iv_stats.is_tx_nobuf++;
|
||||
+ ieee80211_dev_kfree_skb(&skb);
|
||||
+#ifdef ATH_SUPERG_FF
|
||||
+ if (skb2)
|
||||
+ ieee80211_dev_kfree_skb(&skb2);
|
||||
+#endif
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
#define KEY_UNDEFINED(k) ((k).wk_cipher == &ieee80211_cipher_none)
|
||||
--- a/net80211/ieee80211_input.c
|
||||
+++ b/net80211/ieee80211_input.c
|
||||
@@ -204,7 +204,6 @@ ieee80211_input(struct ieee80211vap * va
|
||||
struct ieee80211_frame *wh;
|
||||
struct ieee80211_key *key;
|
||||
struct ether_header *eh;
|
||||
- struct sk_buff *skb2;
|
||||
#ifdef ATH_SUPERG_FF
|
||||
struct llc *llc;
|
||||
#endif
|
||||
@@ -244,20 +243,6 @@ ieee80211_input(struct ieee80211vap * va
|
||||
vap->iv_stats.is_rx_tooshort++;
|
||||
goto out;
|
||||
}
|
||||
- /* Clone the SKB... we assume somewhere in this driver that we 'own'
|
||||
- * the skbuff passed into hard start and we do a lot of messing with it
|
||||
- * but bridges under some cases will not clone for the first pass of skb
|
||||
- * to a bridge port, but will then clone for subsequent ones. This is
|
||||
- * odd behavior but it means that if we have trashed the skb we are given
|
||||
- * then other ports get clones of the residual garbage.
|
||||
- */
|
||||
- if ((skb2 = skb_copy(skb, GFP_ATOMIC)) == NULL) {
|
||||
- vap->iv_devstats.tx_dropped++;
|
||||
- goto out;
|
||||
- }
|
||||
- ieee80211_skb_copy_noderef(skb, skb2);
|
||||
- ieee80211_dev_kfree_skb(&skb);
|
||||
- skb = skb2;
|
||||
|
||||
/*
|
||||
* Bit of a cheat here, we use a pointer for a 3-address
|
||||
@@ -738,7 +723,7 @@ ieee80211_input(struct ieee80211vap * va
|
||||
/* ether_type must be length as FF frames are always LLC/SNAP encap'd */
|
||||
frame_len = ntohs(eh_tmp->ether_type);
|
||||
|
||||
- skb1 = skb_copy(skb, GFP_ATOMIC);
|
||||
+ skb1 = skb_clone(skb, GFP_ATOMIC);
|
||||
if (skb1 == NULL)
|
||||
goto err;
|
||||
ieee80211_skb_copy_noderef(skb, skb1);
|
||||
@@ -1137,7 +1122,7 @@ ieee80211_deliver_data(struct ieee80211_
|
||||
|
||||
if (ETHER_IS_MULTICAST(eh->ether_dhost) && !netif_queue_stopped(dev)) {
|
||||
/* Create a SKB for the BSS to send out. */
|
||||
- skb1 = skb_copy(skb, GFP_ATOMIC);
|
||||
+ skb1 = skb_clone(skb, GFP_ATOMIC);
|
||||
if (skb1)
|
||||
SKB_CB(skb1)->ni = ieee80211_ref_node(vap->iv_bss);
|
||||
}
|
34
net/madwifi/patches/343-txqueue_races.patch
Normal file
34
net/madwifi/patches/343-txqueue_races.patch
Normal file
@ -0,0 +1,34 @@
|
||||
Merged from madwifi trunk r3551, r3552
|
||||
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -8253,6 +8253,17 @@ ath_tx_processq(struct ath_softc *sc, st
|
||||
goto bf_fail;
|
||||
}
|
||||
|
||||
+ /* We make sure we don't remove the TX descriptor on
|
||||
+ * which the HW is pointing since it contains the
|
||||
+ * ds_link field, except if this is the last TX
|
||||
+ * descriptor in the queue */
|
||||
+
|
||||
+ if ((txq->axq_depth > 1) &&
|
||||
+ (bf->bf_daddr == ath_hal_gettxbuf(ah, txq->axq_qnum))) {
|
||||
+ ATH_TXQ_UNLOCK_IRQ_EARLY(txq);
|
||||
+ goto bf_fail;
|
||||
+ }
|
||||
+
|
||||
ATH_TXQ_REMOVE_HEAD(txq, bf_list);
|
||||
ATH_TXQ_UNLOCK_IRQ(txq);
|
||||
|
||||
--- a/ath/if_athvar.h
|
||||
+++ b/ath/if_athvar.h
|
||||
@@ -586,7 +586,8 @@ struct ath_vap {
|
||||
} while (0)
|
||||
#define ATH_TXQ_REMOVE_HEAD(_tq, _field) do { \
|
||||
STAILQ_REMOVE_HEAD(&(_tq)->axq_q, _field); \
|
||||
- (_tq)->axq_depth--; \
|
||||
+ if (--(_tq)->axq_depth <= 0) \
|
||||
+ (_tq)->axq_link = NULL; \
|
||||
} while (0)
|
||||
/* move buffers from MCASTQ to CABQ */
|
||||
#define ATH_TXQ_MOVE_MCASTQ(_tqs,_tqd) do { \
|
11
net/madwifi/patches/344-minstrel_failcnt.patch
Normal file
11
net/madwifi/patches/344-minstrel_failcnt.patch
Normal file
@ -0,0 +1,11 @@
|
||||
--- a/ath_rate/minstrel/minstrel.c
|
||||
+++ b/ath_rate/minstrel/minstrel.c
|
||||
@@ -475,7 +475,7 @@ ath_rate_tx_complete(struct ath_softc *s
|
||||
/* 'tries' is the total number of times we have endeavoured to
|
||||
* send this packet, and is a sum of the #attempts at each
|
||||
* level in the multi-rate retry chain */
|
||||
- tries = ts->ts_shortretry + ts->ts_longretry + 1;
|
||||
+ tries = ts->ts_longretry + 1;
|
||||
|
||||
if (sn->num_rates <= 0) {
|
||||
DPRINTF(sc, "%s: " MAC_FMT " %s no rates yet\n", dev_info,
|
80
net/madwifi/patches/345-minstrel_sampling.patch
Normal file
80
net/madwifi/patches/345-minstrel_sampling.patch
Normal file
@ -0,0 +1,80 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -8103,6 +8103,7 @@ ath_tx_start(struct net_device *dev, str
|
||||
ath_hal_setupxtxdesc(sc->sc_ah, ds, mrr.rate1, mrr.retries1,
|
||||
mrr.rate2, mrr.retries2,
|
||||
mrr.rate3, mrr.retries3);
|
||||
+ bf->rcflags = mrr.privflags;
|
||||
}
|
||||
|
||||
#ifndef ATH_SUPERG_FF
|
||||
--- a/ath/if_athvar.h
|
||||
+++ b/ath/if_athvar.h
|
||||
@@ -446,6 +446,7 @@ struct ath_buf {
|
||||
u_int16_t bf_flags; /* tx descriptor flags */
|
||||
u_int64_t bf_tsf;
|
||||
int16_t bf_channoise;
|
||||
+ unsigned int rcflags;
|
||||
#ifdef ATH_SUPERG_FF
|
||||
/* XXX: combine this with bf_skbaddr if it ever changes to accommodate
|
||||
* multiple segments.
|
||||
--- a/ath_rate/minstrel/minstrel.c
|
||||
+++ b/ath_rate/minstrel/minstrel.c
|
||||
@@ -333,15 +333,19 @@ ath_rate_findrate(struct ath_softc *sc,
|
||||
if (sn->static_rate_ndx >= 0) {
|
||||
ndx = sn->static_rate_ndx;
|
||||
} else {
|
||||
+ int delta;
|
||||
sn->packet_count++;
|
||||
sn->random_n = (sn->a * sn->random_n) + sn->b;
|
||||
offset = sn->random_n & 0xf;
|
||||
- if ((((100 * sn->sample_count) / (sn->sample_count + sn->packet_count)) < ath_lookaround_rate) && (offset < 2)) {
|
||||
+ delta = (sn->packet_count * ath_lookaround_rate / 100) - sn->sample_count;
|
||||
+ if ((delta > 0) && (offset < 2)) {
|
||||
sn->sample_count++;
|
||||
sn->is_sampling = 1;
|
||||
if (sn->packet_count >= 10000) {
|
||||
sn->sample_count = 0;
|
||||
sn->packet_count = 0;
|
||||
+ } else if (delta > sn->num_rates * 2) {
|
||||
+ sn->sample_count += ((delta - sn->num_rates * 2) * ath_lookaround_rate) / 100;
|
||||
}
|
||||
|
||||
/* Don't look for slowest rate (i.e. slowest
|
||||
@@ -398,11 +402,14 @@ ath_rate_get_mrr(struct ath_softc *sc, s
|
||||
if (sn->num_rates <= 0)
|
||||
return;
|
||||
|
||||
+ mrr->privflags = sn->is_sampling;
|
||||
if (sn->is_sampling) {
|
||||
sn->is_sampling = 0;
|
||||
- if (sn->rs_sample_rate_slower)
|
||||
+ if (sn->rs_sample_rate_slower) {
|
||||
rc1 = sn->rs_sample_rate;
|
||||
- else
|
||||
+ if (sn->sample_count > 0)
|
||||
+ sn->sample_count--;
|
||||
+ } else
|
||||
rc1 = sn->max_tp_rate;
|
||||
} else {
|
||||
rc1 = sn->max_tp_rate2;
|
||||
@@ -525,6 +532,9 @@ ath_rate_tx_complete(struct ath_softc *s
|
||||
if (tries <= tries1)
|
||||
return;
|
||||
|
||||
+ if (bf->rcflags)
|
||||
+ sn->sample_count++;
|
||||
+
|
||||
if (tries2 < 0)
|
||||
return;
|
||||
tries = tries - tries1;
|
||||
--- a/net80211/ieee80211_rate.h
|
||||
+++ b/net80211/ieee80211_rate.h
|
||||
@@ -87,6 +87,7 @@ struct ieee80211_mrr {
|
||||
int retries2;
|
||||
int rate3;
|
||||
int retries3;
|
||||
+ int privflags;
|
||||
};
|
||||
|
||||
struct ieee80211_rate_ops {
|
135
net/madwifi/patches/346-protmode_trig.patch
Normal file
135
net/madwifi/patches/346-protmode_trig.patch
Normal file
@ -0,0 +1,135 @@
|
||||
--- a/net80211/ieee80211.c
|
||||
+++ b/net80211/ieee80211.c
|
||||
@@ -333,7 +333,9 @@ ieee80211_ifattach(struct ieee80211com *
|
||||
IEEE80211_MS_TO_TU(IEEE80211_BMISSTHRESH_DEFAULT_MS),
|
||||
ic->ic_lintval), ic->ic_lintval);
|
||||
}
|
||||
-
|
||||
+ ic->ic_protmode_timeout = IEEE80211_PROTMODE_TIMEOUT;
|
||||
+ ic->ic_protmode_rssi = IEEE80211_PROTMODE_RSSITHR;
|
||||
+
|
||||
IEEE80211_LOCK_INIT(ic, "ieee80211com");
|
||||
IEEE80211_VAPS_LOCK_INIT(ic, "ieee80211com_vaps");
|
||||
TAILQ_INIT(&ic->ic_vaps);
|
||||
--- a/net80211/ieee80211_input.c
|
||||
+++ b/net80211/ieee80211_input.c
|
||||
@@ -3411,14 +3411,18 @@ ieee80211_recv_mgmt(struct ieee80211vap
|
||||
IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) {
|
||||
|
||||
/* Assume no ERP IE == 11b AP */
|
||||
- if ((!has_erp || (has_erp && (scan.erp & IEEE80211_ERP_NON_ERP_PRESENT))) &&
|
||||
- !(ic->ic_flags & IEEE80211_F_USEPROT)) {
|
||||
+ if ((!has_erp || (has_erp &&
|
||||
+ (scan.erp & IEEE80211_ERP_NON_ERP_PRESENT))) &&
|
||||
+ (rssi > ic->ic_protmode_rssi)) {
|
||||
struct ieee80211vap *tmpvap;
|
||||
|
||||
- ic->ic_flags |= IEEE80211_F_USEPROT;
|
||||
- TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) {
|
||||
- tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
|
||||
+ if (!(ic->ic_flags & IEEE80211_F_USEPROT)) {
|
||||
+ ic->ic_flags |= IEEE80211_F_USEPROT;
|
||||
+ TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) {
|
||||
+ tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
|
||||
+ }
|
||||
}
|
||||
+ ic->ic_protmode_lasttrig = jiffies;
|
||||
}
|
||||
}
|
||||
|
||||
--- a/net80211/ieee80211_ioctl.h
|
||||
+++ b/net80211/ieee80211_ioctl.h
|
||||
@@ -643,6 +643,8 @@ enum {
|
||||
IEEE80211_PARAM_BEACON_MISS_THRESH_MS = 74, /* Beacon miss threshold (in ms) */
|
||||
IEEE80211_PARAM_MAXRATE = 75, /* Maximum rate (by table index) */
|
||||
IEEE80211_PARAM_MINRATE = 76, /* Minimum rate (by table index) */
|
||||
+ IEEE80211_PARAM_PROTMODE_RSSI = 77, /* RSSI Threshold for enabling protection mode */
|
||||
+ IEEE80211_PARAM_PROTMODE_TIMEOUT = 78, /* Timeout for expiring protection mode */
|
||||
};
|
||||
|
||||
#define SIOCG80211STATS (SIOCDEVPRIVATE+2)
|
||||
--- a/net80211/ieee80211_var.h
|
||||
+++ b/net80211/ieee80211_var.h
|
||||
@@ -128,6 +128,9 @@
|
||||
|
||||
#define IEEE80211_APPIE_MAX 1024
|
||||
|
||||
+#define IEEE80211_PROTMODE_RSSITHR 15 /* default rssi threshold for protection mode trigger */
|
||||
+#define IEEE80211_PROTMODE_TIMEOUT 30 /* timeout for keeping protection mode alive */
|
||||
+
|
||||
#define IEEE80211_PWRCONSTRAINT_VAL(ic) \
|
||||
(((ic)->ic_bsschan->ic_maxregpower > (ic)->ic_curchanmaxpwr) ? \
|
||||
(ic)->ic_bsschan->ic_maxregpower - (ic)->ic_curchanmaxpwr : 0)
|
||||
@@ -324,6 +327,9 @@ struct ieee80211com {
|
||||
u_int16_t ic_newtxpowlimit; /* tx power limit to change to (in 0.5 dBm) */
|
||||
u_int16_t ic_uapsdmaxtriggers; /* max triggers that could arrive */
|
||||
u_int8_t ic_coverageclass; /* coverage class */
|
||||
+ u_int8_t ic_protmode_rssi; /* rssi threshold for protection mode */
|
||||
+ u_int64_t ic_protmode_lasttrig; /* last trigger for protection mode */
|
||||
+ u_int16_t ic_protmode_timeout; /* protection mode timeout */
|
||||
|
||||
/* Channel state:
|
||||
*
|
||||
--- a/net80211/ieee80211_wireless.c
|
||||
+++ b/net80211/ieee80211_wireless.c
|
||||
@@ -2312,6 +2312,12 @@ ieee80211_ioctl_setparam(struct net_devi
|
||||
IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))
|
||||
retv = ENETRESET;
|
||||
break;
|
||||
+ case IEEE80211_PARAM_PROTMODE_TIMEOUT:
|
||||
+ ic->ic_protmode_timeout = value;
|
||||
+ break;
|
||||
+ case IEEE80211_PARAM_PROTMODE_RSSI:
|
||||
+ ic->ic_protmode_rssi = value;
|
||||
+ break;
|
||||
case IEEE80211_PARAM_MCASTCIPHER:
|
||||
if ((vap->iv_caps & cipher2cap(value)) == 0 &&
|
||||
!ieee80211_crypto_available(vap, value))
|
||||
@@ -2955,6 +2961,12 @@ ieee80211_ioctl_getparam(struct net_devi
|
||||
case IEEE80211_PARAM_PROTMODE:
|
||||
param[0] = ic->ic_protmode;
|
||||
break;
|
||||
+ case IEEE80211_PARAM_PROTMODE_TIMEOUT:
|
||||
+ param[0] = ic->ic_protmode_timeout;
|
||||
+ break;
|
||||
+ case IEEE80211_PARAM_PROTMODE_RSSI:
|
||||
+ param[0] = ic->ic_protmode_rssi;
|
||||
+ break;
|
||||
case IEEE80211_PARAM_MCASTCIPHER:
|
||||
param[0] = rsn->rsn_mcastcipher;
|
||||
break;
|
||||
@@ -5346,6 +5358,14 @@ static const struct iw_priv_args ieee802
|
||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "protmode" },
|
||||
{ IEEE80211_PARAM_PROTMODE,
|
||||
0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_protmode" },
|
||||
+ { IEEE80211_PARAM_PROTMODE_RSSI,
|
||||
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "protrssi" },
|
||||
+ { IEEE80211_PARAM_PROTMODE_RSSI,
|
||||
+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_protrssi" },
|
||||
+ { IEEE80211_PARAM_PROTMODE_TIMEOUT,
|
||||
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "prottime" },
|
||||
+ { IEEE80211_PARAM_PROTMODE_TIMEOUT,
|
||||
+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_prottime" },
|
||||
{ IEEE80211_PARAM_MCASTCIPHER,
|
||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "mcastcipher" },
|
||||
{ IEEE80211_PARAM_MCASTCIPHER,
|
||||
--- a/net80211/ieee80211_node.c
|
||||
+++ b/net80211/ieee80211_node.c
|
||||
@@ -1877,6 +1877,17 @@ ieee80211_node_timeout(unsigned long arg
|
||||
|
||||
ieee80211_scan_timeout(ic);
|
||||
ieee80211_timeout_stations(&ic->ic_sta);
|
||||
+ if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
|
||||
+ (ic->ic_protmode_lasttrig + ic->ic_protmode_timeout * HZ <
|
||||
+ jiffies)) {
|
||||
+ struct ieee80211vap *tmpvap;
|
||||
+
|
||||
+ /* expire protection mode */
|
||||
+ ic->ic_flags &= ~IEEE80211_F_USEPROT;
|
||||
+ TAILQ_FOREACH(tmpvap, &ic->ic_vaps, iv_next) {
|
||||
+ tmpvap->iv_flags_ext |= IEEE80211_FEXT_ERPUPDATE;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
ic->ic_inact.expires = jiffies + IEEE80211_INACT_WAIT * HZ;
|
||||
add_timer(&ic->ic_inact);
|
99
net/madwifi/patches/347-tuning.patch
Normal file
99
net/madwifi/patches/347-tuning.patch
Normal file
@ -0,0 +1,99 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -10276,11 +10276,11 @@ ath_setcurmode(struct ath_softc *sc, enu
|
||||
sc->sc_currates = rt;
|
||||
sc->sc_curmode = mode;
|
||||
/*
|
||||
- * All protection frames are transmitted at 2Mb/s for
|
||||
- * 11g, otherwise at 1Mb/s.
|
||||
+ * All protection frames are transmitted at 11Mb/s for
|
||||
+ * 11g, otherwise at 2Mb/s.
|
||||
* XXX select protection rate index from rate table.
|
||||
*/
|
||||
- sc->sc_protrix = (mode == IEEE80211_MODE_11G ? 1 : 0);
|
||||
+ sc->sc_protrix = (mode == IEEE80211_MODE_11G ? 3 : 1);
|
||||
/* rate index used to send mgt frames */
|
||||
sc->sc_minrateix = 0;
|
||||
}
|
||||
--- a/ath/if_athvar.h
|
||||
+++ b/ath/if_athvar.h
|
||||
@@ -272,6 +272,10 @@ static inline struct net_device *_alloc_
|
||||
#define AES_ICV_FIELD_SIZE 8 /* AES ICV field size */
|
||||
#define EXT_IV_FIELD_SIZE 4 /* ext IV field size */
|
||||
|
||||
+/* This is what the HAL uses by default for 11a+g */
|
||||
+#define ATH_DEFAULT_CWMIN 15
|
||||
+#define ATH_DEFAULT_CWMAX 1023
|
||||
+
|
||||
/* XR specific macros */
|
||||
|
||||
#define XR_DEFAULT_GRPPOLL_RATE_STR "0.25 1 1 3 3 6 6 20"
|
||||
--- a/ath_rate/minstrel/minstrel.c
|
||||
+++ b/ath_rate/minstrel/minstrel.c
|
||||
@@ -197,7 +197,7 @@ calc_usecs_unicast_packet(struct ath_sof
|
||||
unsigned int x = 0, tt = 0;
|
||||
unsigned int cix = rt->info[rix].controlRate;
|
||||
int rts = 0, cts = 0;
|
||||
- int cw = WIFI_CW_MIN;
|
||||
+ int cw = ATH_DEFAULT_CWMIN;
|
||||
|
||||
KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
|
||||
|
||||
@@ -281,7 +281,7 @@ calc_usecs_unicast_packet(struct ath_sof
|
||||
tt += (long_retries + 1) * ath_hal_computetxtime(sc->sc_ah, rt, length,
|
||||
rix, AH_TRUE);
|
||||
for (x = 0; x <= short_retries + long_retries; x++) {
|
||||
- cw = MIN(WIFI_CW_MAX, (cw + 1) * 2);
|
||||
+ cw = MIN(ATH_DEFAULT_CWMAX, (cw + 1) * 2);
|
||||
tt += (t_slot * cw / 2);
|
||||
}
|
||||
return tt;
|
||||
--- a/ath_rate/minstrel/minstrel.h
|
||||
+++ b/ath_rate/minstrel/minstrel.h
|
||||
@@ -180,14 +180,6 @@ struct minstrel_node {
|
||||
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
-#if 0
|
||||
-#define WIFI_CW_MIN 31
|
||||
-#define WIFI_CW_MAX 1023
|
||||
-#else
|
||||
-#define WIFI_CW_MIN 3
|
||||
-#define WIFI_CW_MAX 10
|
||||
-#endif
|
||||
-
|
||||
/*
|
||||
* Definitions for pulling the rate and trie counts from
|
||||
* a 5212 h/w descriptor. These Don't belong here; the
|
||||
--- a/ath_rate/sample/sample.c
|
||||
+++ b/ath_rate/sample/sample.c
|
||||
@@ -170,7 +170,7 @@ calc_usecs_unicast_packet(struct ath_sof
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
unsigned int tt = 0;
|
||||
unsigned int x;
|
||||
- unsigned int cw = WIFI_CW_MIN;
|
||||
+ unsigned int cw = ATH_DEFAULT_CWMIN;
|
||||
unsigned int cix = rt->info[rix].controlRate;
|
||||
KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
|
||||
|
||||
@@ -254,7 +254,7 @@ calc_usecs_unicast_packet(struct ath_sof
|
||||
tt += (long_retries+1)*ath_hal_computetxtime(sc->sc_ah, rt, length,
|
||||
rix, AH_TRUE);
|
||||
for (x = 0; x <= short_retries + long_retries; x++) {
|
||||
- cw = MIN(WIFI_CW_MAX, (cw + 1) * 2);
|
||||
+ cw = MIN(ATH_DEFAULT_CWMAX, (cw + 1) * 2);
|
||||
tt += (t_slot * cw / 2);
|
||||
}
|
||||
return tt;
|
||||
--- a/ath_rate/sample/sample.h
|
||||
+++ b/ath_rate/sample/sample.h
|
||||
@@ -106,9 +106,6 @@ struct sample_node {
|
||||
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
-#define WIFI_CW_MIN 31
|
||||
-#define WIFI_CW_MAX 1023
|
||||
-
|
||||
/*
|
||||
* Definitions for pulling the rate and trie counts from
|
||||
* a 5212 h/w descriptor. These Don't belong here; the
|
38
net/madwifi/patches/348-ackcts.patch
Normal file
38
net/madwifi/patches/348-ackcts.patch
Normal file
@ -0,0 +1,38 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -2723,6 +2723,9 @@ ar_device(int devid)
|
||||
static int
|
||||
ath_set_ack_bitrate(struct ath_softc *sc, int high)
|
||||
{
|
||||
+ if (!sc->sc_ackrate_override)
|
||||
+ return 0;
|
||||
+
|
||||
if (ar_device(sc->devid) == 5212 || ar_device(sc->devid) == 5213) {
|
||||
/* set ack to be sent at low bit-rate */
|
||||
/* registers taken from the OpenBSD 5212 HAL */
|
||||
@@ -10791,8 +10794,13 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
|
||||
break;
|
||||
#endif
|
||||
case ATH_ACKRATE:
|
||||
- sc->sc_ackrate = val;
|
||||
- ath_set_ack_bitrate(sc, sc->sc_ackrate);
|
||||
+ if (val == -1)
|
||||
+ sc->sc_ackrate_override = 0;
|
||||
+ else {
|
||||
+ sc->sc_ackrate_override = 1;
|
||||
+ sc->sc_ackrate = val;
|
||||
+ ath_set_ack_bitrate(sc, sc->sc_ackrate);
|
||||
+ }
|
||||
break;
|
||||
case ATH_RP:
|
||||
ath_rp_record(sc,
|
||||
--- a/ath/if_athvar.h
|
||||
+++ b/ath/if_athvar.h
|
||||
@@ -681,6 +681,7 @@ struct ath_softc {
|
||||
unsigned int sc_devstopped:1; /* stopped due to of no tx bufs */
|
||||
unsigned int sc_stagbeacons:1; /* use staggered beacons */
|
||||
unsigned int sc_dfswait:1; /* waiting on channel for radar detect */
|
||||
+ unsigned int sc_ackrate_override:1; /* override ack rate */
|
||||
unsigned int sc_ackrate:1; /* send acks at high bitrate */
|
||||
unsigned int sc_dfs_cac:1; /* waiting on channel for radar detect */
|
||||
unsigned int sc_hasintmit:1; /* Interference mitigation */
|
12
net/madwifi/patches/349-reset.patch
Normal file
12
net/madwifi/patches/349-reset.patch
Normal file
@ -0,0 +1,12 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -8864,8 +8864,7 @@ ath_chan_set(struct ath_softc *sc, struc
|
||||
* needed to do the reset with chanchange = AH_FALSE in order
|
||||
* to receive traffic when peforming high velocity channel
|
||||
* changes. */
|
||||
- if (!ath_hal_reset(ah, sc->sc_opmode, &hchan, AH_TRUE, &status) ||
|
||||
- !ath_hal_reset(ah, sc->sc_opmode, &hchan, AH_FALSE, &status)) {
|
||||
+ if (!ath_hal_reset(ah, sc->sc_opmode, &hchan, AH_TRUE, &status)) {
|
||||
EPRINTF(sc, "Unable to reset channel %u (%u MHz) "
|
||||
"flags 0x%x '%s' (HAL status %u)\n",
|
||||
ieee80211_chan2ieee(ic, chan), chan->ic_freq,
|
11
net/madwifi/patches/350-wisoc_softled.patch
Normal file
11
net/madwifi/patches/350-wisoc_softled.patch
Normal file
@ -0,0 +1,11 @@
|
||||
--- a/ath/if_ath_ahb.c
|
||||
+++ b/ath/if_ath_ahb.c
|
||||
@@ -245,6 +245,8 @@ init_ath_wmac(u_int16_t devid, u_int16_t
|
||||
num_activesc++;
|
||||
/* Ready to process interrupts */
|
||||
|
||||
+ sc->aps_sc.sc_softled = 1; /* SoftLED over GPIO */
|
||||
+ sc->aps_sc.sc_ledpin = config->board->sysLedGpio;
|
||||
sc->aps_sc.sc_invalid = 0;
|
||||
return 0;
|
||||
|
904
net/madwifi/patches/351-scanlist.patch
Normal file
904
net/madwifi/patches/351-scanlist.patch
Normal file
@ -0,0 +1,904 @@
|
||||
--- a/net80211/ieee80211_scan_sta.c
|
||||
+++ b/net80211/ieee80211_scan_sta.c
|
||||
@@ -317,147 +317,6 @@ found:
|
||||
#undef ISPROBE
|
||||
}
|
||||
|
||||
-static struct ieee80211_channel *
|
||||
-find11gchannel(struct ieee80211com *ic, int i, int freq)
|
||||
-{
|
||||
- struct ieee80211_channel *c;
|
||||
- int j;
|
||||
-
|
||||
- /*
|
||||
- * The normal ordering in the channel list is b channel
|
||||
- * immediately followed by g so optimize the search for
|
||||
- * this. We'll still do a full search just in case.
|
||||
- */
|
||||
- for (j = i+1; j < ic->ic_nchans; j++) {
|
||||
- c = &ic->ic_channels[j];
|
||||
- if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c))
|
||||
- return c;
|
||||
- }
|
||||
- for (j = 0; j < i; j++) {
|
||||
- c = &ic->ic_channels[j];
|
||||
- if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c))
|
||||
- return c;
|
||||
- }
|
||||
- return NULL;
|
||||
-}
|
||||
-static const u_int chanflags[] = {
|
||||
- IEEE80211_CHAN_B, /* IEEE80211_MODE_AUTO */
|
||||
- IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */
|
||||
- IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */
|
||||
- IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_11G */
|
||||
- IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */
|
||||
- IEEE80211_CHAN_A, /* IEEE80211_MODE_TURBO_A */ /* for turbo mode look for AP in normal channel */
|
||||
- IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_TURBO_G */
|
||||
- IEEE80211_CHAN_ST, /* IEEE80211_MODE_TURBO_STATIC_A */
|
||||
-};
|
||||
-
|
||||
-static void
|
||||
-add_channels(struct ieee80211com *ic,
|
||||
- struct ieee80211_scan_state *ss,
|
||||
- enum ieee80211_phymode mode, const u_int16_t freq[], int nfreq)
|
||||
-{
|
||||
- struct ieee80211_channel *c, *cg;
|
||||
- u_int modeflags;
|
||||
- int i;
|
||||
-
|
||||
- KASSERT(mode < ARRAY_SIZE(chanflags), ("Unexpected mode %u", mode));
|
||||
- modeflags = chanflags[mode];
|
||||
- for (i = 0; i < nfreq; i++) {
|
||||
- c = ieee80211_find_channel(ic, freq[i], modeflags);
|
||||
- if (c == NULL || isclr(ic->ic_chan_active, c->ic_ieee))
|
||||
- continue;
|
||||
- if (mode == IEEE80211_MODE_AUTO) {
|
||||
- /*
|
||||
- * XXX special-case 11b/g channels so we select
|
||||
- * the g channel if both are present.
|
||||
- */
|
||||
- if (IEEE80211_IS_CHAN_B(c) &&
|
||||
- (cg = find11gchannel(ic, i, c->ic_freq)) != NULL)
|
||||
- c = cg;
|
||||
- }
|
||||
- if (ss->ss_last >= IEEE80211_SCAN_MAX)
|
||||
- break;
|
||||
- ss->ss_chans[ss->ss_last++] = c;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static const u_int16_t rcl1[] = /* 8 FCC channel: 52, 56, 60, 64, 36, 40, 44, 48 */
|
||||
-{ 5260, 5280, 5300, 5320, 5180, 5200, 5220, 5240 };
|
||||
-static const u_int16_t rcl2[] = /* 4 MKK channels: 34, 38, 42, 46 */
|
||||
-{ 5170, 5190, 5210, 5230 };
|
||||
-static const u_int16_t rcl3[] = /* 2.4Ghz ch: 1,6,11,7,13 */
|
||||
-{ 2412, 2437, 2462, 2442, 2472 };
|
||||
-static const u_int16_t rcl4[] = /* 5 FCC channel: 149, 153, 161, 165 */
|
||||
-{ 5745, 5765, 5785, 5805, 5825 };
|
||||
-static const u_int16_t rcl7[] = /* 11 ETSI channel: 100,104,108,112,116,120,124,128,132,136,140 */
|
||||
-{ 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, 5700 };
|
||||
-static const u_int16_t rcl8[] = /* 2.4Ghz ch: 2,3,4,5,8,9,10,12 */
|
||||
-{ 2417, 2422, 2427, 2432, 2447, 2452, 2457, 2467 };
|
||||
-static const u_int16_t rcl9[] = /* 2.4Ghz ch: 14 */
|
||||
-{ 2484 };
|
||||
-static const u_int16_t rcl10[] = /* Added Korean channels 2312-2372 */
|
||||
-{ 2312, 2317, 2322, 2327, 2332, 2337, 2342, 2347, 2352, 2357, 2362, 2367, 2372 };
|
||||
-static const u_int16_t rcl11[] = /* Added Japan channels in 4.9/5.0 spectrum */
|
||||
-{ 5040, 5060, 5080, 4920, 4940, 4960, 4980 };
|
||||
-#ifdef ATH_TURBO_SCAN
|
||||
-static const u_int16_t rcl5[] = /* 3 static turbo channels */
|
||||
-{ 5210, 5250, 5290 };
|
||||
-static const u_int16_t rcl6[] = /* 2 static turbo channels */
|
||||
-{ 5760, 5800 };
|
||||
-static const u_int16_t rcl6x[] = /* 4 FCC3 turbo channels */
|
||||
-{ 5540, 5580, 5620, 5660 };
|
||||
-static const u_int16_t rcl12[] = /* 2.4Ghz Turbo channel 6 */
|
||||
-{ 2437 };
|
||||
-static const u_int16_t rcl13[] = /* dynamic Turbo channels */
|
||||
-{ 5200, 5240, 5280, 5765, 5805 };
|
||||
-#endif /* ATH_TURBO_SCAN */
|
||||
-
|
||||
-struct scanlist {
|
||||
- u_int16_t mode;
|
||||
- u_int16_t count;
|
||||
- const u_int16_t *list;
|
||||
-};
|
||||
-
|
||||
-#define IEEE80211_MODE_TURBO_STATIC_A IEEE80211_MODE_MAX
|
||||
-#define X(a) .count = sizeof(a)/sizeof(a[0]), .list = a
|
||||
-
|
||||
-static const struct scanlist staScanTable[] = {
|
||||
- { IEEE80211_MODE_11B, X(rcl3) },
|
||||
- { IEEE80211_MODE_11A, X(rcl1) },
|
||||
- { IEEE80211_MODE_11A, X(rcl2) },
|
||||
- { IEEE80211_MODE_11B, X(rcl8) },
|
||||
- { IEEE80211_MODE_11B, X(rcl9) },
|
||||
- { IEEE80211_MODE_11A, X(rcl4) },
|
||||
-#ifdef ATH_TURBO_SCAN
|
||||
- { IEEE80211_MODE_TURBO_STATIC_A, X(rcl5) },
|
||||
- { IEEE80211_MODE_TURBO_STATIC_A, X(rcl6) },
|
||||
- { IEEE80211_MODE_TURBO_A, X(rcl6x) },
|
||||
- { IEEE80211_MODE_TURBO_A, X(rcl13) },
|
||||
-#endif /* ATH_TURBO_SCAN */
|
||||
- { IEEE80211_MODE_11A, X(rcl7) },
|
||||
- { IEEE80211_MODE_11B, X(rcl10) },
|
||||
- { IEEE80211_MODE_11A, X(rcl11) },
|
||||
-#ifdef ATH_TURBO_SCAN
|
||||
- { IEEE80211_MODE_TURBO_G, X(rcl12) },
|
||||
-#endif /* ATH_TURBO_SCAN */
|
||||
- { .list = NULL }
|
||||
-};
|
||||
-
|
||||
-#undef X
|
||||
-
|
||||
-static int
|
||||
-checktable(const struct scanlist *scan, const struct ieee80211_channel *c)
|
||||
-{
|
||||
- int i;
|
||||
-
|
||||
- for (; scan->list != NULL; scan++) {
|
||||
- for (i = 0; i < scan->count; i++)
|
||||
- if (scan->list[i] == c->ic_freq)
|
||||
- return 1;
|
||||
- }
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* Start a station-mode scan by populating the channel list.
|
||||
*/
|
||||
@@ -466,81 +325,14 @@ sta_start(struct ieee80211_scan_state *s
|
||||
{
|
||||
struct ieee80211com *ic = vap->iv_ic;
|
||||
struct sta_table *st = ss->ss_priv;
|
||||
- const struct scanlist *scan;
|
||||
enum ieee80211_phymode mode;
|
||||
struct ieee80211_channel *c;
|
||||
int i;
|
||||
|
||||
ss->ss_last = 0;
|
||||
- /*
|
||||
- * Use the table of ordered channels to construct the list
|
||||
- * of channels for scanning. Any channels in the ordered
|
||||
- * list not in the master list will be discarded.
|
||||
- */
|
||||
- for (scan = staScanTable; scan->list != NULL; scan++) {
|
||||
- mode = scan->mode;
|
||||
- if (vap->iv_des_mode != IEEE80211_MODE_AUTO) {
|
||||
- /*
|
||||
- * If a desired mode was specified, scan only
|
||||
- * channels that satisfy that constraint.
|
||||
- */
|
||||
- if (vap->iv_des_mode != mode) {
|
||||
- /*
|
||||
- * The scan table marks 2.4Ghz channels as b
|
||||
- * so if the desired mode is 11g, then use
|
||||
- * the 11b channel list but upgrade the mode.
|
||||
- */
|
||||
- if (vap->iv_des_mode != IEEE80211_MODE_11G ||
|
||||
- mode != IEEE80211_MODE_11B)
|
||||
- continue;
|
||||
- mode = IEEE80211_MODE_11G; /* upgrade */
|
||||
- }
|
||||
- } else {
|
||||
- /*
|
||||
- * This lets ieee80211_scan_add_channels
|
||||
- * upgrade an 11b channel to 11g if available.
|
||||
- */
|
||||
- if (mode == IEEE80211_MODE_11B)
|
||||
- mode = IEEE80211_MODE_AUTO;
|
||||
- }
|
||||
- /* XR does not operate on turbo channels */
|
||||
- if ((vap->iv_flags & IEEE80211_F_XR) &&
|
||||
- (mode == IEEE80211_MODE_TURBO_A ||
|
||||
- mode == IEEE80211_MODE_TURBO_G))
|
||||
- continue;
|
||||
- /*
|
||||
- * Add the list of the channels; any that are not
|
||||
- * in the master channel list will be discarded.
|
||||
- */
|
||||
- add_channels(ic, ss, mode, scan->list, scan->count);
|
||||
- }
|
||||
-
|
||||
- /*
|
||||
- * Add the channels from the ic (from HAL) that are not present
|
||||
- * in the staScanTable.
|
||||
- */
|
||||
- for (i = 0; i < ic->ic_nchans; i++) {
|
||||
- c = &ic->ic_channels[i];
|
||||
- /*
|
||||
- * scan dynamic turbo channels in normal mode.
|
||||
- */
|
||||
- if (IEEE80211_IS_CHAN_DTURBO(c))
|
||||
- continue;
|
||||
- mode = ieee80211_chan2mode(c);
|
||||
- if (vap->iv_des_mode != IEEE80211_MODE_AUTO) {
|
||||
- /*
|
||||
- * If a desired mode was specified, scan only
|
||||
- * channels that satisfy that constraint.
|
||||
- */
|
||||
- if (vap->iv_des_mode != mode)
|
||||
- continue;
|
||||
-
|
||||
- }
|
||||
- if (!checktable(staScanTable, c))
|
||||
- ss->ss_chans[ss->ss_last++] = c;
|
||||
- }
|
||||
-
|
||||
+ ieee80211_scan_add_channels(ic, ss, vap->iv_des_mode);
|
||||
ss->ss_next = 0;
|
||||
+
|
||||
/* XXX tunables */
|
||||
/*
|
||||
* The scanner will stay on station for ss_maxdwell ms (using a
|
||||
@@ -749,17 +541,7 @@ match_bss(struct ieee80211vap *vap,
|
||||
fail = 0;
|
||||
if (isclr(ic->ic_chan_active, ieee80211_chan2ieee(ic, se->se_chan)))
|
||||
fail |= 0x01;
|
||||
- /*
|
||||
- * NB: normally the desired mode is used to construct
|
||||
- * the channel list, but it's possible for the scan
|
||||
- * cache to include entries for stations outside this
|
||||
- * list so we check the desired mode here to weed them
|
||||
- * out.
|
||||
- */
|
||||
- if (vap->iv_des_mode != IEEE80211_MODE_AUTO &&
|
||||
- (se->se_chan->ic_flags & IEEE80211_CHAN_ALLTURBO) !=
|
||||
- chanflags[vap->iv_des_mode])
|
||||
- fail |= 0x01;
|
||||
+
|
||||
if (vap->iv_opmode == IEEE80211_M_IBSS) {
|
||||
if ((se->se_capinfo & IEEE80211_CAPINFO_IBSS) == 0)
|
||||
fail |= 0x02;
|
||||
@@ -1168,78 +950,6 @@ static const struct ieee80211_scanner st
|
||||
.scan_default = ieee80211_sta_join,
|
||||
};
|
||||
|
||||
-/*
|
||||
- * Start an adhoc-mode scan by populating the channel list.
|
||||
- */
|
||||
-static int
|
||||
-adhoc_start(struct ieee80211_scan_state *ss, struct ieee80211vap *vap)
|
||||
-{
|
||||
- struct ieee80211com *ic = vap->iv_ic;
|
||||
- struct sta_table *st = ss->ss_priv;
|
||||
- const struct scanlist *scan;
|
||||
- enum ieee80211_phymode mode;
|
||||
-
|
||||
- ss->ss_last = 0;
|
||||
- /*
|
||||
- * Use the table of ordered channels to construct the list
|
||||
- * of channels for scanning. Any channels in the ordered
|
||||
- * list not in the master list will be discarded.
|
||||
- */
|
||||
- for (scan = staScanTable; scan->list != NULL; scan++) {
|
||||
- mode = scan->mode;
|
||||
- if (vap->iv_des_mode != IEEE80211_MODE_AUTO) {
|
||||
- /*
|
||||
- * If a desired mode was specified, scan only
|
||||
- * channels that satisfy that constraint.
|
||||
- */
|
||||
- if (vap->iv_des_mode != mode) {
|
||||
- /*
|
||||
- * The scan table marks 2.4Ghz channels as b
|
||||
- * so if the desired mode is 11g, then use
|
||||
- * the 11b channel list but upgrade the mode.
|
||||
- */
|
||||
- if (vap->iv_des_mode != IEEE80211_MODE_11G ||
|
||||
- mode != IEEE80211_MODE_11B)
|
||||
- continue;
|
||||
- mode = IEEE80211_MODE_11G; /* upgrade */
|
||||
- }
|
||||
- } else {
|
||||
- /*
|
||||
- * This lets ieee80211_scan_add_channels
|
||||
- * upgrade an 11b channel to 11g if available.
|
||||
- */
|
||||
- if (mode == IEEE80211_MODE_11B)
|
||||
- mode = IEEE80211_MODE_AUTO;
|
||||
- }
|
||||
- /* XR does not operate on turbo channels */
|
||||
- if ((vap->iv_flags & IEEE80211_F_XR) &&
|
||||
- (mode == IEEE80211_MODE_TURBO_A ||
|
||||
- mode == IEEE80211_MODE_TURBO_G))
|
||||
- continue;
|
||||
- /*
|
||||
- * Add the list of the channels; any that are not
|
||||
- * in the master channel list will be discarded.
|
||||
- */
|
||||
- add_channels(ic, ss, mode, scan->list, scan->count);
|
||||
- }
|
||||
- ss->ss_next = 0;
|
||||
- /* XXX tunables */
|
||||
- ss->ss_mindwell = msecs_to_jiffies(200); /* 200ms */
|
||||
- ss->ss_maxdwell = msecs_to_jiffies(200); /* 200ms */
|
||||
-
|
||||
-#ifdef IEEE80211_DEBUG
|
||||
- if (ieee80211_msg_scan(vap)) {
|
||||
- printk("%s: scan set ", vap->iv_dev->name);
|
||||
- ieee80211_scan_dump_channels(ss);
|
||||
- printk(" dwell min %ld max %ld\n",
|
||||
- ss->ss_mindwell, ss->ss_maxdwell);
|
||||
- }
|
||||
-#endif /* IEEE80211_DEBUG */
|
||||
-
|
||||
- st->st_newscan = 1;
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
|
||||
/*
|
||||
* Select a channel to start an adhoc network on.
|
||||
@@ -1405,7 +1115,7 @@ static const struct ieee80211_scanner ad
|
||||
.scan_name = "default",
|
||||
.scan_attach = sta_attach,
|
||||
.scan_detach = sta_detach,
|
||||
- .scan_start = adhoc_start,
|
||||
+ .scan_start = sta_start,
|
||||
.scan_restart = sta_restart,
|
||||
.scan_cancel = sta_cancel,
|
||||
.scan_end = adhoc_pick_bss,
|
||||
--- a/net80211/ieee80211.c
|
||||
+++ b/net80211/ieee80211.c
|
||||
@@ -278,6 +278,11 @@ ieee80211_ifattach(struct ieee80211com *
|
||||
("channel with bogus ieee number %u", c->ic_ieee));
|
||||
setbit(ic->ic_chan_avail, c->ic_ieee);
|
||||
|
||||
+ if (c->ic_scanflags & IEEE80211_NOSCAN_DEFAULT)
|
||||
+ c->ic_scanflags |= IEEE80211_NOSCAN_SET;
|
||||
+ else
|
||||
+ c->ic_scanflags &= ~IEEE80211_NOSCAN_SET;
|
||||
+
|
||||
/* Identify mode capabilities. */
|
||||
if (IEEE80211_IS_CHAN_A(c))
|
||||
ic->ic_modecaps |= 1 << IEEE80211_MODE_11A;
|
||||
@@ -1447,10 +1452,6 @@ ieee80211_media_change(struct net_device
|
||||
vap->iv_fixed_rate = newrate; /* fixed TX rate */
|
||||
error = -ENETRESET;
|
||||
}
|
||||
- if (vap->iv_des_mode != newmode) {
|
||||
- vap->iv_des_mode = newmode; /* desired PHY mode */
|
||||
- error = -ENETRESET;
|
||||
- }
|
||||
return error;
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_media_change);
|
||||
--- a/net80211/_ieee80211.h
|
||||
+++ b/net80211/_ieee80211.h
|
||||
@@ -132,6 +132,11 @@ enum ieee80211_scanmode {
|
||||
IEEE80211_SCAN_FIRST = 2, /* take first suitable candidate */
|
||||
};
|
||||
|
||||
+enum ieee80211_scanflags {
|
||||
+ IEEE80211_NOSCAN_DEFAULT = (1 << 0),
|
||||
+ IEEE80211_NOSCAN_SET = (1 << 1),
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* Channels are specified by frequency and attributes.
|
||||
*/
|
||||
@@ -142,6 +147,7 @@ struct ieee80211_channel {
|
||||
int8_t ic_maxregpower; /* maximum regulatory tx power in dBm */
|
||||
int8_t ic_maxpower; /* maximum tx power in dBm */
|
||||
int8_t ic_minpower; /* minimum tx power in dBm */
|
||||
+ u_int8_t ic_scanflags;
|
||||
};
|
||||
|
||||
#define IEEE80211_CHAN_MAX 255
|
||||
--- a/net80211/ieee80211_ioctl.h
|
||||
+++ b/net80211/ieee80211_ioctl.h
|
||||
@@ -555,6 +555,7 @@ struct ieee80211req_scan_result {
|
||||
#define IEEE80211_IOCTL_WDSADDMAC (SIOCIWFIRSTPRIV+26)
|
||||
#define IEEE80211_IOCTL_WDSDELMAC (SIOCIWFIRSTPRIV+28)
|
||||
#define IEEE80211_IOCTL_KICKMAC (SIOCIWFIRSTPRIV+30)
|
||||
+#define IEEE80211_IOCTL_SETSCANLIST (SIOCIWFIRSTPRIV+31)
|
||||
|
||||
enum {
|
||||
IEEE80211_WMMPARAMS_CWMIN = 1,
|
||||
--- a/net80211/ieee80211_scan_ap.c
|
||||
+++ b/net80211/ieee80211_scan_ap.c
|
||||
@@ -105,11 +105,6 @@ struct scan_entry {
|
||||
};
|
||||
|
||||
struct ap_state {
|
||||
- unsigned int as_vap_desired_mode; /* Used for channel selection,
|
||||
- * vap->iv_des_mode */
|
||||
- unsigned int as_required_mode; /* Used for channel selection,
|
||||
- * filtered version of
|
||||
- * as_vap_desired_mode */
|
||||
int as_maxrssi[IEEE80211_CHAN_MAX]; /* Used for channel selection */
|
||||
|
||||
/* These fields are just for scan caching for returning responses to
|
||||
@@ -129,131 +124,7 @@ struct ap_state {
|
||||
|
||||
static int ap_flush(struct ieee80211_scan_state *);
|
||||
static void action_tasklet(IEEE80211_TQUEUE_ARG);
|
||||
-static struct ieee80211_channel *find11gchannel(struct ieee80211com *ic,
|
||||
- int i, int freq);
|
||||
|
||||
-static const u_int chanflags[] = {
|
||||
- IEEE80211_CHAN_B, /* IEEE80211_MODE_AUTO */
|
||||
- IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */
|
||||
- IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */
|
||||
- IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_11G */
|
||||
- IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */
|
||||
- IEEE80211_CHAN_A, /* IEEE80211_MODE_TURBO_A */ /* for turbo mode
|
||||
- * look for AP in
|
||||
- * normal channel
|
||||
- */
|
||||
- IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_TURBO_G */
|
||||
- IEEE80211_CHAN_ST, /* IEEE80211_MODE_TURBO_STATIC_A */
|
||||
-};
|
||||
-
|
||||
-static const u_int16_t rcl1[] = /* 8 FCC channel: 52, 56, 60, 64,
|
||||
- * 36, 40, 44, 48 */
|
||||
-{ 5260, 5280, 5300, 5320, 5180, 5200, 5220, 5240 };
|
||||
-static const u_int16_t rcl2[] = /* 4 MKK channels: 34, 38, 42, 46 */
|
||||
-{ 5170, 5190, 5210, 5230 };
|
||||
-static const u_int16_t rcl3[] = /* 2.4Ghz ch: 1,6,11,7,13 */
|
||||
-{ 2412, 2437, 2462, 2442, 2472 };
|
||||
-static const u_int16_t rcl4[] = /* 5 FCC channel: 149, 153, 161, 165 */
|
||||
-{ 5745, 5765, 5785, 5805, 5825 };
|
||||
-static const u_int16_t rcl7[] = /* 11 ETSI channel: 100, 104, 108, 112,
|
||||
- * 116, 120, 124, 128,
|
||||
- * 132, 136, 140 */
|
||||
-{ 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680, 5700 };
|
||||
-static const u_int16_t rcl8[] = /* 2.4Ghz ch: 2,3,4,5,8,9,10,12 */
|
||||
-{ 2417, 2422, 2427, 2432, 2447, 2452, 2457, 2467 };
|
||||
-static const u_int16_t rcl9[] = /* 2.4Ghz ch: 14 */
|
||||
-{ 2484 };
|
||||
-static const u_int16_t rcl10[] = /* Added Korean channels 2312-2372 */
|
||||
-{ 2312, 2317, 2322, 2327, 2332, 2337, 2342, 2347, 2352, 2357, 2362, 2367, 2372 };
|
||||
-static const u_int16_t rcl11[] = /* Added Japan channels in 4.9/5.0 spectrum */
|
||||
-{ 5040, 5060, 5080, 4920, 4940, 4960, 4980 };
|
||||
-#ifdef ATH_TURBO_SCAN
|
||||
-static const u_int16_t rcl5[] = /* 3 static turbo channels */
|
||||
-{ 5210, 5250, 5290 };
|
||||
-static const u_int16_t rcl6[] = /* 2 static turbo channels */
|
||||
-{ 5760, 5800 };
|
||||
-static const u_int16_t rcl6x[] = /* 4 FCC3 turbo channels */
|
||||
-{ 5540, 5580, 5620, 5660 };
|
||||
-static const u_int16_t rcl12[] = /* 2.4Ghz Turbo channel 6 */
|
||||
-{ 2437 };
|
||||
-static const u_int16_t rcl13[] = /* dynamic Turbo channels */
|
||||
-{ 5200, 5240, 5280, 5765, 5805 };
|
||||
-#endif /* ATH_TURBO_SCAN */
|
||||
-
|
||||
-struct scanlist {
|
||||
- u_int16_t mode;
|
||||
- u_int16_t count;
|
||||
- const u_int16_t *list;
|
||||
-};
|
||||
-
|
||||
-#define IEEE80211_MODE_TURBO_STATIC_A IEEE80211_MODE_MAX
|
||||
-#define X(a) .count = ARRAY_SIZE(a), .list = a
|
||||
-
|
||||
-static const struct scanlist staScanTable[] = {
|
||||
- { IEEE80211_MODE_11B, X(rcl3) },
|
||||
- { IEEE80211_MODE_11A, X(rcl1) },
|
||||
- { IEEE80211_MODE_11A, X(rcl2) },
|
||||
- { IEEE80211_MODE_11B, X(rcl8) },
|
||||
- { IEEE80211_MODE_11B, X(rcl9) },
|
||||
- { IEEE80211_MODE_11A, X(rcl4) },
|
||||
-#ifdef ATH_TURBO_SCAN
|
||||
- { IEEE80211_MODE_TURBO_STATIC_A, X(rcl5) },
|
||||
- { IEEE80211_MODE_TURBO_STATIC_A, X(rcl6) },
|
||||
- { IEEE80211_MODE_TURBO_A, X(rcl6x) },
|
||||
- { IEEE80211_MODE_TURBO_A, X(rcl13) },
|
||||
-#endif /* ATH_TURBO_SCAN */
|
||||
- { IEEE80211_MODE_11A, X(rcl7) },
|
||||
- { IEEE80211_MODE_11B, X(rcl10) },
|
||||
- { IEEE80211_MODE_11A, X(rcl11) },
|
||||
-#ifdef ATH_TURBO_SCAN
|
||||
- { IEEE80211_MODE_TURBO_G, X(rcl12) },
|
||||
-#endif /* ATH_TURBO_SCAN */
|
||||
- { .list = NULL }
|
||||
-};
|
||||
-
|
||||
-#undef X
|
||||
-/* This function must be invoked with locks acquired */
|
||||
-static void
|
||||
-add_channels(struct ieee80211com *ic,
|
||||
- struct ieee80211_scan_state *ss,
|
||||
- enum ieee80211_phymode mode, const u_int16_t freq[], int nfreq)
|
||||
-{
|
||||
- struct ieee80211_channel *c, *cg;
|
||||
- u_int modeflags;
|
||||
- int i;
|
||||
-
|
||||
- KASSERT(mode < ARRAY_SIZE(chanflags), ("Unexpected mode %u", mode));
|
||||
- modeflags = chanflags[mode];
|
||||
- for (i = 0; i < nfreq; i++) {
|
||||
- c = ieee80211_find_channel(ic, freq[i], modeflags);
|
||||
- if ((c == NULL) || isclr(ic->ic_chan_active, c->ic_ieee))
|
||||
- continue;
|
||||
- if (mode == IEEE80211_MODE_AUTO) {
|
||||
- /* XXX special-case 11b/g channels so we select
|
||||
- * the g channel if both are present. */
|
||||
- if (IEEE80211_IS_CHAN_B(c) &&
|
||||
- (cg = find11gchannel(ic, i, c->ic_freq)) != NULL)
|
||||
- c = cg;
|
||||
- }
|
||||
- if (ss->ss_last >= IEEE80211_SCAN_MAX)
|
||||
- break;
|
||||
- ss->ss_chans[ss->ss_last++] = c;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-/* This function must be invoked with locks acquired */
|
||||
-static int
|
||||
-checktable(const struct scanlist *scan, const struct ieee80211_channel *c)
|
||||
-{
|
||||
- int i;
|
||||
-
|
||||
- for (; scan->list != NULL; scan++) {
|
||||
- for (i = 0; i < scan->count; i++)
|
||||
- if (scan->list[i] == c->ic_freq)
|
||||
- return 1;
|
||||
- }
|
||||
- return 0;
|
||||
-}
|
||||
|
||||
/*
|
||||
* Attach prior to any scanning work.
|
||||
@@ -327,29 +198,6 @@ saveie(u_int8_t **iep, const u_int8_t *i
|
||||
ieee80211_saveie(iep, ie);
|
||||
}
|
||||
|
||||
-/* This function must be invoked with locks acquired */
|
||||
-static struct ieee80211_channel *
|
||||
-find11gchannel(struct ieee80211com *ic, int i, int freq)
|
||||
-{
|
||||
- struct ieee80211_channel *c;
|
||||
- int j;
|
||||
-
|
||||
- /* The normal ordering in the channel list is b channel
|
||||
- * immediately followed by g so optimize the search for
|
||||
- * this. We'll still do a full search just in case. */
|
||||
- for (j = i + 1; j < ic->ic_nchans; j++) {
|
||||
- c = &ic->ic_channels[j];
|
||||
- if ((c->ic_freq == freq) && IEEE80211_IS_CHAN_ANYG(c))
|
||||
- return c;
|
||||
- }
|
||||
- for (j = 0; j < i; j++) {
|
||||
- c = &ic->ic_channels[j];
|
||||
- if ((c->ic_freq == freq) && IEEE80211_IS_CHAN_ANYG(c))
|
||||
- return c;
|
||||
- }
|
||||
- return NULL;
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* Start an ap scan by populating the channel list.
|
||||
*/
|
||||
@@ -358,90 +206,15 @@ ap_start(struct ieee80211_scan_state *ss
|
||||
{
|
||||
struct ap_state *as = ss->ss_priv;
|
||||
struct ieee80211com *ic = NULL;
|
||||
- const struct scanlist *sl = NULL;
|
||||
- struct ieee80211_channel *c = NULL;
|
||||
int i;
|
||||
unsigned int mode = 0;
|
||||
|
||||
SCAN_AP_LOCK_IRQ(as);
|
||||
ic = vap->iv_ic;
|
||||
/* Determine mode flags to match, or leave zero for auto mode */
|
||||
- as->as_vap_desired_mode = vap->iv_des_mode;
|
||||
- as->as_required_mode = 0;
|
||||
- if (as->as_vap_desired_mode != IEEE80211_MODE_AUTO) {
|
||||
- as->as_required_mode = chanflags[as->as_vap_desired_mode];
|
||||
- if ((vap->iv_ath_cap & IEEE80211_ATHC_TURBOP) &&
|
||||
- (as->as_required_mode != IEEE80211_CHAN_ST)) {
|
||||
- /* Fixup for dynamic turbo flags */
|
||||
- if (as->as_vap_desired_mode == IEEE80211_MODE_11G)
|
||||
- as->as_required_mode = IEEE80211_CHAN_108G;
|
||||
- else
|
||||
- as->as_required_mode = IEEE80211_CHAN_108A;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
ss->ss_last = 0;
|
||||
- /* Use the table of ordered channels to construct the list
|
||||
- * of channels for scanning. Any channels in the ordered
|
||||
- * list not in the master list will be discarded. */
|
||||
- for (sl = staScanTable; sl->list != NULL; sl++) {
|
||||
- mode = sl->mode;
|
||||
-
|
||||
- /* The scan table marks 2.4Ghz channels as b
|
||||
- * so if the desired mode is 11g, then use
|
||||
- * the 11b channel list but upgrade the mode. */
|
||||
- if (as->as_vap_desired_mode &&
|
||||
- (as->as_vap_desired_mode != mode) &&
|
||||
- (as->as_vap_desired_mode == IEEE80211_MODE_11G) &&
|
||||
- (mode == IEEE80211_MODE_11B))
|
||||
- mode = IEEE80211_MODE_11G;
|
||||
-
|
||||
- /* If we are in "AUTO" mode, upgrade the mode to auto.
|
||||
- * This lets add_channels upgrade an 11b channel to
|
||||
- * 11g if available. */
|
||||
- if (!as->as_vap_desired_mode && (mode == IEEE80211_MODE_11B))
|
||||
- mode = IEEE80211_MODE_AUTO;
|
||||
-
|
||||
- /* Add the list of the channels; any that are not
|
||||
- * in the master channel list will be discarded. */
|
||||
- add_channels(ic, ss, mode, sl->list, sl->count);
|
||||
- }
|
||||
-
|
||||
- /* Add the channels from the ic (from HAL) that are not present
|
||||
- * in the staScanTable, assuming they pass the sanity checks... */
|
||||
- for (i = 0; i < ic->ic_nchans; i++) {
|
||||
- c = &ic->ic_channels[i];
|
||||
-
|
||||
- /* XR is not supported on turbo channels */
|
||||
- if (IEEE80211_IS_CHAN_TURBO(c) && vap->iv_flags & IEEE80211_F_XR)
|
||||
- continue;
|
||||
-
|
||||
- /* Dynamic channels are scanned in base mode */
|
||||
- if (!as->as_required_mode && !IEEE80211_IS_CHAN_ST(c))
|
||||
- continue;
|
||||
-
|
||||
- /* Use any 11g channel instead of 11b one. */
|
||||
- if (vap->iv_des_mode == IEEE80211_MODE_AUTO &&
|
||||
- IEEE80211_IS_CHAN_B(c) &&
|
||||
- find11gchannel(ic, i, c->ic_freq))
|
||||
- continue;
|
||||
-
|
||||
- /* Do not add channels already put into the scan list by the
|
||||
- * scan table - these have already been filtered by mode
|
||||
- * and for whether they are in the active channel list. */
|
||||
- if (checktable(staScanTable, c))
|
||||
- continue;
|
||||
-
|
||||
- /* Make sure the channel is active */
|
||||
- if ((c == NULL) || isclr(ic->ic_chan_active, c->ic_ieee))
|
||||
- continue;
|
||||
+ ieee80211_scan_add_channels(ic, ss, vap->iv_des_mode);
|
||||
|
||||
- /* Don't overrun */
|
||||
- if (ss->ss_last >= IEEE80211_SCAN_MAX)
|
||||
- break;
|
||||
-
|
||||
- ss->ss_chans[ss->ss_last++] = c;
|
||||
- }
|
||||
ss->ss_next = 0;
|
||||
/* XXX tunables */
|
||||
ss->ss_mindwell = msecs_to_jiffies(200); /* 200ms */
|
||||
@@ -761,18 +534,6 @@ pick_channel(struct ieee80211_scan_state
|
||||
if (IEEE80211_IS_CHAN_RADAR(c->chan))
|
||||
continue;
|
||||
|
||||
- /* Do not select 802.11a ST if mode is specified and is not
|
||||
- * 802.11a ST */
|
||||
- if (as->as_required_mode &&
|
||||
- IEEE80211_IS_CHAN_STURBO(c->chan) &&
|
||||
- (as->as_vap_desired_mode != IEEE80211_MODE_TURBO_STATIC_A))
|
||||
- continue;
|
||||
-
|
||||
- /* Verify mode matches any fixed mode specified */
|
||||
- if((c->chan->ic_flags & as->as_required_mode) !=
|
||||
- as->as_required_mode)
|
||||
- continue;
|
||||
-
|
||||
if ((ic->ic_bsschan != NULL) &&
|
||||
(ic->ic_bsschan != IEEE80211_CHAN_ANYC)) {
|
||||
|
||||
--- a/net80211/ieee80211_scan.c
|
||||
+++ b/net80211/ieee80211_scan.c
|
||||
@@ -958,6 +958,80 @@ ieee80211_scan_flush(struct ieee80211com
|
||||
}
|
||||
}
|
||||
|
||||
+static const u_int chanflags[] = {
|
||||
+ 0, /* IEEE80211_MODE_AUTO */
|
||||
+ IEEE80211_CHAN_A, /* IEEE80211_MODE_11A */
|
||||
+ IEEE80211_CHAN_B, /* IEEE80211_MODE_11B */
|
||||
+ IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_11G */
|
||||
+ IEEE80211_CHAN_FHSS, /* IEEE80211_MODE_FH */
|
||||
+ IEEE80211_CHAN_A, /* IEEE80211_MODE_TURBO_A */ /* for turbo mode look for AP in normal channel */
|
||||
+ IEEE80211_CHAN_PUREG, /* IEEE80211_MODE_TURBO_G */
|
||||
+ IEEE80211_CHAN_ST, /* IEEE80211_MODE_TURBO_STATIC_A */
|
||||
+};
|
||||
+
|
||||
+static struct ieee80211_channel *
|
||||
+find11gchannel(struct ieee80211com *ic, int i, int freq)
|
||||
+{
|
||||
+ struct ieee80211_channel *c;
|
||||
+ int j;
|
||||
+
|
||||
+ /*
|
||||
+ * The normal ordering in the channel list is b channel
|
||||
+ * immediately followed by g so optimize the search for
|
||||
+ * this. We'll still do a full search just in case.
|
||||
+ */
|
||||
+ for (j = i+1; j < ic->ic_nchans; j++) {
|
||||
+ c = &ic->ic_channels[j];
|
||||
+ if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c))
|
||||
+ return c;
|
||||
+ }
|
||||
+ for (j = 0; j < i; j++) {
|
||||
+ c = &ic->ic_channels[j];
|
||||
+ if (c->ic_freq == freq && IEEE80211_IS_CHAN_ANYG(c))
|
||||
+ return c;
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+void
|
||||
+ieee80211_scan_add_channels(struct ieee80211com *ic,
|
||||
+ struct ieee80211_scan_state *ss,
|
||||
+ enum ieee80211_phymode mode)
|
||||
+{
|
||||
+ struct ieee80211_channel *c, *cg;
|
||||
+ u_int modeflags;
|
||||
+ int i;
|
||||
+
|
||||
+ KASSERT(mode < ARRAY_SIZE(chanflags), ("Unexpected mode %u", mode));
|
||||
+ modeflags = chanflags[mode];
|
||||
+ for (i = 0; i < ic->ic_nchans; i++) {
|
||||
+ c = &ic->ic_channels[i];
|
||||
+ if (c == NULL || isclr(ic->ic_chan_active, c->ic_ieee))
|
||||
+ continue;
|
||||
+ if (c->ic_scanflags & IEEE80211_NOSCAN_SET)
|
||||
+ continue;
|
||||
+ if (modeflags &&
|
||||
+ ((c->ic_flags & IEEE80211_CHAN_ALLTURBO) !=
|
||||
+ (modeflags & IEEE80211_CHAN_ALLTURBO)))
|
||||
+ continue;
|
||||
+ if (mode == IEEE80211_MODE_AUTO) {
|
||||
+ /*
|
||||
+ * XXX special-case 11b/g channels so we select
|
||||
+ * the g channel if both are present.
|
||||
+ */
|
||||
+ if (IEEE80211_IS_CHAN_B(c) &&
|
||||
+ (cg = find11gchannel(ic, i, c->ic_freq)) != NULL)
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (ss->ss_last >= IEEE80211_SCAN_MAX)
|
||||
+ break;
|
||||
+ ss->ss_chans[ss->ss_last++] = c;
|
||||
+ }
|
||||
+}
|
||||
+EXPORT_SYMBOL(ieee80211_scan_add_channels);
|
||||
+
|
||||
+
|
||||
/*
|
||||
* Execute radar channel change. This is called when a radar/dfs
|
||||
* signal is detected. AP mode only. Return 1 on success, 0 on
|
||||
--- a/net80211/ieee80211_scan.h
|
||||
+++ b/net80211/ieee80211_scan.h
|
||||
@@ -219,4 +219,7 @@ void ieee80211_scanner_register(enum iee
|
||||
void ieee80211_scanner_unregister(enum ieee80211_opmode,
|
||||
const struct ieee80211_scanner *);
|
||||
void ieee80211_scanner_unregister_all(const struct ieee80211_scanner *);
|
||||
+void ieee80211_scan_add_channels(struct ieee80211com *ic,
|
||||
+ struct ieee80211_scan_state *ss,
|
||||
+ enum ieee80211_phymode mode);
|
||||
#endif /* _NET80211_IEEE80211_SCAN_H_ */
|
||||
--- a/net80211/ieee80211_wireless.c
|
||||
+++ b/net80211/ieee80211_wireless.c
|
||||
@@ -3873,6 +3873,106 @@ ieee80211_ioctl_kickmac(struct net_devic
|
||||
return ieee80211_ioctl_setmlme(dev, info, w, (char *)&mlme);
|
||||
}
|
||||
|
||||
+static inline void setflag(struct ieee80211_channel *c, int flag)
|
||||
+{
|
||||
+ if (flag)
|
||||
+ c->ic_scanflags |= IEEE80211_NOSCAN_SET;
|
||||
+ else
|
||||
+ c->ic_scanflags &= ~IEEE80211_NOSCAN_SET;
|
||||
+}
|
||||
+
|
||||
+static void setscanflag(struct ieee80211com *ic, int min, int max, int set)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < ic->ic_nchans; i++) {
|
||||
+ struct ieee80211_channel *c = &ic->ic_channels[i];
|
||||
+
|
||||
+ if (min == -1) {
|
||||
+ if (!(c->ic_scanflags & IEEE80211_NOSCAN_DEFAULT))
|
||||
+ setflag(c, set);
|
||||
+ } else if ((c->ic_freq >= min) && (c->ic_freq <= max)) {
|
||||
+ setflag(c, set);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ieee80211_ioctl_setscanlist(struct net_device *dev,
|
||||
+ struct iw_request_info *info,
|
||||
+ struct iw_point *data, char *extra)
|
||||
+{
|
||||
+ struct ieee80211vap *vap = dev->priv;
|
||||
+ struct ieee80211com *ic = vap->iv_ic;
|
||||
+ char *s, *next;
|
||||
+ int val = 1;
|
||||
+
|
||||
+ if (data->length <= 0)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ s = kmalloc(data->length + 1, GFP_KERNEL);
|
||||
+ if (!s)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ memset(s, 0, data->length + 1);
|
||||
+ if (copy_from_user(s, data->pointer, data->length))
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ s[data->length - 1] = '\0'; /* ensure null termination */
|
||||
+
|
||||
+ switch(*s) {
|
||||
+ case '-':
|
||||
+ val = 1;
|
||||
+ break;
|
||||
+ case '+':
|
||||
+ val = 0;
|
||||
+ break;
|
||||
+ default:
|
||||
+ goto error;
|
||||
+ }
|
||||
+ s++;
|
||||
+ next = s;
|
||||
+ do {
|
||||
+ next = strchr(s, ',');
|
||||
+ if (next) {
|
||||
+ *next = 0;
|
||||
+ next++;
|
||||
+ }
|
||||
+ if (!strcmp(s, "ALL")) {
|
||||
+ setscanflag(ic, 0, 10000, val);
|
||||
+ } else if (!strcmp(s, "REG")) {
|
||||
+ setscanflag(ic, -1, -1, val);
|
||||
+ } else {
|
||||
+ int min, max;
|
||||
+ char *n, *end = NULL;
|
||||
+
|
||||
+ n = strchr(s, '-');
|
||||
+ if (n) {
|
||||
+ *n = 0;
|
||||
+ n++;
|
||||
+ }
|
||||
+ min = simple_strtoul(s, &end, 10);
|
||||
+ if (end && *end)
|
||||
+ goto error;
|
||||
+ if (n) {
|
||||
+ max = simple_strtoul(n, &end, 10);
|
||||
+ if (end && *end)
|
||||
+ goto error;
|
||||
+ } else {
|
||||
+ max = min;
|
||||
+ }
|
||||
+ setscanflag(ic, min, max, val);
|
||||
+ }
|
||||
+ s = next;
|
||||
+ } while (next);
|
||||
+ return 0;
|
||||
+
|
||||
+error:
|
||||
+ if (s)
|
||||
+ kfree(s);
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
ieee80211_ioctl_addmac(struct net_device *dev, struct iw_request_info *info,
|
||||
void *w, char *extra)
|
||||
@@ -5656,6 +5756,8 @@ static const struct iw_priv_args ieee802
|
||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "minrate"},
|
||||
{IEEE80211_PARAM_MINRATE,
|
||||
0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_minrate"},
|
||||
+ { IEEE80211_IOCTL_SETSCANLIST,
|
||||
+ IW_PRIV_TYPE_CHAR | 255, 0, "setscanlist"},
|
||||
|
||||
#ifdef ATH_REVERSE_ENGINEERING
|
||||
/*
|
||||
@@ -5753,6 +5855,7 @@ static const iw_handler ieee80211_priv_h
|
||||
set_priv(IEEE80211_IOCTL_WDSADDMAC, ieee80211_ioctl_wdsmac),
|
||||
set_priv(IEEE80211_IOCTL_WDSDELMAC, ieee80211_ioctl_wdsdelmac),
|
||||
set_priv(IEEE80211_IOCTL_KICKMAC, ieee80211_ioctl_kickmac),
|
||||
+ set_priv(IEEE80211_IOCTL_SETSCANLIST, ieee80211_ioctl_setscanlist),
|
||||
#ifdef ATH_REVERSE_ENGINEERING
|
||||
set_priv(IEEE80211_IOCTL_READREG, ieee80211_ioctl_readreg),
|
||||
set_priv(IEEE80211_IOCTL_WRITEREG, ieee80211_ioctl_writereg),
|
265
net/madwifi/patches/352-ani_fix.patch
Normal file
265
net/madwifi/patches/352-ani_fix.patch
Normal file
@ -0,0 +1,265 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -1014,9 +1014,7 @@ ath_attach(u_int16_t devid, struct net_d
|
||||
*/
|
||||
sc->sc_hasveol = ath_hal_hasveol(ah);
|
||||
|
||||
- /* Interference mitigation/ambient noise immunity (ANI).
|
||||
- * In modes other than HAL_M_STA, it causes receive sensitivity
|
||||
- * problems for OFDM. */
|
||||
+ /* Interference mitigation/ambient noise immunity (ANI). */
|
||||
sc->sc_hasintmit = ath_hal_hasintmit(ah);
|
||||
|
||||
/* get mac address from hardware */
|
||||
@@ -1144,6 +1142,11 @@ ath_attach(u_int16_t devid, struct net_d
|
||||
sc->sc_rp_lasttsf = 0;
|
||||
sc->sc_last_tsf = 0;
|
||||
|
||||
+ /* set all 3 to auto */
|
||||
+ sc->sc_intmit = -1;
|
||||
+ sc->sc_noise_immunity = -1;
|
||||
+ sc->sc_ofdm_weak_det = -1;
|
||||
+
|
||||
return 0;
|
||||
bad3:
|
||||
ieee80211_ifdetach(ic);
|
||||
@@ -2428,6 +2431,43 @@ ath_chan2flags(struct ieee80211_channel
|
||||
return flags;
|
||||
}
|
||||
|
||||
+static int ath_setintmit(struct ath_softc *sc)
|
||||
+{
|
||||
+ struct ath_hal *ah = sc->sc_ah;
|
||||
+ int ret;
|
||||
+ int val;
|
||||
+
|
||||
+ if (!sc->sc_hasintmit)
|
||||
+ return 0;
|
||||
+
|
||||
+ switch(sc->sc_intmit) {
|
||||
+ case -1:
|
||||
+ if (sc->sc_opmode != IEEE80211_M_MONITOR)
|
||||
+ val = 1;
|
||||
+ else
|
||||
+ val = 0;
|
||||
+ break;
|
||||
+ case 0: /* disabled */
|
||||
+ case 1: /* enabled */
|
||||
+ val = sc->sc_intmit;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return 0;
|
||||
+ }
|
||||
+ ret = ath_hal_setintmit(ah, val);
|
||||
+ if (val)
|
||||
+ goto done;
|
||||
+
|
||||
+ /* manual settings */
|
||||
+ if ((sc->sc_noise_immunity >= 0) && (sc->sc_noise_immunity <= 5))
|
||||
+ ath_hal_setcapability(ah, HAL_CAP_INTMIT, 2, sc->sc_noise_immunity, NULL);
|
||||
+ if ((sc->sc_ofdm_weak_det == 0) || (sc->sc_ofdm_weak_det == 1))
|
||||
+ ath_hal_setcapability(ah, HAL_CAP_INTMIT, 3, sc->sc_ofdm_weak_det, NULL);
|
||||
+
|
||||
+done:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Context: process context
|
||||
*/
|
||||
@@ -2493,8 +2533,7 @@ ath_init(struct net_device *dev)
|
||||
if (sc->sc_softled)
|
||||
ath_hal_gpioCfgOutput(ah, sc->sc_ledpin);
|
||||
|
||||
- if ((sc->sc_opmode != HAL_M_STA) && sc->sc_hasintmit)
|
||||
- ath_hal_setintmit(ah, 0);
|
||||
+ ath_setintmit(sc);
|
||||
|
||||
/*
|
||||
* This is needed only to setup initial state
|
||||
@@ -2530,7 +2569,7 @@ ath_init(struct net_device *dev)
|
||||
* Enable MIB interrupts when there are hardware phy counters.
|
||||
* Note we only do this (at the moment) for station mode.
|
||||
*/
|
||||
- if (sc->sc_needmib && ic->ic_opmode == IEEE80211_M_STA)
|
||||
+ if (sc->sc_needmib && ath_hal_getintmit(ah, NULL))
|
||||
sc->sc_imask |= HAL_INT_MIB;
|
||||
ath_hal_intrset(ah, sc->sc_imask);
|
||||
|
||||
@@ -2787,9 +2826,7 @@ ath_reset(struct net_device *dev)
|
||||
EPRINTF(sc, "Unable to reset hardware: '%s' (HAL status %u)\n",
|
||||
ath_get_hal_status_desc(status), status);
|
||||
|
||||
- if ((sc->sc_opmode != HAL_M_STA) && sc->sc_hasintmit)
|
||||
- ath_hal_setintmit(ah, 0);
|
||||
-
|
||||
+ ath_setintmit(sc);
|
||||
ath_update_txpow(sc); /* update tx power state */
|
||||
ath_radar_update(sc);
|
||||
ath_setdefantenna(sc, sc->sc_defant);
|
||||
@@ -4174,6 +4211,8 @@ ath_calcrxfilter(struct ath_softc *sc)
|
||||
if (sc->sc_nmonvaps > 0)
|
||||
rfilt |= (HAL_RX_FILTER_CONTROL | HAL_RX_FILTER_BEACON |
|
||||
HAL_RX_FILTER_PROBEREQ | HAL_RX_FILTER_PROM);
|
||||
+ if (sc->sc_hasintmit && !sc->sc_needmib && ath_hal_getintmit(ah, NULL))
|
||||
+ rfilt |= HAL_RX_FILTER_PHYERR;
|
||||
if (sc->sc_curchan.privFlags & CHANNEL_DFS)
|
||||
rfilt |= (HAL_RX_FILTER_PHYERR | HAL_RX_FILTER_PHYRADAR);
|
||||
return rfilt;
|
||||
@@ -6526,9 +6565,6 @@ process_rx_again:
|
||||
rs->rs_rssi = 0;
|
||||
|
||||
len = rs->rs_datalen;
|
||||
- /* DMA sync. dies spectacularly if len == 0 */
|
||||
- if (len == 0)
|
||||
- goto rx_next;
|
||||
|
||||
if (rs->rs_more) {
|
||||
/*
|
||||
@@ -8876,9 +8912,7 @@ ath_chan_set(struct ath_softc *sc, struc
|
||||
if (sc->sc_softled)
|
||||
ath_hal_gpioCfgOutput(ah, sc->sc_ledpin);
|
||||
|
||||
- if ((sc->sc_opmode != HAL_M_STA) && sc->sc_hasintmit)
|
||||
- ath_hal_setintmit(ah, 0);
|
||||
-
|
||||
+ ath_setintmit(sc);
|
||||
sc->sc_curchan = hchan;
|
||||
ath_update_txpow(sc); /* update tx power state */
|
||||
ath_radar_update(sc);
|
||||
@@ -10655,9 +10689,54 @@ enum {
|
||||
ATH_RP_IGNORED = 24,
|
||||
ATH_RADAR_IGNORED = 25,
|
||||
ATH_MAXVAPS = 26,
|
||||
+ ATH_INTMIT = 27,
|
||||
+ ATH_NOISE_IMMUNITY = 28,
|
||||
+ ATH_OFDM_WEAK_DET = 29
|
||||
};
|
||||
|
||||
static int
|
||||
+ath_sysctl_set_intmit(struct ath_softc *sc, long ctl, u_int val)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ switch(ctl) {
|
||||
+ case ATH_INTMIT:
|
||||
+ sc->sc_intmit = val;
|
||||
+ break;
|
||||
+ case ATH_NOISE_IMMUNITY:
|
||||
+ sc->sc_noise_immunity = val;
|
||||
+ break;
|
||||
+ case ATH_OFDM_WEAK_DET:
|
||||
+ sc->sc_ofdm_weak_det = val;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ ret = ath_setintmit(sc);
|
||||
+ ath_calcrxfilter(sc);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ath_sysctl_get_intmit(struct ath_softc *sc, long ctl, u_int *val)
|
||||
+{
|
||||
+ struct ath_hal *ah = sc->sc_ah;
|
||||
+
|
||||
+ switch(ctl) {
|
||||
+ case ATH_INTMIT:
|
||||
+ *val = (ath_hal_getcapability(ah, HAL_CAP_INTMIT, 1, NULL) == HAL_OK);
|
||||
+ break;
|
||||
+ case ATH_NOISE_IMMUNITY:
|
||||
+ return ath_hal_getcapability(ah, HAL_CAP_INTMIT, 2, val);
|
||||
+ case ATH_OFDM_WEAK_DET:
|
||||
+ return ath_hal_getcapability(ah, HAL_CAP_INTMIT, 3, val);
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl, write, filp, buffer, lenp, ppos)
|
||||
{
|
||||
struct ath_softc *sc = ctl->extra1;
|
||||
@@ -10843,6 +10922,11 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
|
||||
case ATH_RADAR_IGNORED:
|
||||
sc->sc_radar_ignored = val;
|
||||
break;
|
||||
+ case ATH_INTMIT:
|
||||
+ case ATH_NOISE_IMMUNITY:
|
||||
+ case ATH_OFDM_WEAK_DET:
|
||||
+ ret = ath_sysctl_set_intmit(sc, (long)ctl->extra2, val);
|
||||
+ break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
@@ -10909,6 +10993,11 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
|
||||
case ATH_RADAR_IGNORED:
|
||||
val = sc->sc_radar_ignored;
|
||||
break;
|
||||
+ case ATH_INTMIT:
|
||||
+ case ATH_NOISE_IMMUNITY:
|
||||
+ case ATH_OFDM_WEAK_DET:
|
||||
+ ret = ath_sysctl_get_intmit(sc, (long)ctl->extra2, &val);
|
||||
+ break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
@@ -11086,6 +11175,24 @@ static const ctl_table ath_sysctl_templa
|
||||
.proc_handler = ath_sysctl_halparam,
|
||||
.extra2 = (void *)ATH_RADAR_IGNORED,
|
||||
},
|
||||
+ { .ctl_name = CTL_AUTO,
|
||||
+ .procname = "intmit",
|
||||
+ .mode = 0644,
|
||||
+ .proc_handler = ath_sysctl_halparam,
|
||||
+ .extra2 = (void *)ATH_INTMIT,
|
||||
+ },
|
||||
+ { .ctl_name = CTL_AUTO,
|
||||
+ .procname = "noise_immunity",
|
||||
+ .mode = 0644,
|
||||
+ .proc_handler = ath_sysctl_halparam,
|
||||
+ .extra2 = (void *)ATH_NOISE_IMMUNITY,
|
||||
+ },
|
||||
+ { .ctl_name = CTL_AUTO,
|
||||
+ .procname = "ofdm_weak_det",
|
||||
+ .mode = 0644,
|
||||
+ .proc_handler = ath_sysctl_halparam,
|
||||
+ .extra2 = (void *)ATH_OFDM_WEAK_DET,
|
||||
+ },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
--- a/ath/if_athvar.h
|
||||
+++ b/ath/if_athvar.h
|
||||
@@ -693,6 +693,10 @@ struct ath_softc {
|
||||
unsigned int sc_txcont_power; /* Continuous transmit power in 0.5dBm units */
|
||||
unsigned int sc_txcont_rate; /* Continuous transmit rate in Mbps */
|
||||
|
||||
+ int8_t sc_intmit; /* Interference mitigation enabled, -1 = auto, based on mode, 0/1 = off/on */
|
||||
+ int8_t sc_noise_immunity; /* Noise immunity level, 0-4, -1 == auto) */
|
||||
+ int8_t sc_ofdm_weak_det; /* OFDM weak frames detection, -1 == auto */
|
||||
+
|
||||
/* rate tables */
|
||||
const HAL_RATE_TABLE *sc_rates[IEEE80211_MODE_MAX];
|
||||
const HAL_RATE_TABLE *sc_currates; /* current rate table */
|
||||
--- a/ath/if_ath_hal.h
|
||||
+++ b/ath/if_ath_hal.h
|
||||
@@ -67,14 +67,14 @@ static inline HAL_POWER_MODE ath_hal_get
|
||||
|
||||
static inline HAL_BOOL ath_hal_getdiagstate(struct ath_hal *ah, int request,
|
||||
const void *args, u_int32_t argsize,
|
||||
- void **result,
|
||||
+ void *result,
|
||||
u_int32_t *resultsize)
|
||||
{
|
||||
HAL_BOOL ret;
|
||||
ATH_HAL_LOCK_IRQ(ah->ah_sc);
|
||||
ath_hal_set_function(__func__);
|
||||
ret =
|
||||
- ah->ah_getDiagState(ah, request, args, argsize, *result,
|
||||
+ ah->ah_getDiagState(ah, request, args, argsize, result,
|
||||
resultsize);
|
||||
ath_hal_set_function(NULL);
|
||||
ATH_HAL_UNLOCK_IRQ(ah->ah_sc);
|
19
net/madwifi/patches/353-devid.patch
Normal file
19
net/madwifi/patches/353-devid.patch
Normal file
@ -0,0 +1,19 @@
|
||||
--- a/ath/if_ath_pci.c
|
||||
+++ b/ath/if_ath_pci.c
|
||||
@@ -114,11 +114,15 @@ static struct pci_device_id ath_pci_id_t
|
||||
{ 0x168c, 0x0023, PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ 0x168c, 0x0024, PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ 0x168c, 0x9013, PCI_ANY_ID, PCI_ANY_ID }, /* sonicwall */
|
||||
+ { 0x168c, 0xff16, PCI_ANY_ID, PCI_ANY_ID },
|
||||
+ { 0x168c, 0xff1a, PCI_ANY_ID, PCI_ANY_ID },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static u16 ath_devidmap[][2] = {
|
||||
- { 0x9013, 0x0013 }
|
||||
+ { 0x9013, 0x0013 },
|
||||
+ { 0xff16, 0x0013 },
|
||||
+ { 0xff1a, 0x001a }
|
||||
};
|
||||
|
||||
static int
|
95
net/madwifi/patches/354-lantiq_eeprom.patch
Normal file
95
net/madwifi/patches/354-lantiq_eeprom.patch
Normal file
@ -0,0 +1,95 @@
|
||||
--- a/ath_hal/ah_os.c
|
||||
+++ b/ath_hal/ah_os.c
|
||||
@@ -343,6 +343,46 @@ EXPORT_SYMBOL(ath_hal_func);
|
||||
* NB: see the comments in ah_osdep.h about byte-swapping register
|
||||
* reads and writes to understand what's going on below.
|
||||
*/
|
||||
+
|
||||
+#ifdef CONFIG_LANTIQ
|
||||
+extern int lantiq_emulate_madwifi_eep;
|
||||
+extern unsigned long long lantiq_madwifi_eep_addr;
|
||||
+#define EEPROM_EMULATION 1
|
||||
+#endif
|
||||
+
|
||||
+#ifdef EEPROM_EMULATION
|
||||
+static int ath_hal_eeprom(struct ath_hal *ah, unsigned long addr, int val, int write)
|
||||
+{
|
||||
+ static int addrsel = 0;
|
||||
+ static int rc = 0;
|
||||
+
|
||||
+ if (write) {
|
||||
+ if(addr == 0x6000) {
|
||||
+ addrsel = val * 2;
|
||||
+ rc = 0;
|
||||
+ }
|
||||
+ } else {
|
||||
+ switch(addr)
|
||||
+ {
|
||||
+ case 0x600c:
|
||||
+ if(rc++ < 2)
|
||||
+ val = 0x00000000;
|
||||
+ else
|
||||
+ val = 0x00000002;
|
||||
+ break;
|
||||
+ case 0x6004:
|
||||
+ val = cpu_to_le16(__raw_readw((u16 *) KSEG1ADDR(lantiq_madwifi_eep_addr + addrsel)));
|
||||
+ /* this forces the regdomain to 0x00 (worldwide), as the original setting
|
||||
+ * causes issues with the HAL */
|
||||
+ if (addrsel == 0x17e)
|
||||
+ val = 0;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ return val;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
void __ahdecl
|
||||
ath_hal_reg_write(struct ath_hal *ah, u_int reg, u_int32_t val)
|
||||
{
|
||||
@@ -351,20 +391,33 @@ ath_hal_reg_write(struct ath_hal *ah, u_
|
||||
ath_hal_printf(ah, "%s: WRITE 0x%x <= 0x%x\n",
|
||||
(ath_hal_func ?: "unknown"), reg, val);
|
||||
#endif
|
||||
- _OS_REG_WRITE(ah, reg, val);
|
||||
+#ifdef EEPROM_EMULATION
|
||||
+ if((reg >= 0x6000) && (reg <= 0x6010) && lantiq_emulate_madwifi_eep)
|
||||
+ {
|
||||
+ val = ath_hal_eeprom(ah, reg, val, 1);
|
||||
+ } else
|
||||
+#endif
|
||||
+ _OS_REG_WRITE(ah, reg, val);
|
||||
}
|
||||
EXPORT_SYMBOL(ath_hal_reg_write);
|
||||
|
||||
+
|
||||
/* This should only be called while holding the lock, sc->sc_hal_lock. */
|
||||
u_int32_t __ahdecl
|
||||
ath_hal_reg_read(struct ath_hal *ah, u_int reg)
|
||||
{
|
||||
- u_int32_t val;
|
||||
+ u_int32_t val;
|
||||
+#ifdef EEPROM_EMULATION
|
||||
+ if((reg >= 0x6000) && (reg <= 0x6010) && lantiq_emulate_madwifi_eep)
|
||||
+ {
|
||||
+ val = ath_hal_eeprom(ah, reg, 0, 0);
|
||||
+ } else
|
||||
+#endif
|
||||
+ val = _OS_REG_READ(ah, reg);
|
||||
|
||||
- val = _OS_REG_READ(ah, reg);
|
||||
#ifdef AH_DEBUG
|
||||
if (ath_hal_debug > 1)
|
||||
- ath_hal_printf(ah, "%s: READ 0x%x => 0x%x\n",
|
||||
+ ath_hal_printf(ah, "%s: READ 0x%x => 0x%x\n",
|
||||
(ath_hal_func ?: "unknown"), reg, val);
|
||||
#endif
|
||||
return val;
|
||||
@@ -581,7 +634,6 @@ init_ath_hal(void)
|
||||
{
|
||||
const char *sep;
|
||||
int i;
|
||||
-
|
||||
printk(KERN_INFO "%s: %s (", dev_info, ath_hal_version);
|
||||
sep = "";
|
||||
for (i = 0; ath_hal_buildopts[i] != NULL; i++) {
|
77
net/madwifi/patches/355-eap_auth_disassoc.patch
Normal file
77
net/madwifi/patches/355-eap_auth_disassoc.patch
Normal file
@ -0,0 +1,77 @@
|
||||
This patch causes STA mode interfaces to disassociate if transmission of assoc/auth
|
||||
critical packets failed.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -8334,6 +8334,14 @@ ath_tx_processq(struct ath_softc *sc, st
|
||||
#endif
|
||||
if (ts->ts_status & HAL_TXERR_XRETRY) {
|
||||
sc->sc_stats.ast_tx_xretries++;
|
||||
+ if (SKB_CB(bf->bf_skb)->auth_pkt &&
|
||||
+ (ni->ni_vap->iv_opmode == IEEE80211_M_STA)) {
|
||||
+ struct ieee80211vap *vap = ni->ni_vap;
|
||||
+
|
||||
+ /* if roaming is enabled, try reassociating, otherwise
|
||||
+ * disassociate and go back to the scan state */
|
||||
+ vap->iv_mgtsend.function(vap->iv_mgtsend.data);
|
||||
+ }
|
||||
if (ni->ni_flags & IEEE80211_NODE_UAPSD_TRIG) {
|
||||
ni->ni_stats.ns_tx_eosplost++;
|
||||
DPRINTF(sc, ATH_DEBUG_UAPSD,
|
||||
--- a/net80211/ieee80211_linux.c
|
||||
+++ b/net80211/ieee80211_linux.c
|
||||
@@ -156,6 +156,7 @@ ieee80211_getmgtframe(u_int8_t **frm, u_
|
||||
if (off != 0)
|
||||
skb_reserve(skb, align - off);
|
||||
|
||||
+ SKB_CB(skb)->auth_pkt = 0;
|
||||
SKB_CB(skb)->ni = NULL;
|
||||
SKB_CB(skb)->flags = 0;
|
||||
SKB_CB(skb)->next = NULL;
|
||||
--- a/net80211/ieee80211_linux.h
|
||||
+++ b/net80211/ieee80211_linux.h
|
||||
@@ -393,6 +393,7 @@ typedef spinlock_t acl_lock_t;
|
||||
void (*next_destructor)(struct sk_buff *skb);
|
||||
#endif
|
||||
struct sk_buff *next; /* fast frame sk_buf chain */
|
||||
+ u_int8_t auth_pkt;
|
||||
};
|
||||
|
||||
|
||||
--- a/net80211/ieee80211_output.c
|
||||
+++ b/net80211/ieee80211_output.c
|
||||
@@ -778,6 +778,8 @@ ieee80211_encap(struct ieee80211_node *n
|
||||
else
|
||||
hdrsize = sizeof(struct ieee80211_frame);
|
||||
|
||||
+ SKB_CB(skb)->auth_pkt = (eh.ether_type == __constant_htons(ETHERTYPE_PAE));
|
||||
+
|
||||
switch (vap->iv_opmode) {
|
||||
case IEEE80211_M_IBSS:
|
||||
case IEEE80211_M_AHDEMO:
|
||||
@@ -1622,6 +1624,7 @@ ieee80211_add_xr_param(u_int8_t *frm, st
|
||||
ie->param_len = frm - &ie->param_oui[0];
|
||||
return frm;
|
||||
}
|
||||
+
|
||||
#endif
|
||||
/*
|
||||
* Send a probe request frame with the specified ssid
|
||||
@@ -1886,6 +1889,7 @@ ieee80211_send_mgmt(struct ieee80211_nod
|
||||
sizeof(u_int16_t)+IEEE80211_CHALLENGE_LEN : 0));
|
||||
if (skb == NULL)
|
||||
senderr(ENOMEM, is_tx_nobuf);
|
||||
+ SKB_CB(skb)->auth_pkt = 1;
|
||||
|
||||
((__le16 *)frm)[0] =
|
||||
(is_shared_key) ? htole16(IEEE80211_AUTH_ALG_SHARED)
|
||||
@@ -1960,6 +1964,7 @@ ieee80211_send_mgmt(struct ieee80211_nod
|
||||
vap->app_ie[IEEE80211_APPIE_FRAME_ASSOC_REQ].length);
|
||||
if (skb == NULL)
|
||||
senderr(ENOMEM, is_tx_nobuf);
|
||||
+ SKB_CB(skb)->auth_pkt = 1;
|
||||
|
||||
capinfo = 0;
|
||||
if (vap->iv_opmode == IEEE80211_M_IBSS)
|
49
net/madwifi/patches/356-hidden_ssid.patch
Normal file
49
net/madwifi/patches/356-hidden_ssid.patch
Normal file
@ -0,0 +1,49 @@
|
||||
This patch fixes the detection of hidden SSIDs as transmitted
|
||||
by some cisco systems.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
|
||||
--- a/net80211/ieee80211_scan_sta.c
|
||||
+++ b/net80211/ieee80211_scan_sta.c
|
||||
@@ -209,6 +209,19 @@ saveie(u_int8_t **iep, const u_int8_t *i
|
||||
ieee80211_saveie(iep, ie);
|
||||
}
|
||||
|
||||
+
|
||||
+static inline int is_empty_ssid(u_int8_t *ssid)
|
||||
+{
|
||||
+ if (!ssid)
|
||||
+ return 1;
|
||||
+ if (ssid[1] == 0)
|
||||
+ return 1;
|
||||
+ if ((ssid[1] == 1) && (ssid[2] == 0))
|
||||
+ return 1;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/*
|
||||
* Process a beacon or probe response frame; create an
|
||||
* entry in the scan cache or update any previous entry.
|
||||
@@ -233,8 +246,8 @@ sta_add(struct ieee80211_scan_state *ss,
|
||||
SCAN_STA_LOCK_IRQ(st);
|
||||
LIST_FOREACH(se, &st->st_hash[hash], se_hash)
|
||||
if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr) &&
|
||||
- sp->ssid[1] == se->base.se_ssid[1] &&
|
||||
- !memcmp(se->base.se_ssid+2, sp->ssid+2, se->base.se_ssid[1]))
|
||||
+ (is_empty_ssid(sp->ssid) || (sp->ssid[1] == se->base.se_ssid[1] &&
|
||||
+ !memcmp(se->base.se_ssid+2, sp->ssid+2, se->base.se_ssid[1]))))
|
||||
goto found;
|
||||
|
||||
MALLOC(se, struct sta_entry *, sizeof(struct sta_entry),
|
||||
@@ -252,8 +265,8 @@ found:
|
||||
ise = &se->base;
|
||||
|
||||
/* XXX ap beaconing multiple ssid w/ same bssid */
|
||||
- if (sp->ssid[1] != 0 &&
|
||||
- (ISPROBE(subtype) || ise->se_ssid[1] == 0))
|
||||
+ if (!is_empty_ssid(sp->ssid) &&
|
||||
+ (ISPROBE(subtype) || is_empty_ssid(ise->se_ssid)))
|
||||
memcpy(ise->se_ssid, sp->ssid, 2 + sp->ssid[1]);
|
||||
|
||||
memcpy(ise->se_rates, sp->rates,
|
160
net/madwifi/patches/357-bgscan_thresh.patch
Normal file
160
net/madwifi/patches/357-bgscan_thresh.patch
Normal file
@ -0,0 +1,160 @@
|
||||
Add an optional background scanning threshold triggered by low rssi
|
||||
(useful for passing updated scan results to the supplicant ahead of
|
||||
time, before losing connectivity entirely)
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
|
||||
--- a/net80211/ieee80211_ioctl.h
|
||||
+++ b/net80211/ieee80211_ioctl.h
|
||||
@@ -646,6 +646,7 @@ enum {
|
||||
IEEE80211_PARAM_MINRATE = 76, /* Minimum rate (by table index) */
|
||||
IEEE80211_PARAM_PROTMODE_RSSI = 77, /* RSSI Threshold for enabling protection mode */
|
||||
IEEE80211_PARAM_PROTMODE_TIMEOUT = 78, /* Timeout for expiring protection mode */
|
||||
+ IEEE80211_PARAM_BGSCAN_THRESH = 79, /* bg scan rssi threshold */
|
||||
};
|
||||
|
||||
#define SIOCG80211STATS (SIOCDEVPRIVATE+2)
|
||||
--- a/net80211/ieee80211_var.h
|
||||
+++ b/net80211/ieee80211_var.h
|
||||
@@ -92,6 +92,8 @@
|
||||
#define IEEE80211_BGSCAN_IDLE_MIN 100 /* min idle time (ms) */
|
||||
#define IEEE80211_BGSCAN_IDLE_DEFAULT 250 /* default idle time (ms) */
|
||||
|
||||
+#define IEEE80211_BGSCAN_TRIGGER_INTVL 20 /* min trigger interval for thresh based bgscan (secs) */
|
||||
+
|
||||
#define IEEE80211_COVERAGE_CLASS_MAX 31 /* max coverage class */
|
||||
#define IEEE80211_REGCLASSIDS_MAX 10 /* max regclass id list */
|
||||
|
||||
@@ -219,6 +221,10 @@ struct ieee80211vap {
|
||||
u_int8_t iv_nickname[IEEE80211_NWID_LEN];
|
||||
u_int iv_bgscanidle; /* bg scan idle threshold */
|
||||
u_int iv_bgscanintvl; /* bg scan min interval */
|
||||
+ u_int iv_bgscanthr; /* bg scan rssi threshold */
|
||||
+ u_int iv_bgscantrintvl; /* bg scan trigger interval */
|
||||
+ unsigned long iv_bgscanthr_next; /* last trigger for bgscan */
|
||||
+ unsigned long iv_lastconnect; /* time of last connect attempt */
|
||||
u_int iv_scanvalid; /* scan cache valid threshold */
|
||||
struct ieee80211_roam iv_roam; /* sta-mode roaming state */
|
||||
|
||||
@@ -608,6 +614,7 @@ MALLOC_DECLARE(M_80211_VAP);
|
||||
#define IEEE80211_FEXT_SWBMISS 0x00000400 /* CONF: use software beacon timer */
|
||||
#define IEEE80211_FEXT_DROPUNENC_EAPOL 0x00000800 /* CONF: drop unencrypted eapol frames */
|
||||
#define IEEE80211_FEXT_APPIE_UPDATE 0x00001000 /* STATE: beacon APP IE updated */
|
||||
+#define IEEE80211_FEXT_BGSCAN_THR 0x00002000 /* bgscan due to low rssi */
|
||||
|
||||
#define IEEE80211_COM_UAPSD_ENABLE(_ic) ((_ic)->ic_flags_ext |= IEEE80211_FEXT_UAPSD)
|
||||
#define IEEE80211_COM_UAPSD_DISABLE(_ic) ((_ic)->ic_flags_ext &= ~IEEE80211_FEXT_UAPSD)
|
||||
--- a/net80211/ieee80211_wireless.c
|
||||
+++ b/net80211/ieee80211_wireless.c
|
||||
@@ -2744,6 +2744,9 @@ ieee80211_ioctl_setparam(struct net_devi
|
||||
else
|
||||
retv = EINVAL;
|
||||
break;
|
||||
+ case IEEE80211_PARAM_BGSCAN_THRESH:
|
||||
+ vap->iv_bgscanthr = value;
|
||||
+ break;
|
||||
case IEEE80211_PARAM_MCAST_RATE:
|
||||
/* units are in KILObits per second */
|
||||
if (value >= 256 && value <= 54000)
|
||||
@@ -3144,6 +3147,9 @@ ieee80211_ioctl_getparam(struct net_devi
|
||||
case IEEE80211_PARAM_BGSCAN_INTERVAL:
|
||||
param[0] = vap->iv_bgscanintvl / HZ; /* seconds */
|
||||
break;
|
||||
+ case IEEE80211_PARAM_BGSCAN_THRESH:
|
||||
+ param[0] = vap->iv_bgscanthr; /* rssi */
|
||||
+ break;
|
||||
case IEEE80211_PARAM_MCAST_RATE:
|
||||
param[0] = vap->iv_mcast_rate; /* seconds */
|
||||
break;
|
||||
@@ -5666,6 +5672,10 @@ static const struct iw_priv_args ieee802
|
||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "bgscanintvl" },
|
||||
{ IEEE80211_PARAM_BGSCAN_INTERVAL,
|
||||
0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_bgscanintvl" },
|
||||
+ { IEEE80211_PARAM_BGSCAN_THRESH,
|
||||
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "bgscanthr" },
|
||||
+ { IEEE80211_PARAM_BGSCAN_THRESH,
|
||||
+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_bgscanthr" },
|
||||
{ IEEE80211_PARAM_MCAST_RATE,
|
||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "mcast_rate" },
|
||||
{ IEEE80211_PARAM_MCAST_RATE,
|
||||
--- a/net80211/ieee80211_input.c
|
||||
+++ b/net80211/ieee80211_input.c
|
||||
@@ -3013,8 +3013,10 @@ contbgscan(struct ieee80211vap *vap)
|
||||
{
|
||||
struct ieee80211com *ic = vap->iv_ic;
|
||||
|
||||
+ vap->iv_bgscantrintvl = (vap->iv_bgscantrintvl + 1) % 4;
|
||||
return ((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN) &&
|
||||
- time_after(jiffies, ic->ic_lastdata + vap->iv_bgscanidle));
|
||||
+ (((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN_THR) && !vap->iv_bgscantrintvl) ||
|
||||
+ time_after(jiffies, ic->ic_lastdata + vap->iv_bgscanidle)));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
@@ -3258,6 +3260,25 @@ ieee80211_recv_mgmt(struct ieee80211vap
|
||||
/* record tsf of last beacon */
|
||||
memcpy(ni->ni_tstamp.data, scan.tstamp,
|
||||
sizeof(ni->ni_tstamp));
|
||||
+
|
||||
+ /* When rssi is low, start doing bgscans more frequently to allow
|
||||
+ * the supplicant to make a better switching decision */
|
||||
+ if (!(ic->ic_flags & IEEE80211_F_SCAN) && (rssi < vap->iv_bgscanthr) &&
|
||||
+ (!vap->iv_bgscanthr_next ||
|
||||
+ !time_before(jiffies, vap->iv_bgscanthr_next)) &&
|
||||
+ (vap->iv_state == IEEE80211_S_RUN) &&
|
||||
+ time_after(jiffies, vap->iv_lastconnect +
|
||||
+ msecs_to_jiffies(IEEE80211_BGSCAN_INTVAL_MIN * 1000))) {
|
||||
+ int ret;
|
||||
+
|
||||
+ ic->ic_lastdata = 0;
|
||||
+ ic->ic_lastscan = 0;
|
||||
+ ic->ic_flags_ext |= IEEE80211_FEXT_BGSCAN_THR;
|
||||
+ ret = ieee80211_bg_scan(vap);
|
||||
+ if (ret)
|
||||
+ vap->iv_bgscanthr_next = jiffies + msecs_to_jiffies(IEEE80211_BGSCAN_TRIGGER_INTVL * 1000);
|
||||
+ }
|
||||
+
|
||||
if (ni->ni_intval != scan.bintval) {
|
||||
IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,
|
||||
"beacon interval divergence: "
|
||||
--- a/net80211/ieee80211_scan.c
|
||||
+++ b/net80211/ieee80211_scan.c
|
||||
@@ -616,6 +616,7 @@ ieee80211_cancel_scan(struct ieee80211va
|
||||
|
||||
/* clear bg scan NOPICK and mark cancel request */
|
||||
ss->ss_flags &= ~IEEE80211_SCAN_NOPICK;
|
||||
+ ic->ic_flags_ext &= ~IEEE80211_FEXT_BGSCAN_THR;
|
||||
SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_CANCEL;
|
||||
ss->ss_ops->scan_cancel(ss, vap);
|
||||
/* force it to fire asap */
|
||||
@@ -782,7 +783,7 @@ again:
|
||||
ieee80211_sta_pwrsave(vap, 0);
|
||||
if (ss->ss_next >= ss->ss_last) {
|
||||
ieee80211_notify_scan_done(vap);
|
||||
- ic->ic_flags_ext &= ~IEEE80211_FEXT_BGSCAN;
|
||||
+ ic->ic_flags_ext &= ~(IEEE80211_FEXT_BGSCAN|IEEE80211_FEXT_BGSCAN_THR);
|
||||
}
|
||||
}
|
||||
SCAN_PRIVATE(ss)->ss_iflags &= ~ISCAN_CANCEL;
|
||||
--- a/net80211/ieee80211_proto.c
|
||||
+++ b/net80211/ieee80211_proto.c
|
||||
@@ -1450,6 +1450,7 @@ __ieee80211_newstate(struct ieee80211vap
|
||||
}
|
||||
break;
|
||||
case IEEE80211_S_AUTH:
|
||||
+ vap->iv_lastconnect = jiffies;
|
||||
/* auth frames are possible between IBSS nodes,
|
||||
* see 802.11-1999, chapter 5.7.6 */
|
||||
KASSERT(vap->iv_opmode == IEEE80211_M_STA ||
|
||||
--- a/net80211/ieee80211_output.c
|
||||
+++ b/net80211/ieee80211_output.c
|
||||
@@ -238,7 +238,8 @@ ieee80211_hardstart(struct sk_buff *skb,
|
||||
}
|
||||
|
||||
/* Cancel any running BG scan */
|
||||
- ieee80211_cancel_scan(vap);
|
||||
+ if (!(ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN_THR) && (vap->iv_state == IEEE80211_S_RUN))
|
||||
+ ieee80211_cancel_scan(vap);
|
||||
|
||||
/*
|
||||
* Find the node for the destination so we can do
|
18
net/madwifi/patches/358-ignore_broken_bssid.patch
Normal file
18
net/madwifi/patches/358-ignore_broken_bssid.patch
Normal file
@ -0,0 +1,18 @@
|
||||
Some misconfigured APs broadcast NULL BSSIDs, which can confuse the STA
|
||||
Ignore those when scanning.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
|
||||
--- a/net80211/ieee80211_scan_sta.c
|
||||
+++ b/net80211/ieee80211_scan_sta.c
|
||||
@@ -242,6 +242,10 @@ sta_add(struct ieee80211_scan_state *ss,
|
||||
struct ieee80211_scan_entry *ise;
|
||||
int hash;
|
||||
|
||||
+ /* workaround for broken APs that broadcast NULL BSSIDs */
|
||||
+ if (memcmp(wh->i_addr3, "\x00\x00\x00\x00\x00\x00", 6) == 0)
|
||||
+ return 0;
|
||||
+
|
||||
hash = STA_HASH(macaddr);
|
||||
SCAN_STA_LOCK_IRQ(st);
|
||||
LIST_FOREACH(se, &st->st_hash[hash], se_hash)
|
31
net/madwifi/patches/359-disable_reassoc.patch
Normal file
31
net/madwifi/patches/359-disable_reassoc.patch
Normal file
@ -0,0 +1,31 @@
|
||||
Add a preliminary fix for the reassoc check, but disable reassoc entirely for now
|
||||
until we've figured out why it fails frequently.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
|
||||
--- a/net80211/ieee80211_node.c
|
||||
+++ b/net80211/ieee80211_node.c
|
||||
@@ -599,10 +599,9 @@ ieee80211_ibss_merge(struct ieee80211_no
|
||||
EXPORT_SYMBOL(ieee80211_ibss_merge);
|
||||
|
||||
static __inline int
|
||||
-ssid_equal(const struct ieee80211_node *a, const struct ieee80211_node *b)
|
||||
+bssid_equal(const struct ieee80211_node *a, const struct ieee80211_node *b)
|
||||
{
|
||||
- return (a->ni_esslen == b->ni_esslen &&
|
||||
- memcmp(a->ni_essid, b->ni_essid, a->ni_esslen) == 0);
|
||||
+ return (memcmp(a->ni_bssid, b->ni_bssid, IEEE80211_ADDR_LEN) == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -634,8 +633,8 @@ ieee80211_sta_join1(struct ieee80211_nod
|
||||
* Check if old+new node have the same ssid in which
|
||||
* case we can reassociate when operating in sta mode.
|
||||
*/
|
||||
- canreassoc = ((obss != NULL) &&
|
||||
- (vap->iv_state == IEEE80211_S_RUN) && ssid_equal(obss, selbs));
|
||||
+ canreassoc = 0; /* ((obss != NULL) &&
|
||||
+ (vap->iv_state == IEEE80211_S_RUN) && bssid_equal(obss, selbs)); */
|
||||
vap->iv_bss = selbs;
|
||||
IEEE80211_ADDR_COPY(vap->iv_bssid, selbs->ni_bssid);
|
||||
if (obss != NULL)
|
242
net/madwifi/patches/360-sta_nodes.patch
Normal file
242
net/madwifi/patches/360-sta_nodes.patch
Normal file
@ -0,0 +1,242 @@
|
||||
Drop stale AP nodes from the client list when disconnecting.
|
||||
Fixes some reassoc issues.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
|
||||
--- a/net80211/ieee80211_proto.c
|
||||
+++ b/net80211/ieee80211_proto.c
|
||||
@@ -1348,7 +1348,7 @@ __ieee80211_newstate(struct ieee80211vap
|
||||
IEEE80211_SEND_MGMT(ni,
|
||||
IEEE80211_FC0_SUBTYPE_DISASSOC,
|
||||
IEEE80211_REASON_ASSOC_LEAVE);
|
||||
- ieee80211_sta_leave(ni);
|
||||
+ ieee80211_node_leave(ni);
|
||||
break;
|
||||
case IEEE80211_M_HOSTAP:
|
||||
ieee80211_iterate_nodes(&ic->ic_sta,
|
||||
@@ -1358,12 +1358,14 @@ __ieee80211_newstate(struct ieee80211vap
|
||||
break;
|
||||
}
|
||||
goto reset;
|
||||
+ case IEEE80211_S_AUTH:
|
||||
case IEEE80211_S_ASSOC:
|
||||
switch (vap->iv_opmode) {
|
||||
case IEEE80211_M_STA:
|
||||
IEEE80211_SEND_MGMT(ni,
|
||||
IEEE80211_FC0_SUBTYPE_DEAUTH,
|
||||
IEEE80211_REASON_AUTH_LEAVE);
|
||||
+ ieee80211_node_leave(ni);
|
||||
break;
|
||||
case IEEE80211_M_HOSTAP:
|
||||
ieee80211_iterate_nodes(&ic->ic_sta,
|
||||
@@ -1376,7 +1378,6 @@ __ieee80211_newstate(struct ieee80211vap
|
||||
case IEEE80211_S_SCAN:
|
||||
ieee80211_cancel_scan(vap);
|
||||
goto reset;
|
||||
- case IEEE80211_S_AUTH:
|
||||
reset:
|
||||
ieee80211_reset_bss(vap);
|
||||
break;
|
||||
@@ -1429,10 +1430,12 @@ __ieee80211_newstate(struct ieee80211vap
|
||||
IEEE80211_SCAN_FOREVER,
|
||||
vap->iv_des_nssid, vap->iv_des_ssid,
|
||||
NULL);
|
||||
+ else
|
||||
+ ieee80211_node_leave(vap->iv_bss);
|
||||
break;
|
||||
case IEEE80211_S_RUN: /* beacon miss */
|
||||
if (vap->iv_opmode == IEEE80211_M_STA) {
|
||||
- ieee80211_sta_leave(ni);
|
||||
+ ieee80211_node_leave(ni);
|
||||
vap->iv_flags &= ~IEEE80211_F_SIBSS; /* XXX */
|
||||
if (ic->ic_roaming == IEEE80211_ROAMING_AUTO)
|
||||
ieee80211_check_scan(vap,
|
||||
@@ -1511,7 +1514,7 @@ __ieee80211_newstate(struct ieee80211vap
|
||||
IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 0);
|
||||
break;
|
||||
case IEEE80211_S_RUN:
|
||||
- ieee80211_sta_leave(ni);
|
||||
+ ieee80211_node_leave(ni);
|
||||
if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) {
|
||||
/* NB: caller specifies ASSOC/REASSOC by arg */
|
||||
IEEE80211_SEND_MGMT(ni, arg ?
|
||||
@@ -1779,6 +1782,7 @@ ieee80211_newstate(struct ieee80211vap *
|
||||
ieee80211_state_name[nstate],
|
||||
ieee80211_state_name[dstate]);
|
||||
|
||||
+ ieee80211_update_link_status(vap, nstate, ostate);
|
||||
switch (nstate) {
|
||||
case IEEE80211_S_AUTH:
|
||||
case IEEE80211_S_ASSOC:
|
||||
--- a/net80211/ieee80211_linux.c
|
||||
+++ b/net80211/ieee80211_linux.c
|
||||
@@ -233,33 +233,59 @@ ieee80211_vlan_vdetach(struct ieee80211v
|
||||
}
|
||||
|
||||
void
|
||||
-ieee80211_notify_node_join(struct ieee80211_node *ni, int newassoc)
|
||||
+ieee80211_update_link_status(struct ieee80211vap *vap, int nstate, int ostate)
|
||||
{
|
||||
- struct ieee80211vap *vap = ni->ni_vap;
|
||||
struct net_device *dev = vap->iv_dev;
|
||||
union iwreq_data wreq;
|
||||
+ int active;
|
||||
+
|
||||
+ if (vap->iv_opmode != IEEE80211_M_STA)
|
||||
+ return;
|
||||
+
|
||||
+ if (ostate == nstate)
|
||||
+ return;
|
||||
+
|
||||
+ if (nstate == IEEE80211_S_RUN)
|
||||
+ active = 1;
|
||||
+ else if ((ostate >= IEEE80211_S_AUTH) && (nstate < ostate))
|
||||
+ active = 0;
|
||||
+ else
|
||||
+ return;
|
||||
+
|
||||
+ if (active && !vap->iv_bss)
|
||||
+ return;
|
||||
+
|
||||
+ memset(&wreq, 0, sizeof(wreq));
|
||||
+ wreq.ap_addr.sa_family = ARPHRD_ETHER;
|
||||
|
||||
- if (ni == vap->iv_bss) {
|
||||
- if (newassoc)
|
||||
- netif_carrier_on(dev);
|
||||
- memset(&wreq, 0, sizeof(wreq));
|
||||
+ if (active) {
|
||||
+ //netif_carrier_on(vap->iv_dev);
|
||||
IEEE80211_ADDR_COPY(wreq.addr.sa_data, vap->iv_bssid);
|
||||
- wreq.addr.sa_family = ARPHRD_ETHER;
|
||||
-#ifdef ATH_SUPERG_XR
|
||||
- if (vap->iv_xrvap && vap->iv_flags & IEEE80211_F_XR)
|
||||
- dev = vap->iv_xrvap->iv_dev;
|
||||
-#endif
|
||||
- wireless_send_event(dev, SIOCGIWAP, &wreq, NULL);
|
||||
} else {
|
||||
- memset(&wreq, 0, sizeof(wreq));
|
||||
- IEEE80211_ADDR_COPY(wreq.addr.sa_data, ni->ni_macaddr);
|
||||
- wreq.addr.sa_family = ARPHRD_ETHER;
|
||||
+ //netif_carrier_off(vap->iv_dev);
|
||||
+ memset(wreq.ap_addr.sa_data, 0, ETHER_ADDR_LEN);
|
||||
+ }
|
||||
+ wireless_send_event(dev, SIOCGIWAP, &wreq, NULL);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+ieee80211_notify_node_join(struct ieee80211_node *ni, int newassoc)
|
||||
+{
|
||||
+ struct ieee80211vap *vap = ni->ni_vap;
|
||||
+ struct net_device *dev = vap->iv_dev;
|
||||
+ union iwreq_data wreq;
|
||||
+
|
||||
+ if (ni == vap->iv_bss)
|
||||
+ return;
|
||||
+
|
||||
+ memset(&wreq, 0, sizeof(wreq));
|
||||
+ IEEE80211_ADDR_COPY(wreq.addr.sa_data, ni->ni_macaddr);
|
||||
+ wreq.addr.sa_family = ARPHRD_ETHER;
|
||||
#ifdef ATH_SUPERG_XR
|
||||
- if (vap->iv_xrvap && vap->iv_flags & IEEE80211_F_XR)
|
||||
- dev = vap->iv_xrvap->iv_dev;
|
||||
+ if (vap->iv_xrvap && vap->iv_flags & IEEE80211_F_XR)
|
||||
+ dev = vap->iv_xrvap->iv_dev;
|
||||
#endif
|
||||
- wireless_send_event(dev, IWEVREGISTERED, &wreq, NULL);
|
||||
- }
|
||||
+ wireless_send_event(dev, IWEVREGISTERED, &wreq, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -269,18 +295,14 @@ ieee80211_notify_node_leave(struct ieee8
|
||||
struct net_device *dev = vap->iv_dev;
|
||||
union iwreq_data wreq;
|
||||
|
||||
- if (ni == vap->iv_bss) {
|
||||
- netif_carrier_off(dev);
|
||||
- memset(wreq.ap_addr.sa_data, 0, ETHER_ADDR_LEN);
|
||||
- wreq.ap_addr.sa_family = ARPHRD_ETHER;
|
||||
- wireless_send_event(dev, SIOCGIWAP, &wreq, NULL);
|
||||
- } else {
|
||||
- /* fire off wireless event station leaving */
|
||||
- memset(&wreq, 0, sizeof(wreq));
|
||||
- IEEE80211_ADDR_COPY(wreq.addr.sa_data, ni->ni_macaddr);
|
||||
- wreq.addr.sa_family = ARPHRD_ETHER;
|
||||
- wireless_send_event(dev, IWEVEXPIRED, &wreq, NULL);
|
||||
- }
|
||||
+ if (ni == vap->iv_bss)
|
||||
+ return;
|
||||
+
|
||||
+ /* fire off wireless event station leaving */
|
||||
+ memset(&wreq, 0, sizeof(wreq));
|
||||
+ IEEE80211_ADDR_COPY(wreq.addr.sa_data, ni->ni_macaddr);
|
||||
+ wreq.addr.sa_family = ARPHRD_ETHER;
|
||||
+ wireless_send_event(dev, IWEVEXPIRED, &wreq, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
--- a/net80211/ieee80211_node.c
|
||||
+++ b/net80211/ieee80211_node.c
|
||||
@@ -2332,6 +2332,7 @@ ieee80211_node_leave(struct ieee80211_no
|
||||
count_suppchans(ic, ni, -1);
|
||||
IEEE80211_UNLOCK_IRQ(ic);
|
||||
|
||||
+done:
|
||||
/*
|
||||
* Cleanup station state. In particular clear various
|
||||
* state that might otherwise be reused if the node
|
||||
@@ -2339,7 +2340,7 @@ ieee80211_node_leave(struct ieee80211_no
|
||||
* (and memory is reclaimed).
|
||||
*/
|
||||
ieee80211_sta_leave(ni);
|
||||
-done:
|
||||
+
|
||||
/* Run a cleanup */
|
||||
#ifdef IEEE80211_DEBUG_REFCNT
|
||||
ic->ic_node_cleanup_debug(ni, __func__, __LINE__);
|
||||
--- a/net80211/ieee80211_node.h
|
||||
+++ b/net80211/ieee80211_node.h
|
||||
@@ -60,7 +60,7 @@
|
||||
#define IEEE80211_INACT_PROBE (30/IEEE80211_INACT_WAIT) /* probe */
|
||||
#define IEEE80211_INACT_SCAN (300/IEEE80211_INACT_WAIT) /* scanned */
|
||||
|
||||
-#define IEEE80211_TRANS_WAIT 5 /* mgt frame tx timer (secs) */
|
||||
+#define IEEE80211_TRANS_WAIT 300 /* mgt frame tx timer (msecs) */
|
||||
|
||||
#define IEEE80211_NODE_HASHSIZE 32
|
||||
/* simple hash is enough for variation of macaddr */
|
||||
--- a/net80211/ieee80211_output.c
|
||||
+++ b/net80211/ieee80211_output.c
|
||||
@@ -2141,7 +2141,7 @@ ieee80211_send_mgmt(struct ieee80211_nod
|
||||
|
||||
ieee80211_mgmt_output(ieee80211_ref_node(ni), skb, type);
|
||||
if (timer)
|
||||
- mod_timer(&vap->iv_mgtsend, jiffies + timer * HZ);
|
||||
+ mod_timer(&vap->iv_mgtsend, jiffies + msecs_to_jiffies(timer));
|
||||
return 0;
|
||||
bad:
|
||||
return ret;
|
||||
--- a/net80211/ieee80211_wireless.c
|
||||
+++ b/net80211/ieee80211_wireless.c
|
||||
@@ -514,8 +514,9 @@ ieee80211_ioctl_siwap(struct net_device
|
||||
vap->iv_flags |= IEEE80211_F_DESBSSID;
|
||||
|
||||
IEEE80211_ADDR_COPY(vap->iv_des_bssid, &ap_addr->sa_data);
|
||||
- if (IS_UP_AUTO(vap))
|
||||
+ if (IS_UP(vap->iv_dev)) {
|
||||
ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
|
||||
+ }
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
--- a/net80211/ieee80211_linux.h
|
||||
+++ b/net80211/ieee80211_linux.h
|
||||
@@ -643,6 +643,7 @@ void ieee80211_vlan_vdetach(struct ieee8
|
||||
#define free_netdev(dev) kfree(dev)
|
||||
#endif
|
||||
|
||||
+void ieee80211_update_link_status(struct ieee80211vap *vap, int nstate, int ostate);
|
||||
void ieee80211_ioctl_vattach(struct ieee80211vap *);
|
||||
void ieee80211_ioctl_vdetach(struct ieee80211vap *);
|
||||
struct ifreq;
|
102
net/madwifi/patches/361-bmiss_handling.patch
Normal file
102
net/madwifi/patches/361-bmiss_handling.patch
Normal file
@ -0,0 +1,102 @@
|
||||
Improve the beacon miss handling. Instead of just dropping the connection,
|
||||
send a directed probe request to the AP to see if it's still responding.
|
||||
Schedule a software beacon miss timer in this case, which adds a timeout
|
||||
for the APs probe response.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
|
||||
--- a/net80211/ieee80211_input.c
|
||||
+++ b/net80211/ieee80211_input.c
|
||||
@@ -3400,12 +3400,17 @@ ieee80211_recv_mgmt(struct ieee80211vap
|
||||
}
|
||||
|
||||
/* WDS/Repeater: re-schedule software beacon timer for
|
||||
- * STA. */
|
||||
- if ((vap->iv_state == IEEE80211_S_RUN) &&
|
||||
- (vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS)) {
|
||||
- mod_timer(&vap->iv_swbmiss,
|
||||
+ * STA. Reset consecutive bmiss counter as well */
|
||||
+ IEEE80211_LOCK_IRQ(ic);
|
||||
+ if (vap->iv_state == IEEE80211_S_RUN) {
|
||||
+ vap->iv_bmiss_count = 0;
|
||||
+ if (vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS)
|
||||
+ mod_timer(&vap->iv_swbmiss,
|
||||
jiffies + vap->iv_swbmiss_period);
|
||||
+ else
|
||||
+ del_timer(&vap->iv_swbmiss);
|
||||
}
|
||||
+ IEEE80211_UNLOCK_IRQ(ic);
|
||||
|
||||
/* If scanning, pass the info to the scan module.
|
||||
* Otherwise, check if it's the right time to do
|
||||
--- a/net80211/ieee80211_proto.c
|
||||
+++ b/net80211/ieee80211_proto.c
|
||||
@@ -1209,6 +1209,8 @@ ieee80211_beacon_miss(struct ieee80211co
|
||||
}
|
||||
/* XXX locking */
|
||||
TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
|
||||
+ int count;
|
||||
+
|
||||
IEEE80211_DPRINTF(vap,
|
||||
IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
|
||||
"%s\n", "beacon miss");
|
||||
@@ -1221,6 +1223,29 @@ ieee80211_beacon_miss(struct ieee80211co
|
||||
if (vap->iv_opmode != IEEE80211_M_STA ||
|
||||
vap->iv_state != IEEE80211_S_RUN)
|
||||
continue;
|
||||
+
|
||||
+ IEEE80211_LOCK_IRQ(ic);
|
||||
+ count = vap->iv_bmiss_count++;
|
||||
+ if (count) {
|
||||
+ /* if the counter was already above zero, reset it
|
||||
+ * here, since we're going to do the bmiss handling
|
||||
+ * in any case */
|
||||
+ vap->iv_bmiss_count = 0;
|
||||
+ } else {
|
||||
+ /* schedule the software beacon miss timer, it will be
|
||||
+ * cancelled, if the probe request is acked */
|
||||
+ mod_timer(&vap->iv_swbmiss, jiffies + vap->iv_swbmiss_period);
|
||||
+ }
|
||||
+ IEEE80211_UNLOCK_IRQ(ic);
|
||||
+
|
||||
+ if (!count) {
|
||||
+ ieee80211_send_probereq(vap->iv_bss, vap->iv_myaddr,
|
||||
+ vap->iv_bss->ni_bssid, vap->iv_bss->ni_bssid,
|
||||
+ vap->iv_bss->ni_essid, vap->iv_bss->ni_esslen,
|
||||
+ NULL, 0);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
if (ic->ic_roaming == IEEE80211_ROAMING_AUTO) {
|
||||
#ifdef ATH_SUPERG_DYNTURBO
|
||||
/*
|
||||
@@ -1621,14 +1646,14 @@ __ieee80211_newstate(struct ieee80211vap
|
||||
}
|
||||
|
||||
/* WDS/Repeater: Start software beacon timer for STA */
|
||||
+ vap->iv_swbmiss.function = ieee80211_sta_swbmiss;
|
||||
+ vap->iv_swbmiss.data = (unsigned long) vap;
|
||||
+ vap->iv_swbmiss_period = IEEE80211_TU_TO_JIFFIES(
|
||||
+ vap->iv_ic->ic_bmissthreshold * ni->ni_intval);
|
||||
+
|
||||
if (ostate != IEEE80211_S_RUN &&
|
||||
(vap->iv_opmode == IEEE80211_M_STA &&
|
||||
vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS)) {
|
||||
- vap->iv_swbmiss.function = ieee80211_sta_swbmiss;
|
||||
- vap->iv_swbmiss.data = (unsigned long) vap;
|
||||
- vap->iv_swbmiss_period = IEEE80211_TU_TO_JIFFIES(
|
||||
- vap->iv_ic->ic_bmissthreshold * ni->ni_intval);
|
||||
-
|
||||
mod_timer(&vap->iv_swbmiss, jiffies + vap->iv_swbmiss_period);
|
||||
}
|
||||
|
||||
--- a/net80211/ieee80211_var.h
|
||||
+++ b/net80211/ieee80211_var.h
|
||||
@@ -283,6 +283,7 @@ struct ieee80211vap {
|
||||
|
||||
struct timer_list iv_swbmiss; /* software beacon miss timer */
|
||||
u_int16_t iv_swbmiss_period; /* software beacon miss timer period */
|
||||
+ u_int16_t iv_bmiss_count; /* consecutive beacon miss counter */
|
||||
struct ieee80211_nsparams iv_nsparams; /* new state parameters for tasklet for stajoin1 */
|
||||
struct IEEE80211_TQ_STRUCT iv_stajoin1tq; /* tasklet for newstate action called from stajoin1tq */
|
||||
unsigned int iv_nsdone; /* Done with scheduled newstate tasklet */
|
93
net/madwifi/patches/362-rssithr.patch
Normal file
93
net/madwifi/patches/362-rssithr.patch
Normal file
@ -0,0 +1,93 @@
|
||||
Add an optional threshold for low-rssi disconnection. This can be useful
|
||||
when letting wpa_supplicant control roaming.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
|
||||
--- a/net80211/ieee80211_ioctl.h
|
||||
+++ b/net80211/ieee80211_ioctl.h
|
||||
@@ -647,6 +647,8 @@ enum {
|
||||
IEEE80211_PARAM_PROTMODE_RSSI = 77, /* RSSI Threshold for enabling protection mode */
|
||||
IEEE80211_PARAM_PROTMODE_TIMEOUT = 78, /* Timeout for expiring protection mode */
|
||||
IEEE80211_PARAM_BGSCAN_THRESH = 79, /* bg scan rssi threshold */
|
||||
+ IEEE80211_PARAM_RSSI_DIS_THR = 80, /* rssi threshold for disconnection */
|
||||
+ IEEE80211_PARAM_RSSI_DIS_COUNT = 81, /* counter for rssi threshold */
|
||||
};
|
||||
|
||||
#define SIOCG80211STATS (SIOCDEVPRIVATE+2)
|
||||
--- a/net80211/ieee80211_wireless.c
|
||||
+++ b/net80211/ieee80211_wireless.c
|
||||
@@ -2799,6 +2799,12 @@ ieee80211_ioctl_setparam(struct net_devi
|
||||
case IEEE80211_PARAM_ROAM_RATE_11G:
|
||||
vap->iv_roam.rate11b = value;
|
||||
break;
|
||||
+ case IEEE80211_PARAM_RSSI_DIS_THR:
|
||||
+ vap->iv_rssi_dis_thr = value;
|
||||
+ break;
|
||||
+ case IEEE80211_PARAM_RSSI_DIS_COUNT:
|
||||
+ vap->iv_rssi_dis_max = value;
|
||||
+ break;
|
||||
case IEEE80211_PARAM_UAPSDINFO:
|
||||
if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
|
||||
if (ic->ic_caps & IEEE80211_C_UAPSD) {
|
||||
@@ -3184,6 +3190,12 @@ ieee80211_ioctl_getparam(struct net_devi
|
||||
case IEEE80211_PARAM_ROAM_RATE_11G:
|
||||
param[0] = vap->iv_roam.rate11b;
|
||||
break;
|
||||
+ case IEEE80211_PARAM_RSSI_DIS_THR:
|
||||
+ param[0] = vap->iv_rssi_dis_thr;
|
||||
+ break;
|
||||
+ case IEEE80211_PARAM_RSSI_DIS_COUNT:
|
||||
+ param[0] = vap->iv_rssi_dis_max;
|
||||
+ break;
|
||||
case IEEE80211_PARAM_UAPSDINFO:
|
||||
if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
|
||||
if (IEEE80211_VAP_UAPSD_ENABLED(vap))
|
||||
@@ -5733,6 +5745,14 @@ static const struct iw_priv_args ieee802
|
||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rate11g" },
|
||||
{ IEEE80211_PARAM_ROAM_RATE_11G,
|
||||
0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rate11g" },
|
||||
+ { IEEE80211_PARAM_RSSI_DIS_THR,
|
||||
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rssi_disthr" },
|
||||
+ { IEEE80211_PARAM_RSSI_DIS_THR,
|
||||
+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rssi_disthr" },
|
||||
+ { IEEE80211_PARAM_RSSI_DIS_COUNT,
|
||||
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rssi_discnt" },
|
||||
+ { IEEE80211_PARAM_RSSI_DIS_COUNT,
|
||||
+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rssi_discnt" },
|
||||
{ IEEE80211_PARAM_UAPSDINFO,
|
||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "uapsd" },
|
||||
{ IEEE80211_PARAM_UAPSDINFO,
|
||||
--- a/net80211/ieee80211_input.c
|
||||
+++ b/net80211/ieee80211_input.c
|
||||
@@ -3261,6 +3261,19 @@ ieee80211_recv_mgmt(struct ieee80211vap
|
||||
memcpy(ni->ni_tstamp.data, scan.tstamp,
|
||||
sizeof(ni->ni_tstamp));
|
||||
|
||||
+ /* when rssi falls below the disconnection threshold, drop the connection */
|
||||
+ if ((vap->iv_rssi_dis_thr > 0) && (vap->iv_rssi_dis_max > 0)) {
|
||||
+ if ((rssi > 0) && (rssi < vap->iv_rssi_dis_thr)) {
|
||||
+ if (++vap->iv_rssi_dis_trig > vap->iv_rssi_dis_max) {
|
||||
+ vap->iv_rssi_dis_trig = 0;
|
||||
+ ieee80211_node_leave(ni);
|
||||
+ return;
|
||||
+ }
|
||||
+ } else {
|
||||
+ vap->iv_rssi_dis_trig = 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/* When rssi is low, start doing bgscans more frequently to allow
|
||||
* the supplicant to make a better switching decision */
|
||||
if (!(ic->ic_flags & IEEE80211_F_SCAN) && (rssi < vap->iv_bgscanthr) &&
|
||||
--- a/net80211/ieee80211_var.h
|
||||
+++ b/net80211/ieee80211_var.h
|
||||
@@ -223,6 +223,9 @@ struct ieee80211vap {
|
||||
u_int iv_bgscanintvl; /* bg scan min interval */
|
||||
u_int iv_bgscanthr; /* bg scan rssi threshold */
|
||||
u_int iv_bgscantrintvl; /* bg scan trigger interval */
|
||||
+ u_int iv_rssi_dis_thr; /* rssi disassoc threshold */
|
||||
+ u_int iv_rssi_dis_max; /* max beacons below disconnect threshold */
|
||||
+ u_int iv_rssi_dis_trig; /* rssi disassoc trigger count */
|
||||
unsigned long iv_bgscanthr_next; /* last trigger for bgscan */
|
||||
unsigned long iv_lastconnect; /* time of last connect attempt */
|
||||
u_int iv_scanvalid; /* scan cache valid threshold */
|
11
net/madwifi/patches/363-fix_turbo.patch
Normal file
11
net/madwifi/patches/363-fix_turbo.patch
Normal file
@ -0,0 +1,11 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -4925,7 +4925,7 @@ ath_beacon_generate(struct ath_softc *sc
|
||||
* capability info and arrange for a mode change
|
||||
* if needed.
|
||||
*/
|
||||
- if (sc->sc_dturbo) {
|
||||
+ if (sc->sc_dturbo && NULL != avp->av_boff.bo_tim) {
|
||||
u_int8_t dtim;
|
||||
dtim = ((avp->av_boff.bo_tim[2] == 1) ||
|
||||
(avp->av_boff.bo_tim[3] == 1));
|
13
net/madwifi/patches/364-memory_alloc.patch
Normal file
13
net/madwifi/patches/364-memory_alloc.patch
Normal file
@ -0,0 +1,13 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -539,8 +539,8 @@ ath_attach(u_int16_t devid, struct net_d
|
||||
|
||||
/* Allocate space for dynamically determined maximum VAP count */
|
||||
sc->sc_bslot =
|
||||
- kmalloc(ath_maxvaps * sizeof(struct ieee80211vap), GFP_KERNEL);
|
||||
- memset(sc->sc_bslot, 0, ath_maxvaps * sizeof(struct ieee80211vap));
|
||||
+ kmalloc(ath_maxvaps * sizeof(struct ieee80211vap*), GFP_KERNEL);
|
||||
+ memset(sc->sc_bslot, 0, ath_maxvaps * sizeof(struct ieee80211vap*));
|
||||
|
||||
/*
|
||||
* Cache line size is used to size and align various
|
10
net/madwifi/patches/365-turbo_channelsearch.patch
Normal file
10
net/madwifi/patches/365-turbo_channelsearch.patch
Normal file
@ -0,0 +1,10 @@
|
||||
--- a/net80211/ieee80211.c
|
||||
+++ b/net80211/ieee80211.c
|
||||
@@ -684,6 +684,7 @@ ieee80211_find_channel(struct ieee80211c
|
||||
int i;
|
||||
|
||||
/* Brute force search */
|
||||
+ flags &= IEEE80211_CHAN_ALLTURBO;
|
||||
for (i = 0; i < ic->ic_nchans; i++) {
|
||||
c = &ic->ic_channels[i];
|
||||
if (c->ic_freq == freq &&
|
52
net/madwifi/patches/366-bstuck_thresh.patch
Normal file
52
net/madwifi/patches/366-bstuck_thresh.patch
Normal file
@ -0,0 +1,52 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -389,6 +389,7 @@ static int ath_countrycode = CTRY_DEFAUL
|
||||
static int ath_outdoor = AH_FALSE; /* enable outdoor use */
|
||||
static int ath_xchanmode = AH_TRUE; /* enable extended channels */
|
||||
static int ath_maxvaps = ATH_MAXVAPS_DEFAULT; /* set default maximum vaps */
|
||||
+static int bstuck_thresh = BSTUCK_THRESH; /* Stuck beacon count required for reset */
|
||||
static char *autocreate = NULL;
|
||||
static char *ratectl = DEF_RATE_CTL;
|
||||
static int rfkill = 0;
|
||||
@@ -432,6 +433,7 @@ MODULE_PARM(rfkill, "i");
|
||||
#ifdef ATH_CAP_TPC
|
||||
MODULE_PARM(tpc, "i");
|
||||
#endif
|
||||
+MODULE_PARM(bstuck_thresh, "i");
|
||||
MODULE_PARM(autocreate, "s");
|
||||
MODULE_PARM(ratectl, "s");
|
||||
#else
|
||||
@@ -445,6 +447,7 @@ module_param(rfkill, int, 0600);
|
||||
#ifdef ATH_CAP_TPC
|
||||
module_param(tpc, int, 0600);
|
||||
#endif
|
||||
+module_param(bstuck_thresh, int, 0600);
|
||||
module_param(autocreate, charp, 0600);
|
||||
module_param(ratectl, charp, 0600);
|
||||
#endif
|
||||
@@ -457,6 +460,7 @@ MODULE_PARM_DESC(rfkill, "Enable/disable
|
||||
MODULE_PARM_DESC(tpc, "Enable/disable per-packet transmit power control (TPC) "
|
||||
"capability");
|
||||
#endif
|
||||
+MODULE_PARM_DESC(bstuck_thresh, "Override default stuck beacon threshold");
|
||||
MODULE_PARM_DESC(autocreate, "Create ath device in "
|
||||
"[sta|ap|wds|adhoc|ahdemo|monitor] mode. defaults to sta, use "
|
||||
"'none' to disable");
|
||||
@@ -5072,7 +5076,7 @@ ath_beacon_send(struct ath_softc *sc, in
|
||||
DPRINTF(sc, ATH_DEBUG_BEACON_PROC,
|
||||
"Missed %u consecutive beacons (n_beacon=%u)\n",
|
||||
sc->sc_bmisscount, n_beacon);
|
||||
- if (sc->sc_bmisscount > BSTUCK_THRESH)
|
||||
+ if (sc->sc_bmisscount > bstuck_thresh)
|
||||
ATH_SCHEDULE_TQUEUE(&sc->sc_bstucktq, needmark);
|
||||
return;
|
||||
}
|
||||
@@ -5230,7 +5234,7 @@ ath_bstuck_tasklet(TQUEUE_ARG data)
|
||||
* check will be true, in which case return
|
||||
* without resetting the driver.
|
||||
*/
|
||||
- if (sc->sc_bmisscount <= BSTUCK_THRESH)
|
||||
+ if (sc->sc_bmisscount <= bstuck_thresh)
|
||||
return;
|
||||
EPRINTF(sc, "Stuck beacon; resetting (beacon miss count: %u)\n",
|
||||
sc->sc_bmisscount);
|
77
net/madwifi/patches/367-roaming.patch
Normal file
77
net/madwifi/patches/367-roaming.patch
Normal file
@ -0,0 +1,77 @@
|
||||
Patch adapted from ubnt madwifi patchset
|
||||
|
||||
--- a/net80211/ieee80211_node.c
|
||||
+++ b/net80211/ieee80211_node.c
|
||||
@@ -659,7 +659,7 @@ ieee80211_sta_join1(struct ieee80211_nod
|
||||
*/
|
||||
if (canreassoc) {
|
||||
vap->iv_nsparams.newstate = IEEE80211_S_ASSOC;
|
||||
- vap->iv_nsparams.arg = 0;
|
||||
+ vap->iv_nsparams.arg = IEEE80211_FC0_SUBTYPE_REASSOC_REQ;
|
||||
IEEE80211_SCHEDULE_TQUEUE(&vap->iv_stajoin1tq);
|
||||
} else {
|
||||
vap->iv_nsparams.newstate = IEEE80211_S_AUTH;
|
||||
--- a/net80211/ieee80211_scan_sta.c
|
||||
+++ b/net80211/ieee80211_scan_sta.c
|
||||
@@ -748,14 +748,17 @@ notfound:
|
||||
* a reference to an entry w/o holding the lock on the table.
|
||||
*/
|
||||
static struct sta_entry *
|
||||
-sta_lookup(struct sta_table *st, const u_int8_t macaddr[IEEE80211_ADDR_LEN])
|
||||
+sta_lookup(struct sta_table *st, const u_int8_t macaddr[IEEE80211_ADDR_LEN], struct ieee80211_scan_ssid* essid)
|
||||
{
|
||||
struct sta_entry *se;
|
||||
int hash = STA_HASH(macaddr);
|
||||
|
||||
SCAN_STA_LOCK_IRQ(st);
|
||||
LIST_FOREACH(se, &st->st_hash[hash], se_hash)
|
||||
- if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr))
|
||||
+ if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr) &&
|
||||
+ (essid->len == se->base.se_ssid[1] &&
|
||||
+ !memcmp(se->base.se_ssid+2, essid->ssid,
|
||||
+ se->base.se_ssid[1])))
|
||||
break;
|
||||
SCAN_STA_UNLOCK_IRQ(st);
|
||||
|
||||
@@ -772,7 +775,7 @@ sta_roam_check(struct ieee80211_scan_sta
|
||||
u_int8_t roamRate, curRate;
|
||||
int8_t roamRssi, curRssi;
|
||||
|
||||
- se = sta_lookup(st, ni->ni_macaddr);
|
||||
+ se = sta_lookup(st, ni->ni_macaddr, ss->ss_ssid);
|
||||
if (se == NULL) {
|
||||
/* XXX something is wrong */
|
||||
return;
|
||||
@@ -866,8 +869,8 @@ sta_age(struct ieee80211_scan_state *ss)
|
||||
*/
|
||||
KASSERT(vap->iv_opmode == IEEE80211_M_STA,
|
||||
("wrong mode %u", vap->iv_opmode));
|
||||
- /* XXX turn this off until the ap release is cut */
|
||||
- if (0 && vap->iv_ic->ic_roaming == IEEE80211_ROAMING_AUTO &&
|
||||
+ if (vap->iv_opmode == IEEE80211_M_STA &&
|
||||
+ vap->iv_ic->ic_roaming == IEEE80211_ROAMING_AUTO &&
|
||||
vap->iv_state >= IEEE80211_S_RUN)
|
||||
/* XXX vap is implicit */
|
||||
sta_roam_check(ss, vap);
|
||||
@@ -922,7 +925,11 @@ sta_assoc_fail(struct ieee80211_scan_sta
|
||||
struct sta_table *st = ss->ss_priv;
|
||||
struct sta_entry *se;
|
||||
|
||||
- se = sta_lookup(st, macaddr);
|
||||
+ /* Let outside apps to decide what peer is blacklisted */
|
||||
+ if (ss->ss_vap->iv_ic->ic_roaming == IEEE80211_ROAMING_MANUAL)
|
||||
+ return;
|
||||
+
|
||||
+ se = sta_lookup(st, macaddr, ss->ss_ssid);
|
||||
if (se != NULL) {
|
||||
se->se_fails++;
|
||||
se->se_lastfail = jiffies;
|
||||
@@ -939,7 +946,7 @@ sta_assoc_success(struct ieee80211_scan_
|
||||
struct sta_table *st = ss->ss_priv;
|
||||
struct sta_entry *se;
|
||||
|
||||
- se = sta_lookup(st, macaddr);
|
||||
+ se = sta_lookup(st, macaddr, ss->ss_ssid);
|
||||
if (se != NULL) {
|
||||
#if 0
|
||||
se->se_fails = 0;
|
49
net/madwifi/patches/368-sta_ie_preserve.patch
Normal file
49
net/madwifi/patches/368-sta_ie_preserve.patch
Normal file
@ -0,0 +1,49 @@
|
||||
--- a/net80211/ieee80211_scan_sta.c
|
||||
+++ b/net80211/ieee80211_scan_sta.c
|
||||
@@ -201,8 +201,10 @@ sta_flush_table(struct sta_table *st)
|
||||
}
|
||||
|
||||
static void
|
||||
-saveie(u_int8_t **iep, const u_int8_t *ie)
|
||||
+saveie(u_int8_t **iep, const u_int8_t *ie, int preserve)
|
||||
{
|
||||
+ if (preserve && *iep)
|
||||
+ return;
|
||||
if (ie == NULL)
|
||||
*iep = NULL;
|
||||
else
|
||||
@@ -304,10 +306,10 @@ found:
|
||||
(const struct ieee80211_tim_ie *) sp->tim;
|
||||
ise->se_dtimperiod = tim->tim_period;
|
||||
}
|
||||
- saveie(&ise->se_wme_ie, sp->wme);
|
||||
- saveie(&ise->se_wpa_ie, sp->wpa);
|
||||
- saveie(&ise->se_rsn_ie, sp->rsn);
|
||||
- saveie(&ise->se_ath_ie, sp->ath);
|
||||
+ saveie(&ise->se_wme_ie, sp->wme, 0);
|
||||
+ saveie(&ise->se_wpa_ie, sp->wpa, !sp->isprobe);
|
||||
+ saveie(&ise->se_rsn_ie, sp->rsn, !sp->isprobe);
|
||||
+ saveie(&ise->se_ath_ie, sp->ath, 0);
|
||||
|
||||
/* clear failure count after STA_FAIL_AGE passes */
|
||||
if (se->se_fails && (jiffies - se->se_lastfail) > STA_FAILS_AGE*HZ) {
|
||||
--- a/net80211/ieee80211_input.c
|
||||
+++ b/net80211/ieee80211_input.c
|
||||
@@ -3106,6 +3106,7 @@ ieee80211_recv_mgmt(struct ieee80211vap
|
||||
*/
|
||||
IEEE80211_VERIFY_LENGTH(efrm - frm, 12);
|
||||
memset(&scan, 0, sizeof(scan));
|
||||
+ scan.isprobe = (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) && IEEE80211_ADDR_EQ(wh->i_addr2, vap->iv_myaddr);
|
||||
scan.tstamp = frm;
|
||||
frm += 8;
|
||||
scan.bintval = le16toh(*(__le16 *)frm);
|
||||
--- a/net80211/ieee80211_scan.h
|
||||
+++ b/net80211/ieee80211_scan.h
|
||||
@@ -133,6 +133,7 @@ struct ieee80211_scanparams {
|
||||
u_int8_t erp;
|
||||
u_int16_t bintval;
|
||||
u_int8_t timoff;
|
||||
+ u_int8_t isprobe;
|
||||
u_int8_t *tim;
|
||||
u_int8_t *tstamp;
|
||||
u_int8_t *country;
|
10
net/madwifi/patches/369-mlme_assoc.patch
Normal file
10
net/madwifi/patches/369-mlme_assoc.patch
Normal file
@ -0,0 +1,10 @@
|
||||
--- a/net80211/ieee80211_wireless.c
|
||||
+++ b/net80211/ieee80211_wireless.c
|
||||
@@ -3723,6 +3723,7 @@ ieee80211_ioctl_setmlme(struct net_devic
|
||||
if (vap->iv_opmode == IEEE80211_M_STA) {
|
||||
struct scanlookup lookup;
|
||||
|
||||
+ preempt_scan(dev, 100, 100);
|
||||
lookup.se = NULL;
|
||||
lookup.mac = mlme->im_macaddr;
|
||||
/* XXX use revised api w/ explicit ssid */
|
1665
net/madwifi/patches/370-wdsvap.patch
Normal file
1665
net/madwifi/patches/370-wdsvap.patch
Normal file
File diff suppressed because it is too large
Load Diff
39
net/madwifi/patches/372-queue_vif.patch
Normal file
39
net/madwifi/patches/372-queue_vif.patch
Normal file
@ -0,0 +1,39 @@
|
||||
--- a/net80211/ieee80211_input.c
|
||||
+++ b/net80211/ieee80211_input.c
|
||||
@@ -1198,6 +1198,7 @@ ieee80211_deliver_data(struct ieee80211_
|
||||
}
|
||||
if (skb1 != NULL) {
|
||||
struct ieee80211_node *ni_tmp;
|
||||
+ int ret;
|
||||
skb1->dev = dev;
|
||||
skb_reset_mac_header(skb1);
|
||||
skb_set_network_header(skb1, sizeof(struct ether_header));
|
||||
@@ -1205,7 +1206,12 @@ ieee80211_deliver_data(struct ieee80211_
|
||||
skb1->protocol = __constant_htons(ETH_P_802_2);
|
||||
/* XXX insert vlan tag before queue it? */
|
||||
ni_tmp = SKB_CB(skb1)->ni; /* remember node so we can free it */
|
||||
- if (dev_queue_xmit(skb1) == NET_XMIT_DROP) {
|
||||
+ ret = dev->hard_start_xmit(skb1, dev);
|
||||
+
|
||||
+ if (ret == NETDEV_TX_BUSY)
|
||||
+ ieee80211_dev_kfree_skb(&skb1);
|
||||
+
|
||||
+ else if (ret != NETDEV_TX_OK) {
|
||||
/* If queue dropped the packet because device was
|
||||
* too busy */
|
||||
vap->iv_devstats.tx_dropped++;
|
||||
--- a/net80211/ieee80211_output.c
|
||||
+++ b/net80211/ieee80211_output.c
|
||||
@@ -324,9 +324,10 @@ void ieee80211_parent_queue_xmit(struct
|
||||
/* Dispatch the packet to the parent device */
|
||||
skb->dev = vap->iv_ic->ic_dev;
|
||||
|
||||
- if (dev_queue_xmit(skb) == NET_XMIT_DROP)
|
||||
+ if (netif_queue_stopped(skb->dev))
|
||||
+ ieee80211_dev_kfree_skb(&skb);
|
||||
+ else if (dev_queue_xmit(skb) == NET_XMIT_DROP)
|
||||
vap->iv_devstats.tx_dropped++;
|
||||
-
|
||||
}
|
||||
|
||||
/*
|
12
net/madwifi/patches/373-sanity_check.patch
Normal file
12
net/madwifi/patches/373-sanity_check.patch
Normal file
@ -0,0 +1,12 @@
|
||||
--- a/net80211/ieee80211_input.c
|
||||
+++ b/net80211/ieee80211_input.c
|
||||
@@ -250,6 +250,9 @@ ieee80211_input(struct ieee80211vap * va
|
||||
if (vap->iv_opmode == IEEE80211_M_MONITOR)
|
||||
goto out;
|
||||
|
||||
+ if (!skb->data)
|
||||
+ goto out;
|
||||
+
|
||||
if (skb->len < sizeof(struct ieee80211_frame_min)) {
|
||||
IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
|
||||
ni->ni_macaddr, NULL,
|
22
net/madwifi/patches/374-nbtt_fix.patch
Normal file
22
net/madwifi/patches/374-nbtt_fix.patch
Normal file
@ -0,0 +1,22 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -5486,6 +5486,9 @@ ath_beacon_config(struct ath_softc *sc,
|
||||
ath_beacon_dturbo_config(vap, intval &
|
||||
~(HAL_BEACON_RESET_TSF | HAL_BEACON_ENA));
|
||||
#endif
|
||||
+ if ((nexttbtt & HAL_BEACON_PERIOD) - (ath_hal_gettsf32(ah) >> 10)
|
||||
+ <= ath_hal_sw_beacon_response_time)
|
||||
+ nexttbtt += intval;
|
||||
sc->sc_nexttbtt = nexttbtt;
|
||||
ath_hal_beaconinit(ah, nexttbtt, intval);
|
||||
if (intval & HAL_BEACON_RESET_TSF) {
|
||||
--- a/ath_hal/ah_os.c
|
||||
+++ b/ath_hal/ah_os.c
|
||||
@@ -71,6 +71,7 @@ static int ath_hal_debug = 99;
|
||||
int ath_hal_dma_beacon_response_time = 2; /* in TUs */
|
||||
int ath_hal_sw_beacon_response_time = 10; /* in TUs */
|
||||
int ath_hal_additional_swba_backoff = 0; /* in TUs */
|
||||
+EXPORT_SYMBOL(ath_hal_sw_beacon_response_time);
|
||||
|
||||
struct ath_hal *
|
||||
_ath_hal_attach(u_int16_t devid, HAL_SOFTC sc,
|
141
net/madwifi/patches/375-atim_tsf_update.patch
Normal file
141
net/madwifi/patches/375-atim_tsf_update.patch
Normal file
@ -0,0 +1,141 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -161,6 +161,7 @@ static void ath_beacon_send(struct ath_s
|
||||
static void ath_beacon_return(struct ath_softc *, struct ath_buf *);
|
||||
static void ath_beacon_free(struct ath_softc *);
|
||||
static void ath_beacon_config(struct ath_softc *, struct ieee80211vap *);
|
||||
+static void ath_hw_beacon_stop(struct ath_softc *sc);
|
||||
static int ath_desc_alloc(struct ath_softc *);
|
||||
static void ath_desc_free(struct ath_softc *);
|
||||
static void ath_desc_swap(struct ath_desc *);
|
||||
@@ -2793,6 +2794,72 @@ ath_set_ack_bitrate(struct ath_softc *sc
|
||||
return 1;
|
||||
}
|
||||
|
||||
+static void
|
||||
+ath_hw_beacon_stop(struct ath_softc *sc)
|
||||
+{
|
||||
+ HAL_BEACON_TIMERS btimers;
|
||||
+
|
||||
+ btimers.bt_intval = 0;
|
||||
+ btimers.bt_nexttbtt = 0;
|
||||
+ btimers.bt_nextdba = 0xffffffff;
|
||||
+ btimers.bt_nextswba = 0xffffffff;
|
||||
+ btimers.bt_nextatim = 0;
|
||||
+
|
||||
+ ath_hal_setbeacontimers(sc->sc_ah, &btimers);
|
||||
+}
|
||||
+
|
||||
+/* Fix up the ATIM window after TSF resync */
|
||||
+static int
|
||||
+ath_hw_check_atim(struct ath_softc *sc, int window, int intval)
|
||||
+{
|
||||
+#define AR5K_TIMER0_5210 0x802c /* Next beacon time register */
|
||||
+#define AR5K_TIMER0_5211 0x8028
|
||||
+#define AR5K_TIMER3_5210 0x8038 /* End of ATIM window time register */
|
||||
+#define AR5K_TIMER3_5211 0x8034
|
||||
+ struct ath_hal *ah = sc->sc_ah;
|
||||
+ int dev = sc->sc_ah->ah_macType;
|
||||
+ unsigned int nbtt, atim;
|
||||
+ int is_5210 = 0;
|
||||
+
|
||||
+ /*
|
||||
+ * check if the ATIM window is still correct:
|
||||
+ * 1.) usually ATIM should be NBTT + window
|
||||
+ * 2.) nbtt already updated
|
||||
+ * 3.) nbtt already updated and has wrapped around
|
||||
+ * 4.) atim has wrapped around
|
||||
+ */
|
||||
+ switch(dev) {
|
||||
+ case 5210:
|
||||
+ nbtt = OS_REG_READ(ah, AR5K_TIMER0_5210);
|
||||
+ atim = OS_REG_READ(ah, AR5K_TIMER3_5210);
|
||||
+ is_5210 = 1;
|
||||
+ break;
|
||||
+ case 5211:
|
||||
+ case 5212:
|
||||
+ nbtt = OS_REG_READ(ah, AR5K_TIMER0_5211);
|
||||
+ atim = OS_REG_READ(ah, AR5K_TIMER3_5211);
|
||||
+ break;
|
||||
+ /* NB: 5416+ doesn't do ATIM in hw */
|
||||
+ case 5416:
|
||||
+ default:
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if ((atim - nbtt != window) && /* 1.) */
|
||||
+ (nbtt - atim != intval - window) && /* 2.) */
|
||||
+ ((nbtt | 0x10000) - atim != intval - window) && /* 3.) */
|
||||
+ ((atim | 0x10000) - nbtt != window)) { /* 4.) */
|
||||
+ if (is_5210)
|
||||
+ OS_REG_WRITE(ah, AR5K_TIMER3_5210, nbtt + window );
|
||||
+ else
|
||||
+ OS_REG_WRITE(ah, AR5K_TIMER3_5211, nbtt + window );
|
||||
+ return atim - nbtt;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/*
|
||||
* Reset the hardware w/o losing operational state. This is
|
||||
* basically a more efficient way of doing ath_stop, ath_init,
|
||||
@@ -5294,6 +5361,7 @@ ath_beacon_config(struct ath_softc *sc,
|
||||
u_int64_t tsf, hw_tsf;
|
||||
u_int32_t tsftu, hw_tsftu;
|
||||
u_int32_t intval, nexttbtt = 0;
|
||||
+ unsigned long flags;
|
||||
int reset_tsf = 0;
|
||||
|
||||
if (vap == NULL)
|
||||
@@ -5301,6 +5369,9 @@ ath_beacon_config(struct ath_softc *sc,
|
||||
|
||||
ni = vap->iv_bss;
|
||||
|
||||
+ /* TSF calculation is timing critical - we don't want to be interrupted here */
|
||||
+ local_irq_save(flags);
|
||||
+
|
||||
hw_tsf = ath_hal_gettsf64(ah);
|
||||
tsf = le64_to_cpu(ni->ni_tstamp.tsf);
|
||||
hw_tsftu = hw_tsf >> 10;
|
||||
@@ -5490,15 +5561,27 @@ ath_beacon_config(struct ath_softc *sc,
|
||||
<= ath_hal_sw_beacon_response_time)
|
||||
nexttbtt += intval;
|
||||
sc->sc_nexttbtt = nexttbtt;
|
||||
+
|
||||
+ /* stop beacons before reconfiguring the timers to avoid race
|
||||
+ * conditions. ath_hal_beaconinit will start them again */
|
||||
+ ath_hw_beacon_stop(sc);
|
||||
+
|
||||
ath_hal_beaconinit(ah, nexttbtt, intval);
|
||||
if (intval & HAL_BEACON_RESET_TSF) {
|
||||
sc->sc_last_tsf = 0;
|
||||
}
|
||||
sc->sc_bmisscount = 0;
|
||||
ath_hal_intrset(ah, sc->sc_imask);
|
||||
+
|
||||
+ if ((sc->sc_opmode == HAL_M_IBSS) && ath_hw_check_atim(sc, 1, intval & HAL_BEACON_PERIOD)) {
|
||||
+ DPRINTF(sc, ATH_DEBUG_BEACON,
|
||||
+ "fixed atim window after beacon init\n");
|
||||
+ }
|
||||
}
|
||||
|
||||
ath_beacon_config_debug:
|
||||
+ local_irq_restore(flags);
|
||||
+
|
||||
/* We print all debug messages here, in order to preserve the
|
||||
* time critical aspect of this function */
|
||||
DPRINTF(sc, ATH_DEBUG_BEACON,
|
||||
@@ -6401,6 +6484,11 @@ ath_recv_mgmt(struct ieee80211vap * vap,
|
||||
DPRINTF(sc, ATH_DEBUG_BEACON,
|
||||
"Updated beacon timers\n");
|
||||
}
|
||||
+ if ((sc->sc_opmode == HAL_M_IBSS) &&
|
||||
+ IEEE80211_ADDR_EQ(ni->ni_bssid, vap->iv_bss->ni_bssid) &&
|
||||
+ ath_hw_check_atim(sc, 1, vap->iv_bss->ni_intval)) {
|
||||
+ DPRINTF(sc, ATH_DEBUG_ANY, "Fixed ATIM window after beacon recv\n");
|
||||
+ }
|
||||
/* NB: Fall Through */
|
||||
case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
|
||||
if (vap->iv_opmode == IEEE80211_M_IBSS &&
|
25
net/madwifi/patches/377-disable_vlan_code.patch
Normal file
25
net/madwifi/patches/377-disable_vlan_code.patch
Normal file
@ -0,0 +1,25 @@
|
||||
--- a/net80211/ieee80211_linux.h
|
||||
+++ b/net80211/ieee80211_linux.h
|
||||
@@ -657,22 +657,7 @@ int ieee80211_proc_vcreate(struct ieee80
|
||||
char *);
|
||||
void ieee80211_proc_cleanup(struct ieee80211vap *);
|
||||
|
||||
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
|
||||
-#define IEEE80211_VLAN_TAG_USED 1
|
||||
-
|
||||
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20)
|
||||
-#define vlan_hwaccel_receive_skb(skb, grp, tag) vlan_hwaccel_rx(skb, grp, tag)
|
||||
-#endif
|
||||
-
|
||||
-#ifndef VLAN_GROUP_ARRAY_PART_LEN
|
||||
-#define vlan_group_set_device(group, vid, dev) do { \
|
||||
- group->vlan_devices[vid] = dev; \
|
||||
-} while (0);
|
||||
-#endif
|
||||
-
|
||||
-#else
|
||||
#define IEEE80211_VLAN_TAG_USED 0
|
||||
-#endif
|
||||
void ieee80211_vlan_vattach(struct ieee80211vap *);
|
||||
void ieee80211_vlan_vdetach(struct ieee80211vap *);
|
||||
|
14
net/madwifi/patches/378-adhoc_crash_fix.patch
Normal file
14
net/madwifi/patches/378-adhoc_crash_fix.patch
Normal file
@ -0,0 +1,14 @@
|
||||
--- a/net80211/ieee80211_input.c
|
||||
+++ b/net80211/ieee80211_input.c
|
||||
@@ -3529,6 +3529,11 @@ ieee80211_recv_mgmt(struct ieee80211vap
|
||||
if (ic->ic_flags & IEEE80211_F_SCAN) {
|
||||
ieee80211_add_scan(vap, &scan, wh, subtype, rssi, rtsf);
|
||||
}
|
||||
+
|
||||
+ /* stop processing if the bss channel is not set up yet */
|
||||
+ if (!ic->ic_bsschan || ic->ic_bsschan == IEEE80211_CHAN_ANYC)
|
||||
+ break;
|
||||
+
|
||||
/* NB: Behavior of WDS-Link and Ad-Hoc is very similar here:
|
||||
* When we receive a beacon that belongs to the AP that we're
|
||||
* connected to, use it to refresh the local node info.
|
405
net/madwifi/patches/379-invalid_rate_fix.patch
Normal file
405
net/madwifi/patches/379-invalid_rate_fix.patch
Normal file
@ -0,0 +1,405 @@
|
||||
--- a/ath_rate/minstrel/minstrel.c
|
||||
+++ b/ath_rate/minstrel/minstrel.c
|
||||
@@ -111,27 +111,13 @@
|
||||
#include <net80211/ieee80211_var.h>
|
||||
#include <net80211/ieee80211_rate.h>
|
||||
|
||||
+#include "if_ath_debug.h"
|
||||
#include "if_athvar.h"
|
||||
#include "if_ath_hal.h"
|
||||
#include "ah_desc.h"
|
||||
|
||||
#include "minstrel.h"
|
||||
|
||||
-#ifdef AR_DEBUG
|
||||
-#define MINSTREL_DEBUG
|
||||
-#endif
|
||||
-#ifdef MINSTREL_DEBUG
|
||||
-enum {
|
||||
- ATH_DEBUG_RATE = 0x00000010 /* rate control */
|
||||
-};
|
||||
-#define DPRINTF(sc, _fmt, ...) do { \
|
||||
- if (sc->sc_debug & ATH_DEBUG_RATE) \
|
||||
- printk(_fmt, __VA_ARGS__); \
|
||||
-} while (0)
|
||||
-#else
|
||||
-#define DPRINTF(sc, _fmt, ...)
|
||||
-#endif
|
||||
-
|
||||
#define ONE_SECOND (1000 * 1000) /* 1 second, or 1000 milliseconds; eternity, in other words */
|
||||
|
||||
#include "release.h"
|
||||
@@ -471,11 +457,11 @@ ath_rate_tx_complete(struct ath_softc *s
|
||||
final_rate = sc->sc_hwmap[ts->ts_rate & ~HAL_TXSTAT_ALTRATE].ieeerate;
|
||||
final_ndx = rate_to_ndx(sn, final_rate);
|
||||
if (final_ndx >= sn->num_rates) {
|
||||
- DPRINTF(sc, "%s: final ndx too high\n", __func__);
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "%s: final ndx too high\n", __func__);
|
||||
final_ndx = 0;
|
||||
}
|
||||
if (final_ndx < 0) {
|
||||
- DPRINTF(sc, "%s: final ndx too low\n", __func__);
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "%s: final ndx too low\n", __func__);
|
||||
final_ndx = 0;
|
||||
}
|
||||
|
||||
@@ -485,7 +471,7 @@ ath_rate_tx_complete(struct ath_softc *s
|
||||
tries = ts->ts_longretry + 1;
|
||||
|
||||
if (sn->num_rates <= 0) {
|
||||
- DPRINTF(sc, "%s: " MAC_FMT " %s no rates yet\n", dev_info,
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "%s: " MAC_FMT " %s no rates yet\n", dev_info,
|
||||
MAC_ADDR(an->an_node.ni_macaddr), __func__);
|
||||
return;
|
||||
}
|
||||
@@ -551,7 +537,7 @@ ath_rate_tx_complete(struct ath_softc *s
|
||||
static void
|
||||
ath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew)
|
||||
{
|
||||
- DPRINTF(sc, "%s: " MAC_FMT " %s\n", dev_info,
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "%s: " MAC_FMT " %s\n", dev_info,
|
||||
MAC_ADDR(an->an_node.ni_macaddr), __func__);
|
||||
if (isnew)
|
||||
ath_rate_ctl_reset(sc, &an->an_node);
|
||||
@@ -601,7 +587,7 @@ ath_fill_sample_table(struct minstrel_no
|
||||
p = rates + sprintf(rates, "rates :: %d ", column_index);
|
||||
for (i = 0; i < num_sample_rates; i++)
|
||||
p += sprintf(p, "%2u ", sn->rs_sampleTable[i][column_index]);
|
||||
- DPRINTF(sc, "%s\n", rates);
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "%s\n", rates);
|
||||
};
|
||||
#endif
|
||||
}
|
||||
@@ -628,7 +614,7 @@ ath_rate_ctl_reset(struct ath_softc *sc,
|
||||
sn->is_sampling = 0;
|
||||
|
||||
if (rt == NULL) {
|
||||
- DPRINTF(sc, "no rates yet! mode %u\n", sc->sc_curmode);
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "no rates yet! mode %u\n", sc->sc_curmode);
|
||||
return;
|
||||
}
|
||||
sn->static_rate_ndx = -1;
|
||||
@@ -658,7 +644,7 @@ ath_rate_ctl_reset(struct ath_softc *sc,
|
||||
sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate];
|
||||
}
|
||||
if (sn->rates[x].rix == 0xff) {
|
||||
- DPRINTF(sc, "%s: %s ignore bogus rix at %d\n",
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "%s: %s ignore bogus rix at %d\n",
|
||||
dev_info, __func__, x);
|
||||
continue;
|
||||
}
|
||||
@@ -673,7 +659,7 @@ ath_rate_ctl_reset(struct ath_softc *sc,
|
||||
ni->ni_txrate = 0;
|
||||
|
||||
if (sn->num_rates <= 0) {
|
||||
- DPRINTF(sc, "%s: %s " MAC_FMT " no rates (fixed %d) \n",
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "%s: %s " MAC_FMT " no rates (fixed %d) \n",
|
||||
dev_info, __func__, MAC_ADDR(ni->ni_macaddr),
|
||||
vap->iv_fixed_rate);
|
||||
/* There are no rates yet; we're done */
|
||||
@@ -689,23 +675,23 @@ ath_rate_ctl_reset(struct ath_softc *sc,
|
||||
* the node. We know the rate is there because the
|
||||
* rate set is checked when the station associates. */
|
||||
/* NB: the rate set is assumed sorted */
|
||||
- for (; (srate >= 0) && (ni->ni_rates.rs_rates[srate] & IEEE80211_RATE_VAL) != vap->iv_fixed_rate; srate--);
|
||||
-
|
||||
- KASSERT(srate >= 0,
|
||||
- ("fixed rate %d not in rate set", vap->iv_fixed_rate));
|
||||
+ for (; (srate > 0) && (ni->ni_rates.rs_rates[srate] & IEEE80211_RATE_VAL) != vap->iv_fixed_rate; srate--);
|
||||
|
||||
sn->static_rate_ndx = srate;
|
||||
ni->ni_txrate = srate;
|
||||
- DPRINTF(sc, "%s: %s " MAC_FMT " fixed rate %d%sMbps\n",
|
||||
- dev_info, __func__, MAC_ADDR(ni->ni_macaddr),
|
||||
- sn->rates[srate].rate / 2,
|
||||
- (sn->rates[srate].rate % 2) ? ".5 " : " ");
|
||||
+ if ((ni->ni_rates.rs_rates[srate] & IEEE80211_RATE_VAL) != vap->iv_fixed_rate)
|
||||
+ EPRINTF(sc, "Invalid static rate, falling back to basic rate\n");
|
||||
+ else
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "%s: %s " MAC_FMT " fixed rate %d%sMbps\n",
|
||||
+ dev_info, __func__, MAC_ADDR(ni->ni_macaddr),
|
||||
+ sn->rates[srate].rate / 2,
|
||||
+ (sn->rates[srate].rate % 2) ? ".5 " : " ");
|
||||
return;
|
||||
}
|
||||
|
||||
for (x = 0; x < ni->ni_rates.rs_nrates; x++) {
|
||||
if (sn->rates[x].rix == 0xff) {
|
||||
- DPRINTF(sc, "%s: %s ignore bogus rix at %d\n",
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "%s: %s ignore bogus rix at %d\n",
|
||||
dev_info, __func__, x);
|
||||
continue;
|
||||
}
|
||||
@@ -735,9 +721,9 @@ ath_rate_ctl_reset(struct ath_softc *sc,
|
||||
}
|
||||
|
||||
#if 0
|
||||
- DPRINTF(sc, "%s: Retry table for this node\n", __func__);
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "%s: Retry table for this node\n", __func__);
|
||||
for (x = 0; x < ni->ni_rates.rs_nrates; x++)
|
||||
- DPRINTF(sc, "%2d %2d %6d \n", x, sn->retry_count[x], sn->perfect_tx_time[x]);
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "%2d %2d %6d \n", x, sn->retry_count[x], sn->perfect_tx_time[x]);
|
||||
#endif
|
||||
|
||||
/* Set the initial rate */
|
||||
@@ -781,10 +767,10 @@ ath_timer_function(unsigned long data)
|
||||
unsigned int interval = ath_timer_interval;
|
||||
|
||||
if (dev == NULL)
|
||||
- DPRINTF(sc, "%s: 'dev' is null in this timer \n", __func__);
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "%s: 'dev' is null in this timer \n", __func__);
|
||||
|
||||
if (sc == NULL)
|
||||
- DPRINTF(sc, "%s: 'sc' is null in this timer\n", __func__);
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "%s: 'sc' is null in this timer\n", __func__);
|
||||
|
||||
ic = &sc->sc_ic;
|
||||
|
||||
@@ -808,7 +794,7 @@ ath_timer_function(unsigned long data)
|
||||
|
||||
timer = &(ssc->timer);
|
||||
if (timer == NULL)
|
||||
- DPRINTF(sc, "%s: timer is null - leave it\n", __func__);
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "%s: timer is null - leave it\n", __func__);
|
||||
|
||||
timer->expires = jiffies + ((HZ * interval) / 1000);
|
||||
add_timer(timer);
|
||||
@@ -904,7 +890,7 @@ static struct ath_ratectrl *
|
||||
ath_rate_attach(struct ath_softc *sc)
|
||||
{
|
||||
struct minstrel_softc *osc;
|
||||
- DPRINTF(sc, "%s: %s\n", dev_info, __func__);
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "%s: %s\n", dev_info, __func__);
|
||||
|
||||
_MOD_INC_USE(THIS_MODULE, return NULL);
|
||||
osc = kmalloc(sizeof(struct minstrel_softc), GFP_ATOMIC);
|
||||
@@ -963,7 +949,7 @@ ath_proc_read_nodes(struct ieee80211vap
|
||||
p += sprintf(p, "out of room for node " MAC_FMT "\n\n", MAC_ADDR(ni->ni_macaddr));
|
||||
break;
|
||||
}
|
||||
- DPRINTF(sc, "%s: out of memeory to write tall of the nodes\n", __func__);
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "%s: out of memeory to write tall of the nodes\n", __func__);
|
||||
break;
|
||||
}
|
||||
an = ATH_NODE(ni);
|
||||
--- a/ath_rate/amrr/amrr.c
|
||||
+++ b/ath_rate/amrr/amrr.c
|
||||
@@ -64,24 +64,13 @@
|
||||
#include <net80211/ieee80211_var.h>
|
||||
#include <net80211/ieee80211_rate.h>
|
||||
|
||||
+#include "if_ath_debug.h"
|
||||
#include "if_athvar.h"
|
||||
#include "if_ath_hal.h"
|
||||
#include "ah_desc.h"
|
||||
|
||||
#include "amrr.h"
|
||||
|
||||
-#ifdef AR_DEBUG
|
||||
-#define AMRR_DEBUG
|
||||
-#endif
|
||||
-#ifdef AMRR_DEBUG
|
||||
-#define DPRINTF(sc, _fmt, ...) do { \
|
||||
- if (sc->sc_debug & 0x10) \
|
||||
- printk(_fmt, __VA_ARGS__); \
|
||||
-} while (0)
|
||||
-#else
|
||||
-#define DPRINTF(sc, _fmt, ...)
|
||||
-#endif
|
||||
-
|
||||
static int ath_rateinterval = 1000; /* rate ctl interval (ms) */
|
||||
static int ath_rate_max_success_threshold = 10;
|
||||
static int ath_rate_min_success_threshold = 1;
|
||||
@@ -197,7 +186,7 @@ ath_rate_update(struct ath_softc *sc, st
|
||||
|
||||
KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
|
||||
|
||||
- DPRINTF(sc, "%s: set xmit rate for " MAC_FMT " to %dM\n",
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "%s: set xmit rate for " MAC_FMT " to %dM\n",
|
||||
__func__, MAC_ADDR(ni->ni_macaddr),
|
||||
ni->ni_rates.rs_nrates > 0 ?
|
||||
(ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL) / 2 : 0);
|
||||
@@ -297,9 +286,9 @@ ath_rate_ctl_start(struct ath_softc *sc,
|
||||
* rate set is checked when the station associates.
|
||||
*/
|
||||
srate = ni->ni_rates.rs_nrates - 1;
|
||||
- for (; srate >= 0 && RATE(srate) != vap->iv_fixed_rate; srate--);
|
||||
- KASSERT(srate >= 0,
|
||||
- ("fixed rate %d not in rate set", vap->iv_fixed_rate));
|
||||
+ for (; srate > 0 && RATE(srate) != vap->iv_fixed_rate; srate--);
|
||||
+ if (RATE(srate) != vap->iv_fixed_rate)
|
||||
+ EPRINTF(sc, "Invalid static rate, falling back to basic rate\n");
|
||||
}
|
||||
ath_rate_update(sc, ni, srate);
|
||||
#undef RATE
|
||||
@@ -377,7 +366,7 @@ ath_rate_ctl(void *arg, struct ieee80211
|
||||
|
||||
old_rate = ni->ni_txrate;
|
||||
|
||||
- DPRINTF (sc, "cnt0: %d cnt1: %d cnt2: %d cnt3: %d -- threshold: %d\n",
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "cnt0: %d cnt1: %d cnt2: %d cnt3: %d -- threshold: %d\n",
|
||||
amn->amn_tx_try0_cnt,
|
||||
amn->amn_tx_try1_cnt,
|
||||
amn->amn_tx_try2_cnt,
|
||||
@@ -390,7 +379,7 @@ ath_rate_ctl(void *arg, struct ieee80211
|
||||
amn->amn_recovery = 1;
|
||||
amn->amn_success = 0;
|
||||
ni->ni_txrate++;
|
||||
- DPRINTF(sc, "increase rate to %d\n", ni->ni_txrate);
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "increase rate to %d\n", ni->ni_txrate);
|
||||
} else
|
||||
amn->amn_recovery = 0;
|
||||
} else if (is_failure(amn)) {
|
||||
@@ -401,12 +390,12 @@ ath_rate_ctl(void *arg, struct ieee80211
|
||||
amn->amn_success_threshold *= 2;
|
||||
amn->amn_success_threshold = min(amn->amn_success_threshold,
|
||||
(u_int)ath_rate_max_success_threshold);
|
||||
- DPRINTF(sc, "decrease rate recovery thr: %d\n",
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "decrease rate recovery thr: %d\n",
|
||||
amn->amn_success_threshold);
|
||||
} else {
|
||||
/* simple failure. */
|
||||
amn->amn_success_threshold = ath_rate_min_success_threshold;
|
||||
- DPRINTF(sc, "decrease rate normal thr: %d\n",
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "decrease rate normal thr: %d\n",
|
||||
amn->amn_success_threshold);
|
||||
}
|
||||
amn->amn_recovery = 0;
|
||||
--- a/ath_rate/onoe/onoe.c
|
||||
+++ b/ath_rate/onoe/onoe.c
|
||||
@@ -60,27 +60,13 @@
|
||||
#include <net80211/ieee80211_var.h>
|
||||
#include <net80211/ieee80211_rate.h>
|
||||
|
||||
+#include "if_ath_debug.h"
|
||||
#include "if_athvar.h"
|
||||
#include "if_ath_hal.h"
|
||||
#include "ah_desc.h"
|
||||
|
||||
#include "onoe.h"
|
||||
|
||||
-#ifdef AR_DEBUG
|
||||
-#define ONOE_DEBUG
|
||||
-#endif
|
||||
-#ifdef ONOE_DEBUG
|
||||
-enum {
|
||||
- ATH_DEBUG_RATE = 0x00000010, /* rate control */
|
||||
-};
|
||||
-#define DPRINTF(sc, _fmt, ...) do { \
|
||||
- if (sc->sc_debug & ATH_DEBUG_RATE) \
|
||||
- printk(_fmt, __VA_ARGS__); \
|
||||
-} while (0)
|
||||
-#else
|
||||
-#define DPRINTF(sc, _fmt, ...)
|
||||
-#endif
|
||||
-
|
||||
/*
|
||||
* Default parameters for the rate control algorithm. These are
|
||||
* all tunable with sysctls. The rate controller runs periodically
|
||||
@@ -186,7 +172,7 @@ ath_rate_update(struct ath_softc *sc, st
|
||||
|
||||
KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
|
||||
|
||||
- DPRINTF(sc, "%s: set xmit rate for " MAC_FMT " to %dM\n",
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "%s: set xmit rate for " MAC_FMT " to %dM\n",
|
||||
__func__, MAC_ADDR(ni->ni_macaddr),
|
||||
ni->ni_rates.rs_nrates > 0 ?
|
||||
(ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL) / 2 : 0);
|
||||
@@ -283,9 +269,9 @@ ath_rate_ctl_start(struct ath_softc *sc,
|
||||
*/
|
||||
/* NB: the rate set is assumed sorted */
|
||||
srate = ni->ni_rates.rs_nrates - 1;
|
||||
- for (; srate >= 0 && RATE(srate) != vap->iv_fixed_rate; srate--);
|
||||
- KASSERT(srate >= 0,
|
||||
- ("fixed rate %d not in rate set", vap->iv_fixed_rate));
|
||||
+ for (; srate > 0 && RATE(srate) != vap->iv_fixed_rate; srate--);
|
||||
+ if (RATE(srate) != vap->iv_fixed_rate)
|
||||
+ EPRINTF(sc, "Invalid static rate, falling back to basic rate\n");
|
||||
}
|
||||
ath_rate_update(sc, ni, srate);
|
||||
#undef RATE
|
||||
@@ -364,7 +350,7 @@ ath_rate_ctl(void *arg, struct ieee80211
|
||||
on->on_tx_retr < (on->on_tx_ok * ath_rate_raise) / 100)
|
||||
dir = 1;
|
||||
|
||||
- DPRINTF(sc, MAC_FMT ": ok %d err %d retr %d upper %d dir %d\n",
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, MAC_FMT ": ok %d err %d retr %d upper %d dir %d\n",
|
||||
MAC_ADDR(ni->ni_macaddr),
|
||||
on->on_tx_ok, on->on_tx_err, on->on_tx_retr,
|
||||
on->on_tx_upper, dir);
|
||||
@@ -395,7 +381,7 @@ ath_rate_ctl(void *arg, struct ieee80211
|
||||
}
|
||||
|
||||
if (nrate != ni->ni_txrate) {
|
||||
- DPRINTF(sc, "%s: %dM -> %dM (%d ok, %d err, %d retr)\n",
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "%s: %dM -> %dM (%d ok, %d err, %d retr)\n",
|
||||
__func__,
|
||||
(rs->rs_rates[ni->ni_txrate] & IEEE80211_RATE_VAL) / 2,
|
||||
(rs->rs_rates[nrate] & IEEE80211_RATE_VAL) / 2,
|
||||
--- a/ath_rate/sample/sample.c
|
||||
+++ b/ath_rate/sample/sample.c
|
||||
@@ -62,30 +62,13 @@
|
||||
#include <net80211/ieee80211_var.h>
|
||||
#include <net80211/ieee80211_rate.h>
|
||||
|
||||
+#include "if_ath_debug.h"
|
||||
#include "if_athvar.h"
|
||||
#include "if_ath_hal.h"
|
||||
#include "ah_desc.h"
|
||||
|
||||
#include "sample.h"
|
||||
|
||||
-#ifdef AR_DEBUG
|
||||
-#define SAMPLE_DEBUG
|
||||
-#endif
|
||||
-#ifdef SAMPLE_DEBUG
|
||||
-enum {
|
||||
- ATH_DEBUG_RATE = 0x00000010, /* rate control */
|
||||
- ATH_DEBUG_ANY = 0xffffffff
|
||||
-};
|
||||
-#define DPRINTF(sc, m, fmt, ...) do { \
|
||||
- if (sc->sc_debug & (m)) \
|
||||
- printk(fmt, __VA_ARGS__); \
|
||||
-} while (0)
|
||||
-#else
|
||||
-#define DPRINTF(sc, m, fmt, ...) do { \
|
||||
- (void) sc; \
|
||||
-} while (0)
|
||||
-#endif
|
||||
-
|
||||
/*
|
||||
* This file is an implementation of the SampleRate algorithm
|
||||
* in "Bit-rate Selection in Wireless Networks"
|
||||
@@ -740,7 +723,7 @@ ath_rate_tx_complete(struct ath_softc *s
|
||||
ndx[3] = rate_to_ndx(sn, rate[3]);
|
||||
|
||||
#if 0
|
||||
- DPRINTF(sc, "%s: " MAC_FMT " size %u finaltsidx %u tries %u status %u rate/try %u/%u %u/%u %u/%u %u/%u\n",
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "%s: " MAC_FMT " size %u finaltsidx %u tries %u status %u rate/try %u/%u %u/%u %u/%u %u/%u\n",
|
||||
dev_info, MAC_ADDR(an->an_node.ni_macaddr),
|
||||
bin_to_size(size_to_bin(frame_size)),
|
||||
finalTSIdx,
|
||||
@@ -886,15 +869,16 @@ ath_rate_ctl_reset(struct ath_softc *sc,
|
||||
if ((ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL) == vap->iv_fixed_rate)
|
||||
srate = x;
|
||||
|
||||
- KASSERT(((ni->ni_rates.rs_rates[srate] & IEEE80211_RATE_VAL) == vap->iv_fixed_rate),
|
||||
- ("fixed rate %u not in rate set", vap->iv_fixed_rate));
|
||||
-
|
||||
sn->static_rate_ndx = srate;
|
||||
ni->ni_txrate = srate;
|
||||
- DPRINTF(sc, ATH_DEBUG_RATE, "%s: %s " MAC_FMT " fixed rate %u%sMbps\n",
|
||||
- dev_info, __func__, MAC_ADDR(ni->ni_macaddr),
|
||||
- sn->rates[srate].rate / 2,
|
||||
- (sn->rates[srate].rate % 0x1) ? ".5" : " ");
|
||||
+
|
||||
+ if ((ni->ni_rates.rs_rates[srate] & IEEE80211_RATE_VAL) != vap->iv_fixed_rate)
|
||||
+ EPRINTF(sc, "Invalid static rate, falling back to basic rate\n");
|
||||
+ else
|
||||
+ DPRINTF(sc, ATH_DEBUG_RATE, "%s: %s " MAC_FMT " fixed rate %u%sMbps\n",
|
||||
+ dev_info, __func__, MAC_ADDR(ni->ni_macaddr),
|
||||
+ sn->rates[srate].rate / 2,
|
||||
+ (sn->rates[srate].rate % 0x1) ? ".5" : " ");
|
||||
return;
|
||||
}
|
||||
|
13
net/madwifi/patches/380-noderef_hack.patch
Normal file
13
net/madwifi/patches/380-noderef_hack.patch
Normal file
@ -0,0 +1,13 @@
|
||||
--- a/net80211/ieee80211_node.c
|
||||
+++ b/net80211/ieee80211_node.c
|
||||
@@ -427,8 +427,8 @@ ieee80211_reset_bss(struct ieee80211vap
|
||||
__func__, ni, MAC_ADDR(vap->iv_myaddr));
|
||||
KASSERT(ni != NULL, ("unable to setup inital BSS node"));
|
||||
|
||||
- vap->iv_bss = PASS_NODE(ni);
|
||||
- KASSERT((atomic_read(&vap->iv_bss->ni_refcnt) == 2),
|
||||
+ vap->iv_bss = ieee80211_ref_node(ni);
|
||||
+ KASSERT((atomic_read(&vap->iv_bss->ni_refcnt) == 3),
|
||||
("wrong refcount for new node."));
|
||||
|
||||
if (obss != NULL) {
|
23
net/madwifi/patches/381-ibss_modes.patch
Normal file
23
net/madwifi/patches/381-ibss_modes.patch
Normal file
@ -0,0 +1,23 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -1260,7 +1260,10 @@ ath_vap_create(struct ieee80211com *ic,
|
||||
case IEEE80211_M_IBSS:
|
||||
if ((sc->sc_nvaps != 0) && (ic->ic_opmode == IEEE80211_M_STA))
|
||||
return NULL;
|
||||
- ic_opmode = opmode;
|
||||
+ if (ic->ic_opmode == IEEE80211_M_HOSTAP)
|
||||
+ ic_opmode = ic->ic_opmode;
|
||||
+ else
|
||||
+ ic_opmode = opmode;
|
||||
break;
|
||||
case IEEE80211_M_AHDEMO:
|
||||
case IEEE80211_M_MONITOR:
|
||||
@@ -1455,7 +1458,7 @@ ath_vap_create(struct ieee80211com *ic,
|
||||
* frames. Other modes carry over directly to the HAL.
|
||||
*/
|
||||
if (ic->ic_opmode == IEEE80211_M_AHDEMO)
|
||||
- sc->sc_opmode = HAL_M_IBSS;
|
||||
+ sc->sc_opmode = HAL_M_HOSTAP;
|
||||
else
|
||||
sc->sc_opmode = (HAL_OPMODE) ic->ic_opmode; /* NB: compatible */
|
||||
|
13
net/madwifi/patches/382-relax_bintval.patch
Normal file
13
net/madwifi/patches/382-relax_bintval.patch
Normal file
@ -0,0 +1,13 @@
|
||||
--- a/net80211/ieee80211_var.h
|
||||
+++ b/net80211/ieee80211_var.h
|
||||
@@ -61,8 +61,8 @@
|
||||
#define IEEE80211_DTIM_MIN 1 /* min DTIM period */
|
||||
#define IEEE80211_DTIM_DEFAULT 1 /* default DTIM period */
|
||||
|
||||
-#define IEEE80211_BINTVAL_MAX 1000 /* max beacon interval (TUs) */
|
||||
-#define IEEE80211_BINTVAL_MIN 25 /* min beacon interval (TUs) */
|
||||
+#define IEEE80211_BINTVAL_MAX 5000 /* max beacon interval (TUs) */
|
||||
+#define IEEE80211_BINTVAL_MIN 10 /* min beacon interval (TUs) */
|
||||
#define IEEE80211_BINTVAL_DEFAULT 100 /* default beacon interval (TUs) */
|
||||
#define IEEE80211_BINTVAL_VALID(_bi) \
|
||||
((IEEE80211_BINTVAL_MIN <= (_bi)) && \
|
105
net/madwifi/patches/383-ibss_hostap.patch
Normal file
105
net/madwifi/patches/383-ibss_hostap.patch
Normal file
@ -0,0 +1,105 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -1452,6 +1452,23 @@ ath_vap_create(struct ieee80211com *ic,
|
||||
sc->sc_nstavaps++;
|
||||
else if (opmode == IEEE80211_M_MONITOR)
|
||||
sc->sc_nmonvaps++;
|
||||
+
|
||||
+
|
||||
+ /* Driving the HAL in IBSS sometimes adapts the TSF and other timing registers
|
||||
+ * from received beacons/probes. If that happens, expected TX interrupts may
|
||||
+ * not occur until next reset. Which triggers the "lost beacon" tasklet.
|
||||
+ * Resulting effectively in not sending packets for minutes. Because that only
|
||||
+ * happens in large mesh networks, this mode needs to be activated by a kernel
|
||||
+ * module parameter: hostap_for_ibss=1. Note that using this mode has side
|
||||
+ * effects. Such as not supressing beacons/probe answers randomly when
|
||||
+ * receiving other node beacons. It's recommended to lower the beacon interval
|
||||
+ * then. When using an IBSS-VAP together with an HOSTAP-VAP, you may also need
|
||||
+ * to re-trigger IBSS beacon generation after creating the HOSTAP-VAP by
|
||||
+ * issueing "iwpriv athX bintval 1000".
|
||||
+ */
|
||||
+ if ((flags & IEEE80211_NO_STABEACONS) && (ic->ic_opmode == IEEE80211_M_IBSS))
|
||||
+ sc->sc_opmode = HAL_M_HOSTAP;
|
||||
+ else
|
||||
/*
|
||||
* Adhoc demo mode is a pseudo mode; to the HAL it's
|
||||
* just IBSS mode and the driver doesn't use management
|
||||
@@ -4279,7 +4296,8 @@ ath_calcrxfilter(struct ath_softc *sc)
|
||||
if (ic->ic_opmode != IEEE80211_M_HOSTAP && (dev->flags & IFF_PROMISC))
|
||||
rfilt |= HAL_RX_FILTER_PROM;
|
||||
if (ic->ic_opmode == IEEE80211_M_STA ||
|
||||
- sc->sc_opmode == HAL_M_IBSS || /* NB: AHDEMO too */
|
||||
+ ic->ic_opmode == IEEE80211_M_IBSS ||
|
||||
+ ic->ic_opmode == IEEE80211_M_AHDEMO ||
|
||||
(sc->sc_nostabeacons) || sc->sc_scanning ||
|
||||
(ic->ic_opmode == IEEE80211_M_HOSTAP))
|
||||
rfilt |= HAL_RX_FILTER_BEACON;
|
||||
@@ -6435,6 +6453,33 @@ ath_capture(struct net_device *dev, cons
|
||||
}
|
||||
|
||||
/*
|
||||
+ * Advances (forwards/adds) a microsecond value to current chip's TSF registers
|
||||
+ */
|
||||
+
|
||||
+/* from ath_info.c */
|
||||
+#define AR5K_TSF_L32_5210 0x806c /* TSF (lower 32 bits) */
|
||||
+#define AR5K_TSF_L32_5211 0x804c
|
||||
+#define AR5K_TSF_L32 (ar_device(ah->ah_sc->devid) == 5210 ? \
|
||||
+ AR5K_TSF_L32_5210 : AR5K_TSF_L32_5211)
|
||||
+
|
||||
+#define AR5K_TSF_U32_5210 0x8070
|
||||
+#define AR5K_TSF_U32_5211 0x8050
|
||||
+#define AR5K_TSF_U32 (ar_device(ah->ah_sc->devid) == 5210 ? \
|
||||
+ AR5K_TSF_U32_5210 : AR5K_TSF_U32_5211)
|
||||
+
|
||||
+static inline void ath_hal_settsf64(struct ath_hal *ah, u_int64_t tsf_adv)
|
||||
+{
|
||||
+ ATH_HAL_LOCK_IRQ(ah->ah_sc);
|
||||
+ ath_hal_set_function(__func__);
|
||||
+ tsf_adv += ah->ah_getTsf64(ah);
|
||||
+ OS_REG_WRITE(ah, AR5K_TSF_L32, 0ll);
|
||||
+ OS_REG_WRITE(ah, AR5K_TSF_U32, (tsf_adv >> 32) & 0xffffffffll);
|
||||
+ OS_REG_WRITE(ah, AR5K_TSF_L32, (tsf_adv >> 00) & 0xffffffffll);
|
||||
+ ath_hal_set_function(NULL);
|
||||
+ ATH_HAL_UNLOCK_IRQ(ah->ah_sc);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* Intercept management frames to collect beacon RSSI data and to do
|
||||
* ibss merges. This function is called for all management frames,
|
||||
* including those belonging to other BSS.
|
||||
@@ -6487,10 +6532,19 @@ ath_recv_mgmt(struct ieee80211vap * vap,
|
||||
DPRINTF(sc, ATH_DEBUG_BEACON,
|
||||
"Updated beacon timers\n");
|
||||
}
|
||||
- if ((sc->sc_opmode == HAL_M_IBSS) &&
|
||||
- IEEE80211_ADDR_EQ(ni->ni_bssid, vap->iv_bss->ni_bssid) &&
|
||||
- ath_hw_check_atim(sc, 1, vap->iv_bss->ni_intval)) {
|
||||
- DPRINTF(sc, ATH_DEBUG_ANY, "Fixed ATIM window after beacon recv\n");
|
||||
+ if ((vap->iv_opmode == IEEE80211_M_IBSS) &&
|
||||
+ (sc->sc_opmode == HAL_M_HOSTAP) &&
|
||||
+ IEEE80211_ADDR_EQ(ni->ni_bssid, vap->iv_bss->ni_bssid)) {
|
||||
+ /* In this mode, we drive the HAL in HOSTAP mode. Hence
|
||||
+ * we do the IBSS merging in software. Also do not merge
|
||||
+ * if the difference it too small. Otherwise we are playing
|
||||
+ * tsf-pingpong with other vendors drivers */
|
||||
+ beacon_tsf = le64_to_cpu(ni->ni_tstamp.tsf);
|
||||
+ if (beacon_tsf > rtsf + 0xffff) {
|
||||
+ ath_hal_settsf64(sc->sc_ah, beacon_tsf - rtsf);
|
||||
+ ieee80211_ibss_merge(ni);
|
||||
+ }
|
||||
+ break;
|
||||
}
|
||||
/* NB: Fall Through */
|
||||
case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
|
||||
@@ -6563,6 +6617,10 @@ ath_recv_mgmt(struct ieee80211vap * vap,
|
||||
#endif
|
||||
if (do_merge)
|
||||
ieee80211_ibss_merge(ni);
|
||||
+
|
||||
+ if ((sc->sc_opmode == HAL_M_IBSS) &&
|
||||
+ ath_hw_check_atim(sc, 1, vap->iv_bss->ni_intval))
|
||||
+ DPRINTF(sc, ATH_DEBUG_ANY, "Fixed ATIM window after beacon recv\n");
|
||||
}
|
||||
break;
|
||||
}
|
325
net/madwifi/patches/384-hwdetect.patch
Normal file
325
net/madwifi/patches/384-hwdetect.patch
Normal file
@ -0,0 +1,325 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -62,6 +62,7 @@
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/time.h>
|
||||
+#include <linux/pci.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#include "if_ethersubr.h" /* for ETHER_IS_MULTICAST */
|
||||
@@ -401,6 +402,15 @@ static int outdoor = -1;
|
||||
static int xchanmode = -1;
|
||||
static int beacon_cal = 1;
|
||||
|
||||
+static const struct ath_hw_detect generic_hw_info = {
|
||||
+ .vendor_name = "Unknown",
|
||||
+ .card_name = "Generic",
|
||||
+ .vendor = PCI_ANY_ID,
|
||||
+ .id = PCI_ANY_ID,
|
||||
+ .subvendor = PCI_ANY_ID,
|
||||
+ .subid = PCI_ANY_ID
|
||||
+};
|
||||
+
|
||||
static const char *hal_status_desc[] = {
|
||||
"No error",
|
||||
"No hardware present or device not yet supported",
|
||||
@@ -542,6 +552,8 @@ ath_attach(u_int16_t devid, struct net_d
|
||||
DPRINTF(sc, ATH_DEBUG_ANY, "%s: devid 0x%x\n", __func__, devid);
|
||||
#endif
|
||||
|
||||
+ sc->sc_hwinfo = &generic_hw_info;
|
||||
+
|
||||
/* Allocate space for dynamically determined maximum VAP count */
|
||||
sc->sc_bslot =
|
||||
kmalloc(ath_maxvaps * sizeof(struct ieee80211vap*), GFP_KERNEL);
|
||||
@@ -1508,6 +1520,29 @@ ath_vap_create(struct ieee80211com *ic,
|
||||
return vap;
|
||||
}
|
||||
|
||||
+void
|
||||
+ath_hw_detect(struct ath_softc *sc, const struct ath_hw_detect *cards, int n_cards, u32 vendor, u32 id, u32 subvendor, u32 subid)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < n_cards; i++) {
|
||||
+ const struct ath_hw_detect *c = &cards[i];
|
||||
+
|
||||
+ if ((c->vendor != PCI_ANY_ID) && c->vendor != vendor)
|
||||
+ continue;
|
||||
+ if ((c->id != PCI_ANY_ID) && c->id != id)
|
||||
+ continue;
|
||||
+ if ((c->subvendor != PCI_ANY_ID) && c->subvendor != subvendor)
|
||||
+ continue;
|
||||
+ if ((c->subid != PCI_ANY_ID) && c->subid != subid)
|
||||
+ continue;
|
||||
+
|
||||
+ sc->sc_hwinfo = c;
|
||||
+ sc->sc_poweroffset = c->poweroffset;
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void
|
||||
ath_vap_delete(struct ieee80211vap *vap)
|
||||
{
|
||||
@@ -10225,6 +10260,7 @@ static u_int32_t
|
||||
ath_set_clamped_maxtxpower(struct ath_softc *sc,
|
||||
u_int32_t new_clamped_maxtxpower)
|
||||
{
|
||||
+ new_clamped_maxtxpower -= sc->sc_poweroffset;
|
||||
(void)ath_hal_settxpowlimit(sc->sc_ah, new_clamped_maxtxpower);
|
||||
return ath_get_clamped_maxtxpower(sc);
|
||||
}
|
||||
@@ -10238,6 +10274,7 @@ ath_get_clamped_maxtxpower(struct ath_so
|
||||
{
|
||||
u_int32_t clamped_maxtxpower;
|
||||
(void)ath_hal_getmaxtxpow(sc->sc_ah, &clamped_maxtxpower);
|
||||
+ clamped_maxtxpower += sc->sc_poweroffset;
|
||||
return clamped_maxtxpower;
|
||||
}
|
||||
|
||||
@@ -10821,6 +10858,12 @@ ath_ioctl(struct net_device *dev, struct
|
||||
* is to add module parameters.
|
||||
*/
|
||||
|
||||
+/* sysctls for hardware info */
|
||||
+enum {
|
||||
+ ATH_CARD_VENDOR,
|
||||
+ ATH_CARD_NAME,
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* Dynamic (i.e. per-device) sysctls. These are automatically
|
||||
* mirrored in /proc/sys.
|
||||
@@ -10900,6 +10943,38 @@ ath_sysctl_get_intmit(struct ath_softc *
|
||||
}
|
||||
|
||||
static int
|
||||
+ATH_SYSCTL_DECL(ath_sysctl_hwinfo, ctl, write, filp, buffer, lenp, ppos)
|
||||
+{
|
||||
+ struct ath_softc *sc = ctl->extra1;
|
||||
+ struct ath_hal *ah = sc->sc_ah;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (write)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ATH_LOCK(sc);
|
||||
+ switch((long)ctl->extra2) {
|
||||
+ case ATH_CARD_VENDOR:
|
||||
+ ctl->data = (char *)sc->sc_hwinfo->vendor_name;
|
||||
+ break;
|
||||
+ case ATH_CARD_NAME:
|
||||
+ ctl->data = (char *)sc->sc_hwinfo->card_name;
|
||||
+ break;
|
||||
+ default:
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (ret == 0) {
|
||||
+ ctl->maxlen = strlen(ctl->data);
|
||||
+ ret = ATH_SYSCTL_PROC_DOSTRING(ctl, write, filp,
|
||||
+ buffer, lenp, ppos);
|
||||
+ }
|
||||
+ ATH_UNLOCK(sc);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl, write, filp, buffer, lenp, ppos)
|
||||
{
|
||||
struct ath_softc *sc = ctl->extra1;
|
||||
@@ -11179,6 +11254,24 @@ static int maxint = 0x7fffffff; /* 32-b
|
||||
|
||||
static const ctl_table ath_sysctl_template[] = {
|
||||
{ .ctl_name = CTL_AUTO,
|
||||
+ .procname = "dev_vendor",
|
||||
+ .mode = 0644,
|
||||
+ .proc_handler = ath_sysctl_hwinfo,
|
||||
+ .strategy = &sysctl_string,
|
||||
+ .data = "N/A",
|
||||
+ .maxlen = 1,
|
||||
+ .extra2 = (void *)ATH_CARD_VENDOR,
|
||||
+ },
|
||||
+ { .ctl_name = CTL_AUTO,
|
||||
+ .procname = "dev_name",
|
||||
+ .mode = 0644,
|
||||
+ .proc_handler = ath_sysctl_hwinfo,
|
||||
+ .strategy = &sysctl_string,
|
||||
+ .data = "N/A",
|
||||
+ .maxlen = 1,
|
||||
+ .extra2 = (void *)ATH_CARD_NAME,
|
||||
+ },
|
||||
+ { .ctl_name = CTL_AUTO,
|
||||
.procname = "slottime",
|
||||
.mode = 0644,
|
||||
.proc_handler = ath_sysctl_halparam,
|
||||
--- a/ath/if_athvar.h
|
||||
+++ b/ath/if_athvar.h
|
||||
@@ -168,12 +168,16 @@ static inline struct net_device *_alloc_
|
||||
void __user *buffer, size_t *lenp)
|
||||
#define ATH_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, lenp, ppos) \
|
||||
proc_dointvec(ctl, write, filp, buffer, lenp)
|
||||
+#define ATH_SYSCTL_PROC_DOSTRING(ctl, write, filp, buffer, lenp, ppos) \
|
||||
+ proc_dostring(ctl, write, filp, buffer, lenp)
|
||||
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) */
|
||||
#define ATH_SYSCTL_DECL(f, ctl, write, filp, buffer, lenp, ppos) \
|
||||
f(ctl_table *ctl, int write, struct file *filp, \
|
||||
void __user *buffer, size_t *lenp, loff_t *ppos)
|
||||
#define ATH_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, lenp, ppos) \
|
||||
proc_dointvec(ctl, write, filp, buffer, lenp, ppos)
|
||||
+#define ATH_SYSCTL_PROC_DOSTRING(ctl, write, filp, buffer, lenp, ppos) \
|
||||
+ proc_dostring(ctl, write, filp, buffer, lenp, ppos)
|
||||
#endif
|
||||
|
||||
#define ATH_TIMEOUT 1000
|
||||
@@ -469,6 +473,7 @@ struct ath_hal;
|
||||
struct ath_desc;
|
||||
struct ath_ratectrl;
|
||||
struct ath_tx99;
|
||||
+struct ath_hw_detect;
|
||||
struct proc_dir_entry;
|
||||
|
||||
/*
|
||||
@@ -629,6 +634,7 @@ struct ath_softc {
|
||||
struct ath_ratectrl *sc_rc; /* tx rate control support */
|
||||
struct ath_tx99 *sc_tx99; /* tx99 support */
|
||||
void (*sc_setdefantenna)(struct ath_softc *, u_int);
|
||||
+ const struct ath_hw_detect *sc_hwinfo;
|
||||
|
||||
unsigned int sc_invalid:1; /* being detached */
|
||||
unsigned int sc_mrretry:1; /* multi-rate retry support */
|
||||
@@ -683,6 +689,7 @@ struct ath_softc {
|
||||
const HAL_RATE_TABLE *sc_quarter_rates; /* quarter rate table */
|
||||
HAL_OPMODE sc_opmode; /* current hal operating mode */
|
||||
enum ieee80211_phymode sc_curmode; /* current phy mode */
|
||||
+ u_int sc_poweroffset; /* hardware power offset */
|
||||
u_int16_t sc_curtxpow; /* current tx power limit */
|
||||
u_int16_t sc_curaid; /* current association id */
|
||||
HAL_CHANNEL sc_curchan; /* current h/w channel */
|
||||
@@ -929,4 +936,16 @@ int ar_device(int devid);
|
||||
|
||||
void ath_radar_detected(struct ath_softc *sc, const char* message);
|
||||
|
||||
+struct ath_hw_detect {
|
||||
+ const char *vendor_name;
|
||||
+ const char *card_name;
|
||||
+ u32 vendor;
|
||||
+ u32 id;
|
||||
+ u32 subvendor;
|
||||
+ u32 subid;
|
||||
+ u32 poweroffset;
|
||||
+};
|
||||
+
|
||||
+extern void ath_hw_detect(struct ath_softc *sc, const struct ath_hw_detect *cards, int n_cards, u32 vendor, u32 id, u32 subvendor, u32 subid);
|
||||
+
|
||||
#endif /* _DEV_ATH_ATHVAR_H */
|
||||
--- a/ath/if_ath_ahb.c
|
||||
+++ b/ath/if_ath_ahb.c
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/cache.h>
|
||||
#include <linux/platform_device.h>
|
||||
+#include <linux/pci.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/uaccess.h>
|
||||
@@ -181,12 +182,32 @@ exit_ath_wmac(u_int16_t wlanNum, struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static const char ubnt[] = "Ubiquiti Networks";
|
||||
+/* { vendorname, cardname, vendorid, cardid, subsys vendorid, subsys id, poweroffset } */
|
||||
+static const struct ath_hw_detect cards[] = {
|
||||
+ { ubnt, "PowerStation2 (18V)", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xb102 },
|
||||
+ { ubnt, "PowerStation2 (16D)", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xb202 },
|
||||
+ { ubnt, "PowerStation2 (EXT)", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xb302 },
|
||||
+ { ubnt, "PowerStation5 (22V)", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xb105 },
|
||||
+ { ubnt, "PowerStation5 (EXT)", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xb305 },
|
||||
+ { ubnt, "WispStation5", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xa105 },
|
||||
+ { ubnt, "LiteStation2", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xa002 },
|
||||
+ { ubnt, "LiteStation5", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xa005 },
|
||||
+ { ubnt, "NanoStation2", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xc002 },
|
||||
+ { ubnt, "NanoStation5", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xc005 },
|
||||
+ { ubnt, "NanoStation Loco2", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xc102 },
|
||||
+ { ubnt, "NanoStation Loco5", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xc105 },
|
||||
+ { ubnt, "Bullet2", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xc202 },
|
||||
+ { ubnt, "Bullet5", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xc205 },
|
||||
+};
|
||||
+
|
||||
static int
|
||||
init_ath_wmac(u_int16_t devid, u_int16_t wlanNum, struct ar531x_config *config)
|
||||
{
|
||||
const char *athname;
|
||||
struct net_device *dev;
|
||||
struct ath_ahb_softc *sc;
|
||||
+ u16 *radio_data;
|
||||
|
||||
if (((wlanNum != 0) && (wlanNum != 1)) ||
|
||||
(sclist[wlanNum] != NULL))
|
||||
@@ -248,6 +269,16 @@ init_ath_wmac(u_int16_t devid, u_int16_t
|
||||
sc->aps_sc.sc_softled = 1; /* SoftLED over GPIO */
|
||||
sc->aps_sc.sc_ledpin = config->board->sysLedGpio;
|
||||
sc->aps_sc.sc_invalid = 0;
|
||||
+ radio_data = (u16 *) config->radio;
|
||||
+ if (radio_data) {
|
||||
+ u16 vendor, id, subvendor, subid;
|
||||
+ vendor = radio_data[1];
|
||||
+ id = radio_data[0];
|
||||
+ subvendor = radio_data[8];
|
||||
+ subid = radio_data[7];
|
||||
+ ath_hw_detect(&sc->aps_sc, cards, ARRAY_SIZE(cards), vendor, id, subvendor, subid);
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
|
||||
bad4:
|
||||
--- a/ath/if_ath_pci.c
|
||||
+++ b/ath/if_ath_pci.c
|
||||
@@ -123,6 +123,33 @@ static u16 ath_devidmap[][2] = {
|
||||
{ 0xff1a, 0x001a }
|
||||
};
|
||||
|
||||
+static const char ubnt[] = "Ubiquiti Networks";
|
||||
+/* { vendorname, cardname, vendorid, cardid, subsys vendorid, subsys id, poweroffset } */
|
||||
+static const struct ath_hw_detect cards[] = {
|
||||
+ { ubnt, "XR2", 0x168c, 0x001b, 0x0777, 0x3002, 10 },
|
||||
+ { ubnt, "XR2", 0x168c, 0x001b, 0x7777, 0x3002, 10 },
|
||||
+ { ubnt, "XR2.3", 0x168c, 0x001b, 0x0777, 0x3b02, 10 },
|
||||
+ { ubnt, "XR2.6", 0x168c, 0x001b, 0x0777, 0x3c02, 10 },
|
||||
+ { ubnt, "XR3-2.8", 0x168c, 0x001b, 0x0777, 0x3b03, 10 },
|
||||
+ { ubnt, "XR3-3.6", 0x168c, 0x001b, 0x0777, 0x3c03, 10 },
|
||||
+ { ubnt, "XR3", 0x168c, 0x001b, 0x0777, 0x3003, 10 },
|
||||
+ { ubnt, "XR4", 0x168c, 0x001b, 0x0777, 0x3004, 10 },
|
||||
+ { ubnt, "XR5", 0x168c, 0x001b, 0x0777, 0x3005, 10 },
|
||||
+ { ubnt, "XR5", 0x168c, 0x001b, 0x7777, 0x3005, 10 },
|
||||
+ { ubnt, "XR7", 0x168c, 0x001b, 0x0777, 0x3007, 10 },
|
||||
+ { ubnt, "XR9", 0x168c, 0x001b, 0x0777, 0x3009, 10 },
|
||||
+ { ubnt, "SRC", 0x168c, 0x0013, 0x168c, 0x1042, 1 },
|
||||
+ { ubnt, "SR2", 0x168c, 0x0013, 0x0777, 0x2041, 10 },
|
||||
+ { ubnt, "SR4", 0x168c, 0x0013, 0x0777, 0x2004, 6 },
|
||||
+ { ubnt, "SR4", 0x168c, 0x0013, 0x7777, 0x2004, 6 },
|
||||
+ { ubnt, "SR4C", 0x168c, 0x0013, 0x0777, 0x1004, 6 },
|
||||
+ { ubnt, "SR4C", 0x168c, 0x0013, 0x7777, 0x1004, 6 },
|
||||
+ { ubnt, "SR5", 0x168c, 0x0013, 0x168c, 0x2042, 7 },
|
||||
+ { ubnt, "SR9", 0x168c, 0x0013, 0x7777, 0x2009, 12 },
|
||||
+ { ubnt, "SR71A", 0x168c, 0x0027, 0x168c, 0x2082, 10 },
|
||||
+ { ubnt, "SR71", 0x168c, 0x0027, 0x0777, 0x4082, 10 },
|
||||
+};
|
||||
+
|
||||
static int
|
||||
ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
@@ -257,6 +284,10 @@ ath_pci_probe(struct pci_dev *pdev, cons
|
||||
printk(KERN_INFO "%s: %s: %s: mem=0x%lx, irq=%d\n",
|
||||
dev_info, dev->name, athname ? athname : "Atheros ???", phymem, dev->irq);
|
||||
|
||||
+ ath_hw_detect(&sc->aps_sc, cards, ARRAY_SIZE(cards),
|
||||
+ pdev->vendor, pdev->device,
|
||||
+ pdev->subsystem_vendor, pdev->subsystem_device);
|
||||
+
|
||||
/* ready to process interrupts */
|
||||
sc->aps_sc.sc_invalid = 0;
|
||||
|
10
net/madwifi/patches/385-antenna_fix.patch
Normal file
10
net/madwifi/patches/385-antenna_fix.patch
Normal file
@ -0,0 +1,10 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -6669,6 +6669,7 @@ ath_setdefantenna(struct ath_softc *sc,
|
||||
struct ath_hal *ah = sc->sc_ah;
|
||||
|
||||
/* XXX block beacon interrupts */
|
||||
+ ath_hal_setdiversity(ah, (sc->sc_diversity != 0));
|
||||
ath_hal_setdefantenna(ah, antenna);
|
||||
if (sc->sc_defant != antenna)
|
||||
sc->sc_stats.ast_ant_defswitch++;
|
116
net/madwifi/patches/386-acl_crashfix.patch
Normal file
116
net/madwifi/patches/386-acl_crashfix.patch
Normal file
@ -0,0 +1,116 @@
|
||||
fixes ACL race condition caused by acl list modifications at run time
|
||||
|
||||
Signed-off-by: Sebastian Gottschall <brainslayer@dd-wrt.com>
|
||||
|
||||
--- a/net80211/ieee80211_acl.c
|
||||
+++ b/net80211/ieee80211_acl.c
|
||||
@@ -112,9 +112,9 @@ acl_detach(struct ieee80211vap *vap)
|
||||
{
|
||||
struct aclstate *as = vap->iv_as;
|
||||
|
||||
- ACL_LOCK(as);
|
||||
+ ACL_LOCK_IRQ(as);
|
||||
acl_free_all_locked(as);
|
||||
- ACL_UNLOCK(as);
|
||||
+ ACL_UNLOCK_IRQ(as);
|
||||
vap->iv_as = NULL;
|
||||
ACL_LOCK_DESTROY(as);
|
||||
FREE(as, M_DEVBUF);
|
||||
@@ -128,11 +128,18 @@ _find_acl(struct aclstate *as, const u_i
|
||||
struct acl *acl;
|
||||
int hash;
|
||||
|
||||
+ /* locking needed, as inserts are not atomic */
|
||||
+ ACL_LOCK_IRQ(as);
|
||||
hash = ACL_HASH(macaddr);
|
||||
LIST_FOREACH(acl, &as->as_hash[hash], acl_hash) {
|
||||
- if (IEEE80211_ADDR_EQ(acl->acl_macaddr, macaddr))
|
||||
- return acl;
|
||||
+ if (!IEEE80211_ADDR_EQ(acl->acl_macaddr, macaddr))
|
||||
+ continue;
|
||||
+
|
||||
+ ACL_UNLOCK_IRQ_EARLY(as);
|
||||
+ return acl;
|
||||
}
|
||||
+ ACL_UNLOCK_IRQ(as);
|
||||
+
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -176,11 +183,11 @@ acl_add(struct ieee80211vap *vap, const
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
- ACL_LOCK(as);
|
||||
+ ACL_LOCK_IRQ(as);
|
||||
hash = ACL_HASH(mac);
|
||||
LIST_FOREACH(acl, &as->as_hash[hash], acl_hash) {
|
||||
if (IEEE80211_ADDR_EQ(acl->acl_macaddr, mac)) {
|
||||
- ACL_UNLOCK_EARLY(as);
|
||||
+ ACL_UNLOCK_IRQ_EARLY(as);
|
||||
FREE(new, M_80211_ACL);
|
||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL,
|
||||
"ACL: add " MAC_FMT " failed, already present\n",
|
||||
@@ -191,7 +198,7 @@ acl_add(struct ieee80211vap *vap, const
|
||||
IEEE80211_ADDR_COPY(new->acl_macaddr, mac);
|
||||
TAILQ_INSERT_TAIL(&as->as_list, new, acl_list);
|
||||
LIST_INSERT_HEAD(&as->as_hash[hash], new, acl_hash);
|
||||
- ACL_UNLOCK(as);
|
||||
+ ACL_UNLOCK_IRQ(as);
|
||||
|
||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL,
|
||||
"ACL: add " MAC_FMT "\n", MAC_ADDR(mac));
|
||||
@@ -204,11 +211,11 @@ acl_remove(struct ieee80211vap *vap, con
|
||||
struct aclstate *as = vap->iv_as;
|
||||
struct acl *acl;
|
||||
|
||||
- ACL_LOCK(as);
|
||||
+ ACL_LOCK_IRQ(as);
|
||||
acl = _find_acl(as, mac);
|
||||
if (acl != NULL)
|
||||
_acl_free(as, acl);
|
||||
- ACL_UNLOCK(as);
|
||||
+ ACL_UNLOCK_IRQ(as);
|
||||
|
||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL,
|
||||
"ACL: remove " MAC_FMT "%s\n", MAC_ADDR(mac),
|
||||
@@ -235,9 +242,9 @@ acl_free_all(struct ieee80211vap *vap)
|
||||
|
||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_ACL, "ACL: %s\n", "free all");
|
||||
|
||||
- ACL_LOCK(as);
|
||||
+ ACL_LOCK_IRQ(as);
|
||||
acl_free_all_locked(vap->iv_as);
|
||||
- ACL_UNLOCK(as);
|
||||
+ ACL_UNLOCK_IRQ(as);
|
||||
|
||||
return 0;
|
||||
}
|
||||
--- a/net80211/ieee80211_linux.h
|
||||
+++ b/net80211/ieee80211_linux.h
|
||||
@@ -319,16 +319,15 @@ typedef spinlock_t ieee80211_scan_lock_t
|
||||
typedef spinlock_t acl_lock_t;
|
||||
#define ACL_LOCK_INIT(_as, _name) spin_lock_init(&(_as)->as_lock)
|
||||
#define ACL_LOCK_DESTROY(_as)
|
||||
-#define ACL_LOCK(_as) do { \
|
||||
- ACL_LOCK_CHECK(_as); \
|
||||
- spin_lock(&(_as)->as_lock);
|
||||
-#define ACL_UNLOCK(_as) \
|
||||
- ACL_LOCK_ASSERT(_as); \
|
||||
- spin_unlock(&(_as)->as_lock); \
|
||||
-} while(0)
|
||||
-#define ACL_UNLOCK_EARLY(_as) \
|
||||
- ACL_LOCK_ASSERT(_as); \
|
||||
- spin_unlock(&(_as)->as_lock);
|
||||
+#define ACL_LOCK_IRQ(_as) do { \
|
||||
+ unsigned long __acl_lockflags; \
|
||||
+ spin_lock_irqsave(&(_as)->as_lock, __acl_lockflags);
|
||||
+#define ACL_UNLOCK_IRQ(_as) \
|
||||
+ spin_unlock_irqrestore(&(_as)->as_lock, __acl_lockflags); \
|
||||
+} while (0)
|
||||
+#define ACL_UNLOCK_IRQ_EARLY(_as) do { \
|
||||
+ spin_unlock_irqrestore(&(_as)->as_lock, __acl_lockflags); \
|
||||
+} while (0)
|
||||
|
||||
#if (defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)) && defined(spin_is_locked)
|
||||
#define ACL_LOCK_ASSERT(_as) \
|
85
net/madwifi/patches/387-maxassoc.patch
Normal file
85
net/madwifi/patches/387-maxassoc.patch
Normal file
@ -0,0 +1,85 @@
|
||||
--- a/net80211/ieee80211_var.h
|
||||
+++ b/net80211/ieee80211_var.h
|
||||
@@ -198,6 +198,7 @@ struct ieee80211vap {
|
||||
u_int32_t iv_debug; /* debug msg flags */
|
||||
struct ieee80211_stats iv_stats; /* statistics */
|
||||
|
||||
+ int iv_max_nodes;
|
||||
int iv_monitor_nods_only; /* in monitor mode only nods traffic */
|
||||
int iv_monitor_txf_len; /* in monitor mode, truncate tx packets */
|
||||
int iv_monitor_phy_errors; /* in monitor mode, accept phy errors */
|
||||
--- a/net80211/ieee80211_ioctl.h
|
||||
+++ b/net80211/ieee80211_ioctl.h
|
||||
@@ -650,6 +650,7 @@ enum {
|
||||
IEEE80211_PARAM_RSSI_DIS_THR = 80, /* rssi threshold for disconnection */
|
||||
IEEE80211_PARAM_RSSI_DIS_COUNT = 81, /* counter for rssi threshold */
|
||||
IEEE80211_PARAM_WDS_SEP = 82, /* move wds stations into separate interfaces */
|
||||
+ IEEE80211_PARAM_MAXASSOC = 83, /* maximum associated stations */
|
||||
};
|
||||
|
||||
#define SIOCG80211STATS (SIOCDEVPRIVATE+2)
|
||||
--- a/net80211/ieee80211_wireless.c
|
||||
+++ b/net80211/ieee80211_wireless.c
|
||||
@@ -2875,6 +2875,12 @@ ieee80211_ioctl_setparam(struct net_devi
|
||||
else
|
||||
vap->iv_flags_ext &= ~IEEE80211_FEXT_WDSSEP;
|
||||
break;
|
||||
+ case IEEE80211_PARAM_MAXASSOC:
|
||||
+ if (vap->iv_opmode != IEEE80211_M_HOSTAP)
|
||||
+ retv = -EINVAL;
|
||||
+ else
|
||||
+ vap->iv_max_nodes = value;
|
||||
+ break;
|
||||
#ifdef ATH_REVERSE_ENGINEERING
|
||||
case IEEE80211_PARAM_DUMPREGS:
|
||||
ieee80211_dump_registers(dev, info, w, extra);
|
||||
@@ -3234,6 +3240,9 @@ ieee80211_ioctl_getparam(struct net_devi
|
||||
case IEEE80211_PARAM_WDS_SEP:
|
||||
param[0] = !!(vap->iv_flags_ext & IEEE80211_FEXT_WDSSEP);
|
||||
break;
|
||||
+ case IEEE80211_PARAM_MAXASSOC:
|
||||
+ param[0] = vap->iv_max_nodes;
|
||||
+ break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@@ -5789,6 +5798,10 @@ static const struct iw_priv_args ieee802
|
||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wdssep"},
|
||||
{ IEEE80211_PARAM_WDS_SEP,
|
||||
0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_wdssep"},
|
||||
+ { IEEE80211_PARAM_MAXASSOC,
|
||||
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "maxassoc"},
|
||||
+ { IEEE80211_PARAM_MAXASSOC,
|
||||
+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_maxassoc"},
|
||||
|
||||
#ifdef ATH_REVERSE_ENGINEERING
|
||||
/*
|
||||
--- a/net80211/ieee80211_input.c
|
||||
+++ b/net80211/ieee80211_input.c
|
||||
@@ -4020,7 +4020,26 @@ ieee80211_recv_mgmt(struct ieee80211vap
|
||||
vap->iv_stats.is_rx_assoc_norate++;
|
||||
return;
|
||||
}
|
||||
+ if (vap->iv_max_nodes > 0) {
|
||||
+ unsigned int active_nodes = 0;
|
||||
+ struct ieee80211_node *tni;
|
||||
|
||||
+ IEEE80211_NODE_TABLE_LOCK_IRQ(&ic->ic_sta);
|
||||
+ TAILQ_FOREACH(tni, &ic->ic_sta.nt_node, ni_list) {
|
||||
+ if (tni->ni_vap != vap)
|
||||
+ continue;
|
||||
+ if (tni->ni_associd == 0)
|
||||
+ continue;
|
||||
+ active_nodes++;
|
||||
+ }
|
||||
+ IEEE80211_NODE_TABLE_UNLOCK_IRQ(&ic->ic_sta);
|
||||
+
|
||||
+ if (active_nodes >= vap->iv_max_nodes) {
|
||||
+ /* too many nodes connected */
|
||||
+ ieee80211_node_leave(ni);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
if (ni->ni_associd != 0 &&
|
||||
IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan)) {
|
||||
if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)
|
60
net/madwifi/patches/388-apsta_fix.patch
Normal file
60
net/madwifi/patches/388-apsta_fix.patch
Normal file
@ -0,0 +1,60 @@
|
||||
--- a/net80211/ieee80211_proto.c
|
||||
+++ b/net80211/ieee80211_proto.c
|
||||
@@ -1415,7 +1415,8 @@ __ieee80211_newstate(struct ieee80211vap
|
||||
vap->iv_state = nstate; /* state transition */
|
||||
del_timer(&vap->iv_mgtsend);
|
||||
if ((vap->iv_opmode != IEEE80211_M_HOSTAP) &&
|
||||
- (ostate != IEEE80211_S_SCAN))
|
||||
+ (ostate != IEEE80211_S_SCAN) &&
|
||||
+ !(vap->iv_flags_ext & IEEE80211_FEXT_SCAN_PENDING))
|
||||
ieee80211_cancel_scan(vap); /* background scan */
|
||||
ni = vap->iv_bss; /* NB: no reference held */
|
||||
switch (nstate) {
|
||||
@@ -1457,7 +1458,8 @@ __ieee80211_newstate(struct ieee80211vap
|
||||
}
|
||||
goto reset;
|
||||
case IEEE80211_S_SCAN:
|
||||
- ieee80211_cancel_scan(vap);
|
||||
+ if (!(vap->iv_flags_ext & IEEE80211_FEXT_SCAN_PENDING))
|
||||
+ ieee80211_cancel_scan(vap);
|
||||
goto reset;
|
||||
reset:
|
||||
ieee80211_reset_bss(vap);
|
||||
@@ -1995,7 +1997,9 @@ ieee80211_newstate(struct ieee80211vap *
|
||||
}
|
||||
}
|
||||
}
|
||||
- } else if (dstate == IEEE80211_S_SCAN) {
|
||||
+ } else if ((dstate == IEEE80211_S_SCAN) ||
|
||||
+ (dstate == IEEE80211_S_AUTH) ||
|
||||
+ (dstate == IEEE80211_S_ASSOC)) {
|
||||
/* Force to scan pending... someone is scanning */
|
||||
vap->iv_flags_ext |= IEEE80211_FEXT_SCAN_PENDING;
|
||||
__ieee80211_newstate(vap, IEEE80211_S_INIT, arg);
|
||||
--- a/net80211/ieee80211_output.c
|
||||
+++ b/net80211/ieee80211_output.c
|
||||
@@ -238,7 +238,9 @@ ieee80211_hardstart(struct sk_buff *skb,
|
||||
}
|
||||
|
||||
/* Cancel any running BG scan */
|
||||
- if (!(ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN_THR) && (vap->iv_state == IEEE80211_S_RUN))
|
||||
+ if (!(ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN_THR) &&
|
||||
+ (vap->iv_state == IEEE80211_S_RUN) &&
|
||||
+ (ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN))
|
||||
ieee80211_cancel_scan(vap);
|
||||
|
||||
/*
|
||||
--- a/net80211/ieee80211_wireless.c
|
||||
+++ b/net80211/ieee80211_wireless.c
|
||||
@@ -2728,9 +2728,9 @@ ieee80211_ioctl_setparam(struct net_devi
|
||||
return -EINVAL;
|
||||
vap->iv_flags |= IEEE80211_F_BGSCAN;
|
||||
} else {
|
||||
- /* XXX racey? */
|
||||
+ if (ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN)
|
||||
+ ieee80211_cancel_scan(vap); /* anything current */
|
||||
vap->iv_flags &= ~IEEE80211_F_BGSCAN;
|
||||
- ieee80211_cancel_scan(vap); /* anything current */
|
||||
}
|
||||
break;
|
||||
case IEEE80211_PARAM_BGSCAN_IDLE:
|
249
net/madwifi/patches/389-autochannel.patch
Normal file
249
net/madwifi/patches/389-autochannel.patch
Normal file
@ -0,0 +1,249 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -384,6 +384,7 @@ static u_int32_t ath_get_real_maxtxpower
|
||||
|
||||
static void ath_poll_disable(struct net_device *dev);
|
||||
static void ath_poll_enable(struct net_device *dev);
|
||||
+static void ath_fetch_idle_time(struct ath_softc *sc);
|
||||
|
||||
/* calibrate every 30 secs in steady state but check every second at first. */
|
||||
static int ath_calinterval = ATH_SHORT_CALINTERVAL;
|
||||
@@ -2581,6 +2582,7 @@ ath_init(struct net_device *dev)
|
||||
* be followed by initialization of the appropriate bits
|
||||
* and then setup of the interrupt mask.
|
||||
*/
|
||||
+ ath_fetch_idle_time(sc);
|
||||
sc->sc_curchan.channel = ic->ic_curchan->ic_freq;
|
||||
sc->sc_curchan.channelFlags = ath_chan2flags(ic->ic_curchan);
|
||||
if (!ath_hal_reset(ah, sc->sc_opmode, &sc->sc_curchan, AH_FALSE, &status)) {
|
||||
@@ -2914,6 +2916,48 @@ ath_hw_check_atim(struct ath_softc *sc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#define AR5K_MIBC 0x0040
|
||||
+#define AR5K_MIBC_FREEZE (1 << 1)
|
||||
+#define AR5K_TXFC 0x80ec
|
||||
+#define AR5K_RXFC 0x80f0
|
||||
+#define AR5K_RXCLEAR 0x80f4
|
||||
+#define AR5K_CYCLES 0x80f8
|
||||
+static void
|
||||
+ath_fetch_idle_time(struct ath_softc *sc)
|
||||
+{
|
||||
+ struct ieee80211com *ic = &sc->sc_ic;
|
||||
+ struct ath_hal *ah = sc->sc_ah;
|
||||
+ u_int32_t cc, rx;
|
||||
+ u_int32_t time = 0;
|
||||
+
|
||||
+ if (sc->sc_ah->ah_macType < 5212)
|
||||
+ return;
|
||||
+
|
||||
+ if (!ic->ic_curchan || (ic->ic_curchan == IEEE80211_CHAN_ANYC))
|
||||
+ return;
|
||||
+
|
||||
+ OS_REG_WRITE(ah, AR5K_MIBC, AR5K_MIBC_FREEZE);
|
||||
+ rx = OS_REG_READ(ah, AR5K_RXCLEAR);
|
||||
+ cc = OS_REG_READ(ah, AR5K_CYCLES);
|
||||
+
|
||||
+ if (!cc)
|
||||
+ return;
|
||||
+
|
||||
+ if (rx > cc)
|
||||
+ return; /* should not happen */
|
||||
+
|
||||
+ if (sc->sc_last_chan)
|
||||
+ sc->sc_last_chan->ic_idletime = 100 * (cc - rx) / cc;
|
||||
+ sc->sc_last_chan = ic->ic_curchan;
|
||||
+
|
||||
+ OS_REG_WRITE(ah, AR5K_RXCLEAR, 0);
|
||||
+ OS_REG_WRITE(ah, AR5K_CYCLES, 0);
|
||||
+ OS_REG_WRITE(ah, AR5K_TXFC, 0);
|
||||
+ OS_REG_WRITE(ah, AR5K_RXFC, 0);
|
||||
+ OS_REG_WRITE(ah, AR5K_MIBC, 0);
|
||||
+}
|
||||
+#undef AR5K_RXCLEAR
|
||||
+#undef AR5K_CYCLES
|
||||
|
||||
/*
|
||||
* Reset the hardware w/o losing operational state. This is
|
||||
@@ -2941,6 +2985,7 @@ ath_reset(struct net_device *dev)
|
||||
* Convert to a HAL channel description with the flags
|
||||
* constrained to reflect the current operating mode.
|
||||
*/
|
||||
+ ath_fetch_idle_time(sc);
|
||||
c = ic->ic_curchan;
|
||||
sc->sc_curchan.channel = c->ic_freq;
|
||||
sc->sc_curchan.channelFlags = ath_chan2flags(c);
|
||||
@@ -9023,6 +9068,7 @@ ath_chan_set(struct ath_softc *sc, struc
|
||||
u_int8_t channel_change_required = 0;
|
||||
struct timeval tv;
|
||||
|
||||
+
|
||||
/*
|
||||
* Convert to a HAL channel description with
|
||||
* the flags constrained to reflect the current
|
||||
@@ -9031,6 +9077,14 @@ ath_chan_set(struct ath_softc *sc, struc
|
||||
memset(&hchan, 0, sizeof(HAL_CHANNEL));
|
||||
hchan.channel = chan->ic_freq;
|
||||
hchan.channelFlags = ath_chan2flags(chan);
|
||||
+
|
||||
+ /* don't do duplicate channel changes, but do
|
||||
+ * store the available idle time */
|
||||
+ ath_fetch_idle_time(sc);
|
||||
+ if ((sc->sc_curchan.channel == hchan.channel) &&
|
||||
+ (sc->sc_curchan.channelFlags == hchan.channelFlags))
|
||||
+ return 0;
|
||||
+
|
||||
KASSERT(hchan.channel != 0,
|
||||
("bogus channel %u/0x%x", hchan.channel, hchan.channelFlags));
|
||||
do_gettimeofday(&tv);
|
||||
--- a/ath/if_athvar.h
|
||||
+++ b/ath/if_athvar.h
|
||||
@@ -774,6 +774,7 @@ struct ath_softc {
|
||||
struct ieee80211vap **sc_bslot; /* beacon xmit slots */
|
||||
int sc_bnext; /* next slot for beacon xmit */
|
||||
|
||||
+ struct ieee80211_channel *sc_last_chan;
|
||||
int sc_beacon_cal; /* use beacon timer for calibration */
|
||||
u_int64_t sc_lastcal; /* last time the calibration was performed */
|
||||
struct timer_list sc_cal_ch; /* calibration timer */
|
||||
--- a/net80211/_ieee80211.h
|
||||
+++ b/net80211/_ieee80211.h
|
||||
@@ -148,6 +148,7 @@ struct ieee80211_channel {
|
||||
int8_t ic_maxpower; /* maximum tx power in dBm */
|
||||
int8_t ic_minpower; /* minimum tx power in dBm */
|
||||
u_int8_t ic_scanflags;
|
||||
+ u_int8_t ic_idletime; /* phy idle time in % */
|
||||
};
|
||||
|
||||
#define IEEE80211_CHAN_MAX 255
|
||||
--- a/net80211/ieee80211_scan_ap.c
|
||||
+++ b/net80211/ieee80211_scan_ap.c
|
||||
@@ -417,6 +417,19 @@ pc_cmp_rssi(struct ap_state *as, struct
|
||||
|
||||
/* This function must be invoked with locks acquired */
|
||||
static int
|
||||
+pc_cmp_idletime(struct ieee80211_channel *a,
|
||||
+ struct ieee80211_channel *b)
|
||||
+{
|
||||
+ if (!a->ic_idletime || !b->ic_idletime)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* a is better than b (return < 0) when a has more idle time than b */
|
||||
+ return b->ic_idletime - a->ic_idletime;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* This function must be invoked with locks acquired */
|
||||
+static int
|
||||
pc_cmp_samechan(struct ieee80211com *ic, struct ieee80211_channel *a,
|
||||
struct ieee80211_channel *b)
|
||||
{
|
||||
@@ -451,6 +464,7 @@ pc_cmp(const void *_a, const void *_b)
|
||||
|
||||
EVALUATE_CRITERION(radar, a, b);
|
||||
EVALUATE_CRITERION(keepmode, params, a, b);
|
||||
+ EVALUATE_CRITERION(idletime, a, b);
|
||||
EVALUATE_CRITERION(sc, ic, a, b);
|
||||
/* XXX: rssi useless? pick_channel evaluates it anyway */
|
||||
EVALUATE_CRITERION(rssi, params->ss->ss_priv, a, b);
|
||||
@@ -519,16 +533,9 @@ pick_channel(struct ieee80211_scan_state
|
||||
#endif
|
||||
|
||||
best = NULL;
|
||||
- best_rssi = 0xff; /* If signal is bigger than 0xff, we'd be melting. */
|
||||
|
||||
for (i = 0; i < ss_last; i++) {
|
||||
c = &chans[i];
|
||||
- benefit = best_rssi - as->as_maxrssi[c->chan->ic_ieee];
|
||||
- sta_assoc = ic->ic_sta_assoc;
|
||||
-
|
||||
- /* Don't switch... */
|
||||
- if (benefit <= 0)
|
||||
- continue;
|
||||
|
||||
/* Verify channel is not marked for non-occupancy */
|
||||
if (IEEE80211_IS_CHAN_RADAR(c->chan))
|
||||
@@ -546,31 +553,8 @@ pick_channel(struct ieee80211_scan_state
|
||||
break;
|
||||
}
|
||||
|
||||
- if (sta_assoc != 0) {
|
||||
- int sl = ic->ic_cn_total -
|
||||
- ic->ic_chan_nodes[c->chan->ic_ieee]; /* count */
|
||||
- if (ic->ic_sc_algorithm == IEEE80211_SC_LOOSE) {
|
||||
- int sl_max = ic->ic_sc_sldg * benefit;
|
||||
- sl = 1000 * sl / sta_assoc; /* permil */
|
||||
- IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
|
||||
- "%s: chan %d, dB gained: %d, "
|
||||
- "STAs lost: %d permil (max %d)\n",
|
||||
- __func__, c->chan->ic_ieee,
|
||||
- benefit, sl, sl_max);
|
||||
- if (sl > sl_max)
|
||||
- continue;
|
||||
- } else if (((ic->ic_sc_algorithm ==
|
||||
- IEEE80211_SC_TIGHT) ||
|
||||
- (ic->ic_sc_algorithm ==
|
||||
- IEEE80211_SC_STRICT)) &&
|
||||
- (sl > 0)) {
|
||||
- /* Break the loop as the subsequent chans
|
||||
- * won't be better. */
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
best = c->chan;
|
||||
- best_rssi = as->as_maxrssi[best->ic_ieee];
|
||||
+ break;
|
||||
}
|
||||
|
||||
if (best != NULL) {
|
||||
@@ -599,6 +583,9 @@ ap_end(struct ieee80211_scan_state *ss,
|
||||
("wrong opmode %u", vap->iv_opmode));
|
||||
|
||||
ic = vap->iv_ic;
|
||||
+
|
||||
+ /* record stats for the channel that was scanned last */
|
||||
+ ic->ic_set_channel(ic);
|
||||
bestchan = pick_channel(ss, vap, flags);
|
||||
if (bestchan == NULL) {
|
||||
if (ss->ss_last > 0) {
|
||||
--- a/net80211/ieee80211_scan.c
|
||||
+++ b/net80211/ieee80211_scan.c
|
||||
@@ -1002,20 +1002,34 @@ ieee80211_scan_add_channels(struct ieee8
|
||||
{
|
||||
struct ieee80211_channel *c, *cg;
|
||||
u_int modeflags;
|
||||
+ int has_non_turbo = 0;
|
||||
int i;
|
||||
|
||||
KASSERT(mode < ARRAY_SIZE(chanflags), ("Unexpected mode %u", mode));
|
||||
modeflags = chanflags[mode];
|
||||
for (i = 0; i < ic->ic_nchans; i++) {
|
||||
c = &ic->ic_channels[i];
|
||||
+ if (c->ic_flags & (IEEE80211_CHAN_TURBO | IEEE80211_CHAN_STURBO))
|
||||
+ continue;
|
||||
+
|
||||
+ has_non_turbo = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ for (i = 0; i < ic->ic_nchans; i++) {
|
||||
+ c = &ic->ic_channels[i];
|
||||
if (c == NULL || isclr(ic->ic_chan_active, c->ic_ieee))
|
||||
continue;
|
||||
if (c->ic_scanflags & IEEE80211_NOSCAN_SET)
|
||||
continue;
|
||||
- if (modeflags &&
|
||||
- ((c->ic_flags & IEEE80211_CHAN_ALLTURBO) !=
|
||||
- (modeflags & IEEE80211_CHAN_ALLTURBO)))
|
||||
- continue;
|
||||
+ if (modeflags) {
|
||||
+ if ((c->ic_flags & IEEE80211_CHAN_ALLTURBO) !=
|
||||
+ (modeflags & IEEE80211_CHAN_ALLTURBO))
|
||||
+ continue;
|
||||
+ } else if (has_non_turbo) {
|
||||
+ if ((ss->ss_vap->iv_opmode == IEEE80211_M_HOSTAP) &&
|
||||
+ (c->ic_flags & (IEEE80211_CHAN_TURBO | IEEE80211_CHAN_STURBO)))
|
||||
+ continue;
|
||||
+ }
|
||||
if (mode == IEEE80211_MODE_AUTO) {
|
||||
/*
|
||||
* XXX special-case 11b/g channels so we select
|
13
net/madwifi/patches/390-frame_type.patch
Normal file
13
net/madwifi/patches/390-frame_type.patch
Normal file
@ -0,0 +1,13 @@
|
||||
--- a/net80211/ieee80211_input.c
|
||||
+++ b/net80211/ieee80211_input.c
|
||||
@@ -4443,7 +4443,9 @@ ath_eth_type_trans(struct sk_buff *skb,
|
||||
if (memcmp(eth->h_dest, dev->dev_addr, ETH_ALEN))
|
||||
skb->pkt_type = PACKET_OTHERHOST;
|
||||
|
||||
- return eth->h_proto;
|
||||
+ if ((ntohs(eth->h_proto) >= 1536) || (ntohs(eth->h_proto) < 38))
|
||||
+ return eth->h_proto;
|
||||
+ return htons(ETH_P_802_2);
|
||||
}
|
||||
#endif
|
||||
|
29
net/madwifi/patches/391-vap_auth.patch
Normal file
29
net/madwifi/patches/391-vap_auth.patch
Normal file
@ -0,0 +1,29 @@
|
||||
--- a/net80211/ieee80211_input.c
|
||||
+++ b/net80211/ieee80211_input.c
|
||||
@@ -1375,7 +1375,7 @@ ieee80211_auth_open(struct ieee80211_nod
|
||||
vap->iv_stats.is_rx_bad_auth++; /* XXX maybe a unique error? */
|
||||
if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
|
||||
if (ni == vap->iv_bss) {
|
||||
- ni = ieee80211_dup_bss(vap, wh->i_addr2, 0);
|
||||
+ ni = ieee80211_dup_bss(vap, wh->i_addr2, 1);
|
||||
if (ni == NULL)
|
||||
return;
|
||||
tmpnode = 1;
|
||||
@@ -1763,6 +1763,8 @@ ieee80211_ssid_mismatch(struct ieee80211
|
||||
}
|
||||
|
||||
#define IEEE80211_VERIFY_SSID(_ni, _ssid) do { \
|
||||
+ if ((_ni)->ni_esslen == 0) \
|
||||
+ return; \
|
||||
if ((_ssid)[1] != 0 && \
|
||||
((_ssid)[1] != (_ni)->ni_esslen || \
|
||||
memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) { \
|
||||
@@ -1777,6 +1779,8 @@ ieee80211_ssid_mismatch(struct ieee80211
|
||||
} while (0)
|
||||
#else /* !IEEE80211_DEBUG */
|
||||
#define IEEE80211_VERIFY_SSID(_ni, _ssid) do { \
|
||||
+ if ((_ni)->ni_esslen == 0) \
|
||||
+ return; \
|
||||
if ((_ssid)[1] != 0 && \
|
||||
((_ssid)[1] != (_ni)->ni_esslen || \
|
||||
memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) { \
|
388
net/madwifi/patches/392-remove_wds_nodetracking.patch
Normal file
388
net/madwifi/patches/392-remove_wds_nodetracking.patch
Normal file
@ -0,0 +1,388 @@
|
||||
--- a/net80211/ieee80211_input.c
|
||||
+++ b/net80211/ieee80211_input.c
|
||||
@@ -568,36 +568,6 @@ ieee80211_input(struct ieee80211vap * va
|
||||
}
|
||||
}
|
||||
|
||||
- /* XXX: Useless node mgmt API; make better */
|
||||
- if ((dir == IEEE80211_FC1_DIR_DSTODS) && !vap->iv_wdsnode &&
|
||||
- !ni_wds && !ni->ni_subif) {
|
||||
- struct ieee80211_node_table *nt = &ic->ic_sta;
|
||||
- struct ieee80211_frame_addr4 *wh4;
|
||||
-
|
||||
- if (!(vap->iv_flags_ext & IEEE80211_FEXT_WDS)) {
|
||||
- IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
|
||||
- wh, "data", "%s", "4 addr not allowed");
|
||||
- goto err;
|
||||
- }
|
||||
- wh4 = (struct ieee80211_frame_addr4 *)skb->data;
|
||||
- ni_wds = ieee80211_find_wds_node(nt, wh4->i_addr4);
|
||||
- /* Last call increments ref count if !NULL */
|
||||
- if ((ni_wds != NULL) && (ni_wds != ni)) {
|
||||
- /*
|
||||
- * node with source address (addr4) moved
|
||||
- * to another WDS capable station. remove the
|
||||
- * reference to the previous station and add
|
||||
- * reference to the new one
|
||||
- */
|
||||
- (void) ieee80211_remove_wds_addr(nt, wh4->i_addr4);
|
||||
- ieee80211_add_wds_addr(nt, ni, wh4->i_addr4, 0);
|
||||
- }
|
||||
- if (ni_wds == NULL)
|
||||
- ieee80211_add_wds_addr(nt, ni, wh4->i_addr4, 0);
|
||||
- else
|
||||
- ieee80211_unref_node(&ni_wds);
|
||||
- }
|
||||
-
|
||||
/*
|
||||
* Check for power save state change.
|
||||
*/
|
||||
--- a/net80211/ieee80211_node.c
|
||||
+++ b/net80211/ieee80211_node.c
|
||||
@@ -122,7 +122,6 @@ static void ieee80211_node_table_init(st
|
||||
static void ieee80211_node_table_cleanup(struct ieee80211_node_table *);
|
||||
static void ieee80211_node_table_reset(struct ieee80211_node_table *,
|
||||
struct ieee80211vap *);
|
||||
-static void ieee80211_node_wds_ageout(unsigned long);
|
||||
|
||||
MALLOC_DEFINE(M_80211_NODE, "80211node", "802.11 node state");
|
||||
|
||||
@@ -785,10 +784,6 @@ ieee80211_node_table_init(struct ieee802
|
||||
nt->nt_name = name;
|
||||
nt->nt_scangen = 1;
|
||||
nt->nt_inact_init = inact;
|
||||
- init_timer(&nt->nt_wds_aging_timer);
|
||||
- nt->nt_wds_aging_timer.function = ieee80211_node_wds_ageout;
|
||||
- nt->nt_wds_aging_timer.data = (unsigned long) nt;
|
||||
- mod_timer(&nt->nt_wds_aging_timer, jiffies + HZ * WDS_AGING_TIMER_VAL);
|
||||
}
|
||||
|
||||
static __inline
|
||||
@@ -1204,142 +1199,6 @@ void ieee80211_wds_addif(struct ieee8021
|
||||
schedule_work(&ni->ni_create);
|
||||
}
|
||||
|
||||
-/* Add wds address to the node table */
|
||||
-int
|
||||
-#ifdef IEEE80211_DEBUG_REFCNT
|
||||
-ieee80211_add_wds_addr_debug(struct ieee80211_node_table *nt,
|
||||
- struct ieee80211_node *ni, const u_int8_t *macaddr, u_int8_t wds_static,
|
||||
- const char* func, int line)
|
||||
-#else
|
||||
-ieee80211_add_wds_addr(struct ieee80211_node_table *nt,
|
||||
- struct ieee80211_node *ni, const u_int8_t *macaddr, u_int8_t wds_static)
|
||||
-#endif
|
||||
-{
|
||||
- int hash;
|
||||
- struct ieee80211_wds_addr *wds;
|
||||
-
|
||||
- MALLOC(wds, struct ieee80211_wds_addr *, sizeof(struct ieee80211_wds_addr),
|
||||
- M_80211_WDS, M_NOWAIT | M_ZERO);
|
||||
- if (wds == NULL) {
|
||||
- /* XXX msg */
|
||||
- return 1;
|
||||
- }
|
||||
- if (wds_static)
|
||||
- wds->wds_agingcount = WDS_AGING_STATIC;
|
||||
- else
|
||||
- wds->wds_agingcount = WDS_AGING_COUNT;
|
||||
- hash = IEEE80211_NODE_HASH(macaddr);
|
||||
- IEEE80211_ADDR_COPY(wds->wds_macaddr, macaddr);
|
||||
-
|
||||
- IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
|
||||
-#ifdef IEEE80211_DEBUG_REFCNT
|
||||
- wds->wds_ni = ieee80211_ref_node_debug(ni, func, line);
|
||||
-#else
|
||||
- wds->wds_ni = ieee80211_ref_node(ni);
|
||||
-#endif
|
||||
- LIST_INSERT_HEAD(&nt->nt_wds_hash[hash], wds, wds_hash);
|
||||
- IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
|
||||
- return 0;
|
||||
-}
|
||||
-#ifdef IEEE80211_DEBUG_REFCNT
|
||||
-EXPORT_SYMBOL(ieee80211_add_wds_addr_debug);
|
||||
-#else
|
||||
-EXPORT_SYMBOL(ieee80211_add_wds_addr);
|
||||
-#endif
|
||||
-
|
||||
-/* remove wds address from the wds hash table */
|
||||
-void
|
||||
-#ifdef IEEE80211_DEBUG_REFCNT
|
||||
-ieee80211_remove_wds_addr_debug(struct ieee80211_node_table *nt, const u_int8_t *macaddr,
|
||||
- const char* func, int line)
|
||||
-#else
|
||||
-ieee80211_remove_wds_addr(struct ieee80211_node_table *nt, const u_int8_t *macaddr)
|
||||
-#endif
|
||||
-{
|
||||
- int hash;
|
||||
- struct ieee80211_wds_addr *wds, *twds;
|
||||
-
|
||||
- hash = IEEE80211_NODE_HASH(macaddr);
|
||||
- IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
|
||||
- LIST_FOREACH_SAFE(wds, &nt->nt_wds_hash[hash], wds_hash, twds) {
|
||||
- if (IEEE80211_ADDR_EQ(wds->wds_macaddr, macaddr)) {
|
||||
- LIST_REMOVE(wds, wds_hash);
|
||||
-#ifdef IEEE80211_DEBUG_REFCNT
|
||||
- ieee80211_unref_node_debug(&wds->wds_ni, func, line);
|
||||
-#else
|
||||
- ieee80211_unref_node(&wds->wds_ni);
|
||||
-#endif
|
||||
- FREE(wds, M_80211_WDS);
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
- IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
|
||||
-}
|
||||
-#ifdef IEEE80211_DEBUG_REFCNT
|
||||
-EXPORT_SYMBOL(ieee80211_remove_wds_addr_debug);
|
||||
-#else
|
||||
-EXPORT_SYMBOL(ieee80211_remove_wds_addr);
|
||||
-#endif
|
||||
-
|
||||
-/* Remove node references from wds table */
|
||||
-void
|
||||
-#ifdef IEEE80211_DEBUG_REFCNT
|
||||
-ieee80211_del_wds_node_debug(struct ieee80211_node_table *nt, struct ieee80211_node *ni,
|
||||
- const char* func, int line)
|
||||
-#else
|
||||
-ieee80211_del_wds_node(struct ieee80211_node_table *nt, struct ieee80211_node *ni)
|
||||
-#endif
|
||||
-{
|
||||
- int hash;
|
||||
- struct ieee80211_wds_addr *wds, *twds;
|
||||
-
|
||||
- IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
|
||||
- for (hash = 0; hash < IEEE80211_NODE_HASHSIZE; hash++) {
|
||||
- LIST_FOREACH_SAFE(wds, &nt->nt_wds_hash[hash], wds_hash, twds) {
|
||||
- if (wds->wds_ni == ni) {
|
||||
- LIST_REMOVE(wds, wds_hash);
|
||||
-#ifdef IEEE80211_DEBUG_REFCNT
|
||||
- ieee80211_unref_node_debug(&wds->wds_ni, func, line);
|
||||
-#else
|
||||
- ieee80211_unref_node(&wds->wds_ni);
|
||||
-#endif
|
||||
- FREE(wds, M_80211_WDS);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
|
||||
-}
|
||||
-#ifdef IEEE80211_DEBUG_REFCNT
|
||||
-EXPORT_SYMBOL(ieee80211_del_wds_node_debug);
|
||||
-#else
|
||||
-EXPORT_SYMBOL(ieee80211_del_wds_node);
|
||||
-#endif
|
||||
-
|
||||
-static void
|
||||
-ieee80211_node_wds_ageout(unsigned long data)
|
||||
-{
|
||||
- struct ieee80211_node_table *nt = (struct ieee80211_node_table *)data;
|
||||
- int hash;
|
||||
- struct ieee80211_wds_addr *wds, *twds;
|
||||
-
|
||||
- IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
|
||||
- for (hash = 0; hash < IEEE80211_NODE_HASHSIZE; hash++) {
|
||||
- LIST_FOREACH_SAFE(wds, &nt->nt_wds_hash[hash], wds_hash, twds) {
|
||||
- if (wds->wds_agingcount != WDS_AGING_STATIC) {
|
||||
- if (!wds->wds_agingcount) {
|
||||
- LIST_REMOVE(wds, wds_hash);
|
||||
- ieee80211_unref_node(&wds->wds_ni);
|
||||
- FREE(wds, M_80211_WDS);
|
||||
- } else
|
||||
- wds->wds_agingcount--;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
|
||||
- mod_timer(&nt->nt_wds_aging_timer, jiffies + HZ * WDS_AGING_TIMER_VAL);
|
||||
-}
|
||||
-
|
||||
-
|
||||
/* Add the specified station to the station table.
|
||||
* Allocates a new ieee80211_node* that has a reference count of one
|
||||
* If tmp is 0, it is added to the node table and the reference is used.
|
||||
@@ -1385,34 +1244,6 @@ ieee80211_dup_bss(struct ieee80211vap *v
|
||||
return ni;
|
||||
}
|
||||
|
||||
-static struct ieee80211_node *
|
||||
-#ifdef IEEE80211_DEBUG_REFCNT
|
||||
-ieee80211_find_wds_node_locked_debug(struct ieee80211_node_table *nt,
|
||||
- const u_int8_t *macaddr, const char* func, int line)
|
||||
-#else
|
||||
-ieee80211_find_wds_node_locked(struct ieee80211_node_table *nt,
|
||||
- const u_int8_t *macaddr)
|
||||
-#endif
|
||||
-{
|
||||
- struct ieee80211_wds_addr *wds;
|
||||
- int hash;
|
||||
- IEEE80211_NODE_TABLE_LOCK_ASSERT(nt);
|
||||
-
|
||||
- hash = IEEE80211_NODE_HASH(macaddr);
|
||||
- LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) {
|
||||
- if (IEEE80211_ADDR_EQ(wds->wds_macaddr, macaddr)) {
|
||||
- if (wds->wds_agingcount != WDS_AGING_STATIC)
|
||||
- wds->wds_agingcount = WDS_AGING_COUNT; /* reset the aging count */
|
||||
-#ifdef IEEE80211_DEBUG_REFCNT
|
||||
- return ieee80211_ref_node_debug(wds->wds_ni, func, line);
|
||||
-#else
|
||||
- return ieee80211_ref_node(wds->wds_ni);
|
||||
-#endif
|
||||
- }
|
||||
- }
|
||||
- return NULL;
|
||||
-}
|
||||
-
|
||||
/* NB: A node reference is acquired here; the caller MUST release it. */
|
||||
#ifdef IEEE80211_DEBUG_REFCNT
|
||||
#define ieee80211_find_node_locked(nt, mac) \
|
||||
@@ -1430,7 +1261,6 @@ ieee80211_find_node_locked(struct ieee80
|
||||
{
|
||||
struct ieee80211_node *ni;
|
||||
int hash;
|
||||
- struct ieee80211_wds_addr *wds;
|
||||
|
||||
IEEE80211_NODE_TABLE_LOCK_ASSERT(nt);
|
||||
|
||||
@@ -1445,48 +1275,11 @@ ieee80211_find_node_locked(struct ieee80
|
||||
return ni;
|
||||
}
|
||||
}
|
||||
-
|
||||
- /* Now, we look for the desired mac address in the 4 address
|
||||
- nodes. */
|
||||
- LIST_FOREACH(wds, &nt->nt_wds_hash[hash], wds_hash) {
|
||||
- if (IEEE80211_ADDR_EQ(wds->wds_macaddr, macaddr)) {
|
||||
-#ifdef IEEE80211_DEBUG_REFCNT
|
||||
- return ieee80211_ref_node_debug(wds->wds_ni, func, line);
|
||||
-#else
|
||||
- return ieee80211_ref_node(wds->wds_ni);
|
||||
-#endif
|
||||
- }
|
||||
- }
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ieee80211_node *
|
||||
#ifdef IEEE80211_DEBUG_REFCNT
|
||||
-ieee80211_find_wds_node_debug(struct ieee80211_node_table *nt, const u_int8_t *macaddr,
|
||||
- const char* func, int line)
|
||||
-#else
|
||||
-ieee80211_find_wds_node(struct ieee80211_node_table *nt, const u_int8_t *macaddr)
|
||||
-#endif
|
||||
-{
|
||||
- struct ieee80211_node *ni;
|
||||
-
|
||||
- IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
|
||||
-#ifdef IEEE80211_DEBUG_REFCNT
|
||||
- ni = ieee80211_find_wds_node_locked_debug(nt, macaddr, func, line);
|
||||
-#else
|
||||
- ni = ieee80211_find_wds_node_locked(nt, macaddr);
|
||||
-#endif
|
||||
- IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
|
||||
- return ni;
|
||||
-}
|
||||
-#ifdef IEEE80211_DEBUG_REFCNT
|
||||
-EXPORT_SYMBOL(ieee80211_find_wds_node_debug);
|
||||
-#else
|
||||
-EXPORT_SYMBOL(ieee80211_find_wds_node);
|
||||
-#endif
|
||||
-
|
||||
-struct ieee80211_node *
|
||||
-#ifdef IEEE80211_DEBUG_REFCNT
|
||||
ieee80211_find_node_debug(struct ieee80211_node_table *nt,
|
||||
const u_int8_t *macaddr, const char *func, int line)
|
||||
#else
|
||||
@@ -1838,7 +1631,6 @@ ieee80211_node_table_cleanup(struct ieee
|
||||
ic->ic_node_cleanup(ni);
|
||||
#endif
|
||||
}
|
||||
- del_timer(&nt->nt_wds_aging_timer);
|
||||
IEEE80211_SCAN_LOCK_DESTROY(nt);
|
||||
IEEE80211_NODE_TABLE_LOCK_DESTROY(nt);
|
||||
}
|
||||
@@ -2404,8 +2196,6 @@ ieee80211_node_leave(struct ieee80211_no
|
||||
* so no more references are generated
|
||||
*/
|
||||
if (nt) {
|
||||
- ieee80211_remove_wds_addr(nt, ni->ni_macaddr);
|
||||
- ieee80211_del_wds_node(nt, ni);
|
||||
IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
|
||||
node_table_leave_locked(nt, ni);
|
||||
IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
|
||||
--- a/net80211/ieee80211_node.h
|
||||
+++ b/net80211/ieee80211_node.h
|
||||
@@ -231,13 +231,6 @@ void ieee80211_sta_leave(struct ieee8021
|
||||
#define WDS_AGING_STATIC 0xffff
|
||||
#define WDS_AGING_TIMER_VAL (WDS_AGING_TIME / 2)
|
||||
|
||||
-struct ieee80211_wds_addr {
|
||||
- LIST_ENTRY(ieee80211_wds_addr) wds_hash;
|
||||
- u_int8_t wds_macaddr[IEEE80211_ADDR_LEN];
|
||||
- struct ieee80211_node *wds_ni;
|
||||
- u_int16_t wds_agingcount;
|
||||
-};
|
||||
-
|
||||
/*
|
||||
* Table of ieee80211_node instances. Each ieee80211com
|
||||
* has at least one for holding the scan candidates.
|
||||
@@ -250,11 +243,9 @@ struct ieee80211_node_table {
|
||||
ieee80211_node_table_lock_t nt_nodelock; /* on node table */
|
||||
TAILQ_HEAD(, ieee80211_node) nt_node; /* information of all nodes */
|
||||
ATH_LIST_HEAD(, ieee80211_node) nt_hash[IEEE80211_NODE_HASHSIZE];
|
||||
- ATH_LIST_HEAD(, ieee80211_wds_addr) nt_wds_hash[IEEE80211_NODE_HASHSIZE];
|
||||
ieee80211_scan_lock_t nt_scanlock; /* on nt_scangen */
|
||||
u_int nt_scangen; /* gen# for timeout scan */
|
||||
int nt_inact_init; /* initial node inact setting */
|
||||
- struct timer_list nt_wds_aging_timer; /* timer to age out wds entries */
|
||||
};
|
||||
|
||||
/* Allocates a new ieee80211_node* that has a reference count of one, and
|
||||
@@ -363,47 +354,6 @@ void
|
||||
ieee80211_unref_node(struct ieee80211_node **pni);
|
||||
#endif /* #ifdef IEEE80211_DEBUG_REFCNT */
|
||||
|
||||
-/* Increments reference count of ieee80211_node *ni */
|
||||
-#ifdef IEEE80211_DEBUG_REFCNT
|
||||
-#define ieee80211_add_wds_addr(_table, _node, _mac, _static) \
|
||||
- ieee80211_add_wds_addr_debug(_table, _node, _mac, _static, __func__, __LINE__)
|
||||
-int ieee80211_add_wds_addr_debug(struct ieee80211_node_table *, struct ieee80211_node *,
|
||||
- const u_int8_t *, u_int8_t, const char* func, int line);
|
||||
-#else
|
||||
-int ieee80211_add_wds_addr(struct ieee80211_node_table *, struct ieee80211_node *,
|
||||
- const u_int8_t *, u_int8_t);
|
||||
-#endif /* #ifdef IEEE80211_DEBUG_REFCNT */
|
||||
-
|
||||
-/* Decrements reference count of ieee80211_node *ni */
|
||||
-#ifdef IEEE80211_DEBUG_REFCNT
|
||||
-#define ieee80211_remove_wds_addr(_table, _mac) \
|
||||
- ieee80211_remove_wds_addr_debug(_table, _mac, __func__, __LINE__)
|
||||
-void ieee80211_remove_wds_addr_debug(struct ieee80211_node_table *, const u_int8_t *,
|
||||
- const char* func, int line);
|
||||
-#else
|
||||
-void ieee80211_remove_wds_addr(struct ieee80211_node_table *, const u_int8_t *);
|
||||
-#endif /* #ifdef IEEE80211_DEBUG_REFCNT */
|
||||
-
|
||||
-/* Decrements reference count of node, if found */
|
||||
-#ifdef IEEE80211_DEBUG_REFCNT
|
||||
-#define ieee80211_del_wds_node(_table, _node) \
|
||||
- ieee80211_del_wds_node_debug(_table, _node, __func__, __LINE__)
|
||||
-void ieee80211_del_wds_node_debug(struct ieee80211_node_table *, struct ieee80211_node *,
|
||||
- const char* func, int line);
|
||||
-#else
|
||||
-void ieee80211_del_wds_node(struct ieee80211_node_table *, struct ieee80211_node *);
|
||||
-#endif /* #ifdef IEEE80211_DEBUG_REFCNT */
|
||||
-
|
||||
-/* Increments reference count of node, if found */
|
||||
-#ifdef IEEE80211_DEBUG_REFCNT
|
||||
-#define ieee80211_find_wds_node(_table, _mac) \
|
||||
- ieee80211_find_wds_node_debug(_table, _mac, __func__, __LINE__)
|
||||
-struct ieee80211_node *ieee80211_find_wds_node_debug(struct ieee80211_node_table *,
|
||||
- const u_int8_t *, const char* func, int line);
|
||||
-#else
|
||||
-struct ieee80211_node *ieee80211_find_wds_node(struct ieee80211_node_table *,
|
||||
- const u_int8_t *);
|
||||
-#endif /* #ifdef IEEE80211_DEBUG_REFCNT */
|
||||
typedef void ieee80211_iter_func(void *, struct ieee80211_node *);
|
||||
void ieee80211_iterate_nodes(struct ieee80211_node_table *,
|
||||
ieee80211_iter_func *, void *);
|
491
net/madwifi/patches/393-mbss_vap_auth.patch
Normal file
491
net/madwifi/patches/393-mbss_vap_auth.patch
Normal file
@ -0,0 +1,491 @@
|
||||
--- a/net80211/ieee80211_node.c
|
||||
+++ b/net80211/ieee80211_node.c
|
||||
@@ -123,6 +123,9 @@ static void ieee80211_node_table_cleanup
|
||||
static void ieee80211_node_table_reset(struct ieee80211_node_table *,
|
||||
struct ieee80211vap *);
|
||||
|
||||
+static struct ieee80211_node *
|
||||
+lookup_rxnode(struct ieee80211com *ic, struct ieee80211vap *vap, const u_int8_t *addr);
|
||||
+
|
||||
MALLOC_DEFINE(M_80211_NODE, "80211node", "802.11 node state");
|
||||
|
||||
void
|
||||
@@ -697,7 +700,7 @@ ieee80211_sta_join(struct ieee80211vap *
|
||||
struct ieee80211com *ic = vap->iv_ic;
|
||||
struct ieee80211_node *ni;
|
||||
|
||||
- ni = ieee80211_find_node(&ic->ic_sta, se->se_macaddr);
|
||||
+ ni = lookup_rxnode(ic, vap, se->se_macaddr);
|
||||
if (ni == NULL) {
|
||||
ni = ieee80211_alloc_node_table(vap, se->se_macaddr);
|
||||
IEEE80211_DPRINTF(vap, IEEE80211_MSG_ASSOC,
|
||||
@@ -1394,6 +1397,53 @@ ieee80211_add_neighbor(struct ieee80211v
|
||||
return ni;
|
||||
}
|
||||
|
||||
+struct ieee80211vap *
|
||||
+ieee80211_find_rxvap(struct ieee80211com *ic, const u_int8_t *mac)
|
||||
+{
|
||||
+ struct ieee80211vap *vap;
|
||||
+
|
||||
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
|
||||
+ if (IEEE80211_ADDR_EQ(vap->iv_myaddr, mac))
|
||||
+ return vap;
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+EXPORT_SYMBOL(ieee80211_find_rxvap);
|
||||
+
|
||||
+static struct ieee80211_node *
|
||||
+lookup_rxnode(struct ieee80211com *ic, struct ieee80211vap *vap,
|
||||
+ const u_int8_t *addr)
|
||||
+{
|
||||
+ struct ieee80211_node_table *nt;
|
||||
+ struct ieee80211_node *ni = NULL;
|
||||
+ int use_bss = 0;
|
||||
+ int hash;
|
||||
+
|
||||
+ nt = &ic->ic_sta;
|
||||
+ IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
|
||||
+ hash = IEEE80211_NODE_HASH(addr);
|
||||
+ LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) {
|
||||
+ if (IEEE80211_ADDR_EQ(ni->ni_macaddr, addr)) {
|
||||
+ /* allow multiple nodes on different vaps */
|
||||
+ if (vap && (ni->ni_vap != vap))
|
||||
+ continue;
|
||||
+
|
||||
+ ieee80211_ref_node(ni);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* no match found */
|
||||
+ ni = NULL;
|
||||
+
|
||||
+out:
|
||||
+ IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
|
||||
+ return ni;
|
||||
+#undef IS_PSPOLL
|
||||
+#undef IS_CTL
|
||||
+}
|
||||
+
|
||||
+
|
||||
/*
|
||||
* Return the node for the sender of a frame; if the sender is unknown return
|
||||
* NULL. The caller is expected to deal with this. (The frame is sent to all
|
||||
@@ -1403,10 +1453,10 @@ ieee80211_add_neighbor(struct ieee80211v
|
||||
*/
|
||||
struct ieee80211_node *
|
||||
#ifdef IEEE80211_DEBUG_REFCNT
|
||||
-ieee80211_find_rxnode_debug(struct ieee80211com *ic,
|
||||
+ieee80211_find_rxnode_debug(struct ieee80211com *ic, struct ieee80211vap *vap,
|
||||
const struct ieee80211_frame_min *wh, const char *func, int line)
|
||||
#else
|
||||
-ieee80211_find_rxnode(struct ieee80211com *ic,
|
||||
+ieee80211_find_rxnode(struct ieee80211com *ic, struct ieee80211vap *vap,
|
||||
const struct ieee80211_frame_min *wh)
|
||||
#endif
|
||||
{
|
||||
@@ -1414,9 +1464,8 @@ ieee80211_find_rxnode(struct ieee80211co
|
||||
((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
|
||||
#define IS_PSPOLL(wh) \
|
||||
((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_PS_POLL)
|
||||
- struct ieee80211_node_table *nt;
|
||||
- struct ieee80211_node *ni;
|
||||
- struct ieee80211vap *vap, *avp;
|
||||
+ struct ieee80211_node *ni = NULL;
|
||||
+ struct ieee80211vap *avp;
|
||||
const u_int8_t *addr;
|
||||
|
||||
if (IS_CTL(wh) && !IS_PSPOLL(wh) /*&& !IS_RTS(ah)*/)
|
||||
@@ -1429,32 +1478,25 @@ ieee80211_find_rxnode(struct ieee80211co
|
||||
|
||||
/* XXX check ic_bss first in station mode */
|
||||
/* XXX 4-address frames? */
|
||||
- nt = &ic->ic_sta;
|
||||
- IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
|
||||
if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) {
|
||||
- TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
|
||||
+ if (vap) { /* assume unicast if vap is set, mcast not supported for wds */
|
||||
TAILQ_FOREACH(avp, &vap->iv_wdslinks, iv_wdsnext) {
|
||||
- if (!IEEE80211_ADDR_EQ(addr, avp->wds_mac))
|
||||
+ if (!IEEE80211_ADDR_EQ(addr, avp->wds_mac) ||
|
||||
+ !IEEE80211_ADDR_EQ(wh->i_addr1, avp->iv_myaddr))
|
||||
continue;
|
||||
|
||||
if (avp->iv_wdsnode)
|
||||
- return ieee80211_ref_node(avp->iv_wdsnode);
|
||||
- else
|
||||
- return NULL;
|
||||
+ ni = ieee80211_ref_node(avp->iv_wdsnode);
|
||||
+ return ni;
|
||||
}
|
||||
+ if (!(vap->iv_flags_ext & IEEE80211_FEXT_WDS))
|
||||
+ return NULL;
|
||||
+ } else {
|
||||
+ return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
-#ifdef IEEE80211_DEBUG_REFCNT
|
||||
- ni = ieee80211_find_node_locked_debug(nt, addr, func, line);
|
||||
-#else
|
||||
- ni = ieee80211_find_node_locked(nt, addr);
|
||||
-#endif
|
||||
- IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
|
||||
-
|
||||
- return ni;
|
||||
-#undef IS_PSPOLL
|
||||
-#undef IS_CTL
|
||||
+ return lookup_rxnode(ic, vap, addr);
|
||||
}
|
||||
#ifdef IEEE80211_DEBUG_REFCNT
|
||||
EXPORT_SYMBOL(ieee80211_find_rxnode_debug);
|
||||
@@ -1479,15 +1521,14 @@ ieee80211_find_txnode(struct ieee80211va
|
||||
struct ieee80211com *ic = vap->iv_ic;
|
||||
struct ieee80211_node_table *nt;
|
||||
struct ieee80211_node *ni = NULL;
|
||||
+ int hash;
|
||||
|
||||
- IEEE80211_LOCK_IRQ(ic);
|
||||
if (vap->iv_opmode == IEEE80211_M_WDS) {
|
||||
if (vap->iv_wdsnode && (vap->iv_state == IEEE80211_S_RUN))
|
||||
return ieee80211_ref_node(vap->iv_wdsnode);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
- IEEE80211_UNLOCK_IRQ(ic);
|
||||
|
||||
/*
|
||||
* The destination address should be in the node table
|
||||
@@ -1505,11 +1546,22 @@ ieee80211_find_txnode(struct ieee80211va
|
||||
/* XXX: Can't hold lock across dup_bss due to recursive locking. */
|
||||
nt = &vap->iv_ic->ic_sta;
|
||||
IEEE80211_NODE_TABLE_LOCK_IRQ(nt);
|
||||
+ hash = IEEE80211_NODE_HASH(mac);
|
||||
+ LIST_FOREACH(ni, &nt->nt_hash[hash], ni_hash) {
|
||||
+ if (ni->ni_vap != vap)
|
||||
+ continue;
|
||||
+
|
||||
+ if (IEEE80211_ADDR_EQ(ni->ni_macaddr, mac)) {
|
||||
#ifdef IEEE80211_DEBUG_REFCNT
|
||||
- ni = ieee80211_find_node_locked_debug(nt, mac, func, line);
|
||||
+ ieee80211_ref_node_debug(ni, func, line);
|
||||
#else
|
||||
- ni = ieee80211_find_node_locked(nt, mac);
|
||||
+ ieee80211_ref_node(ni);
|
||||
#endif
|
||||
+ goto found;
|
||||
+ }
|
||||
+ }
|
||||
+ ni = NULL;
|
||||
+found:
|
||||
IEEE80211_NODE_TABLE_UNLOCK_IRQ(nt);
|
||||
|
||||
if (ni == NULL) {
|
||||
@@ -1964,13 +2016,32 @@ remove_worse_nodes(void *arg, struct iee
|
||||
}
|
||||
}
|
||||
|
||||
+static void
|
||||
+remove_duplicate_nodes(void *arg, struct ieee80211_node *ni)
|
||||
+{
|
||||
+ struct ieee80211_node *rni = arg;
|
||||
+
|
||||
+ if (ni == rni)
|
||||
+ return;
|
||||
+
|
||||
+ if (ni->ni_vap == rni->ni_vap)
|
||||
+ return;
|
||||
+
|
||||
+ if (!IEEE80211_ADDR_EQ(rni->ni_macaddr, ni->ni_macaddr))
|
||||
+ return;
|
||||
+
|
||||
+ ieee80211_node_leave(ni);
|
||||
+}
|
||||
+
|
||||
void
|
||||
ieee80211_node_join(struct ieee80211_node *ni, int resp)
|
||||
{
|
||||
struct ieee80211com *ic = ni->ni_ic;
|
||||
struct ieee80211vap *vap = ni->ni_vap;
|
||||
+ struct ieee80211_node *tni;
|
||||
int newassoc;
|
||||
|
||||
+ ieee80211_iterate_nodes(&ic->ic_sta, remove_duplicate_nodes, ni);
|
||||
if (ni->ni_associd == 0) {
|
||||
u_int16_t aid;
|
||||
|
||||
--- a/net80211/ieee80211_input.c
|
||||
+++ b/net80211/ieee80211_input.c
|
||||
@@ -216,16 +216,14 @@ ieee80211_input(struct ieee80211vap * va
|
||||
|
||||
type = -1; /* undefined */
|
||||
|
||||
- if (!vap)
|
||||
- goto out;
|
||||
+ if (!vap || !vap->iv_bss || !vap->iv_dev || !vap->iv_ic)
|
||||
+ goto discard;
|
||||
|
||||
ic = vap->iv_ic;
|
||||
- if (!ic)
|
||||
- goto out;
|
||||
-
|
||||
dev = vap->iv_dev;
|
||||
- if (!dev)
|
||||
- goto out;
|
||||
+
|
||||
+ if ((vap->iv_dev->flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
|
||||
+ goto discard;
|
||||
|
||||
/* initialize ni as in the previous API */
|
||||
if (ni_or_null == NULL) {
|
||||
@@ -233,9 +231,10 @@ ieee80211_input(struct ieee80211vap * va
|
||||
* guarantee its existence during the following call, hence
|
||||
* briefly grab our own reference. */
|
||||
ni = ieee80211_ref_node(vap->iv_bss);
|
||||
+ KASSERT(ni != NULL, ("null node"));
|
||||
+ } else {
|
||||
+ ni->ni_inact = ni->ni_inact_reload;
|
||||
}
|
||||
- KASSERT(ni != NULL, ("null node"));
|
||||
- ni->ni_inact = ni->ni_inact_reload;
|
||||
|
||||
KASSERT(skb->len >= sizeof(struct ieee80211_frame_min),
|
||||
("frame length too short: %u", skb->len));
|
||||
@@ -844,10 +843,11 @@ ieee80211_input(struct ieee80211vap * va
|
||||
err:
|
||||
vap->iv_devstats.rx_errors++;
|
||||
out:
|
||||
- if (skb != NULL)
|
||||
- ieee80211_dev_kfree_skb(&skb);
|
||||
if (ni_or_null == NULL)
|
||||
ieee80211_unref_node(&ni);
|
||||
+discard:
|
||||
+ if (skb != NULL)
|
||||
+ ieee80211_dev_kfree_skb(&skb);
|
||||
return type;
|
||||
#undef HAS_SEQ
|
||||
}
|
||||
@@ -929,16 +929,23 @@ int
|
||||
ieee80211_input_all(struct ieee80211com *ic,
|
||||
struct sk_buff *skb, int rssi, u_int64_t rtsf)
|
||||
{
|
||||
+ struct ieee80211_frame_min *wh = (struct ieee80211_frame_min *) skb->data;
|
||||
struct ieee80211vap *vap;
|
||||
int type = -1;
|
||||
|
||||
/* XXX locking */
|
||||
TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
|
||||
+ struct ieee80211_node *ni = NULL;
|
||||
struct sk_buff *skb1;
|
||||
|
||||
if ((vap->iv_dev->flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
|
||||
continue;
|
||||
|
||||
+ if ((vap->iv_opmode == IEEE80211_M_HOSTAP) &&
|
||||
+ !IEEE80211_IS_MULTICAST(wh->i_addr1))
|
||||
+ continue;
|
||||
+
|
||||
+ ni = ieee80211_find_rxnode(ic, vap, wh);
|
||||
if (TAILQ_NEXT(vap, iv_next) != NULL) {
|
||||
skb1 = skb_copy(skb, GFP_ATOMIC);
|
||||
if (skb1 == NULL) {
|
||||
@@ -950,8 +957,12 @@ ieee80211_input_all(struct ieee80211com
|
||||
skb1 = skb;
|
||||
skb = NULL;
|
||||
}
|
||||
- type = ieee80211_input(vap, NULL, skb1, rssi, rtsf);
|
||||
+ type = ieee80211_input(vap, ni, skb1, rssi, rtsf);
|
||||
+ if (ni)
|
||||
+ ieee80211_unref_node(&ni);
|
||||
}
|
||||
+
|
||||
+out:
|
||||
if (skb != NULL) /* no vaps, reclaim skb */
|
||||
ieee80211_dev_kfree_skb(&skb);
|
||||
return type;
|
||||
@@ -1147,11 +1158,9 @@ ieee80211_deliver_data(struct ieee80211_
|
||||
* sending it will not work; just let it be
|
||||
* delivered normally.
|
||||
*/
|
||||
- struct ieee80211_node *ni1 = ieee80211_find_node(
|
||||
- &vap->iv_ic->ic_sta, eh->ether_dhost);
|
||||
+ struct ieee80211_node *ni1 = ieee80211_find_txnode(vap, eh->ether_dhost);
|
||||
if (ni1 != NULL) {
|
||||
- if (ni1->ni_vap == vap &&
|
||||
- ieee80211_node_is_authorized(ni1) &&
|
||||
+ if (ieee80211_node_is_authorized(ni1) &&
|
||||
!ni1->ni_subif &&
|
||||
ni1 != vap->iv_bss) {
|
||||
|
||||
@@ -3520,6 +3529,7 @@ ieee80211_recv_mgmt(struct ieee80211vap
|
||||
(vap->iv_opmode == IEEE80211_M_WDS)) &&
|
||||
(scan.capinfo & IEEE80211_CAPINFO_ESS))) {
|
||||
struct ieee80211vap *avp = NULL;
|
||||
+ int do_unref = 0;
|
||||
int found = 0;
|
||||
|
||||
IEEE80211_LOCK_IRQ(vap->iv_ic);
|
||||
@@ -3553,10 +3563,12 @@ ieee80211_recv_mgmt(struct ieee80211vap
|
||||
ni->ni_associd |= 0xc000;
|
||||
avp->iv_wdsnode = ieee80211_ref_node(ni);
|
||||
IEEE80211_UNLOCK_IRQ(ic);
|
||||
- } else if (vap->iv_opmode == IEEE80211_M_IBSS) {
|
||||
+ } else if ((vap->iv_opmode == IEEE80211_M_IBSS) &&
|
||||
+ IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_bssid)) {
|
||||
/* Create a new entry in the neighbor table. */
|
||||
ni = ieee80211_add_neighbor(vap, wh, &scan);
|
||||
}
|
||||
+ do_unref = 1;
|
||||
} else {
|
||||
/*
|
||||
* Copy data from beacon to neighbor table.
|
||||
@@ -3595,6 +3607,8 @@ ieee80211_recv_mgmt(struct ieee80211vap
|
||||
ni->ni_rssi = rssi;
|
||||
ni->ni_rtsf = rtsf;
|
||||
ni->ni_last_rx = jiffies;
|
||||
+ if (do_unref)
|
||||
+ ieee80211_unref_node(&ni);
|
||||
}
|
||||
}
|
||||
break;
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -6589,9 +6589,8 @@ ath_recv_mgmt(struct ieee80211vap * vap,
|
||||
|
||||
sc->sc_recv_mgmt(vap, ni_or_null, skb, subtype, rssi, rtsf);
|
||||
|
||||
-
|
||||
/* Lookup the new node if any (this grabs a reference to it) */
|
||||
- ni = ieee80211_find_rxnode(vap->iv_ic,
|
||||
+ ni = ieee80211_find_rxnode(vap->iv_ic, vap,
|
||||
(const struct ieee80211_frame_min *)skb->data);
|
||||
if (ni == NULL) {
|
||||
DPRINTF(sc, ATH_DEBUG_BEACON, "Dropping; node unknown.\n");
|
||||
@@ -6746,7 +6745,9 @@ ath_rx_poll(struct net_device *dev, int
|
||||
struct ath_desc *ds;
|
||||
struct ath_rx_status *rs;
|
||||
struct sk_buff *skb = NULL;
|
||||
+ struct ieee80211vap *vap;
|
||||
struct ieee80211_node *ni;
|
||||
+ const struct ieee80211_frame_min *wh;
|
||||
unsigned int len;
|
||||
int type;
|
||||
u_int phyerr;
|
||||
@@ -6901,12 +6902,15 @@ rx_accept:
|
||||
skb_trim(skb, skb->len - IEEE80211_CRC_LEN);
|
||||
|
||||
if (mic_fail) {
|
||||
+ wh = (const struct ieee80211_frame_min *) skb->data;
|
||||
+
|
||||
/* Ignore control frames which are reported with mic error */
|
||||
- if ((((struct ieee80211_frame *)skb->data)->i_fc[0] &
|
||||
+ if ((wh->i_fc[0] &
|
||||
IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL)
|
||||
goto drop_micfail;
|
||||
|
||||
- ni = ieee80211_find_rxnode(ic, (const struct ieee80211_frame_min *) skb->data);
|
||||
+ vap = ieee80211_find_rxvap(ic, wh->i_addr1);
|
||||
+ ni = ieee80211_find_rxnode(ic, vap, wh);
|
||||
|
||||
if (ni && ni->ni_table) {
|
||||
ieee80211_check_mic(ni, skb);
|
||||
@@ -6968,11 +6972,24 @@ drop_micfail:
|
||||
* for its use. If the sender is unknown spam the
|
||||
* frame; it'll be dropped where it's not wanted.
|
||||
*/
|
||||
- if (rs->rs_keyix != HAL_RXKEYIX_INVALID &&
|
||||
+ wh = (const struct ieee80211_frame_min *) skb->data;
|
||||
+ if ((rs->rs_keyix != HAL_RXKEYIX_INVALID) &&
|
||||
(ni = sc->sc_keyixmap[rs->rs_keyix]) != NULL) {
|
||||
/* Fast path: node is present in the key map;
|
||||
* grab a reference for processing the frame. */
|
||||
- ni = ieee80211_ref_node(ni);
|
||||
+ ieee80211_ref_node(ni);
|
||||
+ if ((ATH_GET_VAP_ID(wh->i_addr1) !=
|
||||
+ ATH_GET_VAP_ID(ni->ni_vap->iv_myaddr)) ||
|
||||
+ ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) ==
|
||||
+ IEEE80211_FC1_DIR_DSTODS)) {
|
||||
+ /* key cache node lookup is fast, but it can
|
||||
+ * lead to problems in multi-bss (foreign vap
|
||||
+ * node reference) or wds (wdsap node ref instead
|
||||
+ * of base ap node ref).
|
||||
+ * use slowpath lookup in both cases
|
||||
+ */
|
||||
+ goto lookup_slowpath;
|
||||
+ }
|
||||
ATH_RSSI_LPF(ATH_NODE(ni)->an_avgrssi, rs->rs_rssi);
|
||||
type = ieee80211_input(ni->ni_vap, ni, skb, rs->rs_rssi, bf->bf_tsf);
|
||||
ieee80211_unref_node(&ni);
|
||||
@@ -6981,24 +6998,39 @@ drop_micfail:
|
||||
* No key index or no entry, do a lookup and
|
||||
* add the node to the mapping table if possible.
|
||||
*/
|
||||
- ni = ieee80211_find_rxnode(ic,
|
||||
- (const struct ieee80211_frame_min *)skb->data);
|
||||
+
|
||||
+lookup_slowpath:
|
||||
+ if (IEEE80211_IS_MULTICAST(wh->i_addr1))
|
||||
+ vap = NULL;
|
||||
+ else
|
||||
+ vap = ieee80211_find_rxvap(ic, wh->i_addr1);
|
||||
+
|
||||
+ if (vap)
|
||||
+ ni = ieee80211_find_rxnode(ic, vap, wh);
|
||||
+ else
|
||||
+ ni = NULL;
|
||||
+
|
||||
if (ni != NULL) {
|
||||
ieee80211_keyix_t keyix;
|
||||
|
||||
ATH_RSSI_LPF(ATH_NODE(ni)->an_avgrssi, rs->rs_rssi);
|
||||
- type = ieee80211_input(ni->ni_vap, ni, skb, rs->rs_rssi, bf->bf_tsf);
|
||||
+ type = ieee80211_input(vap, ni, skb, rs->rs_rssi, bf->bf_tsf);
|
||||
/*
|
||||
* If the station has a key cache slot assigned
|
||||
* update the key->node mapping table.
|
||||
*/
|
||||
keyix = ni->ni_ucastkey.wk_keyix;
|
||||
if (keyix != IEEE80211_KEYIX_NONE &&
|
||||
- sc->sc_keyixmap[keyix] == NULL)
|
||||
+ sc->sc_keyixmap[keyix] == NULL) {
|
||||
sc->sc_keyixmap[keyix] = ieee80211_ref_node(ni);
|
||||
+ }
|
||||
ieee80211_unref_node(&ni);
|
||||
- } else
|
||||
- type = ieee80211_input_all(ic, skb, rs->rs_rssi, bf->bf_tsf);
|
||||
+ } else {
|
||||
+ if (vap)
|
||||
+ type = ieee80211_input(vap, NULL, skb, rs->rs_rssi, bf->bf_tsf);
|
||||
+ else
|
||||
+ type = ieee80211_input_all(ic, skb, rs->rs_rssi, bf->bf_tsf);
|
||||
+ }
|
||||
}
|
||||
|
||||
if (sc->sc_diversity) {
|
||||
--- a/net80211/ieee80211_node.h
|
||||
+++ b/net80211/ieee80211_node.h
|
||||
@@ -286,15 +286,18 @@ struct ieee80211_node *ieee80211_find_no
|
||||
const u_int8_t *);
|
||||
#endif /* #ifdef IEEE80211_DEBUG_REFCNT */
|
||||
|
||||
+struct ieee80211vap *
|
||||
+ieee80211_find_rxvap(struct ieee80211com *ic, const u_int8_t *mac);
|
||||
+
|
||||
/* Returns a ieee80211_node* with refcount incremented, if found */
|
||||
#ifdef IEEE80211_DEBUG_REFCNT
|
||||
-#define ieee80211_find_rxnode(_nt, _wh) \
|
||||
- ieee80211_find_rxnode_debug(_nt, _wh, __func__, __LINE__)
|
||||
+#define ieee80211_find_rxnode(_nt, _vap, _wh) \
|
||||
+ ieee80211_find_rxnode_debug(_nt, _vap, _wh, __func__, __LINE__)
|
||||
struct ieee80211_node *ieee80211_find_rxnode_debug(struct ieee80211com *,
|
||||
- const struct ieee80211_frame_min *, const char *, int);
|
||||
+ struct ieee80211vap *, const struct ieee80211_frame_min *, const char *, int);
|
||||
#else
|
||||
struct ieee80211_node *ieee80211_find_rxnode(struct ieee80211com *,
|
||||
- const struct ieee80211_frame_min *);
|
||||
+ struct ieee80211vap *, const struct ieee80211_frame_min *);
|
||||
#endif /* #ifdef IEEE80211_DEBUG_REFCNT */
|
||||
|
||||
/* Returns a ieee80211_node* with refcount incremented, if found */
|
64
net/madwifi/patches/394-probereq.patch
Normal file
64
net/madwifi/patches/394-probereq.patch
Normal file
@ -0,0 +1,64 @@
|
||||
--- a/net80211/ieee80211_input.c
|
||||
+++ b/net80211/ieee80211_input.c
|
||||
@@ -3621,6 +3621,8 @@ ieee80211_recv_mgmt(struct ieee80211vap
|
||||
vap->iv_stats.is_rx_mgtdiscard++;
|
||||
return;
|
||||
}
|
||||
+ if (vap->iv_no_probereq)
|
||||
+ return;
|
||||
if (IEEE80211_IS_MULTICAST(wh->i_addr2)) {
|
||||
/* frame must be directed */
|
||||
vap->iv_stats.is_rx_mgtdiscard++; /* XXX: stat */
|
||||
--- a/net80211/ieee80211_ioctl.h
|
||||
+++ b/net80211/ieee80211_ioctl.h
|
||||
@@ -651,6 +651,7 @@ enum {
|
||||
IEEE80211_PARAM_RSSI_DIS_COUNT = 81, /* counter for rssi threshold */
|
||||
IEEE80211_PARAM_WDS_SEP = 82, /* move wds stations into separate interfaces */
|
||||
IEEE80211_PARAM_MAXASSOC = 83, /* maximum associated stations */
|
||||
+ IEEE80211_PARAM_PROBEREQ = 84, /* enable handling of probe requests */
|
||||
};
|
||||
|
||||
#define SIOCG80211STATS (SIOCDEVPRIVATE+2)
|
||||
--- a/net80211/ieee80211_var.h
|
||||
+++ b/net80211/ieee80211_var.h
|
||||
@@ -198,6 +198,7 @@ struct ieee80211vap {
|
||||
u_int32_t iv_debug; /* debug msg flags */
|
||||
struct ieee80211_stats iv_stats; /* statistics */
|
||||
|
||||
+ int iv_no_probereq;
|
||||
int iv_max_nodes;
|
||||
int iv_monitor_nods_only; /* in monitor mode only nods traffic */
|
||||
int iv_monitor_txf_len; /* in monitor mode, truncate tx packets */
|
||||
--- a/net80211/ieee80211_wireless.c
|
||||
+++ b/net80211/ieee80211_wireless.c
|
||||
@@ -2881,6 +2881,9 @@ ieee80211_ioctl_setparam(struct net_devi
|
||||
else
|
||||
vap->iv_max_nodes = value;
|
||||
break;
|
||||
+ case IEEE80211_PARAM_PROBEREQ:
|
||||
+ vap->iv_no_probereq = !value;
|
||||
+ break;
|
||||
#ifdef ATH_REVERSE_ENGINEERING
|
||||
case IEEE80211_PARAM_DUMPREGS:
|
||||
ieee80211_dump_registers(dev, info, w, extra);
|
||||
@@ -3243,6 +3246,9 @@ ieee80211_ioctl_getparam(struct net_devi
|
||||
case IEEE80211_PARAM_MAXASSOC:
|
||||
param[0] = vap->iv_max_nodes;
|
||||
break;
|
||||
+ case IEEE80211_PARAM_PROBEREQ:
|
||||
+ param[0] = !vap->iv_no_probereq;
|
||||
+ break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@@ -5802,6 +5808,10 @@ static const struct iw_priv_args ieee802
|
||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "maxassoc"},
|
||||
{ IEEE80211_PARAM_MAXASSOC,
|
||||
0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_maxassoc"},
|
||||
+ { IEEE80211_PARAM_PROBEREQ,
|
||||
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "probereq"},
|
||||
+ { IEEE80211_PARAM_PROBEREQ,
|
||||
+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_probereq"},
|
||||
|
||||
#ifdef ATH_REVERSE_ENGINEERING
|
||||
/*
|
11
net/madwifi/patches/395-ath_ff_unmap.patch
Normal file
11
net/madwifi/patches/395-ath_ff_unmap.patch
Normal file
@ -0,0 +1,11 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -13534,7 +13534,7 @@ cleanup_ath_buf(struct ath_softc *sc, st
|
||||
bus_unmap_single(
|
||||
sc->sc_bdev,
|
||||
bf->bf_skbaddrff[i],
|
||||
- (direction == BUS_DMA_TODEVICE ?
|
||||
+ (direction == BUS_DMA_FROMDEVICE ?
|
||||
sc->sc_rxbufsize : ffskb->len),
|
||||
direction);
|
||||
bf->bf_skbaddrff[i] = 0;
|
65
net/madwifi/patches/396-napi_ff_fix.patch
Normal file
65
net/madwifi/patches/396-napi_ff_fix.patch
Normal file
@ -0,0 +1,65 @@
|
||||
--- a/ath/if_ath.c
|
||||
+++ b/ath/if_ath.c
|
||||
@@ -6734,10 +6734,10 @@ ath_rx_poll(struct net_device *dev, int
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
|
||||
struct ath_softc *sc = container_of(napi, struct ath_softc, sc_napi);
|
||||
struct net_device *dev = sc->sc_dev;
|
||||
- u_int rx_limit = budget;
|
||||
+ int rx_limit = budget;
|
||||
#else
|
||||
struct ath_softc *sc = dev->priv;
|
||||
- u_int rx_limit = min(dev->quota, *budget);
|
||||
+ int rx_limit = min(dev->quota, *budget);
|
||||
#endif
|
||||
struct ath_buf *bf;
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
@@ -6780,13 +6780,15 @@ process_rx_again:
|
||||
break;
|
||||
}
|
||||
|
||||
- if (rx_limit-- < 2) {
|
||||
+ processed += ic->ic_recv;
|
||||
+ rx_limit -= ic->ic_recv;
|
||||
+ ic->ic_recv = 0;
|
||||
+
|
||||
+ /* keep a reserve for napi */
|
||||
+ if (rx_limit < 4) {
|
||||
early_stop = 1;
|
||||
break;
|
||||
}
|
||||
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
|
||||
- processed++;
|
||||
-#endif
|
||||
|
||||
skb = bf->bf_skb;
|
||||
if (skb == NULL) {
|
||||
@@ -7074,8 +7076,8 @@ rx_next:
|
||||
if (sc->sc_isr & HAL_INT_RX) {
|
||||
u_int64_t hw_tsf = ath_hal_gettsf64(ah);
|
||||
sc->sc_isr &= ~HAL_INT_RX;
|
||||
- local_irq_restore(flags);
|
||||
ath_uapsd_processtriggers(sc, hw_tsf);
|
||||
+ local_irq_restore(flags);
|
||||
goto process_rx_again;
|
||||
}
|
||||
local_irq_restore(flags);
|
||||
--- a/net80211/ieee80211_input.c
|
||||
+++ b/net80211/ieee80211_input.c
|
||||
@@ -1206,6 +1206,7 @@ ieee80211_deliver_data(struct ieee80211_
|
||||
}
|
||||
}
|
||||
|
||||
+ vap->iv_ic->ic_recv++;
|
||||
if (skb != NULL) {
|
||||
skb->dev = dev;
|
||||
|
||||
--- a/net80211/ieee80211_var.h
|
||||
+++ b/net80211/ieee80211_var.h
|
||||
@@ -323,6 +323,7 @@ struct ieee80211com {
|
||||
struct ifmedia ic_media; /* interface media config */
|
||||
u_int8_t ic_myaddr[IEEE80211_ADDR_LEN];
|
||||
struct timer_list ic_inact; /* mgmt/inactivity timer */
|
||||
+ u_int ic_recv; /* frame received counter */
|
||||
|
||||
unsigned int ic_subifs;
|
||||
u_int32_t ic_flags; /* state flags */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user