aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/Kconfig9
-rw-r--r--drivers/net/wireless/airo.c455
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c2
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c2
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c8
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c4
-rw-r--r--drivers/net/wireless/hostap/hostap_pci.c4
-rw-r--r--drivers/net/wireless/hostap/hostap_plx.c13
-rw-r--r--include/linux/wireless.h10
-rw-r--r--include/net/iw_handler.h12
-rw-r--r--net/core/rtnetlink.c98
-rw-r--r--net/core/wireless.c911
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_assoc.c9
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_auth.c12
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_priv.h9
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_scan.c7
16 files changed, 1264 insertions, 301 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 5b0a19a5058d..6a1033ec06cf 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -25,6 +25,15 @@ config NET_RADIO
25 the tools from 25 the tools from
26 <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>. 26 <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
27 27
28config NET_WIRELESS_RTNETLINK
29 bool "Wireless Extension API over RtNetlink"
30 ---help---
31 Support the Wireless Extension API over the RtNetlink socket
32 in addition to the traditional ioctl interface (selected above).
33
34 For now, few tools use this facility, but it might grow in the
35 future. The only downside is that it adds 4.5 kB to your kernel.
36
28# Note : the cards are obsolete (can't buy them anymore), but the drivers 37# Note : the cards are obsolete (can't buy them anymore), but the drivers
29# are not, as people are still using them... 38# are not, as people are still using them...
30comment "Obsolete Wireless cards support (pre-802.11)" 39comment "Obsolete Wireless cards support (pre-802.11)"
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 864937a409e5..108d9fed8f07 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -770,6 +770,11 @@ typedef struct {
770} BSSListRid; 770} BSSListRid;
771 771
772typedef struct { 772typedef struct {
773 BSSListRid bss;
774 struct list_head list;
775} BSSListElement;
776
777typedef struct {
773 u8 rssipct; 778 u8 rssipct;
774 u8 rssidBm; 779 u8 rssidBm;
775} tdsRssiEntry; 780} tdsRssiEntry;
@@ -902,6 +907,7 @@ static char swversion[] = "2.1";
902#define NUM_MODULES 2 907#define NUM_MODULES 2
903#define MIC_MSGLEN_MAX 2400 908#define MIC_MSGLEN_MAX 2400
904#define EMMH32_MSGLEN_MAX MIC_MSGLEN_MAX 909#define EMMH32_MSGLEN_MAX MIC_MSGLEN_MAX
910#define AIRO_DEF_MTU 2312
905 911
906typedef struct { 912typedef struct {
907 u32 size; // size 913 u32 size; // size
@@ -1119,6 +1125,8 @@ static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket,
1119static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi); 1125static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi);
1120static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm); 1126static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm);
1121 1127
1128static void airo_networks_free(struct airo_info *ai);
1129
1122struct airo_info { 1130struct airo_info {
1123 struct net_device_stats stats; 1131 struct net_device_stats stats;
1124 struct net_device *dev; 1132 struct net_device *dev;
@@ -1150,7 +1158,7 @@ struct airo_info {
1150#define FLAG_COMMIT 13 1158#define FLAG_COMMIT 13
1151#define FLAG_RESET 14 1159#define FLAG_RESET 14
1152#define FLAG_FLASHING 15 1160#define FLAG_FLASHING 15
1153#define JOB_MASK 0x1ff0000 1161#define JOB_MASK 0x2ff0000
1154#define JOB_DIE 16 1162#define JOB_DIE 16
1155#define JOB_XMIT 17 1163#define JOB_XMIT 17
1156#define JOB_XMIT11 18 1164#define JOB_XMIT11 18
@@ -1160,6 +1168,7 @@ struct airo_info {
1160#define JOB_EVENT 22 1168#define JOB_EVENT 22
1161#define JOB_AUTOWEP 23 1169#define JOB_AUTOWEP 23
1162#define JOB_WSTATS 24 1170#define JOB_WSTATS 24
1171#define JOB_SCAN_RESULTS 25
1163 int (*bap_read)(struct airo_info*, u16 *pu16Dst, int bytelen, 1172 int (*bap_read)(struct airo_info*, u16 *pu16Dst, int bytelen,
1164 int whichbap); 1173 int whichbap);
1165 unsigned short *flash; 1174 unsigned short *flash;
@@ -1176,7 +1185,7 @@ struct airo_info {
1176 } xmit, xmit11; 1185 } xmit, xmit11;
1177 struct net_device *wifidev; 1186 struct net_device *wifidev;
1178 struct iw_statistics wstats; // wireless stats 1187 struct iw_statistics wstats; // wireless stats
1179 unsigned long scan_timestamp; /* Time started to scan */ 1188 unsigned long scan_timeout; /* Time scan should be read */
1180 struct iw_spy_data spy_data; 1189 struct iw_spy_data spy_data;
1181 struct iw_public_data wireless_data; 1190 struct iw_public_data wireless_data;
1182 /* MIC stuff */ 1191 /* MIC stuff */
@@ -1198,6 +1207,10 @@ struct airo_info {
1198 APListRid *APList; 1207 APListRid *APList;
1199#define PCI_SHARED_LEN 2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE 1208#define PCI_SHARED_LEN 2*MPI_MAX_FIDS*PKTSIZE+RIDSIZE
1200 char proc_name[IFNAMSIZ]; 1209 char proc_name[IFNAMSIZ];
1210
1211 struct list_head network_list;
1212 struct list_head network_free_list;
1213 BSSListElement *networks;
1201}; 1214};
1202 1215
1203static inline int bap_read(struct airo_info *ai, u16 *pu16Dst, int bytelen, 1216static inline int bap_read(struct airo_info *ai, u16 *pu16Dst, int bytelen,
@@ -1216,6 +1229,22 @@ static int flashgchar(struct airo_info *ai,int matchbyte,int dwelltime);
1216static int flashputbuf(struct airo_info *ai); 1229static int flashputbuf(struct airo_info *ai);
1217static int flashrestart(struct airo_info *ai,struct net_device *dev); 1230static int flashrestart(struct airo_info *ai,struct net_device *dev);
1218 1231
1232#define airo_print(type, name, fmt, args...) \
1233 { printk(type "airo(%s): " fmt "\n", name, ##args); }
1234
1235#define airo_print_info(name, fmt, args...) \
1236 airo_print(KERN_INFO, name, fmt, ##args)
1237
1238#define airo_print_dbg(name, fmt, args...) \
1239 airo_print(KERN_DEBUG, name, fmt, ##args)
1240
1241#define airo_print_warn(name, fmt, args...) \
1242 airo_print(KERN_WARNING, name, fmt, ##args)
1243
1244#define airo_print_err(name, fmt, args...) \
1245 airo_print(KERN_ERR, name, fmt, ##args)
1246
1247
1219/*********************************************************************** 1248/***********************************************************************
1220 * MIC ROUTINES * 1249 * MIC ROUTINES *
1221 *********************************************************************** 1250 ***********************************************************************
@@ -1294,7 +1323,7 @@ static int micsetup(struct airo_info *ai) {
1294 ai->tfm = crypto_alloc_tfm("aes", CRYPTO_TFM_REQ_MAY_SLEEP); 1323 ai->tfm = crypto_alloc_tfm("aes", CRYPTO_TFM_REQ_MAY_SLEEP);
1295 1324
1296 if (ai->tfm == NULL) { 1325 if (ai->tfm == NULL) {
1297 printk(KERN_ERR "airo: failed to load transform for AES\n"); 1326 airo_print_err(ai->dev->name, "failed to load transform for AES");
1298 return ERROR; 1327 return ERROR;
1299 } 1328 }
1300 1329
@@ -1726,11 +1755,11 @@ static int writeWepKeyRid(struct airo_info*ai, WepKeyRid *pwkr, int perm, int lo
1726 wkr.kindex = cpu_to_le16(wkr.kindex); 1755 wkr.kindex = cpu_to_le16(wkr.kindex);
1727 wkr.klen = cpu_to_le16(wkr.klen); 1756 wkr.klen = cpu_to_le16(wkr.klen);
1728 rc = PC4500_writerid(ai, RID_WEP_TEMP, &wkr, sizeof(wkr), lock); 1757 rc = PC4500_writerid(ai, RID_WEP_TEMP, &wkr, sizeof(wkr), lock);
1729 if (rc!=SUCCESS) printk(KERN_ERR "airo: WEP_TEMP set %x\n", rc); 1758 if (rc!=SUCCESS) airo_print_err(ai->dev->name, "WEP_TEMP set %x", rc);
1730 if (perm) { 1759 if (perm) {
1731 rc = PC4500_writerid(ai, RID_WEP_PERM, &wkr, sizeof(wkr), lock); 1760 rc = PC4500_writerid(ai, RID_WEP_PERM, &wkr, sizeof(wkr), lock);
1732 if (rc!=SUCCESS) { 1761 if (rc!=SUCCESS) {
1733 printk(KERN_ERR "airo: WEP_PERM set %x\n", rc); 1762 airo_print_err(ai->dev->name, "WEP_PERM set %x", rc);
1734 } 1763 }
1735 } 1764 }
1736 return rc; 1765 return rc;
@@ -1909,7 +1938,7 @@ static int mpi_start_xmit(struct sk_buff *skb, struct net_device *dev) {
1909 struct airo_info *ai = dev->priv; 1938 struct airo_info *ai = dev->priv;
1910 1939
1911 if (!skb) { 1940 if (!skb) {
1912 printk(KERN_ERR "airo: %s: skb==NULL\n",__FUNCTION__); 1941 airo_print_err(dev->name, "%s: skb == NULL!",__FUNCTION__);
1913 return 0; 1942 return 0;
1914 } 1943 }
1915 npacks = skb_queue_len (&ai->txq); 1944 npacks = skb_queue_len (&ai->txq);
@@ -1955,8 +1984,8 @@ static int mpi_send_packet (struct net_device *dev)
1955 /* get a packet to send */ 1984 /* get a packet to send */
1956 1985
1957 if ((skb = skb_dequeue(&ai->txq)) == 0) { 1986 if ((skb = skb_dequeue(&ai->txq)) == 0) {
1958 printk (KERN_ERR 1987 airo_print_err(dev->name,
1959 "airo: %s: Dequeue'd zero in send_packet()\n", 1988 "%s: Dequeue'd zero in send_packet()",
1960 __FUNCTION__); 1989 __FUNCTION__);
1961 return 0; 1990 return 0;
1962 } 1991 }
@@ -2108,7 +2137,7 @@ static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) {
2108 u32 *fids = priv->fids; 2137 u32 *fids = priv->fids;
2109 2138
2110 if ( skb == NULL ) { 2139 if ( skb == NULL ) {
2111 printk( KERN_ERR "airo: skb == NULL!!!\n" ); 2140 airo_print_err(dev->name, "%s: skb == NULL!", __FUNCTION__);
2112 return 0; 2141 return 0;
2113 } 2142 }
2114 2143
@@ -2179,7 +2208,7 @@ static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) {
2179 } 2208 }
2180 2209
2181 if ( skb == NULL ) { 2210 if ( skb == NULL ) {
2182 printk( KERN_ERR "airo: skb == NULL!!!\n" ); 2211 airo_print_err(dev->name, "%s: skb == NULL!", __FUNCTION__);
2183 return 0; 2212 return 0;
2184 } 2213 }
2185 2214
@@ -2364,6 +2393,8 @@ void stop_airo_card( struct net_device *dev, int freeres )
2364 dev_kfree_skb(skb); 2393 dev_kfree_skb(skb);
2365 } 2394 }
2366 2395
2396 airo_networks_free (ai);
2397
2367 kfree(ai->flash); 2398 kfree(ai->flash);
2368 kfree(ai->rssi); 2399 kfree(ai->rssi);
2369 kfree(ai->APList); 2400 kfree(ai->APList);
@@ -2434,7 +2465,7 @@ static int mpi_init_descriptors (struct airo_info *ai)
2434 cmd.parm2 = MPI_MAX_FIDS; 2465 cmd.parm2 = MPI_MAX_FIDS;
2435 rc=issuecommand(ai, &cmd, &rsp); 2466 rc=issuecommand(ai, &cmd, &rsp);
2436 if (rc != SUCCESS) { 2467 if (rc != SUCCESS) {
2437 printk(KERN_ERR "airo: Couldn't allocate RX FID\n"); 2468 airo_print_err(ai->dev->name, "Couldn't allocate RX FID");
2438 return rc; 2469 return rc;
2439 } 2470 }
2440 2471
@@ -2462,7 +2493,7 @@ static int mpi_init_descriptors (struct airo_info *ai)
2462 2493
2463 rc=issuecommand(ai, &cmd, &rsp); 2494 rc=issuecommand(ai, &cmd, &rsp);
2464 if (rc != SUCCESS) { 2495 if (rc != SUCCESS) {
2465 printk(KERN_ERR "airo: Couldn't allocate TX FID\n"); 2496 airo_print_err(ai->dev->name, "Couldn't allocate TX FID");
2466 return rc; 2497 return rc;
2467 } 2498 }
2468 2499
@@ -2476,7 +2507,7 @@ static int mpi_init_descriptors (struct airo_info *ai)
2476 cmd.parm2 = 1; /* Magic number... */ 2507 cmd.parm2 = 1; /* Magic number... */
2477 rc=issuecommand(ai, &cmd, &rsp); 2508 rc=issuecommand(ai, &cmd, &rsp);
2478 if (rc != SUCCESS) { 2509 if (rc != SUCCESS) {
2479 printk(KERN_ERR "airo: Couldn't allocate RID\n"); 2510 airo_print_err(ai->dev->name, "Couldn't allocate RID");
2480 return rc; 2511 return rc;
2481 } 2512 }
2482 2513
@@ -2508,25 +2539,25 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
2508 aux_len = AUXMEMSIZE; 2539 aux_len = AUXMEMSIZE;
2509 2540
2510 if (!request_mem_region(mem_start, mem_len, name)) { 2541 if (!request_mem_region(mem_start, mem_len, name)) {
2511 printk(KERN_ERR "airo: Couldn't get region %x[%x] for %s\n", 2542 airo_print_err(ai->dev->name, "Couldn't get region %x[%x] for %s",
2512 (int)mem_start, (int)mem_len, name); 2543 (int)mem_start, (int)mem_len, name);
2513 goto out; 2544 goto out;
2514 } 2545 }
2515 if (!request_mem_region(aux_start, aux_len, name)) { 2546 if (!request_mem_region(aux_start, aux_len, name)) {
2516 printk(KERN_ERR "airo: Couldn't get region %x[%x] for %s\n", 2547 airo_print_err(ai->dev->name, "Couldn't get region %x[%x] for %s",
2517 (int)aux_start, (int)aux_len, name); 2548 (int)aux_start, (int)aux_len, name);
2518 goto free_region1; 2549 goto free_region1;
2519 } 2550 }
2520 2551
2521 ai->pcimem = ioremap(mem_start, mem_len); 2552 ai->pcimem = ioremap(mem_start, mem_len);
2522 if (!ai->pcimem) { 2553 if (!ai->pcimem) {
2523 printk(KERN_ERR "airo: Couldn't map region %x[%x] for %s\n", 2554 airo_print_err(ai->dev->name, "Couldn't map region %x[%x] for %s",
2524 (int)mem_start, (int)mem_len, name); 2555 (int)mem_start, (int)mem_len, name);
2525 goto free_region2; 2556 goto free_region2;
2526 } 2557 }
2527 ai->pciaux = ioremap(aux_start, aux_len); 2558 ai->pciaux = ioremap(aux_start, aux_len);
2528 if (!ai->pciaux) { 2559 if (!ai->pciaux) {
2529 printk(KERN_ERR "airo: Couldn't map region %x[%x] for %s\n", 2560 airo_print_err(ai->dev->name, "Couldn't map region %x[%x] for %s",
2530 (int)aux_start, (int)aux_len, name); 2561 (int)aux_start, (int)aux_len, name);
2531 goto free_memmap; 2562 goto free_memmap;
2532 } 2563 }
@@ -2534,7 +2565,7 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
2534 /* Reserve PKTSIZE for each fid and 2K for the Rids */ 2565 /* Reserve PKTSIZE for each fid and 2K for the Rids */
2535 ai->shared = pci_alloc_consistent(pci, PCI_SHARED_LEN, &ai->shared_dma); 2566 ai->shared = pci_alloc_consistent(pci, PCI_SHARED_LEN, &ai->shared_dma);
2536 if (!ai->shared) { 2567 if (!ai->shared) {
2537 printk(KERN_ERR "airo: Couldn't alloc_consistent %d\n", 2568 airo_print_err(ai->dev->name, "Couldn't alloc_consistent %d",
2538 PCI_SHARED_LEN); 2569 PCI_SHARED_LEN);
2539 goto free_auxmap; 2570 goto free_auxmap;
2540 } 2571 }
@@ -2626,7 +2657,7 @@ static void wifi_setup(struct net_device *dev)
2626 2657
2627 dev->type = ARPHRD_IEEE80211; 2658 dev->type = ARPHRD_IEEE80211;
2628 dev->hard_header_len = ETH_HLEN; 2659 dev->hard_header_len = ETH_HLEN;
2629 dev->mtu = 2312; 2660 dev->mtu = AIRO_DEF_MTU;
2630 dev->addr_len = ETH_ALEN; 2661 dev->addr_len = ETH_ALEN;
2631 dev->tx_queue_len = 100; 2662 dev->tx_queue_len = 100;
2632 2663
@@ -2670,6 +2701,42 @@ static int reset_card( struct net_device *dev , int lock) {
2670 return 0; 2701 return 0;
2671} 2702}
2672 2703
2704#define MAX_NETWORK_COUNT 64
2705static int airo_networks_allocate(struct airo_info *ai)
2706{
2707 if (ai->networks)
2708 return 0;
2709
2710 ai->networks =
2711 kzalloc(MAX_NETWORK_COUNT * sizeof(BSSListElement),
2712 GFP_KERNEL);
2713 if (!ai->networks) {
2714 airo_print_warn(ai->dev->name, "Out of memory allocating beacons");
2715 return -ENOMEM;
2716 }
2717
2718 return 0;
2719}
2720
2721static void airo_networks_free(struct airo_info *ai)
2722{
2723 if (!ai->networks)
2724 return;
2725 kfree(ai->networks);
2726 ai->networks = NULL;
2727}
2728
2729static void airo_networks_initialize(struct airo_info *ai)
2730{
2731 int i;
2732
2733 INIT_LIST_HEAD(&ai->network_free_list);
2734 INIT_LIST_HEAD(&ai->network_list);
2735 for (i = 0; i < MAX_NETWORK_COUNT; i++)
2736 list_add_tail(&ai->networks[i].list,
2737 &ai->network_free_list);
2738}
2739
2673static struct net_device *_init_airo_card( unsigned short irq, int port, 2740static struct net_device *_init_airo_card( unsigned short irq, int port,
2674 int is_pcmcia, struct pci_dev *pci, 2741 int is_pcmcia, struct pci_dev *pci,
2675 struct device *dmdev ) 2742 struct device *dmdev )
@@ -2681,22 +2748,22 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
2681 /* Create the network device object. */ 2748 /* Create the network device object. */
2682 dev = alloc_etherdev(sizeof(*ai)); 2749 dev = alloc_etherdev(sizeof(*ai));
2683 if (!dev) { 2750 if (!dev) {
2684 printk(KERN_ERR "airo: Couldn't alloc_etherdev\n"); 2751 airo_print_err("", "Couldn't alloc_etherdev");
2685 return NULL; 2752 return NULL;
2686 } 2753 }
2687 if (dev_alloc_name(dev, dev->name) < 0) { 2754 if (dev_alloc_name(dev, dev->name) < 0) {
2688 printk(KERN_ERR "airo: Couldn't get name!\n"); 2755 airo_print_err("", "Couldn't get name!");
2689 goto err_out_free; 2756 goto err_out_free;
2690 } 2757 }
2691 2758
2692 ai = dev->priv; 2759 ai = dev->priv;
2693 ai->wifidev = NULL; 2760 ai->wifidev = NULL;
2694 ai->flags = 0; 2761 ai->flags = 0;
2762 ai->dev = dev;
2695 if (pci && (pci->device == 0x5000 || pci->device == 0xa504)) { 2763 if (pci && (pci->device == 0x5000 || pci->device == 0xa504)) {
2696 printk(KERN_DEBUG "airo: Found an MPI350 card\n"); 2764 airo_print_dbg(dev->name, "Found an MPI350 card");
2697 set_bit(FLAG_MPI, &ai->flags); 2765 set_bit(FLAG_MPI, &ai->flags);
2698 } 2766 }
2699 ai->dev = dev;
2700 spin_lock_init(&ai->aux_lock); 2767 spin_lock_init(&ai->aux_lock);
2701 sema_init(&ai->sem, 1); 2768 sema_init(&ai->sem, 1);
2702 ai->config.len = 0; 2769 ai->config.len = 0;
@@ -2711,6 +2778,10 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
2711 if (rc) 2778 if (rc)
2712 goto err_out_thr; 2779 goto err_out_thr;
2713 2780
2781 if (airo_networks_allocate (ai))
2782 goto err_out_unlink;
2783 airo_networks_initialize (ai);
2784
2714 /* The Airo-specific entries in the device structure. */ 2785 /* The Airo-specific entries in the device structure. */
2715 if (test_bit(FLAG_MPI,&ai->flags)) { 2786 if (test_bit(FLAG_MPI,&ai->flags)) {
2716 skb_queue_head_init (&ai->txq); 2787 skb_queue_head_init (&ai->txq);
@@ -2732,33 +2803,33 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
2732 2803
2733 SET_NETDEV_DEV(dev, dmdev); 2804 SET_NETDEV_DEV(dev, dmdev);
2734 2805
2735
2736 reset_card (dev, 1); 2806 reset_card (dev, 1);
2737 msleep(400); 2807 msleep(400);
2738 2808
2739 rc = request_irq( dev->irq, airo_interrupt, SA_SHIRQ, dev->name, dev ); 2809 rc = request_irq( dev->irq, airo_interrupt, SA_SHIRQ, dev->name, dev );
2740 if (rc) { 2810 if (rc) {
2741 printk(KERN_ERR "airo: register interrupt %d failed, rc %d\n", irq, rc ); 2811 airo_print_err(dev->name, "register interrupt %d failed, rc %d",
2812 irq, rc);
2742 goto err_out_unlink; 2813 goto err_out_unlink;
2743 } 2814 }
2744 if (!is_pcmcia) { 2815 if (!is_pcmcia) {
2745 if (!request_region( dev->base_addr, 64, dev->name )) { 2816 if (!request_region( dev->base_addr, 64, dev->name )) {
2746 rc = -EBUSY; 2817 rc = -EBUSY;
2747 printk(KERN_ERR "airo: Couldn't request region\n"); 2818 airo_print_err(dev->name, "Couldn't request region");
2748 goto err_out_irq; 2819 goto err_out_irq;
2749 } 2820 }
2750 } 2821 }
2751 2822
2752 if (test_bit(FLAG_MPI,&ai->flags)) { 2823 if (test_bit(FLAG_MPI,&ai->flags)) {
2753 if (mpi_map_card(ai, pci, dev->name)) { 2824 if (mpi_map_card(ai, pci, dev->name)) {
2754 printk(KERN_ERR "airo: Could not map memory\n"); 2825 airo_print_err(dev->name, "Could not map memory");
2755 goto err_out_res; 2826 goto err_out_res;
2756 } 2827 }
2757 } 2828 }
2758 2829
2759 if (probe) { 2830 if (probe) {
2760 if ( setup_card( ai, dev->dev_addr, 1 ) != SUCCESS ) { 2831 if ( setup_card( ai, dev->dev_addr, 1 ) != SUCCESS ) {
2761 printk( KERN_ERR "airo: MAC could not be enabled\n" ); 2832 airo_print_err(dev->name, "MAC could not be enabled" );
2762 rc = -EIO; 2833 rc = -EIO;
2763 goto err_out_map; 2834 goto err_out_map;
2764 } 2835 }
@@ -2769,21 +2840,20 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
2769 2840
2770 rc = register_netdev(dev); 2841 rc = register_netdev(dev);
2771 if (rc) { 2842 if (rc) {
2772 printk(KERN_ERR "airo: Couldn't register_netdev\n"); 2843 airo_print_err(dev->name, "Couldn't register_netdev");
2773 goto err_out_map; 2844 goto err_out_map;
2774 } 2845 }
2775 ai->wifidev = init_wifidev(ai, dev); 2846 ai->wifidev = init_wifidev(ai, dev);
2776 2847
2777 set_bit(FLAG_REGISTERED,&ai->flags); 2848 set_bit(FLAG_REGISTERED,&ai->flags);
2778 printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n", 2849 airo_print_info(dev->name, "MAC enabled %x:%x:%x:%x:%x:%x",
2779 dev->name,
2780 dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], 2850 dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
2781 dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] ); 2851 dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] );
2782 2852
2783 /* Allocate the transmit buffers */ 2853 /* Allocate the transmit buffers */
2784 if (probe && !test_bit(FLAG_MPI,&ai->flags)) 2854 if (probe && !test_bit(FLAG_MPI,&ai->flags))
2785 for( i = 0; i < MAX_FIDS; i++ ) 2855 for( i = 0; i < MAX_FIDS; i++ )
2786 ai->fids[i] = transmit_allocate(ai,2312,i>=MAX_FIDS/2); 2856 ai->fids[i] = transmit_allocate(ai,AIRO_DEF_MTU,i>=MAX_FIDS/2);
2787 2857
2788 setup_proc_entry( dev, dev->priv ); /* XXX check for failure */ 2858 setup_proc_entry( dev, dev->priv ); /* XXX check for failure */
2789 netif_start_queue(dev); 2859 netif_start_queue(dev);
@@ -2840,16 +2910,16 @@ int reset_airo_card( struct net_device *dev )
2840 return -1; 2910 return -1;
2841 2911
2842 if ( setup_card(ai, dev->dev_addr, 1 ) != SUCCESS ) { 2912 if ( setup_card(ai, dev->dev_addr, 1 ) != SUCCESS ) {
2843 printk( KERN_ERR "airo: MAC could not be enabled\n" ); 2913 airo_print_err(dev->name, "MAC could not be enabled");
2844 return -1; 2914 return -1;
2845 } 2915 }
2846 printk( KERN_INFO "airo: MAC enabled %s %x:%x:%x:%x:%x:%x\n", dev->name, 2916 airo_print_info(dev->name, "MAC enabled %x:%x:%x:%x:%x:%x",
2847 dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], 2917 dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
2848 dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); 2918 dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
2849 /* Allocate the transmit buffers if needed */ 2919 /* Allocate the transmit buffers if needed */
2850 if (!test_bit(FLAG_MPI,&ai->flags)) 2920 if (!test_bit(FLAG_MPI,&ai->flags))
2851 for( i = 0; i < MAX_FIDS; i++ ) 2921 for( i = 0; i < MAX_FIDS; i++ )
2852 ai->fids[i] = transmit_allocate (ai,2312,i>=MAX_FIDS/2); 2922 ai->fids[i] = transmit_allocate (ai,AIRO_DEF_MTU,i>=MAX_FIDS/2);
2853 2923
2854 enable_interrupts( ai ); 2924 enable_interrupts( ai );
2855 netif_wake_queue(dev); 2925 netif_wake_queue(dev);
@@ -2875,6 +2945,65 @@ static void airo_send_event(struct net_device *dev) {
2875 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); 2945 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
2876} 2946}
2877 2947
2948static void airo_process_scan_results (struct airo_info *ai) {
2949 union iwreq_data wrqu;
2950 BSSListRid BSSList;
2951 int rc;
2952 BSSListElement * loop_net;
2953 BSSListElement * tmp_net;
2954
2955 /* Blow away current list of scan results */
2956 list_for_each_entry_safe (loop_net, tmp_net, &ai->network_list, list) {
2957 list_move_tail (&loop_net->list, &ai->network_free_list);
2958 /* Don't blow away ->list, just BSS data */
2959 memset (loop_net, 0, sizeof (loop_net->bss));
2960 }
2961
2962 /* Try to read the first entry of the scan result */
2963 rc = PC4500_readrid(ai, RID_BSSLISTFIRST, &BSSList, sizeof(BSSList), 0);
2964 if((rc) || (BSSList.index == 0xffff)) {
2965 /* No scan results */
2966 goto out;
2967 }
2968
2969 /* Read and parse all entries */
2970 tmp_net = NULL;
2971 while((!rc) && (BSSList.index != 0xffff)) {
2972 /* Grab a network off the free list */
2973 if (!list_empty(&ai->network_free_list)) {
2974 tmp_net = list_entry(ai->network_free_list.next,
2975 BSSListElement, list);
2976 list_del(ai->network_free_list.next);
2977 }
2978
2979 if (tmp_net != NULL) {
2980 memcpy(tmp_net, &BSSList, sizeof(tmp_net->bss));
2981 list_add_tail(&tmp_net->list, &ai->network_list);
2982 tmp_net = NULL;
2983 }
2984
2985 /* Read next entry */
2986 rc = PC4500_readrid(ai, RID_BSSLISTNEXT,
2987 &BSSList, sizeof(BSSList), 0);
2988 }
2989
2990out:
2991 ai->scan_timeout = 0;
2992 clear_bit(JOB_SCAN_RESULTS, &ai->flags);
2993 up(&ai->sem);
2994
2995 /* Send an empty event to user space.
2996 * We don't send the received data on
2997 * the event because it would require
2998 * us to do complex transcoding, and
2999 * we want to minimise the work done in
3000 * the irq handler. Use a request to
3001 * extract the data - Jean II */
3002 wrqu.data.length = 0;
3003 wrqu.data.flags = 0;
3004 wireless_send_event(ai->dev, SIOCGIWSCAN, &wrqu, NULL);
3005}
3006
2878static int airo_thread(void *data) { 3007static int airo_thread(void *data) {
2879 struct net_device *dev = data; 3008 struct net_device *dev = data;
2880 struct airo_info *ai = dev->priv; 3009 struct airo_info *ai = dev->priv;
@@ -2904,13 +3033,26 @@ static int airo_thread(void *data) {
2904 set_current_state(TASK_INTERRUPTIBLE); 3033 set_current_state(TASK_INTERRUPTIBLE);
2905 if (ai->flags & JOB_MASK) 3034 if (ai->flags & JOB_MASK)
2906 break; 3035 break;
2907 if (ai->expires) { 3036 if (ai->expires || ai->scan_timeout) {
2908 if (time_after_eq(jiffies,ai->expires)){ 3037 if (ai->scan_timeout &&
3038 time_after_eq(jiffies,ai->scan_timeout)){
3039 set_bit(JOB_SCAN_RESULTS,&ai->flags);
3040 break;
3041 } else if (ai->expires &&
3042 time_after_eq(jiffies,ai->expires)){
2909 set_bit(JOB_AUTOWEP,&ai->flags); 3043 set_bit(JOB_AUTOWEP,&ai->flags);
2910 break; 3044 break;
2911 } 3045 }
2912 if (!signal_pending(current)) { 3046 if (!signal_pending(current)) {
2913 schedule_timeout(ai->expires - jiffies); 3047 unsigned long wake_at;
3048 if (!ai->expires || !ai->scan_timeout) {
3049 wake_at = max(ai->expires,
3050 ai->scan_timeout);
3051 } else {
3052 wake_at = min(ai->expires,
3053 ai->scan_timeout);
3054 }
3055 schedule_timeout(wake_at - jiffies);
2914 continue; 3056 continue;
2915 } 3057 }
2916 } else if (!signal_pending(current)) { 3058 } else if (!signal_pending(current)) {
@@ -2953,6 +3095,10 @@ static int airo_thread(void *data) {
2953 airo_send_event(dev); 3095 airo_send_event(dev);
2954 else if (test_bit(JOB_AUTOWEP, &ai->flags)) 3096 else if (test_bit(JOB_AUTOWEP, &ai->flags))
2955 timer_func(dev); 3097 timer_func(dev);
3098 else if (test_bit(JOB_SCAN_RESULTS, &ai->flags))
3099 airo_process_scan_results(ai);
3100 else /* Shouldn't get here, but we make sure to unlock */
3101 up(&ai->sem);
2956 } 3102 }
2957 complete_and_exit (&ai->thr_exited, 0); 3103 complete_and_exit (&ai->thr_exited, 0);
2958} 3104}
@@ -3047,19 +3193,15 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs)
3047 * and reassociations as valid status 3193 * and reassociations as valid status
3048 * Jean II */ 3194 * Jean II */
3049 if(newStatus == ASSOCIATED) { 3195 if(newStatus == ASSOCIATED) {
3050 if (apriv->scan_timestamp) { 3196#if 0
3051 /* Send an empty event to user space. 3197 /* FIXME: Grabbing scan results here
3052 * We don't send the received data on 3198 * seems to be too early??? Just wait for
3053 * the event because it would require 3199 * timeout instead. */
3054 * us to do complex transcoding, and 3200 if (apriv->scan_timeout > 0) {
3055 * we want to minimise the work done in 3201 set_bit(JOB_SCAN_RESULTS, &apriv->flags);
3056 * the irq handler. Use a request to 3202 wake_up_interruptible(&apriv->thr_wait);
3057 * extract the data - Jean II */
3058 wrqu.data.length = 0;
3059 wrqu.data.flags = 0;
3060 wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
3061 apriv->scan_timestamp = 0;
3062 } 3203 }
3204#endif
3063 if (down_trylock(&apriv->sem) != 0) { 3205 if (down_trylock(&apriv->sem) != 0) {
3064 set_bit(JOB_EVENT, &apriv->flags); 3206 set_bit(JOB_EVENT, &apriv->flags);
3065 wake_up_interruptible(&apriv->thr_wait); 3207 wake_up_interruptible(&apriv->thr_wait);
@@ -3117,8 +3259,8 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs)
3117 } 3259 }
3118 len = le16_to_cpu(hdr.len); 3260 len = le16_to_cpu(hdr.len);
3119 3261
3120 if (len > 2312) { 3262 if (len > AIRO_DEF_MTU) {
3121 printk( KERN_ERR "airo: Bad size %d\n", len ); 3263 airo_print_err(apriv->dev->name, "Bad size %d", len);
3122 goto badrx; 3264 goto badrx;
3123 } 3265 }
3124 if (len == 0) 3266 if (len == 0)
@@ -3161,10 +3303,12 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs)
3161 bap_read (apriv, &gap, sizeof(gap), BAP0); 3303 bap_read (apriv, &gap, sizeof(gap), BAP0);
3162 gap = le16_to_cpu(gap); 3304 gap = le16_to_cpu(gap);
3163 if (gap) { 3305 if (gap) {
3164 if (gap <= 8) 3306 if (gap <= 8) {
3165 bap_read (apriv, tmpbuf, gap, BAP0); 3307 bap_read (apriv, tmpbuf, gap, BAP0);
3166 else 3308 } else {
3167 printk(KERN_ERR "airo: gaplen too big. Problems will follow...\n"); 3309 airo_print_err(apriv->dev->name, "gaplen too "
3310 "big. Problems will follow...");
3311 }
3168 } 3312 }
3169 bap_read (apriv, buffer + hdrlen/2, len, BAP0); 3313 bap_read (apriv, buffer + hdrlen/2, len, BAP0);
3170 } else { 3314 } else {
@@ -3281,12 +3425,13 @@ exitrx:
3281 } 3425 }
3282 } else { 3426 } else {
3283 OUT4500( apriv, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC)); 3427 OUT4500( apriv, EVACK, status & (EV_TX | EV_TXCPY | EV_TXEXC));
3284 printk( KERN_ERR "airo: Unallocated FID was used to xmit\n" ); 3428 airo_print_err(apriv->dev->name, "Unallocated FID was "
3429 "used to xmit" );
3285 } 3430 }
3286 } 3431 }
3287exittx: 3432exittx:
3288 if ( status & ~STATUS_INTS & ~IGNORE_INTS ) 3433 if ( status & ~STATUS_INTS & ~IGNORE_INTS )
3289 printk( KERN_WARNING "airo: Got weird status %x\n", 3434 airo_print_warn(apriv->dev->name, "Got weird status %x",
3290 status & ~STATUS_INTS & ~IGNORE_INTS ); 3435 status & ~STATUS_INTS & ~IGNORE_INTS );
3291 } 3436 }
3292 3437
@@ -3359,8 +3504,8 @@ static int enable_MAC( struct airo_info *ai, Resp *rsp, int lock ) {
3359 up(&ai->sem); 3504 up(&ai->sem);
3360 3505
3361 if (rc) 3506 if (rc)
3362 printk(KERN_ERR "%s: Cannot enable MAC, err=%d\n", 3507 airo_print_err(ai->dev->name, "%s: Cannot enable MAC, err=%d",
3363 __FUNCTION__,rc); 3508 __FUNCTION__, rc);
3364 return rc; 3509 return rc;
3365} 3510}
3366 3511
@@ -3489,8 +3634,8 @@ void mpi_receive_802_11 (struct airo_info *ai)
3489 if (ai->wifidev == NULL) 3634 if (ai->wifidev == NULL)
3490 hdr.len = 0; 3635 hdr.len = 0;
3491 len = le16_to_cpu(hdr.len); 3636 len = le16_to_cpu(hdr.len);
3492 if (len > 2312) { 3637 if (len > AIRO_DEF_MTU) {
3493 printk( KERN_ERR "airo: Bad size %d\n", len ); 3638 airo_print_err(ai->dev->name, "Bad size %d", len);
3494 goto badrx; 3639 goto badrx;
3495 } 3640 }
3496 if (len == 0) 3641 if (len == 0)
@@ -3531,8 +3676,8 @@ void mpi_receive_802_11 (struct airo_info *ai)
3531 if (gap <= 8) 3676 if (gap <= 8)
3532 ptr += gap; 3677 ptr += gap;
3533 else 3678 else
3534 printk(KERN_ERR 3679 airo_print_err(ai->dev->name,
3535 "airo: gaplen too big. Problems will follow...\n"); 3680 "gaplen too big. Problems will follow...");
3536 } 3681 }
3537 memcpy ((char *)buffer + hdrlen, ptr, len); 3682 memcpy ((char *)buffer + hdrlen, ptr, len);
3538 ptr += len; 3683 ptr += len;
@@ -3604,15 +3749,15 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
3604 if (issuecommand(ai, &cmd, &rsp) != SUCCESS) { 3749 if (issuecommand(ai, &cmd, &rsp) != SUCCESS) {
3605 if (lock) 3750 if (lock)
3606 up(&ai->sem); 3751 up(&ai->sem);
3607 printk(KERN_ERR "airo: Error checking for AUX port\n"); 3752 airo_print_err(ai->dev->name, "Error checking for AUX port");
3608 return ERROR; 3753 return ERROR;
3609 } 3754 }
3610 if (!aux_bap || rsp.status & 0xff00) { 3755 if (!aux_bap || rsp.status & 0xff00) {
3611 ai->bap_read = fast_bap_read; 3756 ai->bap_read = fast_bap_read;
3612 printk(KERN_DEBUG "airo: Doing fast bap_reads\n"); 3757 airo_print_dbg(ai->dev->name, "Doing fast bap_reads");
3613 } else { 3758 } else {
3614 ai->bap_read = aux_bap_read; 3759 ai->bap_read = aux_bap_read;
3615 printk(KERN_DEBUG "airo: Doing AUX bap_reads\n"); 3760 airo_print_dbg(ai->dev->name, "Doing AUX bap_reads");
3616 } 3761 }
3617 } 3762 }
3618 if (lock) 3763 if (lock)
@@ -3643,7 +3788,8 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
3643 if (cap_rid.softCap & 8) 3788 if (cap_rid.softCap & 8)
3644 ai->config.rmode |= RXMODE_NORMALIZED_RSSI; 3789 ai->config.rmode |= RXMODE_NORMALIZED_RSSI;
3645 else 3790 else
3646 printk(KERN_WARNING "airo: unknown received signal level scale\n"); 3791 airo_print_warn(ai->dev->name, "unknown received signal "
3792 "level scale");
3647 } 3793 }
3648 ai->config.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS; 3794 ai->config.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS;
3649 ai->config.authType = AUTH_OPEN; 3795 ai->config.authType = AUTH_OPEN;
@@ -3706,7 +3852,8 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
3706 3852
3707 status = enable_MAC(ai, &rsp, lock); 3853 status = enable_MAC(ai, &rsp, lock);
3708 if ( status != SUCCESS || (rsp.status & 0xFF00) != 0) { 3854 if ( status != SUCCESS || (rsp.status & 0xFF00) != 0) {
3709 printk( KERN_ERR "airo: Bad MAC enable reason = %x, rid = %x, offset = %d\n", rsp.rsp0, rsp.rsp1, rsp.rsp2 ); 3855 airo_print_err(ai->dev->name, "Bad MAC enable reason = %x, rid = %x,"
3856 " offset = %d", rsp.rsp0, rsp.rsp1, rsp.rsp2 );
3710 return ERROR; 3857 return ERROR;
3711 } 3858 }
3712 3859
@@ -3749,8 +3896,8 @@ static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) {
3749 } 3896 }
3750 3897
3751 if ( max_tries == -1 ) { 3898 if ( max_tries == -1 ) {
3752 printk( KERN_ERR 3899 airo_print_err(ai->dev->name,
3753 "airo: Max tries exceeded when issueing command\n" ); 3900 "Max tries exceeded when issueing command");
3754 if (IN4500(ai, COMMAND) & COMMAND_BUSY) 3901 if (IN4500(ai, COMMAND) & COMMAND_BUSY)
3755 OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY); 3902 OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY);
3756 return ERROR; 3903 return ERROR;
@@ -3762,11 +3909,11 @@ static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) {
3762 pRsp->rsp1 = IN4500(ai, RESP1); 3909 pRsp->rsp1 = IN4500(ai, RESP1);
3763 pRsp->rsp2 = IN4500(ai, RESP2); 3910 pRsp->rsp2 = IN4500(ai, RESP2);
3764 if ((pRsp->status & 0xff00)!=0 && pCmd->cmd != CMD_SOFTRESET) { 3911 if ((pRsp->status & 0xff00)!=0 && pCmd->cmd != CMD_SOFTRESET) {
3765 printk (KERN_ERR "airo: cmd= %x\n", pCmd->cmd); 3912 airo_print_err(ai->dev->name, "cmd= %x\n", pCmd->cmd);
3766 printk (KERN_ERR "airo: status= %x\n", pRsp->status); 3913 airo_print_err(ai->dev->name, "status= %x\n", pRsp->status);
3767 printk (KERN_ERR "airo: Rsp0= %x\n", pRsp->rsp0); 3914 airo_print_err(ai->dev->name, "Rsp0= %x\n", pRsp->rsp0);
3768 printk (KERN_ERR "airo: Rsp1= %x\n", pRsp->rsp1); 3915 airo_print_err(ai->dev->name, "Rsp1= %x\n", pRsp->rsp1);
3769 printk (KERN_ERR "airo: Rsp2= %x\n", pRsp->rsp2); 3916 airo_print_err(ai->dev->name, "Rsp2= %x\n", pRsp->rsp2);
3770 } 3917 }
3771 3918
3772 // clear stuck command busy if necessary 3919 // clear stuck command busy if necessary
@@ -3799,15 +3946,15 @@ static int bap_setup(struct airo_info *ai, u16 rid, u16 offset, int whichbap )
3799 } 3946 }
3800 } else if ( status & BAP_ERR ) { 3947 } else if ( status & BAP_ERR ) {
3801 /* invalid rid or offset */ 3948 /* invalid rid or offset */
3802 printk( KERN_ERR "airo: BAP error %x %d\n", 3949 airo_print_err(ai->dev->name, "BAP error %x %d",
3803 status, whichbap ); 3950 status, whichbap );
3804 return ERROR; 3951 return ERROR;
3805 } else if (status & BAP_DONE) { // success 3952 } else if (status & BAP_DONE) { // success
3806 return SUCCESS; 3953 return SUCCESS;
3807 } 3954 }
3808 if ( !(max_tries--) ) { 3955 if ( !(max_tries--) ) {
3809 printk( KERN_ERR 3956 airo_print_err(ai->dev->name,
3810 "airo: BAP setup error too many retries\n" ); 3957 "airo: BAP setup error too many retries\n");
3811 return ERROR; 3958 return ERROR;
3812 } 3959 }
3813 // -- PC4500 missed it, try again 3960 // -- PC4500 missed it, try again
@@ -3962,8 +4109,8 @@ static int PC4500_readrid(struct airo_info *ai, u16 rid, void *pBuf, int len, in
3962 len = min(len, (int)le16_to_cpu(*(u16*)pBuf)) - 2; 4109 len = min(len, (int)le16_to_cpu(*(u16*)pBuf)) - 2;
3963 4110
3964 if ( len <= 2 ) { 4111 if ( len <= 2 ) {
3965 printk( KERN_ERR 4112 airo_print_err(ai->dev->name,
3966 "airo: Rid %x has a length of %d which is too short\n", 4113 "Rid %x has a length of %d which is too short",
3967 (int)rid, (int)len ); 4114 (int)rid, (int)len );
3968 rc = ERROR; 4115 rc = ERROR;
3969 goto done; 4116 goto done;
@@ -3996,8 +4143,8 @@ static int PC4500_writerid(struct airo_info *ai, u16 rid,
3996 Resp rsp; 4143 Resp rsp;
3997 4144
3998 if (test_bit(FLAG_ENABLED, &ai->flags) && (RID_WEP_TEMP != rid)) 4145 if (test_bit(FLAG_ENABLED, &ai->flags) && (RID_WEP_TEMP != rid))
3999 printk(KERN_ERR 4146 airo_print_err(ai->dev->name,
4000 "%s: MAC should be disabled (rid=%04x)\n", 4147 "%s: MAC should be disabled (rid=%04x)",
4001 __FUNCTION__, rid); 4148 __FUNCTION__, rid);
4002 memset(&cmd, 0, sizeof(cmd)); 4149 memset(&cmd, 0, sizeof(cmd));
4003 memset(&rsp, 0, sizeof(rsp)); 4150 memset(&rsp, 0, sizeof(rsp));
@@ -4013,7 +4160,7 @@ static int PC4500_writerid(struct airo_info *ai, u16 rid,
4013 &ai->config_desc.rid_desc, sizeof(Rid)); 4160 &ai->config_desc.rid_desc, sizeof(Rid));
4014 4161
4015 if (len < 4 || len > 2047) { 4162 if (len < 4 || len > 2047) {
4016 printk(KERN_ERR "%s: len=%d\n",__FUNCTION__,len); 4163 airo_print_err(ai->dev->name, "%s: len=%d", __FUNCTION__, len);
4017 rc = -1; 4164 rc = -1;
4018 } else { 4165 } else {
4019 memcpy((char *)ai->config_desc.virtual_host_addr, 4166 memcpy((char *)ai->config_desc.virtual_host_addr,
@@ -4021,10 +4168,10 @@ static int PC4500_writerid(struct airo_info *ai, u16 rid,
4021 4168
4022 rc = issuecommand(ai, &cmd, &rsp); 4169 rc = issuecommand(ai, &cmd, &rsp);
4023 if ((rc & 0xff00) != 0) { 4170 if ((rc & 0xff00) != 0) {
4024 printk(KERN_ERR "%s: Write rid Error %d\n", 4171 airo_print_err(ai->dev->name, "%s: Write rid Error %d",
4025 __FUNCTION__,rc); 4172 __FUNCTION__, rc);
4026 printk(KERN_ERR "%s: Cmd=%04x\n", 4173 airo_print_err(ai->dev->name, "%s: Cmd=%04x",
4027 __FUNCTION__,cmd.cmd); 4174 __FUNCTION__, cmd.cmd);
4028 } 4175 }
4029 4176
4030 if ((rsp.status & 0x7f00)) 4177 if ((rsp.status & 0x7f00))
@@ -4123,7 +4270,7 @@ static int transmit_802_3_packet(struct airo_info *ai, int len, char *pPacket)
4123 len >>= 16; 4270 len >>= 16;
4124 4271
4125 if (len <= ETH_ALEN * 2) { 4272 if (len <= ETH_ALEN * 2) {
4126 printk( KERN_WARNING "Short packet %d\n", len ); 4273 airo_print_warn(ai->dev->name, "Short packet %d", len);
4127 return ERROR; 4274 return ERROR;
4128 } 4275 }
4129 len -= ETH_ALEN * 2; 4276 len -= ETH_ALEN * 2;
@@ -4187,7 +4334,7 @@ static int transmit_802_11_packet(struct airo_info *ai, int len, char *pPacket)
4187 } 4334 }
4188 4335
4189 if (len < hdrlen) { 4336 if (len < hdrlen) {
4190 printk( KERN_WARNING "Short packet %d\n", len ); 4337 airo_print_warn(ai->dev->name, "Short packet %d", len);
4191 return ERROR; 4338 return ERROR;
4192 } 4339 }
4193 4340
@@ -4584,15 +4731,14 @@ static int proc_stats_rid_open( struct inode *inode,
4584 i*4<stats.len; i++){ 4731 i*4<stats.len; i++){
4585 if (!statsLabels[i]) continue; 4732 if (!statsLabels[i]) continue;
4586 if (j+strlen(statsLabels[i])+16>4096) { 4733 if (j+strlen(statsLabels[i])+16>4096) {
4587 printk(KERN_WARNING 4734 airo_print_warn(apriv->dev->name,
4588 "airo: Potentially disasterous buffer overflow averted!\n"); 4735 "Potentially disasterous buffer overflow averted!");
4589 break; 4736 break;
4590 } 4737 }
4591 j+=sprintf(data->rbuffer+j, "%s: %u\n", statsLabels[i], vals[i]); 4738 j+=sprintf(data->rbuffer+j, "%s: %u\n", statsLabels[i], vals[i]);
4592 } 4739 }
4593 if (i*4>=stats.len){ 4740 if (i*4>=stats.len){
4594 printk(KERN_WARNING 4741 airo_print_warn(apriv->dev->name, "Got a short rid");
4595 "airo: Got a short rid\n");
4596 } 4742 }
4597 data->readlen = j; 4743 data->readlen = j;
4598 return 0; 4744 return 0;
@@ -4754,7 +4900,7 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
4754 4900
4755 line += 14; 4901 line += 14;
4756 v = get_dec_u16(line, &i, 4); 4902 v = get_dec_u16(line, &i, 4);
4757 v = (v<0) ? 0 : ((v>2312) ? 2312 : v); 4903 v = (v<0) ? 0 : ((v>AIRO_DEF_MTU) ? AIRO_DEF_MTU : v);
4758 ai->config.rtsThres = (u16)v; 4904 ai->config.rtsThres = (u16)v;
4759 set_bit (FLAG_COMMIT, &ai->flags); 4905 set_bit (FLAG_COMMIT, &ai->flags);
4760 } else if ( !strncmp( line, "TXMSDULifetime: ", 16 ) ) { 4906 } else if ( !strncmp( line, "TXMSDULifetime: ", 16 ) ) {
@@ -4788,7 +4934,7 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
4788 4934
4789 line += 15; 4935 line += 15;
4790 v = get_dec_u16(line, &i, 4); 4936 v = get_dec_u16(line, &i, 4);
4791 v = (v<256) ? 256 : ((v>2312) ? 2312 : v); 4937 v = (v<256) ? 256 : ((v>AIRO_DEF_MTU) ? AIRO_DEF_MTU : v);
4792 v = v & 0xfffe; /* Make sure its even */ 4938 v = v & 0xfffe; /* Make sure its even */
4793 ai->config.fragThresh = (u16)v; 4939 ai->config.fragThresh = (u16)v;
4794 set_bit (FLAG_COMMIT, &ai->flags); 4940 set_bit (FLAG_COMMIT, &ai->flags);
@@ -4798,8 +4944,7 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
4798 case 'd': ai->config.modulation=MOD_DEFAULT; set_bit(FLAG_COMMIT, &ai->flags); break; 4944 case 'd': ai->config.modulation=MOD_DEFAULT; set_bit(FLAG_COMMIT, &ai->flags); break;
4799 case 'c': ai->config.modulation=MOD_CCK; set_bit(FLAG_COMMIT, &ai->flags); break; 4945 case 'c': ai->config.modulation=MOD_CCK; set_bit(FLAG_COMMIT, &ai->flags); break;
4800 case 'm': ai->config.modulation=MOD_MOK; set_bit(FLAG_COMMIT, &ai->flags); break; 4946 case 'm': ai->config.modulation=MOD_MOK; set_bit(FLAG_COMMIT, &ai->flags); break;
4801 default: 4947 default: airo_print_warn(ai->dev->name, "Unknown modulation");
4802 printk( KERN_WARNING "airo: Unknown modulation\n" );
4803 } 4948 }
4804 } else if (!strncmp(line, "Preamble: ", 10)) { 4949 } else if (!strncmp(line, "Preamble: ", 10)) {
4805 line += 10; 4950 line += 10;
@@ -4807,10 +4952,10 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
4807 case 'a': ai->config.preamble=PREAMBLE_AUTO; set_bit(FLAG_COMMIT, &ai->flags); break; 4952 case 'a': ai->config.preamble=PREAMBLE_AUTO; set_bit(FLAG_COMMIT, &ai->flags); break;
4808 case 'l': ai->config.preamble=PREAMBLE_LONG; set_bit(FLAG_COMMIT, &ai->flags); break; 4953 case 'l': ai->config.preamble=PREAMBLE_LONG; set_bit(FLAG_COMMIT, &ai->flags); break;
4809 case 's': ai->config.preamble=PREAMBLE_SHORT; set_bit(FLAG_COMMIT, &ai->flags); break; 4954 case 's': ai->config.preamble=PREAMBLE_SHORT; set_bit(FLAG_COMMIT, &ai->flags); break;
4810 default: printk(KERN_WARNING "airo: Unknown preamble\n"); 4955 default: airo_print_warn(ai->dev->name, "Unknown preamble");
4811 } 4956 }
4812 } else { 4957 } else {
4813 printk( KERN_WARNING "Couldn't figure out %s\n", line ); 4958 airo_print_warn(ai->dev->name, "Couldn't figure out %s", line);
4814 } 4959 }
4815 while( line[0] && line[0] != '\n' ) line++; 4960 while( line[0] && line[0] != '\n' ) line++;
4816 if ( line[0] ) line++; 4961 if ( line[0] ) line++;
@@ -5076,7 +5221,7 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
5076 } 5221 }
5077 j = 2; 5222 j = 2;
5078 } else { 5223 } else {
5079 printk(KERN_ERR "airo: WepKey passed invalid key index\n"); 5224 airo_print_err(ai->dev->name, "WepKey passed invalid key index");
5080 return; 5225 return;
5081 } 5226 }
5082 5227
@@ -5489,17 +5634,16 @@ static int __init airo_init_module( void )
5489 airo_entry->gid = proc_gid; 5634 airo_entry->gid = proc_gid;
5490 5635
5491 for( i = 0; i < 4 && io[i] && irq[i]; i++ ) { 5636 for( i = 0; i < 4 && io[i] && irq[i]; i++ ) {
5492 printk( KERN_INFO 5637 airo_print_info("", "Trying to configure ISA adapter at irq=%d "
5493 "airo: Trying to configure ISA adapter at irq=%d io=0x%x\n", 5638 "io=0x%x", irq[i], io[i] );
5494 irq[i], io[i] );
5495 if (init_airo_card( irq[i], io[i], 0, NULL )) 5639 if (init_airo_card( irq[i], io[i], 0, NULL ))
5496 have_isa_dev = 1; 5640 have_isa_dev = 1;
5497 } 5641 }
5498 5642
5499#ifdef CONFIG_PCI 5643#ifdef CONFIG_PCI
5500 printk( KERN_INFO "airo: Probing for PCI adapters\n" ); 5644 airo_print_info("", "Probing for PCI adapters");
5501 pci_register_driver(&airo_driver); 5645 pci_register_driver(&airo_driver);
5502 printk( KERN_INFO "airo: Finished probing for PCI adapters\n" ); 5646 airo_print_info("", "Finished probing for PCI adapters");
5503#endif 5647#endif
5504 5648
5505 /* Always exit with success, as we are a library module 5649 /* Always exit with success, as we are a library module
@@ -5511,7 +5655,7 @@ static int __init airo_init_module( void )
5511static void __exit airo_cleanup_module( void ) 5655static void __exit airo_cleanup_module( void )
5512{ 5656{
5513 while( airo_devices ) { 5657 while( airo_devices ) {
5514 printk( KERN_INFO "airo: Unregistering %s\n", airo_devices->dev->name ); 5658 airo_print_info(airo_devices->dev->name, "Unregistering...\n");
5515 stop_airo_card( airo_devices->dev, 1 ); 5659 stop_airo_card( airo_devices->dev, 1 );
5516 } 5660 }
5517#ifdef CONFIG_PCI 5661#ifdef CONFIG_PCI
@@ -5622,7 +5766,8 @@ static int airo_set_freq(struct net_device *dev,
5622 /* We should do a better check than that, 5766 /* We should do a better check than that,
5623 * based on the card capability !!! */ 5767 * based on the card capability !!! */
5624 if((channel < 1) || (channel > 14)) { 5768 if((channel < 1) || (channel > 14)) {
5625 printk(KERN_DEBUG "%s: New channel value of %d is invalid!\n", dev->name, fwrq->m); 5769 airo_print_dbg(dev->name, "New channel value of %d is invalid!",
5770 fwrq->m);
5626 rc = -EINVAL; 5771 rc = -EINVAL;
5627 } else { 5772 } else {
5628 readConfigRid(local, 1); 5773 readConfigRid(local, 1);
@@ -5946,8 +6091,8 @@ static int airo_set_rts(struct net_device *dev,
5946 int rthr = vwrq->value; 6091 int rthr = vwrq->value;
5947 6092
5948 if(vwrq->disabled) 6093 if(vwrq->disabled)
5949 rthr = 2312; 6094 rthr = AIRO_DEF_MTU;
5950 if((rthr < 0) || (rthr > 2312)) { 6095 if((rthr < 0) || (rthr > AIRO_DEF_MTU)) {
5951 return -EINVAL; 6096 return -EINVAL;
5952 } 6097 }
5953 readConfigRid(local, 1); 6098 readConfigRid(local, 1);
@@ -5970,7 +6115,7 @@ static int airo_get_rts(struct net_device *dev,
5970 6115
5971 readConfigRid(local, 1); 6116 readConfigRid(local, 1);
5972 vwrq->value = local->config.rtsThres; 6117 vwrq->value = local->config.rtsThres;
5973 vwrq->disabled = (vwrq->value >= 2312); 6118 vwrq->disabled = (vwrq->value >= AIRO_DEF_MTU);
5974 vwrq->fixed = 1; 6119 vwrq->fixed = 1;
5975 6120
5976 return 0; 6121 return 0;
@@ -5989,8 +6134,8 @@ static int airo_set_frag(struct net_device *dev,
5989 int fthr = vwrq->value; 6134 int fthr = vwrq->value;
5990 6135
5991 if(vwrq->disabled) 6136 if(vwrq->disabled)
5992 fthr = 2312; 6137 fthr = AIRO_DEF_MTU;
5993 if((fthr < 256) || (fthr > 2312)) { 6138 if((fthr < 256) || (fthr > AIRO_DEF_MTU)) {
5994 return -EINVAL; 6139 return -EINVAL;
5995 } 6140 }
5996 fthr &= ~0x1; /* Get an even value - is it really needed ??? */ 6141 fthr &= ~0x1; /* Get an even value - is it really needed ??? */
@@ -6014,7 +6159,7 @@ static int airo_get_frag(struct net_device *dev,
6014 6159
6015 readConfigRid(local, 1); 6160 readConfigRid(local, 1);
6016 vwrq->value = local->config.fragThresh; 6161 vwrq->value = local->config.fragThresh;
6017 vwrq->disabled = (vwrq->value >= 2312); 6162 vwrq->disabled = (vwrq->value >= AIRO_DEF_MTU);
6018 vwrq->fixed = 1; 6163 vwrq->fixed = 1;
6019 6164
6020 return 0; 6165 return 0;
@@ -6709,9 +6854,9 @@ static int airo_get_range(struct net_device *dev,
6709 range->throughput = 1500 * 1000; 6854 range->throughput = 1500 * 1000;
6710 6855
6711 range->min_rts = 0; 6856 range->min_rts = 0;
6712 range->max_rts = 2312; 6857 range->max_rts = AIRO_DEF_MTU;
6713 range->min_frag = 256; 6858 range->min_frag = 256;
6714 range->max_frag = 2312; 6859 range->max_frag = AIRO_DEF_MTU;
6715 6860
6716 if(cap_rid.softCap & 2) { 6861 if(cap_rid.softCap & 2) {
6717 // WEP: RC4 40 bits 6862 // WEP: RC4 40 bits
@@ -6972,6 +7117,7 @@ static int airo_set_scan(struct net_device *dev,
6972 struct airo_info *ai = dev->priv; 7117 struct airo_info *ai = dev->priv;
6973 Cmd cmd; 7118 Cmd cmd;
6974 Resp rsp; 7119 Resp rsp;
7120 int wake = 0;
6975 7121
6976 /* Note : you may have realised that, as this is a SET operation, 7122 /* Note : you may have realised that, as this is a SET operation,
6977 * this is privileged and therefore a normal user can't 7123 * this is privileged and therefore a normal user can't
@@ -6981,17 +7127,25 @@ static int airo_set_scan(struct net_device *dev,
6981 * Jean II */ 7127 * Jean II */
6982 if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN; 7128 if (ai->flags & FLAG_RADIO_MASK) return -ENETDOWN;
6983 7129
7130 if (down_interruptible(&ai->sem))
7131 return -ERESTARTSYS;
7132
7133 /* If there's already a scan in progress, don't
7134 * trigger another one. */
7135 if (ai->scan_timeout > 0)
7136 goto out;
7137
6984 /* Initiate a scan command */ 7138 /* Initiate a scan command */
6985 memset(&cmd, 0, sizeof(cmd)); 7139 memset(&cmd, 0, sizeof(cmd));
6986 cmd.cmd=CMD_LISTBSS; 7140 cmd.cmd=CMD_LISTBSS;
6987 if (down_interruptible(&ai->sem))
6988 return -ERESTARTSYS;
6989 issuecommand(ai, &cmd, &rsp); 7141 issuecommand(ai, &cmd, &rsp);
6990 ai->scan_timestamp = jiffies; 7142 ai->scan_timeout = RUN_AT(3*HZ);
6991 up(&ai->sem); 7143 wake = 1;
6992
6993 /* At this point, just return to the user. */
6994 7144
7145out:
7146 up(&ai->sem);
7147 if (wake)
7148 wake_up_interruptible(&ai->thr_wait);
6995 return 0; 7149 return 0;
6996} 7150}
6997 7151
@@ -7111,59 +7265,38 @@ static int airo_get_scan(struct net_device *dev,
7111 char *extra) 7265 char *extra)
7112{ 7266{
7113 struct airo_info *ai = dev->priv; 7267 struct airo_info *ai = dev->priv;
7114 BSSListRid BSSList; 7268 BSSListElement *net;
7115 int rc; 7269 int err = 0;
7116 char *current_ev = extra; 7270 char *current_ev = extra;
7117 7271
7118 /* When we are associated again, the scan has surely finished. 7272 /* If a scan is in-progress, return -EAGAIN */
7119 * Just in case, let's make sure enough time has elapsed since 7273 if (ai->scan_timeout > 0)
7120 * we started the scan. - Javier */
7121 if(ai->scan_timestamp && time_before(jiffies,ai->scan_timestamp+3*HZ)) {
7122 /* Important note : we don't want to block the caller
7123 * until results are ready for various reasons.
7124 * First, managing wait queues is complex and racy
7125 * (there may be multiple simultaneous callers).
7126 * Second, we grab some rtnetlink lock before comming
7127 * here (in dev_ioctl()).
7128 * Third, the caller can wait on the Wireless Event
7129 * - Jean II */
7130 return -EAGAIN; 7274 return -EAGAIN;
7131 }
7132 ai->scan_timestamp = 0;
7133 7275
7134 /* There's only a race with proc_BSSList_open(), but its 7276 if (down_interruptible(&ai->sem))
7135 * consequences are begnign. So I don't bother fixing it - Javier */ 7277 return -EAGAIN;
7136
7137 /* Try to read the first entry of the scan result */
7138 rc = PC4500_readrid(ai, RID_BSSLISTFIRST, &BSSList, sizeof(BSSList), 1);
7139 if((rc) || (BSSList.index == 0xffff)) {
7140 /* Client error, no scan results...
7141 * The caller need to restart the scan. */
7142 return -ENODATA;
7143 }
7144 7278
7145 /* Read and parse all entries */ 7279 list_for_each_entry (net, &ai->network_list, list) {
7146 while((!rc) && (BSSList.index != 0xffff)) {
7147 /* Translate to WE format this entry */ 7280 /* Translate to WE format this entry */
7148 current_ev = airo_translate_scan(dev, current_ev, 7281 current_ev = airo_translate_scan(dev, current_ev,
7149 extra + dwrq->length, 7282 extra + dwrq->length,
7150 &BSSList); 7283 &net->bss);
7151 7284
7152 /* Check if there is space for one more entry */ 7285 /* Check if there is space for one more entry */
7153 if((extra + dwrq->length - current_ev) <= IW_EV_ADDR_LEN) { 7286 if((extra + dwrq->length - current_ev) <= IW_EV_ADDR_LEN) {
7154 /* Ask user space to try again with a bigger buffer */ 7287 /* Ask user space to try again with a bigger buffer */
7155 return -E2BIG; 7288 err = -E2BIG;
7289 goto out;
7156 } 7290 }
7157
7158 /* Read next entry */
7159 rc = PC4500_readrid(ai, RID_BSSLISTNEXT,
7160 &BSSList, sizeof(BSSList), 1);
7161 } 7291 }
7292
7162 /* Length of data */ 7293 /* Length of data */
7163 dwrq->length = (current_ev - extra); 7294 dwrq->length = (current_ev - extra);
7164 dwrq->flags = 0; /* todo */ 7295 dwrq->flags = 0; /* todo */
7165 7296
7166 return 0; 7297out:
7298 up(&ai->sem);
7299 return err;
7167} 7300}
7168 7301
7169/*------------------------------------------------------------------*/ 7302/*------------------------------------------------------------------*/
@@ -7711,7 +7844,7 @@ static int cmdreset(struct airo_info *ai) {
7711 disable_MAC(ai, 1); 7844 disable_MAC(ai, 1);
7712 7845
7713 if(!waitbusy (ai)){ 7846 if(!waitbusy (ai)){
7714 printk(KERN_INFO "Waitbusy hang before RESET\n"); 7847 airo_print_info(ai->dev->name, "Waitbusy hang before RESET");
7715 return -EBUSY; 7848 return -EBUSY;
7716 } 7849 }
7717 7850
@@ -7720,7 +7853,7 @@ static int cmdreset(struct airo_info *ai) {
7720 ssleep(1); /* WAS 600 12/7/00 */ 7853 ssleep(1); /* WAS 600 12/7/00 */
7721 7854
7722 if(!waitbusy (ai)){ 7855 if(!waitbusy (ai)){
7723 printk(KERN_INFO "Waitbusy hang AFTER RESET\n"); 7856 airo_print_info(ai->dev->name, "Waitbusy hang AFTER RESET");
7724 return -EBUSY; 7857 return -EBUSY;
7725 } 7858 }
7726 return 0; 7859 return 0;
@@ -7748,7 +7881,7 @@ static int setflashmode (struct airo_info *ai) {
7748 7881
7749 if(!waitbusy(ai)) { 7882 if(!waitbusy(ai)) {
7750 clear_bit (FLAG_FLASHING, &ai->flags); 7883 clear_bit (FLAG_FLASHING, &ai->flags);
7751 printk(KERN_INFO "Waitbusy hang after setflash mode\n"); 7884 airo_print_info(ai->dev->name, "Waitbusy hang after setflash mode");
7752 return -EIO; 7885 return -EIO;
7753 } 7886 }
7754 return 0; 7887 return 0;
@@ -7777,7 +7910,7 @@ static int flashpchar(struct airo_info *ai,int byte,int dwelltime) {
7777 7910
7778 /* timeout for busy clear wait */ 7911 /* timeout for busy clear wait */
7779 if(waittime <= 0 ){ 7912 if(waittime <= 0 ){
7780 printk(KERN_INFO "flash putchar busywait timeout! \n"); 7913 airo_print_info(ai->dev->name, "flash putchar busywait timeout!");
7781 return -EBUSY; 7914 return -EBUSY;
7782 } 7915 }
7783 7916
@@ -7866,7 +7999,7 @@ static int flashrestart(struct airo_info *ai,struct net_device *dev){
7866 if (!test_bit(FLAG_MPI,&ai->flags)) 7999 if (!test_bit(FLAG_MPI,&ai->flags))
7867 for( i = 0; i < MAX_FIDS; i++ ) { 8000 for( i = 0; i < MAX_FIDS; i++ ) {
7868 ai->fids[i] = transmit_allocate 8001 ai->fids[i] = transmit_allocate
7869 ( ai, 2312, i >= MAX_FIDS / 2 ); 8002 ( ai, AIRO_DEF_MTU, i >= MAX_FIDS / 2 );
7870 } 8003 }
7871 8004
7872 ssleep(1); /* Added 12/7/00 */ 8005 ssleep(1); /* Added 12/7/00 */
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index 753a1de6664b..06c3fa32b310 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -3141,7 +3141,7 @@ int hostap_add_sta(struct ap_data *ap, u8 *sta_addr)
3141 if (ret == 1) { 3141 if (ret == 1) {
3142 sta = ap_add_sta(ap, sta_addr); 3142 sta = ap_add_sta(ap, sta_addr);
3143 if (!sta) 3143 if (!sta)
3144 ret = -1; 3144 return -1;
3145 sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC; 3145 sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC;
3146 sta->ap = 1; 3146 sta->ap = 1;
3147 memset(sta->supported_rates, 0, sizeof(sta->supported_rates)); 3147 memset(sta->supported_rates, 0, sizeof(sta->supported_rates));
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index f8f4503475f9..d335b250923a 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -585,8 +585,6 @@ static int prism2_config(dev_link_t *link)
585 parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL); 585 parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL);
586 hw_priv = kmalloc(sizeof(*hw_priv), GFP_KERNEL); 586 hw_priv = kmalloc(sizeof(*hw_priv), GFP_KERNEL);
587 if (parse == NULL || hw_priv == NULL) { 587 if (parse == NULL || hw_priv == NULL) {
588 kfree(parse);
589 kfree(hw_priv);
590 ret = -ENOMEM; 588 ret = -ENOMEM;
591 goto failed; 589 goto failed;
592 } 590 }
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index b1f142d9e232..328e9a1d13b5 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -928,15 +928,15 @@ static int hfa384x_set_rid(struct net_device *dev, u16 rid, void *buf, int len)
928 928
929 res = hfa384x_cmd(dev, HFA384X_CMDCODE_ACCESS_WRITE, rid, NULL, NULL); 929 res = hfa384x_cmd(dev, HFA384X_CMDCODE_ACCESS_WRITE, rid, NULL, NULL);
930 up(&local->rid_bap_sem); 930 up(&local->rid_bap_sem);
931
931 if (res) { 932 if (res) {
932 printk(KERN_DEBUG "%s: hfa384x_set_rid: CMDCODE_ACCESS_WRITE " 933 printk(KERN_DEBUG "%s: hfa384x_set_rid: CMDCODE_ACCESS_WRITE "
933 "failed (res=%d, rid=%04x, len=%d)\n", 934 "failed (res=%d, rid=%04x, len=%d)\n",
934 dev->name, res, rid, len); 935 dev->name, res, rid, len);
935 return res;
936 }
937 936
938 if (res == -ETIMEDOUT) 937 if (res == -ETIMEDOUT)
939 prism2_hw_reset(dev); 938 prism2_hw_reset(dev);
939 }
940 940
941 return res; 941 return res;
942} 942}
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index f3e0ce1ee037..8b37e824dfcb 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -3358,10 +3358,6 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
3358 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { 3358 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
3359 if (!sta_ptr) 3359 if (!sta_ptr)
3360 local->tx_keyidx = i; 3360 local->tx_keyidx = i;
3361 else if (i) {
3362 ret = -EINVAL;
3363 goto done;
3364 }
3365 } 3361 }
3366 3362
3367 3363
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
index 2e85bdced2dd..194f07097581 100644
--- a/drivers/net/wireless/hostap/hostap_pci.c
+++ b/drivers/net/wireless/hostap/hostap_pci.c
@@ -307,7 +307,7 @@ static int prism2_pci_probe(struct pci_dev *pdev,
307 memset(hw_priv, 0, sizeof(*hw_priv)); 307 memset(hw_priv, 0, sizeof(*hw_priv));
308 308
309 if (pci_enable_device(pdev)) 309 if (pci_enable_device(pdev))
310 return -EIO; 310 goto err_out_free;
311 311
312 phymem = pci_resource_start(pdev, 0); 312 phymem = pci_resource_start(pdev, 0);
313 313
@@ -368,6 +368,8 @@ static int prism2_pci_probe(struct pci_dev *pdev,
368 err_out_disable: 368 err_out_disable:
369 pci_disable_device(pdev); 369 pci_disable_device(pdev);
370 prism2_free_local_data(dev); 370 prism2_free_local_data(dev);
371
372 err_out_free:
371 kfree(hw_priv); 373 kfree(hw_priv);
372 374
373 return -ENODEV; 375 return -ENODEV;
diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
index 94fe2449f099..edaaa943eb8f 100644
--- a/drivers/net/wireless/hostap/hostap_plx.c
+++ b/drivers/net/wireless/hostap/hostap_plx.c
@@ -368,7 +368,7 @@ static int prism2_plx_check_cis(void __iomem *attr_mem, int attr_len,
368 368
369 switch (cis[pos]) { 369 switch (cis[pos]) {
370 case CISTPL_CONFIG: 370 case CISTPL_CONFIG:
371 if (cis[pos + 1] < 1) 371 if (cis[pos + 1] < 2)
372 goto cis_error; 372 goto cis_error;
373 rmsz = (cis[pos + 2] & 0x3c) >> 2; 373 rmsz = (cis[pos + 2] & 0x3c) >> 2;
374 rasz = cis[pos + 2] & 0x03; 374 rasz = cis[pos + 2] & 0x03;
@@ -390,7 +390,7 @@ static int prism2_plx_check_cis(void __iomem *attr_mem, int attr_len,
390 break; 390 break;
391 391
392 case CISTPL_MANFID: 392 case CISTPL_MANFID:
393 if (cis[pos + 1] < 4) 393 if (cis[pos + 1] < 5)
394 goto cis_error; 394 goto cis_error;
395 manfid1 = cis[pos + 2] + (cis[pos + 3] << 8); 395 manfid1 = cis[pos + 2] + (cis[pos + 3] << 8);
396 manfid2 = cis[pos + 4] + (cis[pos + 5] << 8); 396 manfid2 = cis[pos + 4] + (cis[pos + 5] << 8);
@@ -452,7 +452,7 @@ static int prism2_plx_probe(struct pci_dev *pdev,
452 memset(hw_priv, 0, sizeof(*hw_priv)); 452 memset(hw_priv, 0, sizeof(*hw_priv));
453 453
454 if (pci_enable_device(pdev)) 454 if (pci_enable_device(pdev))
455 return -EIO; 455 goto err_out_free;
456 456
457 /* National Datacomm NCP130 based on TMD7160, not PLX9052. */ 457 /* National Datacomm NCP130 based on TMD7160, not PLX9052. */
458 tmd7160 = (pdev->vendor == 0x15e8) && (pdev->device == 0x0131); 458 tmd7160 = (pdev->vendor == 0x15e8) && (pdev->device == 0x0131);
@@ -567,9 +567,6 @@ static int prism2_plx_probe(struct pci_dev *pdev,
567 return hostap_hw_ready(dev); 567 return hostap_hw_ready(dev);
568 568
569 fail: 569 fail:
570 prism2_free_local_data(dev);
571 kfree(hw_priv);
572
573 if (irq_registered && dev) 570 if (irq_registered && dev)
574 free_irq(dev->irq, dev); 571 free_irq(dev->irq, dev);
575 572
@@ -577,6 +574,10 @@ static int prism2_plx_probe(struct pci_dev *pdev,
577 iounmap(attr_mem); 574 iounmap(attr_mem);
578 575
579 pci_disable_device(pdev); 576 pci_disable_device(pdev);
577 prism2_free_local_data(dev);
578
579 err_out_free:
580 kfree(hw_priv);
580 581
581 return -ENODEV; 582 return -ENODEV;
582} 583}
diff --git a/include/linux/wireless.h b/include/linux/wireless.h
index a555a0f7a7b4..13588564b42b 100644
--- a/include/linux/wireless.h
+++ b/include/linux/wireless.h
@@ -1,10 +1,10 @@
1/* 1/*
2 * This file define a set of standard wireless extensions 2 * This file define a set of standard wireless extensions
3 * 3 *
4 * Version : 19 18.3.05 4 * Version : 20 17.2.06
5 * 5 *
6 * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> 6 * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
7 * Copyright (c) 1997-2005 Jean Tourrilhes, All Rights Reserved. 7 * Copyright (c) 1997-2006 Jean Tourrilhes, All Rights Reserved.
8 */ 8 */
9 9
10#ifndef _LINUX_WIRELESS_H 10#ifndef _LINUX_WIRELESS_H
@@ -80,7 +80,7 @@
80 * (there is some stuff that will be added in the future...) 80 * (there is some stuff that will be added in the future...)
81 * I just plan to increment with each new version. 81 * I just plan to increment with each new version.
82 */ 82 */
83#define WIRELESS_EXT 19 83#define WIRELESS_EXT 20
84 84
85/* 85/*
86 * Changes : 86 * Changes :
@@ -204,6 +204,10 @@
204 * - Add IW_QUAL_ALL_UPDATED and IW_QUAL_ALL_INVALID macros 204 * - Add IW_QUAL_ALL_UPDATED and IW_QUAL_ALL_INVALID macros
205 * - Add explicit flag to tell stats are in dBm : IW_QUAL_DBM 205 * - Add explicit flag to tell stats are in dBm : IW_QUAL_DBM
206 * - Add IW_IOCTL_IDX() and IW_EVENT_IDX() macros 206 * - Add IW_IOCTL_IDX() and IW_EVENT_IDX() macros
207 *
208 * V19 to V20
209 * ----------
210 * - RtNetlink requests support (SET/GET)
207 */ 211 */
208 212
209/**************************** CONSTANTS ****************************/ 213/**************************** CONSTANTS ****************************/
diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h
index a2c5e0b88422..10559e937d27 100644
--- a/include/net/iw_handler.h
+++ b/include/net/iw_handler.h
@@ -4,7 +4,7 @@
4 * Version : 7 18.3.05 4 * Version : 7 18.3.05
5 * 5 *
6 * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> 6 * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
7 * Copyright (c) 2001-2005 Jean Tourrilhes, All Rights Reserved. 7 * Copyright (c) 2001-2006 Jean Tourrilhes, All Rights Reserved.
8 */ 8 */
9 9
10#ifndef _IW_HANDLER_H 10#ifndef _IW_HANDLER_H
@@ -436,6 +436,16 @@ extern int dev_get_wireless_info(char * buffer, char **start, off_t offset,
436/* Handle IOCTLs, called in net/core/dev.c */ 436/* Handle IOCTLs, called in net/core/dev.c */
437extern int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd); 437extern int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd);
438 438
439/* Handle RtNetlink requests, called in net/core/rtnetlink.c */
440extern int wireless_rtnetlink_set(struct net_device * dev,
441 char * data,
442 int len);
443extern int wireless_rtnetlink_get(struct net_device * dev,
444 char * data,
445 int len,
446 char ** p_buf,
447 int * p_len);
448
439/* Second : functions that may be called by driver modules */ 449/* Second : functions that may be called by driver modules */
440 450
441/* Send a single event to user space */ 451/* Send a single event to user space */
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index ae10d3740faa..3fcfa9c59e1f 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -51,6 +51,10 @@
51#include <net/sock.h> 51#include <net/sock.h>
52#include <net/pkt_sched.h> 52#include <net/pkt_sched.h>
53#include <net/netlink.h> 53#include <net/netlink.h>
54#ifdef CONFIG_NET_WIRELESS_RTNETLINK
55#include <linux/wireless.h>
56#include <net/iw_handler.h>
57#endif /* CONFIG_NET_WIRELESS_RTNETLINK */
54 58
55static DEFINE_MUTEX(rtnl_mutex); 59static DEFINE_MUTEX(rtnl_mutex);
56 60
@@ -467,6 +471,17 @@ static int do_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
467 goto out; 471 goto out;
468 } 472 }
469 473
474#ifdef CONFIG_NET_WIRELESS_RTNETLINK
475 if (ida[IFLA_WIRELESS - 1]) {
476
477 /* Call Wireless Extensions.
478 * Various stuff checked in there... */
479 err = wireless_rtnetlink_set(dev, RTA_DATA(ida[IFLA_WIRELESS - 1]), ida[IFLA_WIRELESS - 1]->rta_len);
480 if (err)
481 goto out;
482 }
483#endif /* CONFIG_NET_WIRELESS_RTNETLINK */
484
470 err = 0; 485 err = 0;
471 486
472out: 487out:
@@ -477,6 +492,83 @@ out:
477 return err; 492 return err;
478} 493}
479 494
495#ifdef CONFIG_NET_WIRELESS_RTNETLINK
496static int do_getlink(struct sk_buff *in_skb, struct nlmsghdr* in_nlh, void *arg)
497{
498 struct ifinfomsg *ifm = NLMSG_DATA(in_nlh);
499 struct rtattr **ida = arg;
500 struct net_device *dev;
501 struct ifinfomsg *r;
502 struct nlmsghdr *nlh;
503 int err = -ENOBUFS;
504 struct sk_buff *skb;
505 unsigned char *b;
506 char *iw_buf = NULL;
507 int iw_buf_len = 0;
508
509 if (ifm->ifi_index >= 0)
510 dev = dev_get_by_index(ifm->ifi_index);
511 else
512 return -EINVAL;
513 if (!dev)
514 return -ENODEV;
515
516#ifdef CONFIG_NET_WIRELESS_RTNETLINK
517 if (ida[IFLA_WIRELESS - 1]) {
518
519 /* Call Wireless Extensions. We need to know the size before
520 * we can alloc. Various stuff checked in there... */
521 err = wireless_rtnetlink_get(dev, RTA_DATA(ida[IFLA_WIRELESS - 1]), ida[IFLA_WIRELESS - 1]->rta_len, &iw_buf, &iw_buf_len);
522 if (err)
523 goto out;
524 }
525#endif /* CONFIG_NET_WIRELESS_RTNETLINK */
526
527 /* Create a skb big enough to include all the data.
528 * Some requests are way bigger than 4k... Jean II */
529 skb = alloc_skb((NLMSG_LENGTH(sizeof(*r))) + (RTA_SPACE(iw_buf_len)),
530 GFP_KERNEL);
531 if (!skb)
532 goto out;
533 b = skb->tail;
534
535 /* Put in the message the usual good stuff */
536 nlh = NLMSG_PUT(skb, NETLINK_CB(in_skb).pid, in_nlh->nlmsg_seq,
537 RTM_NEWLINK, sizeof(*r));
538 r = NLMSG_DATA(nlh);
539 r->ifi_family = AF_UNSPEC;
540 r->__ifi_pad = 0;
541 r->ifi_type = dev->type;
542 r->ifi_index = dev->ifindex;
543 r->ifi_flags = dev->flags;
544 r->ifi_change = 0;
545
546 /* Put the wireless payload if it exist */
547 if(iw_buf != NULL)
548 RTA_PUT(skb, IFLA_WIRELESS, iw_buf_len,
549 iw_buf + IW_EV_POINT_OFF);
550
551 nlh->nlmsg_len = skb->tail - b;
552
553 /* Needed ? */
554 NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid;
555
556 err = netlink_unicast(rtnl, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT);
557 if (err > 0)
558 err = 0;
559out:
560 if(iw_buf != NULL)
561 kfree(iw_buf);
562 dev_put(dev);
563 return err;
564
565rtattr_failure:
566nlmsg_failure:
567 kfree_skb(skb);
568 goto out;
569}
570#endif /* CONFIG_NET_WIRELESS_RTNETLINK */
571
480static int rtnetlink_dump_all(struct sk_buff *skb, struct netlink_callback *cb) 572static int rtnetlink_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
481{ 573{
482 int idx; 574 int idx;
@@ -642,7 +734,11 @@ static void rtnetlink_rcv(struct sock *sk, int len)
642 734
643static struct rtnetlink_link link_rtnetlink_table[RTM_NR_MSGTYPES] = 735static struct rtnetlink_link link_rtnetlink_table[RTM_NR_MSGTYPES] =
644{ 736{
645 [RTM_GETLINK - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo }, 737 [RTM_GETLINK - RTM_BASE] = {
738#ifdef CONFIG_NET_WIRELESS_RTNETLINK
739 .doit = do_getlink,
740#endif /* CONFIG_NET_WIRELESS_RTNETLINK */
741 .dumpit = rtnetlink_dump_ifinfo },
646 [RTM_SETLINK - RTM_BASE] = { .doit = do_setlink }, 742 [RTM_SETLINK - RTM_BASE] = { .doit = do_setlink },
647 [RTM_GETADDR - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, 743 [RTM_GETADDR - RTM_BASE] = { .dumpit = rtnetlink_dump_all },
648 [RTM_GETROUTE - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, 744 [RTM_GETROUTE - RTM_BASE] = { .dumpit = rtnetlink_dump_all },
diff --git a/net/core/wireless.c b/net/core/wireless.c
index 2add7ed609e9..81d6995fcfdb 100644
--- a/net/core/wireless.c
+++ b/net/core/wireless.c
@@ -2,7 +2,7 @@
2 * This file implement the Wireless Extensions APIs. 2 * This file implement the Wireless Extensions APIs.
3 * 3 *
4 * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> 4 * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
5 * Copyright (c) 1997-2005 Jean Tourrilhes, All Rights Reserved. 5 * Copyright (c) 1997-2006 Jean Tourrilhes, All Rights Reserved.
6 * 6 *
7 * (As all part of the Linux kernel, this file is GPL) 7 * (As all part of the Linux kernel, this file is GPL)
8 */ 8 */
@@ -65,6 +65,9 @@
65 * o Start deprecating dev->get_wireless_stats, output a warning 65 * o Start deprecating dev->get_wireless_stats, output a warning
66 * o If IW_QUAL_DBM is set, show dBm values in /proc/net/wireless 66 * o If IW_QUAL_DBM is set, show dBm values in /proc/net/wireless
67 * o Don't loose INVALID/DBM flags when clearing UPDATED flags (iwstats) 67 * o Don't loose INVALID/DBM flags when clearing UPDATED flags (iwstats)
68 *
69 * v8 - 17.02.06 - Jean II
70 * o RtNetlink requests support (SET/GET)
68 */ 71 */
69 72
70/***************************** INCLUDES *****************************/ 73/***************************** INCLUDES *****************************/
@@ -89,11 +92,13 @@
89 92
90/* Debugging stuff */ 93/* Debugging stuff */
91#undef WE_IOCTL_DEBUG /* Debug IOCTL API */ 94#undef WE_IOCTL_DEBUG /* Debug IOCTL API */
95#undef WE_RTNETLINK_DEBUG /* Debug RtNetlink API */
92#undef WE_EVENT_DEBUG /* Debug Event dispatcher */ 96#undef WE_EVENT_DEBUG /* Debug Event dispatcher */
93#undef WE_SPY_DEBUG /* Debug enhanced spy support */ 97#undef WE_SPY_DEBUG /* Debug enhanced spy support */
94 98
95/* Options */ 99/* Options */
96#define WE_EVENT_NETLINK /* Propagate events using rtnetlink */ 100//CONFIG_NET_WIRELESS_RTNETLINK /* Wireless requests over RtNetlink */
101#define WE_EVENT_RTNETLINK /* Propagate events using RtNetlink */
97#define WE_SET_EVENT /* Generate an event on some set commands */ 102#define WE_SET_EVENT /* Generate an event on some set commands */
98 103
99/************************* GLOBAL VARIABLES *************************/ 104/************************* GLOBAL VARIABLES *************************/
@@ -156,13 +161,18 @@ static const struct iw_ioctl_description standard_ioctl[] = {
156 .header_type = IW_HEADER_TYPE_NULL, 161 .header_type = IW_HEADER_TYPE_NULL,
157 }, 162 },
158 [SIOCGIWPRIV - SIOCIWFIRST] = { /* (handled directly by us) */ 163 [SIOCGIWPRIV - SIOCIWFIRST] = { /* (handled directly by us) */
159 .header_type = IW_HEADER_TYPE_NULL, 164 .header_type = IW_HEADER_TYPE_POINT,
165 .token_size = sizeof(struct iw_priv_args),
166 .max_tokens = 16,
167 .flags = IW_DESCR_FLAG_NOMAX,
160 }, 168 },
161 [SIOCSIWSTATS - SIOCIWFIRST] = { 169 [SIOCSIWSTATS - SIOCIWFIRST] = {
162 .header_type = IW_HEADER_TYPE_NULL, 170 .header_type = IW_HEADER_TYPE_NULL,
163 }, 171 },
164 [SIOCGIWSTATS - SIOCIWFIRST] = { /* (handled directly by us) */ 172 [SIOCGIWSTATS - SIOCIWFIRST] = { /* (handled directly by us) */
165 .header_type = IW_HEADER_TYPE_NULL, 173 .header_type = IW_HEADER_TYPE_POINT,
174 .token_size = 1,
175 .max_tokens = sizeof(struct iw_statistics),
166 .flags = IW_DESCR_FLAG_DUMP, 176 .flags = IW_DESCR_FLAG_DUMP,
167 }, 177 },
168 [SIOCSIWSPY - SIOCIWFIRST] = { 178 [SIOCSIWSPY - SIOCIWFIRST] = {
@@ -529,6 +539,70 @@ static inline int adjust_priv_size(__u16 args,
529 return num * iw_priv_type_size[type]; 539 return num * iw_priv_type_size[type];
530} 540}
531 541
542/* ---------------------------------------------------------------- */
543/*
544 * Standard Wireless Handler : get wireless stats
545 * Allow programatic access to /proc/net/wireless even if /proc
546 * doesn't exist... Also more efficient...
547 */
548static int iw_handler_get_iwstats(struct net_device * dev,
549 struct iw_request_info * info,
550 union iwreq_data * wrqu,
551 char * extra)
552{
553 /* Get stats from the driver */
554 struct iw_statistics *stats;
555
556 stats = get_wireless_stats(dev);
557 if (stats != (struct iw_statistics *) NULL) {
558
559 /* Copy statistics to extra */
560 memcpy(extra, stats, sizeof(struct iw_statistics));
561 wrqu->data.length = sizeof(struct iw_statistics);
562
563 /* Check if we need to clear the updated flag */
564 if(wrqu->data.flags != 0)
565 stats->qual.updated &= ~IW_QUAL_ALL_UPDATED;
566 return 0;
567 } else
568 return -EOPNOTSUPP;
569}
570
571/* ---------------------------------------------------------------- */
572/*
573 * Standard Wireless Handler : get iwpriv definitions
574 * Export the driver private handler definition
575 * They will be picked up by tools like iwpriv...
576 */
577static int iw_handler_get_private(struct net_device * dev,
578 struct iw_request_info * info,
579 union iwreq_data * wrqu,
580 char * extra)
581{
582 /* Check if the driver has something to export */
583 if((dev->wireless_handlers->num_private_args == 0) ||
584 (dev->wireless_handlers->private_args == NULL))
585 return -EOPNOTSUPP;
586
587 /* Check if there is enough buffer up there */
588 if(wrqu->data.length < dev->wireless_handlers->num_private_args) {
589 /* User space can't know in advance how large the buffer
590 * needs to be. Give it a hint, so that we can support
591 * any size buffer we want somewhat efficiently... */
592 wrqu->data.length = dev->wireless_handlers->num_private_args;
593 return -E2BIG;
594 }
595
596 /* Set the number of available ioctls. */
597 wrqu->data.length = dev->wireless_handlers->num_private_args;
598
599 /* Copy structure to the user buffer. */
600 memcpy(extra, dev->wireless_handlers->private_args,
601 sizeof(struct iw_priv_args) * wrqu->data.length);
602
603 return 0;
604}
605
532 606
533/******************** /proc/net/wireless SUPPORT ********************/ 607/******************** /proc/net/wireless SUPPORT ********************/
534/* 608/*
@@ -630,81 +704,14 @@ int __init wireless_proc_init(void)
630 704
631/* ---------------------------------------------------------------- */ 705/* ---------------------------------------------------------------- */
632/* 706/*
633 * Allow programatic access to /proc/net/wireless even if /proc
634 * doesn't exist... Also more efficient...
635 */
636static inline int dev_iwstats(struct net_device *dev, struct ifreq *ifr)
637{
638 /* Get stats from the driver */
639 struct iw_statistics *stats;
640
641 stats = get_wireless_stats(dev);
642 if (stats != (struct iw_statistics *) NULL) {
643 struct iwreq * wrq = (struct iwreq *)ifr;
644
645 /* Copy statistics to the user buffer */
646 if(copy_to_user(wrq->u.data.pointer, stats,
647 sizeof(struct iw_statistics)))
648 return -EFAULT;
649
650 /* Check if we need to clear the updated flag */
651 if(wrq->u.data.flags != 0)
652 stats->qual.updated &= ~IW_QUAL_ALL_UPDATED;
653 return 0;
654 } else
655 return -EOPNOTSUPP;
656}
657
658/* ---------------------------------------------------------------- */
659/*
660 * Export the driver private handler definition
661 * They will be picked up by tools like iwpriv...
662 */
663static inline int ioctl_export_private(struct net_device * dev,
664 struct ifreq * ifr)
665{
666 struct iwreq * iwr = (struct iwreq *) ifr;
667
668 /* Check if the driver has something to export */
669 if((dev->wireless_handlers->num_private_args == 0) ||
670 (dev->wireless_handlers->private_args == NULL))
671 return -EOPNOTSUPP;
672
673 /* Check NULL pointer */
674 if(iwr->u.data.pointer == NULL)
675 return -EFAULT;
676
677 /* Check if there is enough buffer up there */
678 if(iwr->u.data.length < dev->wireless_handlers->num_private_args) {
679 /* User space can't know in advance how large the buffer
680 * needs to be. Give it a hint, so that we can support
681 * any size buffer we want somewhat efficiently... */
682 iwr->u.data.length = dev->wireless_handlers->num_private_args;
683 return -E2BIG;
684 }
685
686 /* Set the number of available ioctls. */
687 iwr->u.data.length = dev->wireless_handlers->num_private_args;
688
689 /* Copy structure to the user buffer. */
690 if (copy_to_user(iwr->u.data.pointer,
691 dev->wireless_handlers->private_args,
692 sizeof(struct iw_priv_args) * iwr->u.data.length))
693 return -EFAULT;
694
695 return 0;
696}
697
698/* ---------------------------------------------------------------- */
699/*
700 * Wrapper to call a standard Wireless Extension handler. 707 * Wrapper to call a standard Wireless Extension handler.
701 * We do various checks and also take care of moving data between 708 * We do various checks and also take care of moving data between
702 * user space and kernel space. 709 * user space and kernel space.
703 */ 710 */
704static inline int ioctl_standard_call(struct net_device * dev, 711static int ioctl_standard_call(struct net_device * dev,
705 struct ifreq * ifr, 712 struct ifreq * ifr,
706 unsigned int cmd, 713 unsigned int cmd,
707 iw_handler handler) 714 iw_handler handler)
708{ 715{
709 struct iwreq * iwr = (struct iwreq *) ifr; 716 struct iwreq * iwr = (struct iwreq *) ifr;
710 const struct iw_ioctl_description * descr; 717 const struct iw_ioctl_description * descr;
@@ -1048,14 +1055,20 @@ int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd)
1048 { 1055 {
1049 case SIOCGIWSTATS: 1056 case SIOCGIWSTATS:
1050 /* Get Wireless Stats */ 1057 /* Get Wireless Stats */
1051 return dev_iwstats(dev, ifr); 1058 return ioctl_standard_call(dev,
1059 ifr,
1060 cmd,
1061 &iw_handler_get_iwstats);
1052 1062
1053 case SIOCGIWPRIV: 1063 case SIOCGIWPRIV:
1054 /* Check if we have some wireless handlers defined */ 1064 /* Check if we have some wireless handlers defined */
1055 if(dev->wireless_handlers != NULL) { 1065 if(dev->wireless_handlers != NULL) {
1056 /* We export to user space the definition of 1066 /* We export to user space the definition of
1057 * the private handler ourselves */ 1067 * the private handler ourselves */
1058 return ioctl_export_private(dev, ifr); 1068 return ioctl_standard_call(dev,
1069 ifr,
1070 cmd,
1071 &iw_handler_get_private);
1059 } 1072 }
1060 // ## Fall-through for old API ## 1073 // ## Fall-through for old API ##
1061 default: 1074 default:
@@ -1088,16 +1101,739 @@ int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd)
1088 return -EINVAL; 1101 return -EINVAL;
1089} 1102}
1090 1103
1104/********************** RTNETLINK REQUEST API **********************/
1105/*
1106 * The alternate user space API to configure all those Wireless Extensions
1107 * is through RtNetlink.
1108 * This API support only the new driver API (iw_handler).
1109 *
1110 * This RtNetlink API use the same query/reply model as the ioctl API.
1111 * Maximum effort has been done to fit in the RtNetlink model, and
1112 * we support both RtNetlink Set and RtNelink Get operations.
1113 * On the other hand, we don't offer Dump operations because of the
1114 * following reasons :
1115 * o Large number of parameters, most optional
1116 * o Large size of some parameters (> 100 bytes)
1117 * o Each parameters need to be extracted from hardware
1118 * o Scan requests can take seconds and disable network activity.
1119 * Because of this high cost/overhead, we want to return only the
1120 * parameters the user application is really interested in.
1121 * We could offer partial Dump using the IW_DESCR_FLAG_DUMP flag.
1122 *
1123 * The API uses the standard RtNetlink socket. When the RtNetlink code
1124 * find a IFLA_WIRELESS field in a RtNetlink SET_LINK request,
1125 * it calls here.
1126 */
1127
1128#ifdef CONFIG_NET_WIRELESS_RTNETLINK
1129/* ---------------------------------------------------------------- */
1130/*
1131 * Wrapper to call a standard Wireless Extension GET handler.
1132 * We do various checks and call the handler with the proper args.
1133 */
1134static int rtnetlink_standard_get(struct net_device * dev,
1135 struct iw_event * request,
1136 int request_len,
1137 iw_handler handler,
1138 char ** p_buf,
1139 int * p_len)
1140{
1141 const struct iw_ioctl_description * descr = NULL;
1142 unsigned int cmd;
1143 union iwreq_data * wrqu;
1144 int hdr_len;
1145 struct iw_request_info info;
1146 char * buffer = NULL;
1147 int buffer_size = 0;
1148 int ret = -EINVAL;
1149
1150 /* Get the description of the Request */
1151 cmd = request->cmd;
1152 if((cmd - SIOCIWFIRST) >= standard_ioctl_num)
1153 return -EOPNOTSUPP;
1154 descr = &(standard_ioctl[cmd - SIOCIWFIRST]);
1155
1156#ifdef WE_RTNETLINK_DEBUG
1157 printk(KERN_DEBUG "%s (WE.r) : Found standard handler for 0x%04X\n",
1158 dev->name, cmd);
1159 printk(KERN_DEBUG "%s (WE.r) : Header type : %d, Token type : %d, size : %d, token : %d\n", dev->name, descr->header_type, descr->token_type, descr->token_size, descr->max_tokens);
1160#endif /* WE_RTNETLINK_DEBUG */
1161
1162 /* Check if wrqu is complete */
1163 hdr_len = event_type_size[descr->header_type];
1164 if(request_len < hdr_len) {
1165#ifdef WE_RTNETLINK_DEBUG
1166 printk(KERN_DEBUG
1167 "%s (WE.r) : Wireless request too short (%d)\n",
1168 dev->name, request_len);
1169#endif /* WE_RTNETLINK_DEBUG */
1170 return -EINVAL;
1171 }
1172
1173 /* Prepare the call */
1174 info.cmd = cmd;
1175 info.flags = 0;
1176
1177 /* Check if we have extra data in the reply or not */
1178 if(descr->header_type != IW_HEADER_TYPE_POINT) {
1179
1180 /* Create the kernel buffer that we will return.
1181 * It's at an offset to match the TYPE_POINT case... */
1182 buffer_size = request_len + IW_EV_POINT_OFF;
1183 buffer = kmalloc(buffer_size, GFP_KERNEL);
1184 if (buffer == NULL) {
1185 return -ENOMEM;
1186 }
1187 /* Copy event data */
1188 memcpy(buffer + IW_EV_POINT_OFF, request, request_len);
1189 /* Use our own copy of wrqu */
1190 wrqu = (union iwreq_data *) (buffer + IW_EV_POINT_OFF
1191 + IW_EV_LCP_LEN);
1192
1193 /* No extra arguments. Trivial to handle */
1194 ret = handler(dev, &info, wrqu, NULL);
1195
1196 } else {
1197 union iwreq_data wrqu_point;
1198 char * extra = NULL;
1199 int extra_size = 0;
1200
1201 /* Get a temp copy of wrqu (skip pointer) */
1202 memcpy(((char *) &wrqu_point) + IW_EV_POINT_OFF,
1203 ((char *) request) + IW_EV_LCP_LEN,
1204 IW_EV_POINT_LEN - IW_EV_LCP_LEN);
1205
1206 /* Calculate space needed by arguments. Always allocate
1207 * for max space. Easier, and won't last long... */
1208 extra_size = descr->max_tokens * descr->token_size;
1209 /* Support for very large requests */
1210 if((descr->flags & IW_DESCR_FLAG_NOMAX) &&
1211 (wrqu_point.data.length > descr->max_tokens))
1212 extra_size = (wrqu_point.data.length
1213 * descr->token_size);
1214 buffer_size = extra_size + IW_EV_POINT_LEN + IW_EV_POINT_OFF;
1215#ifdef WE_RTNETLINK_DEBUG
1216 printk(KERN_DEBUG "%s (WE.r) : Malloc %d bytes (%d bytes)\n",
1217 dev->name, extra_size, buffer_size);
1218#endif /* WE_RTNETLINK_DEBUG */
1219
1220 /* Create the kernel buffer that we will return */
1221 buffer = kmalloc(buffer_size, GFP_KERNEL);
1222 if (buffer == NULL) {
1223 return -ENOMEM;
1224 }
1225
1226 /* Put wrqu in the right place (just before extra).
1227 * Leave space for IWE header and dummy pointer...
1228 * Note that IW_EV_LCP_LEN==4 bytes, so it's still aligned...
1229 */
1230 memcpy(buffer + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
1231 ((char *) &wrqu_point) + IW_EV_POINT_OFF,
1232 IW_EV_POINT_LEN - IW_EV_LCP_LEN);
1233 wrqu = (union iwreq_data *) (buffer + IW_EV_LCP_LEN);
1234
1235 /* Extra comes logically after that. Offset +12 bytes. */
1236 extra = buffer + IW_EV_POINT_OFF + IW_EV_POINT_LEN;
1237
1238 /* Call the handler */
1239 ret = handler(dev, &info, wrqu, extra);
1240
1241 /* Calculate real returned length */
1242 extra_size = (wrqu->data.length * descr->token_size);
1243 /* Re-adjust reply size */
1244 request->len = extra_size + IW_EV_POINT_LEN;
1245
1246 /* Put the iwe header where it should, i.e. scrap the
1247 * dummy pointer. */
1248 memcpy(buffer + IW_EV_POINT_OFF, request, IW_EV_LCP_LEN);
1249
1250#ifdef WE_RTNETLINK_DEBUG
1251 printk(KERN_DEBUG "%s (WE.r) : Reply 0x%04X, hdr_len %d, tokens %d, extra_size %d, buffer_size %d\n", dev->name, cmd, hdr_len, wrqu->data.length, extra_size, buffer_size);
1252#endif /* WE_RTNETLINK_DEBUG */
1253
1254 /* Check if there is enough buffer up there */
1255 if(wrqu_point.data.length < wrqu->data.length)
1256 ret = -E2BIG;
1257 }
1258
1259 /* Return the buffer to the caller */
1260 if (!ret) {
1261 *p_buf = buffer;
1262 *p_len = request->len;
1263 } else {
1264 /* Cleanup */
1265 if(buffer)
1266 kfree(buffer);
1267 }
1268
1269 return ret;
1270}
1271
1272/* ---------------------------------------------------------------- */
1273/*
1274 * Wrapper to call a standard Wireless Extension SET handler.
1275 * We do various checks and call the handler with the proper args.
1276 */
1277static inline int rtnetlink_standard_set(struct net_device * dev,
1278 struct iw_event * request,
1279 int request_len,
1280 iw_handler handler)
1281{
1282 const struct iw_ioctl_description * descr = NULL;
1283 unsigned int cmd;
1284 union iwreq_data * wrqu;
1285 union iwreq_data wrqu_point;
1286 int hdr_len;
1287 char * extra = NULL;
1288 int extra_size = 0;
1289 struct iw_request_info info;
1290 int ret = -EINVAL;
1291
1292 /* Get the description of the Request */
1293 cmd = request->cmd;
1294 if((cmd - SIOCIWFIRST) >= standard_ioctl_num)
1295 return -EOPNOTSUPP;
1296 descr = &(standard_ioctl[cmd - SIOCIWFIRST]);
1297
1298#ifdef WE_RTNETLINK_DEBUG
1299 printk(KERN_DEBUG "%s (WE.r) : Found standard SET handler for 0x%04X\n",
1300 dev->name, cmd);
1301 printk(KERN_DEBUG "%s (WE.r) : Header type : %d, Token type : %d, size : %d, token : %d\n", dev->name, descr->header_type, descr->token_type, descr->token_size, descr->max_tokens);
1302#endif /* WE_RTNETLINK_DEBUG */
1303
1304 /* Extract fixed header from request. This is properly aligned. */
1305 wrqu = &request->u;
1306
1307 /* Check if wrqu is complete */
1308 hdr_len = event_type_size[descr->header_type];
1309 if(request_len < hdr_len) {
1310#ifdef WE_RTNETLINK_DEBUG
1311 printk(KERN_DEBUG
1312 "%s (WE.r) : Wireless request too short (%d)\n",
1313 dev->name, request_len);
1314#endif /* WE_RTNETLINK_DEBUG */
1315 return -EINVAL;
1316 }
1317
1318 /* Prepare the call */
1319 info.cmd = cmd;
1320 info.flags = 0;
1321
1322 /* Check if we have extra data in the request or not */
1323 if(descr->header_type != IW_HEADER_TYPE_POINT) {
1324
1325 /* No extra arguments. Trivial to handle */
1326 ret = handler(dev, &info, wrqu, NULL);
1327
1328 } else {
1329 int extra_len;
1330
1331 /* Put wrqu in the right place (skip pointer) */
1332 memcpy(((char *) &wrqu_point) + IW_EV_POINT_OFF,
1333 wrqu, IW_EV_POINT_LEN - IW_EV_LCP_LEN);
1334 /* Don't forget about the event code... */
1335 wrqu = &wrqu_point;
1336
1337 /* Check if number of token fits within bounds */
1338 if(wrqu_point.data.length > descr->max_tokens)
1339 return -E2BIG;
1340 if(wrqu_point.data.length < descr->min_tokens)
1341 return -EINVAL;
1342
1343 /* Real length of payload */
1344 extra_len = wrqu_point.data.length * descr->token_size;
1345
1346 /* Check if request is self consistent */
1347 if((request_len - hdr_len) < extra_len) {
1348#ifdef WE_RTNETLINK_DEBUG
1349 printk(KERN_DEBUG "%s (WE.r) : Wireless request data too short (%d)\n",
1350 dev->name, extra_size);
1351#endif /* WE_RTNETLINK_DEBUG */
1352 return -EINVAL;
1353 }
1354
1355#ifdef WE_RTNETLINK_DEBUG
1356 printk(KERN_DEBUG "%s (WE.r) : Malloc %d bytes\n",
1357 dev->name, extra_size);
1358#endif /* WE_RTNETLINK_DEBUG */
1359
1360 /* Always allocate for max space. Easier, and won't last
1361 * long... */
1362 extra_size = descr->max_tokens * descr->token_size;
1363 extra = kmalloc(extra_size, GFP_KERNEL);
1364 if (extra == NULL)
1365 return -ENOMEM;
1366
1367 /* Copy extra in aligned buffer */
1368 memcpy(extra, ((char *) request) + hdr_len, extra_len);
1369
1370 /* Call the handler */
1371 ret = handler(dev, &info, &wrqu_point, extra);
1372 }
1373
1374#ifdef WE_SET_EVENT
1375 /* Generate an event to notify listeners of the change */
1376 if((descr->flags & IW_DESCR_FLAG_EVENT) &&
1377 ((ret == 0) || (ret == -EIWCOMMIT))) {
1378 if(descr->flags & IW_DESCR_FLAG_RESTRICT)
1379 /* If the event is restricted, don't
1380 * export the payload */
1381 wireless_send_event(dev, cmd, wrqu, NULL);
1382 else
1383 wireless_send_event(dev, cmd, wrqu, extra);
1384 }
1385#endif /* WE_SET_EVENT */
1386
1387 /* Cleanup - I told you it wasn't that long ;-) */
1388 if(extra)
1389 kfree(extra);
1390
1391 /* Call commit handler if needed and defined */
1392 if(ret == -EIWCOMMIT)
1393 ret = call_commit_handler(dev);
1394
1395 return ret;
1396}
1397
1398/* ---------------------------------------------------------------- */
1399/*
1400 * Wrapper to call a private Wireless Extension GET handler.
1401 * Same as above...
1402 * It's not as nice and slimline as the standard wrapper. The cause
1403 * is struct iw_priv_args, which was not really designed for the
1404 * job we are going here.
1405 *
1406 * IMPORTANT : This function prevent to set and get data on the same
1407 * IOCTL and enforce the SET/GET convention. Not doing it would be
1408 * far too hairy...
1409 * If you need to set and get data at the same time, please don't use
1410 * a iw_handler but process it in your ioctl handler (i.e. use the
1411 * old driver API).
1412 */
1413static inline int rtnetlink_private_get(struct net_device * dev,
1414 struct iw_event * request,
1415 int request_len,
1416 iw_handler handler,
1417 char ** p_buf,
1418 int * p_len)
1419{
1420 const struct iw_priv_args * descr = NULL;
1421 unsigned int cmd;
1422 union iwreq_data * wrqu;
1423 int hdr_len;
1424 struct iw_request_info info;
1425 int extra_size = 0;
1426 int i;
1427 char * buffer = NULL;
1428 int buffer_size = 0;
1429 int ret = -EINVAL;
1430
1431 /* Get the description of the Request */
1432 cmd = request->cmd;
1433 for(i = 0; i < dev->wireless_handlers->num_private_args; i++)
1434 if(cmd == dev->wireless_handlers->private_args[i].cmd) {
1435 descr = &(dev->wireless_handlers->private_args[i]);
1436 break;
1437 }
1438 if(descr == NULL)
1439 return -EOPNOTSUPP;
1440
1441#ifdef WE_RTNETLINK_DEBUG
1442 printk(KERN_DEBUG "%s (WE.r) : Found private handler for 0x%04X\n",
1443 dev->name, cmd);
1444 printk(KERN_DEBUG "%s (WE.r) : Name %s, set %X, get %X\n",
1445 dev->name, descr->name, descr->set_args, descr->get_args);
1446#endif /* WE_RTNETLINK_DEBUG */
1447
1448 /* Compute the max size of the get arguments */
1449 extra_size = get_priv_size(descr->get_args);
1450
1451 /* Does it fits in wrqu ? */
1452 if((descr->get_args & IW_PRIV_SIZE_FIXED) &&
1453 (extra_size <= IFNAMSIZ)) {
1454 hdr_len = extra_size;
1455 extra_size = 0;
1456 } else {
1457 hdr_len = IW_EV_POINT_LEN;
1458 }
1459
1460 /* Check if wrqu is complete */
1461 if(request_len < hdr_len) {
1462#ifdef WE_RTNETLINK_DEBUG
1463 printk(KERN_DEBUG
1464 "%s (WE.r) : Wireless request too short (%d)\n",
1465 dev->name, request_len);
1466#endif /* WE_RTNETLINK_DEBUG */
1467 return -EINVAL;
1468 }
1469
1470 /* Prepare the call */
1471 info.cmd = cmd;
1472 info.flags = 0;
1473
1474 /* Check if we have a pointer to user space data or not. */
1475 if(extra_size == 0) {
1476
1477 /* Create the kernel buffer that we will return.
1478 * It's at an offset to match the TYPE_POINT case... */
1479 buffer_size = request_len + IW_EV_POINT_OFF;
1480 buffer = kmalloc(buffer_size, GFP_KERNEL);
1481 if (buffer == NULL) {
1482 return -ENOMEM;
1483 }
1484 /* Copy event data */
1485 memcpy(buffer + IW_EV_POINT_OFF, request, request_len);
1486 /* Use our own copy of wrqu */
1487 wrqu = (union iwreq_data *) (buffer + IW_EV_POINT_OFF
1488 + IW_EV_LCP_LEN);
1489
1490 /* No extra arguments. Trivial to handle */
1491 ret = handler(dev, &info, wrqu, (char *) wrqu);
1492
1493 } else {
1494 char * extra;
1495
1496 /* Buffer for full reply */
1497 buffer_size = extra_size + IW_EV_POINT_LEN + IW_EV_POINT_OFF;
1498
1499#ifdef WE_RTNETLINK_DEBUG
1500 printk(KERN_DEBUG "%s (WE.r) : Malloc %d bytes (%d bytes)\n",
1501 dev->name, extra_size, buffer_size);
1502#endif /* WE_RTNETLINK_DEBUG */
1503
1504 /* Create the kernel buffer that we will return */
1505 buffer = kmalloc(buffer_size, GFP_KERNEL);
1506 if (buffer == NULL) {
1507 return -ENOMEM;
1508 }
1509
1510 /* Put wrqu in the right place (just before extra).
1511 * Leave space for IWE header and dummy pointer...
1512 * Note that IW_EV_LCP_LEN==4 bytes, so it's still aligned...
1513 */
1514 memcpy(buffer + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
1515 ((char *) request) + IW_EV_LCP_LEN,
1516 IW_EV_POINT_LEN - IW_EV_LCP_LEN);
1517 wrqu = (union iwreq_data *) (buffer + IW_EV_LCP_LEN);
1518
1519 /* Extra comes logically after that. Offset +12 bytes. */
1520 extra = buffer + IW_EV_POINT_OFF + IW_EV_POINT_LEN;
1521
1522 /* Call the handler */
1523 ret = handler(dev, &info, wrqu, extra);
1524
1525 /* Adjust for the actual length if it's variable,
1526 * avoid leaking kernel bits outside. */
1527 if (!(descr->get_args & IW_PRIV_SIZE_FIXED))
1528 extra_size = adjust_priv_size(descr->get_args, wrqu);
1529 /* Re-adjust reply size */
1530 request->len = extra_size + IW_EV_POINT_LEN;
1531
1532 /* Put the iwe header where it should, i.e. scrap the
1533 * dummy pointer. */
1534 memcpy(buffer + IW_EV_POINT_OFF, request, IW_EV_LCP_LEN);
1535
1536#ifdef WE_RTNETLINK_DEBUG
1537 printk(KERN_DEBUG "%s (WE.r) : Reply 0x%04X, hdr_len %d, tokens %d, extra_size %d, buffer_size %d\n", dev->name, cmd, hdr_len, wrqu->data.length, extra_size, buffer_size);
1538#endif /* WE_RTNETLINK_DEBUG */
1539 }
1540
1541 /* Return the buffer to the caller */
1542 if (!ret) {
1543 *p_buf = buffer;
1544 *p_len = request->len;
1545 } else {
1546 /* Cleanup */
1547 if(buffer)
1548 kfree(buffer);
1549 }
1550
1551 return ret;
1552}
1553
1554/* ---------------------------------------------------------------- */
1555/*
1556 * Wrapper to call a private Wireless Extension SET handler.
1557 * Same as above...
1558 * It's not as nice and slimline as the standard wrapper. The cause
1559 * is struct iw_priv_args, which was not really designed for the
1560 * job we are going here.
1561 *
1562 * IMPORTANT : This function prevent to set and get data on the same
1563 * IOCTL and enforce the SET/GET convention. Not doing it would be
1564 * far too hairy...
1565 * If you need to set and get data at the same time, please don't use
1566 * a iw_handler but process it in your ioctl handler (i.e. use the
1567 * old driver API).
1568 */
1569static inline int rtnetlink_private_set(struct net_device * dev,
1570 struct iw_event * request,
1571 int request_len,
1572 iw_handler handler)
1573{
1574 const struct iw_priv_args * descr = NULL;
1575 unsigned int cmd;
1576 union iwreq_data * wrqu;
1577 union iwreq_data wrqu_point;
1578 int hdr_len;
1579 char * extra = NULL;
1580 int extra_size = 0;
1581 int offset = 0; /* For sub-ioctls */
1582 struct iw_request_info info;
1583 int i;
1584 int ret = -EINVAL;
1585
1586 /* Get the description of the Request */
1587 cmd = request->cmd;
1588 for(i = 0; i < dev->wireless_handlers->num_private_args; i++)
1589 if(cmd == dev->wireless_handlers->private_args[i].cmd) {
1590 descr = &(dev->wireless_handlers->private_args[i]);
1591 break;
1592 }
1593 if(descr == NULL)
1594 return -EOPNOTSUPP;
1595
1596#ifdef WE_RTNETLINK_DEBUG
1597 printk(KERN_DEBUG "%s (WE.r) : Found private handler for 0x%04X\n",
1598 ifr->ifr_name, cmd);
1599 printk(KERN_DEBUG "%s (WE.r) : Name %s, set %X, get %X\n",
1600 dev->name, descr->name, descr->set_args, descr->get_args);
1601#endif /* WE_RTNETLINK_DEBUG */
1602
1603 /* Compute the size of the set arguments */
1604 /* Check for sub-ioctl handler */
1605 if(descr->name[0] == '\0')
1606 /* Reserve one int for sub-ioctl index */
1607 offset = sizeof(__u32);
1608
1609 /* Size of set arguments */
1610 extra_size = get_priv_size(descr->set_args);
1611
1612 /* Does it fits in wrqu ? */
1613 if((descr->set_args & IW_PRIV_SIZE_FIXED) &&
1614 (extra_size <= IFNAMSIZ)) {
1615 hdr_len = IW_EV_LCP_LEN + extra_size;
1616 extra_size = 0;
1617 } else {
1618 hdr_len = IW_EV_POINT_LEN;
1619 }
1620
1621 /* Extract fixed header from request. This is properly aligned. */
1622 wrqu = &request->u;
1623
1624 /* Check if wrqu is complete */
1625 if(request_len < hdr_len) {
1626#ifdef WE_RTNETLINK_DEBUG
1627 printk(KERN_DEBUG
1628 "%s (WE.r) : Wireless request too short (%d)\n",
1629 dev->name, request_len);
1630#endif /* WE_RTNETLINK_DEBUG */
1631 return -EINVAL;
1632 }
1633
1634 /* Prepare the call */
1635 info.cmd = cmd;
1636 info.flags = 0;
1637
1638 /* Check if we have a pointer to user space data or not. */
1639 if(extra_size == 0) {
1640
1641 /* No extra arguments. Trivial to handle */
1642 ret = handler(dev, &info, wrqu, (char *) wrqu);
1643
1644 } else {
1645 int extra_len;
1646
1647 /* Put wrqu in the right place (skip pointer) */
1648 memcpy(((char *) &wrqu_point) + IW_EV_POINT_OFF,
1649 wrqu, IW_EV_POINT_LEN - IW_EV_LCP_LEN);
1650
1651 /* Does it fits within bounds ? */
1652 if(wrqu_point.data.length > (descr->set_args &
1653 IW_PRIV_SIZE_MASK))
1654 return -E2BIG;
1655
1656 /* Real length of payload */
1657 extra_len = adjust_priv_size(descr->set_args, &wrqu_point);
1658
1659 /* Check if request is self consistent */
1660 if((request_len - hdr_len) < extra_len) {
1661#ifdef WE_RTNETLINK_DEBUG
1662 printk(KERN_DEBUG "%s (WE.r) : Wireless request data too short (%d)\n",
1663 dev->name, extra_size);
1664#endif /* WE_RTNETLINK_DEBUG */
1665 return -EINVAL;
1666 }
1667
1668#ifdef WE_RTNETLINK_DEBUG
1669 printk(KERN_DEBUG "%s (WE.r) : Malloc %d bytes\n",
1670 dev->name, extra_size);
1671#endif /* WE_RTNETLINK_DEBUG */
1672
1673 /* Always allocate for max space. Easier, and won't last
1674 * long... */
1675 extra = kmalloc(extra_size, GFP_KERNEL);
1676 if (extra == NULL)
1677 return -ENOMEM;
1678
1679 /* Copy extra in aligned buffer */
1680 memcpy(extra, ((char *) request) + hdr_len, extra_len);
1681
1682 /* Call the handler */
1683 ret = handler(dev, &info, &wrqu_point, extra);
1684
1685 /* Cleanup - I told you it wasn't that long ;-) */
1686 kfree(extra);
1687 }
1688
1689 /* Call commit handler if needed and defined */
1690 if(ret == -EIWCOMMIT)
1691 ret = call_commit_handler(dev);
1692
1693 return ret;
1694}
1695
1696/* ---------------------------------------------------------------- */
1697/*
1698 * Main RtNetlink dispatcher. Called from the main networking code
1699 * (do_getlink() in net/core/rtnetlink.c).
1700 * Check the type of Request and call the appropriate wrapper...
1701 */
1702int wireless_rtnetlink_get(struct net_device * dev,
1703 char * data,
1704 int len,
1705 char ** p_buf,
1706 int * p_len)
1707{
1708 struct iw_event * request = (struct iw_event *) data;
1709 iw_handler handler;
1710
1711 /* Check length */
1712 if(len < IW_EV_LCP_LEN) {
1713 printk(KERN_DEBUG "%s (WE.r) : RtNetlink request too short (%d)\n",
1714 dev->name, len);
1715 return -EINVAL;
1716 }
1717
1718 /* ReCheck length (len may have padding) */
1719 if(request->len > len) {
1720 printk(KERN_DEBUG "%s (WE.r) : RtNetlink request len invalid (%d-%d)\n",
1721 dev->name, request->len, len);
1722 return -EINVAL;
1723 }
1724
1725 /* Only accept GET requests in here */
1726 if(!IW_IS_GET(request->cmd))
1727 return -EOPNOTSUPP;
1728
1729 /* Special cases */
1730 if(request->cmd == SIOCGIWSTATS)
1731 /* Get Wireless Stats */
1732 return rtnetlink_standard_get(dev,
1733 request,
1734 request->len,
1735 &iw_handler_get_iwstats,
1736 p_buf, p_len);
1737 if(request->cmd == SIOCGIWPRIV) {
1738 /* Check if we have some wireless handlers defined */
1739 if(dev->wireless_handlers == NULL)
1740 return -EOPNOTSUPP;
1741 /* Get Wireless Stats */
1742 return rtnetlink_standard_get(dev,
1743 request,
1744 request->len,
1745 &iw_handler_get_private,
1746 p_buf, p_len);
1747 }
1748
1749 /* Basic check */
1750 if (!netif_device_present(dev))
1751 return -ENODEV;
1752
1753 /* Try to find the handler */
1754 handler = get_handler(dev, request->cmd);
1755 if(handler != NULL) {
1756 /* Standard and private are not the same */
1757 if(request->cmd < SIOCIWFIRSTPRIV)
1758 return rtnetlink_standard_get(dev,
1759 request,
1760 request->len,
1761 handler,
1762 p_buf, p_len);
1763 else
1764 return rtnetlink_private_get(dev,
1765 request,
1766 request->len,
1767 handler,
1768 p_buf, p_len);
1769 }
1770
1771 return -EOPNOTSUPP;
1772}
1773
1774/* ---------------------------------------------------------------- */
1775/*
1776 * Main RtNetlink dispatcher. Called from the main networking code
1777 * (do_setlink() in net/core/rtnetlink.c).
1778 * Check the type of Request and call the appropriate wrapper...
1779 */
1780int wireless_rtnetlink_set(struct net_device * dev,
1781 char * data,
1782 int len)
1783{
1784 struct iw_event * request = (struct iw_event *) data;
1785 iw_handler handler;
1786
1787 /* Check length */
1788 if(len < IW_EV_LCP_LEN) {
1789 printk(KERN_DEBUG "%s (WE.r) : RtNetlink request too short (%d)\n",
1790 dev->name, len);
1791 return -EINVAL;
1792 }
1793
1794 /* ReCheck length (len may have padding) */
1795 if(request->len > len) {
1796 printk(KERN_DEBUG "%s (WE.r) : RtNetlink request len invalid (%d-%d)\n",
1797 dev->name, request->len, len);
1798 return -EINVAL;
1799 }
1800
1801 /* Only accept SET requests in here */
1802 if(!IW_IS_SET(request->cmd))
1803 return -EOPNOTSUPP;
1804
1805 /* Basic check */
1806 if (!netif_device_present(dev))
1807 return -ENODEV;
1808
1809 /* New driver API : try to find the handler */
1810 handler = get_handler(dev, request->cmd);
1811 if(handler != NULL) {
1812 /* Standard and private are not the same */
1813 if(request->cmd < SIOCIWFIRSTPRIV)
1814 return rtnetlink_standard_set(dev,
1815 request,
1816 request->len,
1817 handler);
1818 else
1819 return rtnetlink_private_set(dev,
1820 request,
1821 request->len,
1822 handler);
1823 }
1824
1825 return -EOPNOTSUPP;
1826}
1827#endif /* CONFIG_NET_WIRELESS_RTNETLINK */
1828
1829
1091/************************* EVENT PROCESSING *************************/ 1830/************************* EVENT PROCESSING *************************/
1092/* 1831/*
1093 * Process events generated by the wireless layer or the driver. 1832 * Process events generated by the wireless layer or the driver.
1094 * Most often, the event will be propagated through rtnetlink 1833 * Most often, the event will be propagated through rtnetlink
1095 */ 1834 */
1096 1835
1097#ifdef WE_EVENT_NETLINK 1836#ifdef WE_EVENT_RTNETLINK
1098/* "rtnl" is defined in net/core/rtnetlink.c, but we need it here.
1099 * It is declared in <linux/rtnetlink.h> */
1100
1101/* ---------------------------------------------------------------- */ 1837/* ---------------------------------------------------------------- */
1102/* 1838/*
1103 * Fill a rtnetlink message with our event data. 1839 * Fill a rtnetlink message with our event data.
@@ -1121,12 +1857,11 @@ static inline int rtnetlink_fill_iwinfo(struct sk_buff * skb,
1121 r->__ifi_pad = 0; 1857 r->__ifi_pad = 0;
1122 r->ifi_type = dev->type; 1858 r->ifi_type = dev->type;
1123 r->ifi_index = dev->ifindex; 1859 r->ifi_index = dev->ifindex;
1124 r->ifi_flags = dev->flags; 1860 r->ifi_flags = dev_get_flags(dev);
1125 r->ifi_change = 0; /* Wireless changes don't affect those flags */ 1861 r->ifi_change = 0; /* Wireless changes don't affect those flags */
1126 1862
1127 /* Add the wireless events in the netlink packet */ 1863 /* Add the wireless events in the netlink packet */
1128 RTA_PUT(skb, IFLA_WIRELESS, 1864 RTA_PUT(skb, IFLA_WIRELESS, event_len, event);
1129 event_len, event);
1130 1865
1131 nlh->nlmsg_len = skb->tail - b; 1866 nlh->nlmsg_len = skb->tail - b;
1132 return skb->len; 1867 return skb->len;
@@ -1163,7 +1898,7 @@ static inline void rtmsg_iwinfo(struct net_device * dev,
1163 NETLINK_CB(skb).dst_group = RTNLGRP_LINK; 1898 NETLINK_CB(skb).dst_group = RTNLGRP_LINK;
1164 netlink_broadcast(rtnl, skb, 0, RTNLGRP_LINK, GFP_ATOMIC); 1899 netlink_broadcast(rtnl, skb, 0, RTNLGRP_LINK, GFP_ATOMIC);
1165} 1900}
1166#endif /* WE_EVENT_NETLINK */ 1901#endif /* WE_EVENT_RTNETLINK */
1167 1902
1168/* ---------------------------------------------------------------- */ 1903/* ---------------------------------------------------------------- */
1169/* 1904/*
@@ -1255,10 +1990,10 @@ void wireless_send_event(struct net_device * dev,
1255 if(extra != NULL) 1990 if(extra != NULL)
1256 memcpy(((char *) event) + hdr_len, extra, extra_len); 1991 memcpy(((char *) event) + hdr_len, extra, extra_len);
1257 1992
1258#ifdef WE_EVENT_NETLINK 1993#ifdef WE_EVENT_RTNETLINK
1259 /* rtnetlink event channel */ 1994 /* Send via the RtNetlink event channel */
1260 rtmsg_iwinfo(dev, (char *) event, event_len); 1995 rtmsg_iwinfo(dev, (char *) event, event_len);
1261#endif /* WE_EVENT_NETLINK */ 1996#endif /* WE_EVENT_RTNETLINK */
1262 1997
1263 /* Cleanup */ 1998 /* Cleanup */
1264 kfree(event); 1999 kfree(event);
diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c
index c788377f5648..be61de78dfa4 100644
--- a/net/ieee80211/softmac/ieee80211softmac_assoc.c
+++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c
@@ -38,7 +38,7 @@ static void
38ieee80211softmac_assoc(struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net) 38ieee80211softmac_assoc(struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net)
39{ 39{
40 unsigned long flags; 40 unsigned long flags;
41 function_enter(); 41
42 /* Switch to correct channel for this network */ 42 /* Switch to correct channel for this network */
43 mac->set_channel(mac->dev, net->channel); 43 mac->set_channel(mac->dev, net->channel);
44 44
@@ -64,8 +64,6 @@ ieee80211softmac_assoc_timeout(void *d)
64 struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d; 64 struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d;
65 unsigned long flags; 65 unsigned long flags;
66 66
67 function_enter();
68
69 spin_lock_irqsave(&mac->lock, flags); 67 spin_lock_irqsave(&mac->lock, flags);
70 /* we might race against ieee80211softmac_handle_assoc_response, 68 /* we might race against ieee80211softmac_handle_assoc_response,
71 * so make sure only one of us does something */ 69 * so make sure only one of us does something */
@@ -89,7 +87,6 @@ ieee80211softmac_disassoc(struct ieee80211softmac_device *mac, u16 reason)
89{ 87{
90 unsigned long flags; 88 unsigned long flags;
91 struct ieee80211softmac_network *found; 89 struct ieee80211softmac_network *found;
92 function_enter();
93 90
94 if (mac->associnfo.bssvalid && mac->associated) { 91 if (mac->associnfo.bssvalid && mac->associated) {
95 found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); 92 found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);
@@ -173,8 +170,6 @@ ieee80211softmac_assoc_work(void *d)
173 struct ieee80211_network *net = NULL, *best = NULL; 170 struct ieee80211_network *net = NULL, *best = NULL;
174 unsigned long flags; 171 unsigned long flags;
175 172
176 function_enter();
177
178 /* meh */ 173 /* meh */
179 if (mac->associated) 174 if (mac->associated)
180 ieee80211softmac_disassoc(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT); 175 ieee80211softmac_disassoc(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT);
@@ -391,8 +386,6 @@ ieee80211softmac_handle_reassoc_req(struct net_device * dev,
391 struct ieee80211softmac_device *mac = ieee80211_priv(dev); 386 struct ieee80211softmac_device *mac = ieee80211_priv(dev);
392 struct ieee80211softmac_network *network; 387 struct ieee80211softmac_network *network;
393 388
394 function_enter();
395
396 network = ieee80211softmac_get_network_by_bssid(mac, resp->header.addr3); 389 network = ieee80211softmac_get_network_by_bssid(mac, resp->header.addr3);
397 if (!network) { 390 if (!network) {
398 dprintkl(KERN_INFO PFX "reassoc request from unknown network\n"); 391 dprintkl(KERN_INFO PFX "reassoc request from unknown network\n");
diff --git a/net/ieee80211/softmac/ieee80211softmac_auth.c b/net/ieee80211/softmac/ieee80211softmac_auth.c
index ac09e0c836ee..9a0eac6c61eb 100644
--- a/net/ieee80211/softmac/ieee80211softmac_auth.c
+++ b/net/ieee80211/softmac/ieee80211softmac_auth.c
@@ -36,8 +36,6 @@ ieee80211softmac_auth_req(struct ieee80211softmac_device *mac,
36 struct ieee80211softmac_auth_queue_item *auth; 36 struct ieee80211softmac_auth_queue_item *auth;
37 unsigned long flags; 37 unsigned long flags;
38 38
39 function_enter();
40
41 if (net->authenticating) 39 if (net->authenticating)
42 return 0; 40 return 0;
43 41
@@ -78,8 +76,6 @@ ieee80211softmac_auth_queue(void *data)
78 struct ieee80211softmac_network *net; 76 struct ieee80211softmac_network *net;
79 unsigned long flags; 77 unsigned long flags;
80 78
81 function_enter();
82
83 auth = (struct ieee80211softmac_auth_queue_item *)data; 79 auth = (struct ieee80211softmac_auth_queue_item *)data;
84 net = auth->net; 80 net = auth->net;
85 mac = auth->mac; 81 mac = auth->mac;
@@ -128,8 +124,6 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
128 unsigned long flags; 124 unsigned long flags;
129 u8 * data; 125 u8 * data;
130 126
131 function_enter();
132
133 /* Find correct auth queue item */ 127 /* Find correct auth queue item */
134 spin_lock_irqsave(&mac->lock, flags); 128 spin_lock_irqsave(&mac->lock, flags);
135 list_for_each(list_ptr, &mac->auth_queue) { 129 list_for_each(list_ptr, &mac->auth_queue) {
@@ -277,8 +271,6 @@ ieee80211softmac_deauth_from_net(struct ieee80211softmac_device *mac,
277 struct list_head *list_ptr; 271 struct list_head *list_ptr;
278 unsigned long flags; 272 unsigned long flags;
279 273
280 function_enter();
281
282 /* Lock and reset status flags */ 274 /* Lock and reset status flags */
283 spin_lock_irqsave(&mac->lock, flags); 275 spin_lock_irqsave(&mac->lock, flags);
284 net->authenticating = 0; 276 net->authenticating = 0;
@@ -320,8 +312,6 @@ ieee80211softmac_deauth_req(struct ieee80211softmac_device *mac,
320{ 312{
321 int ret; 313 int ret;
322 314
323 function_enter();
324
325 /* Make sure the network is authenticated */ 315 /* Make sure the network is authenticated */
326 if (!net->authenticated) 316 if (!net->authenticated)
327 { 317 {
@@ -348,8 +338,6 @@ ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *de
348 struct ieee80211softmac_network *net = NULL; 338 struct ieee80211softmac_network *net = NULL;
349 struct ieee80211softmac_device *mac = ieee80211_priv(dev); 339 struct ieee80211softmac_device *mac = ieee80211_priv(dev);
350 340
351 function_enter();
352
353 if (!deauth) { 341 if (!deauth) {
354 dprintk("deauth without deauth packet. eek!\n"); 342 dprintk("deauth without deauth packet. eek!\n");
355 return 0; 343 return 0;
diff --git a/net/ieee80211/softmac/ieee80211softmac_priv.h b/net/ieee80211/softmac/ieee80211softmac_priv.h
index 258da14937be..9ba7dbd161eb 100644
--- a/net/ieee80211/softmac/ieee80211softmac_priv.h
+++ b/net/ieee80211/softmac/ieee80211softmac_priv.h
@@ -75,15 +75,6 @@
75# define dprintk(f, x...) do { /* nothing */ } while (0) 75# define dprintk(f, x...) do { /* nothing */ } while (0)
76#endif 76#endif
77 77
78#ifdef function_enter
79# undef function_enter
80#endif
81#ifdef CONFIG_IEEE80211_SOFTMAC_DEBUG
82# define function_enter() do { printk(KERN_DEBUG PFX "%s:%d:%s()\n", __FILE__, __LINE__, __FUNCTION__); } while (0)
83#else
84# define function_enter() do { /* nothing */ } while (0)
85#endif
86
87/* private definitions and prototypes */ 78/* private definitions and prototypes */
88 79
89/*** prototypes from _scan.c */ 80/*** prototypes from _scan.c */
diff --git a/net/ieee80211/softmac/ieee80211softmac_scan.c b/net/ieee80211/softmac/ieee80211softmac_scan.c
index 290ddb0951d6..bb9ab8b45d09 100644
--- a/net/ieee80211/softmac/ieee80211softmac_scan.c
+++ b/net/ieee80211/softmac/ieee80211softmac_scan.c
@@ -232,6 +232,13 @@ void ieee80211softmac_scan_finished(struct ieee80211softmac_device *sm)
232 sm->scanning = 0; 232 sm->scanning = 0;
233 spin_unlock_irqrestore(&sm->lock, flags); 233 spin_unlock_irqrestore(&sm->lock, flags);
234 234
235 if (sm->associnfo.bssvalid) {
236 struct ieee80211softmac_network *net;
237
238 net = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid);
239 if (net)
240 sm->set_channel(sm->dev, net->channel);
241 }
235 ieee80211softmac_call_events(sm, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, NULL); 242 ieee80211softmac_call_events(sm, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, NULL);
236} 243}
237EXPORT_SYMBOL_GPL(ieee80211softmac_scan_finished); 244EXPORT_SYMBOL_GPL(ieee80211softmac_scan_finished);