30
30
#include <linux/if_arp.h>
31
31
#include <net/iw_handler.h>
32
32
#include <linux/rtnetlink.h>
33
#include <asm/scatterlist.h>
34
34
#include <asm/uaccess.h>
36
36
#include "wrapper.h"
37
#include "pe_linker.h"
38
37
#include "iw_ndis.h"
39
38
#include "loader.h"
42
#include "wrapper_exports.h"
41
45
#ifndef NDISWRAPPER_VERSION
42
#error You must run make from the toplevel directory
46
#error ndiswrapper version is not defined; run 'make' only from ndiswrapper \
47
directory or driver directory
45
/* Define this if you are developing and ndis_init_one crashes.
46
When using the old PCI-API a reboot is not needed when this
47
function crashes. A simple rmmod -f will do the trick and
51
50
static char *if_name = "wlan%d";
52
51
int proc_uid, proc_gid;
53
52
static int hangcheck_interval;
54
/* used to implement Windows spinlocks */
55
spinlock_t spinlock_kspin_lock;
55
57
NW_MODULE_PARM_STRING(if_name, 0400);
56
MODULE_PARM_DESC(if_name, "Network interface name or template (default: wlan%d)");
58
MODULE_PARM_DESC(if_name, "Network interface name or template "
57
60
NW_MODULE_PARM_INT(proc_uid, 0600);
58
MODULE_PARM_DESC(proc_uid, "The uid of the files created in /proc (default: 0).");
61
MODULE_PARM_DESC(proc_uid, "The uid of the files created in /proc "
59
63
NW_MODULE_PARM_INT(proc_gid, 0600);
60
MODULE_PARM_DESC(proc_gid, "The gid of the files created in /proc (default: 0).");
64
MODULE_PARM_DESC(proc_gid, "The gid of the files created in /proc "
61
66
NW_MODULE_PARM_INT(hangcheck_interval, 0600);
62
67
/* 0 - default value provided by NDIS driver,
63
68
* positive value - force hangcheck interval to that many seconds
64
69
* negative value - disable hangcheck
66
MODULE_PARM_DESC(hangcheck_interval, "The interval, in seconds, for checking if driver is hung. (default: 0)");
68
extern struct list_head wrap_allocs;
69
extern struct wrap_spinlock wrap_allocs_lock;
70
extern struct wrap_spinlock dispatch_event_lock;
71
NW_MODULE_PARM_INT(debug, 0600);
72
MODULE_PARM_DESC(debug, "debug level");
74
MODULE_PARM_DESC(hangcheck_interval, "The interval, in seconds, for checking"
75
" if driver is hung. (default: 0)");
77
MODULE_AUTHOR("ndiswrapper team <ndiswrapper-general@lists.sourceforge.net>");
79
MODULE_VERSION(NDISWRAPPER_VERSION);
72
81
static void ndis_set_rx_mode(struct net_device *dev);
82
static void set_multicast_list(struct net_device *dev,
83
struct ndis_handle *handle);
77
int miniport_reset(struct ndis_handle *handle)
88
NDIS_STATUS miniport_reset(struct ndis_handle *handle)
81
struct miniport_char *miniport = &handle->driver->miniport_char;
92
struct miniport_char *miniport;
83
TRACEENTER2("%s", "");
96
TRACEENTER2("handle: %p", handle);
85
98
if (handle->reset_status)
86
99
return NDIS_STATUS_PENDING;
88
101
if (down_interruptible(&handle->ndis_comm_mutex))
89
102
TRACEEXIT3(return NDIS_STATUS_FAILURE);
103
miniport = &handle->driver->miniport_char;
91
104
/* reset_status is used for two purposes: to check if windows
92
105
* driver needs us to reset filters etc (as per NDIS) and to
93
106
* check if another reset is in progress */
94
107
handle->reset_status = NDIS_STATUS_PENDING;
95
108
handle->ndis_comm_res = NDIS_STATUS_PENDING;
96
109
handle->ndis_comm_done = 0;
110
cur_lookahead = handle->cur_lookahead;
111
max_lookahead = handle->max_lookahead;
97
112
irql = raise_irql(DISPATCH_LEVEL);
98
res = miniport->reset(&handle->reset_status, handle->adapter_ctx);
113
res = LIN2WIN2(miniport->reset, &handle->reset_status,
114
handle->adapter_ctx);
101
117
DBGTRACE2("res = %08X, reset_status = %08X",
102
118
res, handle->reset_status);
103
119
if (res == NDIS_STATUS_PENDING) {
104
if (!wait_event_interruptible_timeout(
120
if (wait_event_interruptible_timeout(
105
121
handle->ndis_comm_wq,
106
122
(handle->ndis_comm_done == 1), 1*HZ))
107
handle->ndis_comm_res = NDIS_STATUS_FAILURE;
108
res = handle->ndis_comm_res;
123
res = handle->ndis_comm_res;
125
res = NDIS_STATUS_FAILURE;
109
126
DBGTRACE2("res = %08X, reset_status = %08X",
110
127
res, handle->reset_status);
134
147
* Perform a sync query and deal with the possibility of an async operation.
135
148
* This function must be called from process context as it will sleep.
137
int miniport_query_info_needed(struct ndis_handle *handle, unsigned int oid,
138
char *buf, unsigned int bufsize,
139
unsigned int *needed)
150
NDIS_STATUS miniport_query_info_needed(struct ndis_handle *handle,
151
ndis_oid oid, void *buf,
152
ULONG bufsize, ULONG *needed)
141
unsigned int res, written;
156
struct miniport_char *miniport = &handle->driver->miniport_char;
143
struct miniport_char *miniport = &handle->driver->miniport_char;
145
159
TRACEENTER3("query is at %p", miniport->query);
147
161
if (down_interruptible(&handle->ndis_comm_mutex))
148
162
TRACEEXIT3(return NDIS_STATUS_FAILURE);
150
163
handle->ndis_comm_done = 0;
151
164
irql = raise_irql(DISPATCH_LEVEL);
152
res = miniport->query(handle->adapter_ctx, oid, buf, bufsize,
165
res = LIN2WIN6(miniport->query, handle->adapter_ctx, oid, buf, bufsize,
154
167
lower_irql(irql);
156
169
DBGTRACE3("res = %08x", res);
157
170
if (res == NDIS_STATUS_PENDING) {
158
171
/* wait for NdisMQueryInformationComplete upto HZ */
159
if (!wait_event_interruptible_timeout(
172
if (wait_event_interruptible_timeout(
160
173
handle->ndis_comm_wq,
161
174
(handle->ndis_comm_done == 1), 1*HZ))
162
handle->ndis_comm_res = NDIS_STATUS_FAILURE;
163
res = handle->ndis_comm_res;
175
res = handle->ndis_comm_res;
177
res = NDIS_STATUS_FAILURE;
165
179
up(&handle->ndis_comm_mutex);
166
180
TRACEEXIT3(return res);
169
int miniport_query_info(struct ndis_handle *handle, unsigned int oid,
170
char *buf, unsigned int bufsize)
183
NDIS_STATUS miniport_query_info(struct ndis_handle *handle, ndis_oid oid,
184
void *buf, ULONG bufsize)
172
unsigned int res, needed;
174
res = miniport_query_info_needed(handle, oid, buf, bufsize,
189
res = miniport_query_info_needed(handle, oid, buf, bufsize, &needed);
181
195
* Perform a sync setinfo and deal with the possibility of an async operation.
182
196
* This function must be called from process context as it will sleep.
184
int miniport_set_info(struct ndis_handle *handle, unsigned int oid, char *buf,
185
unsigned int bufsize)
198
NDIS_STATUS miniport_set_info(struct ndis_handle *handle, ndis_oid oid,
199
void *buf, ULONG bufsize)
187
unsigned int res, written, needed;
202
ULONG written, needed;
203
struct miniport_char *miniport = &handle->driver->miniport_char;
189
struct miniport_char *miniport = &handle->driver->miniport_char;
191
206
TRACEENTER3("setinfo is at %p", miniport->setinfo);
193
208
if (down_interruptible(&handle->ndis_comm_mutex))
194
209
TRACEEXIT3(return NDIS_STATUS_FAILURE);
196
210
handle->ndis_comm_done = 0;
197
211
irql = raise_irql(DISPATCH_LEVEL);
198
res = miniport->setinfo(handle->adapter_ctx, oid, buf, bufsize,
212
res = LIN2WIN6(miniport->setinfo, handle->adapter_ctx, oid, buf,
213
bufsize, &written, &needed);
200
215
DBGTRACE3("res = %08x", res);
203
217
if (res == NDIS_STATUS_PENDING) {
204
218
/* wait for NdisMSetInformationComplete upto HZ */
205
if (!wait_event_interruptible_timeout(
219
if (wait_event_interruptible_timeout(
206
220
handle->ndis_comm_wq,
207
221
(handle->ndis_comm_done == 1), 1*HZ))
208
handle->ndis_comm_res = NDIS_STATUS_FAILURE;
209
res = handle->ndis_comm_res;
222
res = handle->ndis_comm_res;
224
res = NDIS_STATUS_FAILURE;
211
226
up(&handle->ndis_comm_mutex);
218
233
/* Make a query that has an int as the result. */
219
int miniport_query_int(struct ndis_handle *handle, int oid, int *data)
234
NDIS_STATUS miniport_query_int(struct ndis_handle *handle, ndis_oid oid,
223
res = miniport_query_info(handle, oid, (char*)data, sizeof(int));
239
res = miniport_query_info(handle, oid, data, sizeof(ULONG));
231
int miniport_set_int(struct ndis_handle *handle, int oid, int data)
233
return miniport_set_info(handle, oid, (char *)&data, sizeof(int));
237
static u32 ndis_get_link(struct net_device *dev)
239
struct ndis_handle *handle = dev->priv;
240
return handle->link_status;
243
static struct ethtool_ops ndis_ethtool_ops = {
244
.get_link = ndis_get_link,
247
NDIS_STATUS miniport_set_int(struct ndis_handle *handle, ndis_oid oid,
250
return miniport_set_info(handle, oid, &data, sizeof(data));
249
254
* MiniportInitialize
251
int miniport_init(struct ndis_handle *handle)
256
NDIS_STATUS miniport_init(struct ndis_handle *handle)
254
UINT medium_index, res;
255
UINT medium_array[] = {NDIS_MEDIUM_802_3};
258
NDIS_STATUS status, res;
260
UINT medium_array[] = {NdisMedium802_3};
256
261
struct miniport_char *miniport = &handle->driver->miniport_char;
258
263
TRACEENTER1("driver init routine is at %p", miniport->init);
447
452
schedule_work(&handle->wrapper_worker);
450
static struct ndis_packet *alloc_packet(struct ndis_handle *handle,
451
struct ndis_buffer *buffer)
455
static struct ndis_packet *allocate_send_packet(struct ndis_handle *handle,
453
458
struct ndis_packet *packet;
455
packet = kmalloc(sizeof(struct ndis_packet), GFP_ATOMIC);
460
packet = allocate_ndis_packet();
459
memset(packet, 0, sizeof(*packet));
461
if (handle->use_scatter_gather) {
462
/* FIXME: do USB drivers call this? */
464
PCI_DMA_MAP_SINGLE(handle->dev.pci,
465
buffer->data, buffer->len,
467
packet->sg_list.len = 1;
468
packet->sg_element.address.quad = packet->dataphys;
469
packet->sg_element.len = buffer->len;
470
packet->sg_list.elements = &packet->sg_element;
471
packet->extension.info[NDIS_SCLIST_INFO] = &packet->sg_list;
474
packet->private.oob_offset = offsetof(struct ndis_packet, oob_tx);
476
464
packet->private.nr_pages = NDIS_BUFFER_TO_SPAN_PAGES(buffer);
477
packet->private.len = buffer->len;
465
packet->private.len = MmGetMdlByteCount(buffer);
478
466
packet->private.count = 1;
479
packet->private.valid_counts = 1;
467
packet->private.valid_counts = TRUE;
481
469
packet->private.buffer_head = buffer;
482
470
packet->private.buffer_tail = buffer;
472
if (handle->use_sg_dma) {
473
packet->ndis_sg_element.address =
474
PCI_DMA_MAP_SINGLE(handle->dev.pci,
475
MmGetMdlVirtualAddress(buffer),
476
MmGetMdlByteCount(buffer),
479
packet->ndis_sg_element.length = MmGetMdlByteCount(buffer);
480
packet->ndis_sg_list.nent = 1;
481
packet->ndis_sg_list.elements = &packet->ndis_sg_element;
482
packet->extension.info[ScatterGatherListPacketInfo] =
483
&packet->ndis_sg_list;
487
static void free_packet(struct ndis_handle *handle, struct ndis_packet *packet)
489
static void free_send_packet(struct ndis_handle *handle,
490
struct ndis_packet *packet)
494
TRACEENTER3("packet: %p", packet);
490
496
ERROR("illegal packet from %p", handle);
494
kfree(packet->private.buffer_head->data);
495
kfree(packet->private.buffer_head);
497
if (packet->dataphys) {
498
/* FIXME: do USB drivers call this? */
499
PCI_DMA_UNMAP_SINGLE(handle->dev.pci, packet->dataphys,
500
packet->private.len, PCI_DMA_TODEVICE);
500
buffer = packet->private.buffer_head;
501
if (handle->use_sg_dma)
502
PCI_DMA_UNMAP_SINGLE(handle->dev.pci,
503
packet->ndis_sg_element.address,
504
packet->ndis_sg_element.length,
507
DBGTRACE3("freeing buffer %p", buffer);
508
kfree(MmGetMdlVirtualAddress(buffer));
511
DBGTRACE3("freeing packet %p", packet);
512
free_ndis_packet(packet);
507
517
* MiniportSend and MiniportSendPackets
508
* this function is called from bh disabled context, so no need to raise
509
* irql to DISPATCH_LEVEL during MiniportSend(Packets)
518
* this function is called with lock held in DISPATCH_LEVEL, so no need
519
* to raise irql to DISPATCH_LEVEL during MiniportSend(Packets)
511
521
static int send_packets(struct ndis_handle *handle, unsigned int start,
512
522
unsigned int pending)
515
525
struct miniport_char *miniport = &handle->driver->miniport_char;
516
526
unsigned int sent, n;
517
527
struct ndis_packet *packet;
519
529
TRACEENTER3("start: %d, pending: %d", start, pending);
531
if (pending > handle->max_send_packets)
532
n = handle->max_send_packets;
521
536
if (miniport->send_packets) {
523
if (pending > handle->max_send_packets)
524
n = handle->max_send_packets;
530
DBGTRACE3("sending %d packets", n);
533
/* copy packets from xmit_ring to linear xmit_array array */
538
/* copy packets from xmit ring to linear xmit array */
534
539
for (i = 0; i < n; i++) {
535
540
int j = (start + i) % XMIT_RING_SIZE;
536
541
handle->xmit_array[i] = handle->xmit_ring[j];
538
miniport->send_packets(handle->adapter_ctx,
539
handle->xmit_array, n);
543
LIN2WIN3(miniport->send_packets, handle->adapter_ctx,
544
handle->xmit_array, n);
540
546
if (test_bit(ATTR_SERIALIZED, &handle->attributes)) {
541
for (sent = 0; sent < n && handle->send_ok;
547
for (sent = 0; sent < n && handle->send_ok; sent++) {
543
548
packet = handle->xmit_array[sent];
544
switch(packet->status) {
549
switch(packet->oob_data.status) {
545
550
case NDIS_STATUS_SUCCESS:
546
551
sendpacket_done(handle, packet);
633
639
static int start_xmit(struct sk_buff *skb, struct net_device *dev)
635
641
struct ndis_handle *handle = dev->priv;
636
struct ndis_buffer *buffer;
637
643
struct ndis_packet *packet;
638
644
unsigned int xmit_ring_next_slot;
640
char *data = kmalloc(skb->len, GFP_ATOMIC);
648
data = kmalloc(skb->len, GFP_ATOMIC);
644
buffer = kmalloc(sizeof(struct ndis_buffer), GFP_ATOMIC);
652
buffer = allocate_init_mdl(data, skb->len);
657
packet = allocate_send_packet(handle, buffer);
650
664
skb_copy_and_csum_dev(skb, data);
653
buffer->len = skb->len;
654
packet = alloc_packet(handle, buffer);
660
665
dev_kfree_skb(skb);
662
wrap_spin_lock(&handle->xmit_ring_lock, PASSIVE_LEVEL);
667
irql = kspin_lock_irql(&handle->xmit_lock, DISPATCH_LEVEL);
663
668
xmit_ring_next_slot =
664
669
(handle->xmit_ring_start +
665
670
handle->xmit_ring_pending) % XMIT_RING_SIZE;
778
786
ndis_close(handle->net_dev);
779
787
netif_carrier_off(handle->net_dev);
781
set_bit(SHUTDOWN, &handle->wrapper_work);
783
789
/* flush_scheduled_work here causes crash with 2.4 kernels */
784
790
/* instead, throw away pending packets */
785
wrap_spin_lock(&handle->xmit_ring_lock, DISPATCH_LEVEL);
791
irql = kspin_lock_irql(&handle->xmit_lock, DISPATCH_LEVEL);
786
792
while (handle->xmit_ring_pending) {
787
793
struct ndis_packet *packet;
789
795
packet = handle->xmit_ring[handle->xmit_ring_start];
790
free_packet(handle, packet);
796
free_send_packet(handle, packet);
791
797
handle->xmit_ring_start =
792
798
(handle->xmit_ring_start + 1) % XMIT_RING_SIZE;
793
799
handle->xmit_ring_pending--;
795
wrap_spin_unlock(&handle->xmit_ring_lock);
801
kspin_unlock_irql(&handle->xmit_lock, irql);
797
miniport_set_int(handle, NDIS_OID_DISASSOCIATE, 0);
803
miniport_set_int(handle, OID_802_11_DISASSOCIATE, 0);
799
805
if (handle->net_dev)
800
806
unregister_netdev(handle->net_dev);
802
printk(KERN_INFO "%s: device %s removed\n", DRV_NAME,
808
printk(KERN_INFO "%s: device %s removed\n", DRIVER_NAME,
803
809
handle->net_dev->name);
805
812
DBGTRACE1("%d, %p",
806
813
test_bit(ATTR_SURPRISE_REMOVE, &handle->attributes),
807
814
miniport->pnp_event_notify);
808
815
if (test_bit(ATTR_SURPRISE_REMOVE, &handle->attributes) &&
809
816
miniport->pnp_event_notify) {
810
miniport->pnp_event_notify(handle->adapter_ctx,
811
NDIS_PNP_SURPRISE_REMOVED,
817
LIN2WIN4(miniport->pnp_event_notify, handle->adapter_ctx,
818
NdisDevicePnPEventSurpriseRemoved, NULL, 0);
815
821
DBGTRACE1("halting device %s", handle->driver->name);
816
822
miniport_halt(handle);
817
823
DBGTRACE1("halt successful");
825
if (handle->xmit_array)
826
kfree(handle->xmit_array);
819
827
if (handle->multicast_list)
820
828
kfree(handle->multicast_list);
821
829
if (handle->net_dev)
822
830
free_netdev(handle->net_dev);
824
if (handle->phys_device_obj)
825
kfree(handle->phys_device_obj);
828
834
static void link_status_handler(struct ndis_handle *handle)
830
836
struct ndis_assoc_info *ndis_assoc_info;
831
837
unsigned char *wpa_assoc_info, *assoc_info, *p, *ies;
832
838
union iwreq_data wrqu;
834
841
const int assoc_size = sizeof(*ndis_assoc_info) + IW_CUSTOM_MAX;
835
842
struct encr_info *encr_info = &handle->encr_info;
839
DBGTRACE2("link status: %d", handle->link_status);
844
TRACEENTER2("link status: %d", handle->link_status);
840
845
if (handle->link_status == 0) {
841
if (handle->encr_mode == ENCR1_ENABLED ||
842
handle->op_mode == NDIS_MODE_ADHOC) {
846
if (handle->encr_mode == Ndis802_11Encryption1Enabled ||
847
handle->infrastructure_mode == Ndis802_11IBSS) {
843
848
for (i = 0; i < MAX_ENCR_KEYS; i++) {
844
849
if (encr_info->keys[i].length == 0)
846
if (add_wep_key(handle, encr_info->keys[i].key,
847
encr_info->keys[i].length, i))
848
WARNING("setting wep key %d failed",
851
add_wep_key(handle, encr_info->keys[i].key,
852
encr_info->keys[i].length, i);
852
855
set_bit(SET_ESSID, &handle->wrapper_work);
853
856
schedule_work(&handle->wrapper_worker);
854
857
TRACEEXIT2(return);
857
859
/* FIXME: not clear if NDIS says keys should
858
860
* be cleared here */
942
945
static void set_packet_filter(struct ndis_handle *handle)
944
947
struct net_device *dev = (struct net_device *)handle->net_dev;
945
unsigned long packet_filter;
948
951
packet_filter = (NDIS_PACKET_TYPE_DIRECTED |
949
952
NDIS_PACKET_TYPE_BROADCAST |
950
953
NDIS_PACKET_TYPE_ALL_MULTICAST);
952
955
if (dev->flags & IFF_PROMISC) {
953
DBGTRACE1("%s", "Going into promiscuous mode");
954
printk(KERN_WARNING "promiscuous mode is not "
955
"supported by NDIS; only packets sent "
956
"from/to this host will be seen\n");
957
packet_filter |= NDIS_PACKET_TYPE_ALL_LOCAL;
956
packet_filter |= NDIS_PACKET_TYPE_ALL_LOCAL |
957
NDIS_PACKET_TYPE_PROMISCUOUS;
958
958
} else if ((dev->mc_count > handle->multicast_list_size) ||
959
959
(dev->flags & IFF_ALLMULTI) ||
960
960
(handle->multicast_list == 0)) {
961
/* Too many to filter perfectly -- accept all multicasts. */
963
DBGTRACE1("Multicast list to long. Accepting all");
961
/* too many to filter perfectly -- accept all multicasts. */
962
DBGTRACE1("multicast list too long; accepting all");
964
963
packet_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
965
964
} else if (dev->mc_count > 0) {
966
965
packet_filter |= NDIS_PACKET_TYPE_MULTICAST;
967
966
set_multicast_list(dev, handle);
970
res = miniport_set_info(handle, NDIS_OID_PACKET_FILTER,
971
(char *)&packet_filter, sizeof(packet_filter));
969
res = miniport_set_info(handle, OID_GEN_CURRENT_PACKET_FILTER,
970
&packet_filter, sizeof(packet_filter));
971
if (res && (packet_filter & NDIS_PACKET_TYPE_PROMISCUOUS)) {
972
/* 802.11 drivers may fail when PROMISCUOUS flag is
973
* set, so try without */
974
packet_filter &= ~NDIS_PACKET_TYPE_PROMISCUOUS;
975
res = miniport_set_info(handle, OID_GEN_CURRENT_PACKET_FILTER,
976
&packet_filter, sizeof(packet_filter));
972
978
if (res && res != NDIS_STATUS_NOT_SUPPORTED)
973
ERROR("Unable to set packet filter (%08X)", res);
979
ERROR("unable to set packet filter (%08X)", res);
974
980
TRACEEXIT2(return);
979
985
struct iw_statistics *iw_stats = &handle->wireless_stats;
980
986
struct ndis_wireless_stats ndis_stats;
984
990
if (handle->reset_status)
986
res = miniport_query_info(handle, NDIS_OID_RSSI, (char *)&rssi,
992
res = miniport_query_info(handle, OID_802_11_RSSI, &rssi,
988
994
iw_stats->qual.level = rssi;
990
996
memset(&ndis_stats, 0, sizeof(ndis_stats));
991
res = miniport_query_info(handle, NDIS_OID_STATISTICS,
992
(char *)&ndis_stats, sizeof(ndis_stats));
997
res = miniport_query_info(handle, OID_802_11_STATISTICS,
998
&ndis_stats, sizeof(ndis_stats));
993
999
if (res == NDIS_STATUS_NOT_SUPPORTED)
994
1000
iw_stats->qual.qual = ((rssi & 0x7F) * 100) / 154;
996
iw_stats->discard.retries = (__u32)ndis_stats.retry +
997
(__u32)ndis_stats.multi_retry;
998
iw_stats->discard.misc = (__u32)ndis_stats.fcs_err +
999
(__u32)ndis_stats.rtss_fail +
1000
(__u32)ndis_stats.ack_fail +
1001
(__u32)ndis_stats.frame_dup;
1002
iw_stats->discard.retries = (u32)ndis_stats.retry +
1003
(u32)ndis_stats.multi_retry;
1004
iw_stats->discard.misc = (u32)ndis_stats.fcs_err +
1005
(u32)ndis_stats.rtss_fail +
1006
(u32)ndis_stats.ack_fail +
1007
(u32)ndis_stats.frame_dup;
1003
if ((__u32)ndis_stats.tx_frag)
1009
if ((u32)ndis_stats.tx_frag)
1004
1010
iw_stats->qual.qual = 100 - 100 *
1005
((__u32)ndis_stats.retry +
1006
2 * (__u32)ndis_stats.multi_retry +
1007
3 * (__u32)ndis_stats.failed) /
1008
(6 * (__u32)ndis_stats.tx_frag);
1011
((u32)ndis_stats.retry +
1012
2 * (u32)ndis_stats.multi_retry +
1013
3 * (u32)ndis_stats.failed) /
1014
(6 * (u32)ndis_stats.tx_frag);
1010
1016
iw_stats->qual.qual = 100;
1095
1113
static void check_capa(struct ndis_handle *handle)
1099
1117
struct ndis_assoc_info ndis_assoc_info;
1100
1118
struct ndis_add_key ndis_key;
1102
1120
TRACEENTER1("%s", "");
1104
1122
/* check if WEP is supported */
1105
if (set_encr_mode(handle, ENCR1_ENABLED) ||
1106
miniport_query_int(handle, NDIS_OID_ENCR_STATUS, &i))
1109
set_bit(CAPA_WEP, &handle->capa);
1123
if (set_encr_mode(handle, Ndis802_11Encryption1Enabled) == 0 &&
1124
miniport_query_int(handle,
1125
OID_802_11_ENCRYPTION_STATUS, &i) == 0 &&
1126
(i == Ndis802_11Encryption1Enabled ||
1127
i == Ndis802_11Encryption1KeyAbsent))
1128
set_bit(Ndis802_11Encryption1Enabled, &handle->capa);
1111
1130
/* check if WPA is supported */
1112
set_encr_mode(handle, ENCR_DISABLED);
1113
1131
DBGTRACE2("%s", "");
1114
if (set_auth_mode(handle, AUTHMODE_WPA) ||
1115
miniport_query_int(handle, NDIS_OID_AUTH_MODE, &i) ||
1132
if (set_auth_mode(handle, Ndis802_11AuthModeWPA) ||
1133
miniport_query_int(handle, OID_802_11_AUTHENTICATION_MODE, &i) ||
1134
i != Ndis802_11AuthModeWPA)
1117
1135
TRACEEXIT1(return);
1119
1137
/* check for highest encryption */
1120
for (mode = ENCR3_ENABLED; mode != ENCR_DISABLED; ) {
1121
DBGTRACE1("checking encryption mode %d", mode);
1122
if (set_encr_mode(handle, mode) ||
1123
miniport_query_int(handle, NDIS_OID_ENCR_STATUS, &i))
1138
if (set_encr_mode(handle, Ndis802_11Encryption3Enabled) == 0 &&
1139
miniport_query_int(handle,
1140
OID_802_11_ENCRYPTION_STATUS, &i) == 0 &&
1141
(i == Ndis802_11Encryption3Enabled ||
1142
i == Ndis802_11Encryption3KeyAbsent))
1143
mode = Ndis802_11Encryption3Enabled;
1144
else if (set_encr_mode(handle, Ndis802_11Encryption2Enabled) == 0 &&
1145
miniport_query_int(handle,
1146
OID_802_11_ENCRYPTION_STATUS, &i) == 0 &&
1147
(i == Ndis802_11Encryption2Enabled ||
1148
i == Ndis802_11Encryption2KeyAbsent))
1149
mode = Ndis802_11Encryption2Enabled;
1150
else if (set_encr_mode(handle, Ndis802_11Encryption1Enabled) == 0 &&
1151
miniport_query_int(handle,
1152
OID_802_11_ENCRYPTION_STATUS, &i) == 0 &&
1153
(i == Ndis802_11Encryption1Enabled ||
1154
i == Ndis802_11Encryption1KeyAbsent))
1155
mode = Ndis802_11Encryption1Enabled;
1157
mode = Ndis802_11EncryptionDisabled;
1126
if (mode == ENCR3_ENABLED) {
1127
if (i == mode || i == ENCR3_ABSENT)
1130
mode = ENCR2_ENABLED;
1131
} else if (mode == ENCR2_ENABLED) {
1132
if (i == mode || i == ENCR2_ABSENT)
1135
mode = ENCR1_ENABLED;
1137
mode = ENCR_DISABLED;
1139
1159
DBGTRACE1("highest encryption mode supported = %d", mode);
1140
set_encr_mode(handle, mode);
1142
if (mode == ENCR_DISABLED)
1161
if (mode == Ndis802_11EncryptionDisabled)
1143
1162
TRACEEXIT1(return);
1145
set_bit(CAPA_WEP, &handle->capa);
1146
if (mode == ENCR1_ENABLED)
1164
set_bit(Ndis802_11Encryption1Enabled, &handle->capa);
1165
if (mode == Ndis802_11Encryption1Enabled)
1147
1166
TRACEEXIT1(return);
1149
1168
ndis_key.length = 32;
1150
1169
ndis_key.index = 0xC0000001;
1151
1170
ndis_key.struct_size = sizeof(ndis_key);
1152
res = miniport_set_info(handle, NDIS_OID_ADD_KEY, (char *)&ndis_key,
1171
res = miniport_set_info(handle, OID_802_11_ADD_KEY, &ndis_key,
1153
1172
ndis_key.struct_size);
1155
DBGTRACE2("add key returns %08X, size = %ld\n",
1156
res, (unsigned long)sizeof(ndis_key));
1174
DBGTRACE2("add key returns %08X, size = %lu",
1175
res, (unsigned long)sizeof(ndis_key));
1157
1176
if (res != NDIS_STATUS_INVALID_DATA)
1158
1177
TRACEEXIT1(return);
1159
res = miniport_query_info(handle, NDIS_OID_ASSOC_INFO,
1160
(char *)&ndis_assoc_info,
1161
sizeof(ndis_assoc_info));
1178
res = miniport_query_info(handle, OID_802_11_ASSOCIATION_INFORMATION,
1179
&ndis_assoc_info, sizeof(ndis_assoc_info));
1162
1180
DBGTRACE2("assoc info returns %d", res);
1163
1181
if (res == NDIS_STATUS_NOT_SUPPORTED)
1164
1182
TRACEEXIT1(return);
1166
set_bit(CAPA_WPA, &handle->capa);
1167
if (mode == ENCR3_ENABLED)
1168
set_bit(CAPA_AES, &handle->capa);
1169
set_bit(CAPA_TKIP, &handle->capa);
1184
set_bit(Ndis802_11Encryption2Enabled, &handle->capa);
1185
if (mode == Ndis802_11Encryption3Enabled)
1186
set_bit(Ndis802_11Encryption3Enabled, &handle->capa);
1171
1188
TRACEEXIT1(return);
1326
1350
netif_stop_queue(dev);
1327
printk(KERN_INFO "%s: %s ethernet device " MACSTR " using driver %s\n",
1328
dev->name, DRV_NAME, MAC2STR(dev->dev_addr),
1329
handle->driver->name);
1351
printk(KERN_INFO "%s: %s ethernet device " MACSTR " using driver %s,"
1352
" configuration file %s\n",
1353
dev->name, DRIVER_NAME, MAC2STR(dev->dev_addr),
1354
handle->driver->name, handle->device->conf_file_name);
1331
1356
check_capa(handle);
1333
1358
DBGTRACE1("capbilities = %ld", handle->capa);
1334
1359
printk(KERN_INFO "%s: encryption modes supported: %s%s%s\n",
1336
test_bit(CAPA_WEP, &handle->capa) ? "WEP" : "none",
1337
test_bit(CAPA_TKIP, &handle->capa) ? ", WPA with TKIP" : "",
1338
test_bit(CAPA_AES, &handle->capa) ? ", WPA with AES/CCMP" : "");
1361
test_bit(Ndis802_11Encryption1Enabled, &handle->capa) ?
1363
test_bit(Ndis802_11Encryption2Enabled, &handle->capa) ?
1364
", WPA with TKIP" : "",
1365
test_bit(Ndis802_11Encryption3Enabled, &handle->capa) ?
1366
", WPA with AES/CCMP" : "");
1340
1368
/* check_capa changes auth_mode and encr_mode, so set them again */
1341
set_mode(handle, NDIS_MODE_INFRA);
1342
set_auth_mode(handle, AUTHMODE_OPEN);
1343
set_encr_mode(handle, ENCR_DISABLED);
1369
set_infra_mode(handle, Ndis802_11Infrastructure);
1370
set_auth_mode(handle, Ndis802_11AuthModeOpen);
1371
set_encr_mode(handle, Ndis802_11EncryptionDisabled);
1372
set_essid(handle, "", 0);
1345
1374
/* some cards (e.g., RaLink) need a scan before they can associate */
1346
miniport_set_int(handle, NDIS_OID_BSSID_LIST_SCAN, 0);
1348
1377
hangcheck_add(handle);
1349
1378
stats_timer_add(handle);
1389
1420
handle->send_ok = 0;
1391
1422
INIT_WORK(&handle->xmit_work, xmit_worker, handle);
1392
wrap_spin_lock_init(&handle->xmit_ring_lock);
1393
1423
handle->xmit_ring_start = 0;
1394
1424
handle->xmit_ring_pending = 0;
1396
wrap_spin_lock_init(&handle->send_packet_done_lock);
1426
kspin_lock_init(&handle->send_packet_done_lock);
1398
handle->encr_mode = ENCR_DISABLED;
1399
handle->auth_mode = AUTHMODE_OPEN;
1428
handle->encr_mode = Ndis802_11EncryptionDisabled;
1429
handle->auth_mode = Ndis802_11AuthModeOpen;
1400
1430
handle->capa = 0;
1401
1431
handle->attributes = 0;
1403
1433
handle->reset_status = 0;
1405
1435
INIT_LIST_HEAD(&handle->timers);
1406
wrap_spin_lock_init(&handle->timers_lock);
1436
kspin_lock_init(&handle->timers_lock);
1408
handle->rx_packet = &NdisMIndicateReceivePacket;
1409
handle->send_complete = &NdisMSendComplete;
1410
handle->send_resource_avail = &NdisMSendResourcesAvailable;
1411
handle->status = &NdisMIndicateStatus;
1412
handle->status_complete = &NdisMIndicateStatusComplete;
1413
handle->query_complete = &NdisMQueryInformationComplete;
1414
handle->set_complete = &NdisMSetInformationComplete;
1415
handle->reset_complete = &NdisMResetComplete;
1416
handle->eth_rx_indicate = &EthRxIndicateHandler;
1417
handle->eth_rx_complete = &EthRxComplete;
1418
handle->td_complete = &NdisMTransferDataComplete;
1438
handle->rx_packet = WRAP_FUNC_PTR(NdisMIndicateReceivePacket);
1439
handle->send_complete = WRAP_FUNC_PTR(NdisMSendComplete);
1440
handle->send_resource_avail =
1441
WRAP_FUNC_PTR(NdisMSendResourcesAvailable);
1442
handle->status = WRAP_FUNC_PTR(NdisMIndicateStatus);
1443
handle->status_complete = WRAP_FUNC_PTR(NdisMIndicateStatusComplete);
1444
handle->query_complete = WRAP_FUNC_PTR(NdisMQueryInformationComplete);
1445
handle->set_complete = WRAP_FUNC_PTR(NdisMSetInformationComplete);
1446
handle->reset_complete = WRAP_FUNC_PTR(NdisMResetComplete);
1447
handle->eth_rx_indicate = WRAP_FUNC_PTR(EthRxIndicateHandler);
1448
handle->eth_rx_complete = WRAP_FUNC_PTR(EthRxComplete);
1449
handle->td_complete = WRAP_FUNC_PTR(NdisMTransferDataComplete);
1419
1450
handle->driver->miniport_char.adapter_shutdown = NULL;
1421
1452
handle->map_count = 0;
1446
1477
ndiswrapper_procfs_remove();
1450
1483
static int __init wrapper_init(void)
1485
char *argv[] = {"loadndisdriver",
1452
1486
#if defined DEBUG && DEBUG >= 1
1453
char *argv[] = {"loadndisdriver", "1", NDISWRAPPER_VERSION, "-a", 0};
1455
char *argv[] = {"loadndisdriver", "0", NDISWRAPPER_VERSION, "-a", 0};
1491
, NDISWRAPPER_VERSION, "-a", 0};
1492
char *env[] = {NULL};
1495
spin_lock_init(&spinlock_kspin_lock);
1496
#if defined(DEBUG) && DEBUG > 0
1460
1501
printk(KERN_INFO "%s version %s%s loaded (preempt=%s,smp=%s)\n",
1461
DRV_NAME, NDISWRAPPER_VERSION, EXTRA_VERSION,
1502
DRIVER_NAME, NDISWRAPPER_VERSION, EXTRA_VERSION,
1462
1503
#if defined CONFIG_PREEMPT
1475
TRACEEXIT1(return -EPERM);
1515
if (misc_funcs_init() || ntoskernel_init() || ndis_init() ||
1477
1521
module_cleanup();
1522
ERROR("couldn't initialize %s", DRIVER_NAME);
1478
1523
TRACEEXIT1(return -EPERM);
1481
INIT_LIST_HEAD(&wrap_allocs);
1482
wrap_spin_lock_init(&wrap_allocs_lock);
1483
wrap_spin_lock_init(&dispatch_event_lock);
1484
1525
ndiswrapper_procfs_init();
1485
1526
DBGTRACE1("%s", "calling loadndisdriver");
1527
err = call_usermodehelper("/sbin/loadndisdriver", argv, env
1486
1528
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
1487
err = call_usermodehelper("/sbin/loadndisdriver", argv, env, 1);
1489
err = call_usermodehelper("/sbin/loadndisdriver", argv, env);
1493
1533
ERROR("loadndiswrapper failed (%d); check system log "
1494
1534
"for messages from 'loadndisdriver'", err);