Commit 11e5bb60 authored by Jeff Garzik's avatar Jeff Garzik

Merge redhat.com:/garz/repo/linus-2.6

into redhat.com:/garz/repo/net-drivers-2.6
parents 29fa971b 7a508e5b
...@@ -2107,14 +2107,16 @@ S: Germany ...@@ -2107,14 +2107,16 @@ S: Germany
N: Arnaldo Carvalho de Melo N: Arnaldo Carvalho de Melo
E: acme@conectiva.com.br E: acme@conectiva.com.br
E: acme@kernel.org
E: acme@gnu.org E: acme@gnu.org
W: http://bazar.conectiva.com.br/~acme W: http://bazar2.conectiva.com.br/~acme
W: http://advogato.org/person/acme W: http://advogato.org/person/acme
P: 1024D/9224DF01 D5DF E3BB E3C8 BCBB F8AD 841A B6AB 4681 9224 DF01 P: 1024D/9224DF01 D5DF E3BB E3C8 BCBB F8AD 841A B6AB 4681 9224 DF01
D: wanrouter hacking D: wanrouter hacking
D: misc Makefile, Config.in, drivers and network stacks fixes D: misc Makefile, Config.in, drivers and network stacks fixes
D: IPX Maintainer D: IPX & LLC network stacks maintainer
D: Cyclom 2X synchronous card driver D: Cyclom 2X synchronous card driver
D: wl3501 PCMCIA wireless card driver
D: i18n for minicom, net-tools, util-linux, fetchmail, etc D: i18n for minicom, net-tools, util-linux, fetchmail, etc
S: Conectiva S.A. S: Conectiva S.A.
S: R. Tocantins, 89 - Cristo Rei S: R. Tocantins, 89 - Cristo Rei
...@@ -2360,6 +2362,15 @@ S: Zum Schiersteiner Grund 2 ...@@ -2360,6 +2362,15 @@ S: Zum Schiersteiner Grund 2
S: 55127 Mainz S: 55127 Mainz
S: Germany S: Germany
N: Gustavo Niemeyer
E: niemeyer@conectiva.com
W: https://moin.conectiva.com.br/GustavoNiemeyer
D: wl3501 PCMCIA wireless card initial support for wireless extensions in 2.4
S: Conectiva S.A.
S: R. Tocantins 89
S: 80050-430 Curitiba PR
S: Brazil
N: David C. Niemi N: David C. Niemi
E: niemi@tux.org E: niemi@tux.org
W: http://www.tux.org/~niemi/ W: http://www.tux.org/~niemi/
......
...@@ -478,7 +478,7 @@ S: Maintained ...@@ -478,7 +478,7 @@ S: Maintained
CYCLADES 2X SYNC CARD DRIVER CYCLADES 2X SYNC CARD DRIVER
P: Arnaldo Carvalho de Melo P: Arnaldo Carvalho de Melo
M: acme@conectiva.com.br M: acme@conectiva.com.br
W: http://www.conectiva.com.br/~acme W: http://advogato.org/person/acme
L: cycsyn-devel@bazar.conectiva.com.br L: cycsyn-devel@bazar.conectiva.com.br
S: Maintained S: Maintained
...@@ -2180,6 +2180,12 @@ M: zaga@fly.cc.fer.hr ...@@ -2180,6 +2180,12 @@ M: zaga@fly.cc.fer.hr
L: linux-scsi@vger.kernel.org L: linux-scsi@vger.kernel.org
S: Maintained S: Maintained
WL3501 WIRELESS PCMCIA CARD DRIVER
P: Arnaldo Carvalho de Melo
M: acme@conectiva.com.br
W: http://advogato.org/person/acme
S: Maintained
X.25 NETWORK LAYER X.25 NETWORK LAYER
P: Henner Eisen P: Henner Eisen
M: eis@baty.hanse.de M: eis@baty.hanse.de
......
...@@ -657,7 +657,7 @@ static int __init am79c961_init(void) ...@@ -657,7 +657,7 @@ static int __init am79c961_init(void)
struct dev_priv *priv; struct dev_priv *priv;
int i, ret; int i, ret;
dev = init_etherdev(NULL, sizeof(struct dev_priv)); dev = alloc_etherdev(sizeof(struct dev_priv));
ret = -ENOMEM; ret = -ENOMEM;
if (!dev) if (!dev)
goto out; goto out;
...@@ -715,12 +715,13 @@ static int __init am79c961_init(void) ...@@ -715,12 +715,13 @@ static int __init am79c961_init(void)
dev->set_multicast_list = am79c961_setmulticastlist; dev->set_multicast_list = am79c961_setmulticastlist;
dev->tx_timeout = am79c961_timeout; dev->tx_timeout = am79c961_timeout;
return 0; ret = register_netdev(dev);
if (ret == 0)
return 0;
release: release:
release_region(dev->base_addr, 0x18); release_region(dev->base_addr, 0x18);
nodev: nodev:
unregister_netdev(dev);
kfree(dev); kfree(dev);
out: out:
return ret; return ret;
......
...@@ -706,16 +706,6 @@ static int ether00_open(struct net_device* dev) ...@@ -706,16 +706,6 @@ static int ether00_open(struct net_device* dev)
if (!is_valid_ether_addr(dev->dev_addr)) if (!is_valid_ether_addr(dev->dev_addr))
return -EINVAL; return -EINVAL;
/* Allocate private memory */
dev->priv=kmalloc(sizeof(struct net_priv),GFP_KERNEL);
if(!dev->priv)
return -ENOMEM;
memset(dev->priv,0,sizeof(struct net_priv));
priv=(struct net_priv*)dev->priv;
priv->tq_memupdate.routine=ether00_mem_update;
priv->tq_memupdate.data=(void*) dev;
spin_lock_init(&priv->rx_lock);
/* Install interrupt handlers */ /* Install interrupt handlers */
result=request_irq(dev->irq,ether00_int,0,"ether00",dev); result=request_irq(dev->irq,ether00_int,0,"ether00",dev);
if(result) if(result)
...@@ -772,7 +762,6 @@ static int ether00_open(struct net_device* dev) ...@@ -772,7 +762,6 @@ static int ether00_open(struct net_device* dev)
open_err2: open_err2:
free_irq(dev->irq,dev); free_irq(dev->irq,dev);
open_err1: open_err1:
kfree(dev->priv);
return result; return result;
} }
...@@ -848,7 +837,6 @@ static int ether00_stop(struct net_device* dev) ...@@ -848,7 +837,6 @@ static int ether00_stop(struct net_device* dev)
free_irq(dev->irq,dev); free_irq(dev->irq,dev);
free_irq(2,dev); free_irq(2,dev);
iounmap(priv->dma_data); iounmap(priv->dma_data);
kfree(priv);
return 0; return 0;
} }
...@@ -901,23 +889,6 @@ static void ether00_get_ethernet_address(struct net_device* dev) ...@@ -901,23 +889,6 @@ static void ether00_get_ethernet_address(struct net_device* dev)
} }
static int ether00_init(struct net_device* dev)
{
ether_setup(dev);
dev->open=ether00_open;
dev->stop=ether00_stop;
dev->set_multicast_list=ether00_set_multicast;
dev->hard_start_xmit=ether00_tx;
dev->get_stats=ether00_stats;
ether00_get_ethernet_address(dev);
SET_MODULE_OWNER(dev);
return 0;
}
/* /*
* Keep a mapping of dev_info addresses -> port lines to use when * Keep a mapping of dev_info addresses -> port lines to use when
* removing ports dev==NULL indicates unused entry * removing ports dev==NULL indicates unused entry
...@@ -929,13 +900,13 @@ static struct net_device* dev_list[ETH_NR]; ...@@ -929,13 +900,13 @@ static struct net_device* dev_list[ETH_NR];
static int ether00_add_device(struct pldhs_dev_info* dev_info,void* dev_ps_data) static int ether00_add_device(struct pldhs_dev_info* dev_info,void* dev_ps_data)
{ {
struct net_device *dev; struct net_device *dev;
struct net_priv *priv;
void *map_addr; void *map_addr;
int result; int result;
int i; int i;
i=0; i=0;
while(dev_list[i]) while(dev_list[i] && i < ETH_NR)
i++; i++;
if(i==ETH_NR){ if(i==ETH_NR){
...@@ -944,37 +915,61 @@ static int ether00_add_device(struct pldhs_dev_info* dev_info,void* dev_ps_data) ...@@ -944,37 +915,61 @@ static int ether00_add_device(struct pldhs_dev_info* dev_info,void* dev_ps_data)
} }
dev=kmalloc(sizeof(struct net_device),GFP_KERNEL); if (!request_mem_region(dev_info->base_addr, MAC_REG_SIZE, "ether00"))
if(!dev){ return -EBUSY;
return -ENOMEM;
dev = alloc_etherdev(sizeof(struct net_priv));
if(!dev) {
result = -ENOMEM;
goto out_release;
} }
memset(dev,0,sizeof(struct net_device)); memset(dev,0,sizeof(struct net_device));
memset(dev->priv, 0, sizeof(struct net_priv));
priv = dev->priv;
priv->tq_memupdate.routine=ether00_mem_update;
priv->tq_memupdate.data=(void*) dev;
spin_lock_init(&priv->rx_lock);
map_addr=ioremap_nocache(dev_info->base_addr,SZ_4K); map_addr=ioremap_nocache(dev_info->base_addr,SZ_4K);
if(!map_addr){ if(!map_addr){
return -ENOMEM; result = -ENOMEM;
out_kfree;
} }
dev->init=ether00_init; dev->open=ether00_open;
strcpy(dev->name,"eth%d"); dev->stop=ether00_stop;
dev->set_multicast_list=ether00_set_multicast;
dev->hard_start_xmit=ether00_tx;
dev->get_stats=ether00_stats;
ether00_get_ethernet_address(dev);
SET_MODULE_OWNER(dev);
dev->base_addr=(unsigned int)map_addr; dev->base_addr=(unsigned int)map_addr;
dev->irq=dev_info->irq; dev->irq=dev_info->irq;
dev->features=NETIF_F_DYNALLOC | NETIF_F_HW_CSUM; dev->features=NETIF_F_DYNALLOC | NETIF_F_HW_CSUM;
if(check_mem_region((unsigned int)map_addr, MAC_REG_SIZE)){
return -EBUSY;
}
request_mem_region((unsigned int)map_addr, MAC_REG_SIZE, "ether00");
result=register_netdev(dev); result=register_netdev(dev);
if(result){ if(result){
printk("Ether00: Error %i registering driver\n",result); printk("Ether00: Error %i registering driver\n",result);
return result; goto out_unmap;
} }
printk("registered ether00 device at %#x\n",dev_info->base_addr); printk("registered ether00 device at %#x\n",dev_info->base_addr);
dev_list[i]=dev; dev_list[i]=dev;
return result; return result;
out_unmap:
iounmap(map_addr);
out_kfree:
kfree(dev);
out_release:
release_mem_region(dev_info->base_addr, MAC_REG_SIZE);
return result;
} }
......
...@@ -722,7 +722,7 @@ ether1_sendpacket (struct sk_buff *skb, struct net_device *dev) ...@@ -722,7 +722,7 @@ ether1_sendpacket (struct sk_buff *skb, struct net_device *dev)
tx.tx_command = CMD_TX | CMD_INTR; tx.tx_command = CMD_TX | CMD_INTR;
tx.tx_link = nopaddr; tx.tx_link = nopaddr;
tx.tx_tbdoffset = tbdaddr; tx.tx_tbdoffset = tbdaddr;
tbd.tbd_opts = TBD_EOL | len; tbd.tbd_opts = TBD_EOL | skb->len;
tbd.tbd_link = I82586_NULL; tbd.tbd_link = I82586_NULL;
tbd.tbd_bufl = dataddr; tbd.tbd_bufl = dataddr;
tbd.tbd_bufh = 0; tbd.tbd_bufh = 0;
...@@ -1013,7 +1013,7 @@ ether1_probe(struct expansion_card *ec, const struct ecard_id *id) ...@@ -1013,7 +1013,7 @@ ether1_probe(struct expansion_card *ec, const struct ecard_id *id)
ether1_banner(); ether1_banner();
dev = init_etherdev(NULL, sizeof(struct ether1_priv)); dev = alloc_etherdev(sizeof(struct ether1_priv));
if (!dev) { if (!dev) {
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
...@@ -1057,13 +1057,16 @@ ether1_probe(struct expansion_card *ec, const struct ecard_id *id) ...@@ -1057,13 +1057,16 @@ ether1_probe(struct expansion_card *ec, const struct ecard_id *id)
dev->tx_timeout = ether1_timeout; dev->tx_timeout = ether1_timeout;
dev->watchdog_timeo = 5 * HZ / 100; dev->watchdog_timeo = 5 * HZ / 100;
ret = register_netdev(dev);
if (ret)
goto release;
ecard_set_drvdata(ec, dev); ecard_set_drvdata(ec, dev);
return 0; return 0;
release: release:
release_region(dev->base_addr, 16); release_region(dev->base_addr, 16);
release_region(dev->base_addr + 0x800, 4096); release_region(dev->base_addr + 0x800, 4096);
unregister_netdev(dev);
kfree(dev); kfree(dev);
out: out:
return ret; return ret;
......
...@@ -822,7 +822,7 @@ ether3_probe(struct expansion_card *ec, const struct ecard_id *id) ...@@ -822,7 +822,7 @@ ether3_probe(struct expansion_card *ec, const struct ecard_id *id)
ether3_banner(); ether3_banner();
dev = init_etherdev(NULL, sizeof(struct dev_priv)); dev = alloc_etherdev(sizeof(struct dev_priv));
if (!dev) { if (!dev) {
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
...@@ -898,13 +898,16 @@ ether3_probe(struct expansion_card *ec, const struct ecard_id *id) ...@@ -898,13 +898,16 @@ ether3_probe(struct expansion_card *ec, const struct ecard_id *id)
dev->tx_timeout = ether3_timeout; dev->tx_timeout = ether3_timeout;
dev->watchdog_timeo = 5 * HZ / 100; dev->watchdog_timeo = 5 * HZ / 100;
ret = register_netdev(dev);
if (ret)
goto failed;
ecard_set_drvdata(ec, dev); ecard_set_drvdata(ec, dev);
return 0; return 0;
failed: failed:
release_region(dev->base_addr, 128); release_region(dev->base_addr, 128);
free: free:
unregister_netdev(dev);
kfree(dev); kfree(dev);
out: out:
return ret; return ret;
......
...@@ -551,14 +551,14 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id) ...@@ -551,14 +551,14 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
etherh_banner(); etherh_banner();
dev = init_etherdev(NULL, sizeof(struct etherh_priv)); dev = alloc_etherdev(sizeof(struct etherh_priv));
if (!dev) { if (!dev) {
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
} }
/* /*
* init_etherdev allocs and zeros dev->priv * alloc_etherdev allocs and zeros dev->priv
*/ */
eh = dev->priv; eh = dev->priv;
...@@ -694,17 +694,19 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id) ...@@ -694,17 +694,19 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
etherh_reset(dev); etherh_reset(dev);
NS8390_init(dev, 0); NS8390_init(dev, 0);
ret = register_netdev(dev);
if (ret)
goto release;
ecard_set_drvdata(ec, dev); ecard_set_drvdata(ec, dev);
return 0; return 0;
release: release:
release_region(dev->base_addr, 16); release_region(dev->base_addr, 16);
free: free:
unregister_netdev(dev);
kfree(dev->priv);
kfree(dev); kfree(dev);
out: out:
return ret; return ret;
} }
......
...@@ -203,7 +203,69 @@ enum wl3501_status { ...@@ -203,7 +203,69 @@ enum wl3501_status {
#define IW_REG_DOMAIN_MKK1 0x41 /* Channel 1-14 Japan */ #define IW_REG_DOMAIN_MKK1 0x41 /* Channel 1-14 Japan */
#define IW_REG_DOMAIN_ISRAEL 0x50 /* Channel 3 - 9 Israel */ #define IW_REG_DOMAIN_ISRAEL 0x50 /* Channel 3 - 9 Israel */
#define WL3501_ESSID_MAX_LEN (IW_ESSID_MAX_SIZE + 2) #define IW_MGMT_RATE_LABEL_MANDATORY 128 /* MSB */
enum iw_mgmt_rate_labels {
IW_MGMT_RATE_LABEL_1MBIT = 2,
IW_MGMT_RATE_LABEL_2MBIT = 4,
IW_MGMT_RATE_LABEL_5_5MBIT = 11,
IW_MGMT_RATE_LABEL_11MBIT = 22,
};
enum iw_mgmt_info_element_ids {
IW_MGMT_INFO_ELEMENT_SSID, /* Service Set Identity */
IW_MGMT_INFO_ELEMENT_SUPPORTED_RATES,
IW_MGMT_INFO_ELEMENT_FH_PARAMETER_SET,
IW_MGMT_INFO_ELEMENT_DS_PARAMETER_SET,
IW_MGMT_INFO_ELEMENT_CS_PARAMETER_SET,
IW_MGMT_INFO_ELEMENT_CS_TIM, /* Traffic Information Map */
IW_MGMT_INFO_ELEMENT_IBSS_PARAMETER_SET,
/* 7-15: Reserved, unused */
IW_MGMT_INFO_ELEMENT_CHALLENGE_TEXT = 16,
/* 17-31 Reserved for challenge text extension */
/* 32-255 Reserved, unused */
};
struct iw_mgmt_info_element {
u8 id; /* one of enum iw_mgmt_info_element_ids,
but sizeof(enum) > sizeof(u8) :-( */
u8 len;
u8 data[0];
} __attribute__ ((packed));
struct iw_mgmt_essid_pset {
struct iw_mgmt_info_element el;
u8 essid[IW_ESSID_MAX_SIZE];
} __attribute__ ((packed));
/*
* According to 802.11 Wireless Netowors, the definitive guide - O'Reilly
* Pg 75
*/
#define IW_DATA_RATE_MAX_LABELS 8
struct iw_mgmt_data_rset {
struct iw_mgmt_info_element el;
u8 data_rate_labels[IW_DATA_RATE_MAX_LABELS];
} __attribute__ ((packed));
struct iw_mgmt_ds_pset {
struct iw_mgmt_info_element el;
u8 chan;
} __attribute__ ((packed));
struct iw_mgmt_cf_pset {
struct iw_mgmt_info_element el;
u8 cfp_count;
u8 cfp_period;
u16 cfp_max_duration;
u16 cfp_dur_remaining;
} __attribute__ ((packed));
struct iw_mgmt_ibss_pset {
struct iw_mgmt_info_element el;
u16 atim_window;
} __attribute__ ((packed));
struct wl3501_tx_hdr { struct wl3501_tx_hdr {
u16 tx_cnt; u16 tx_cnt;
...@@ -244,19 +306,19 @@ struct wl3501_rx_hdr { ...@@ -244,19 +306,19 @@ struct wl3501_rx_hdr {
}; };
struct wl3501_start_req { struct wl3501_start_req {
u16 next_blk; u16 next_blk;
u8 sig_id; u8 sig_id;
u8 bss_type; u8 bss_type;
u16 beacon_period; u16 beacon_period;
u16 dtim_period; u16 dtim_period;
u16 probe_delay; u16 probe_delay;
u16 cap_info; u16 cap_info;
char ssid[WL3501_ESSID_MAX_LEN]; struct iw_mgmt_essid_pset ssid;
u8 bss_basic_rate_set[10]; struct iw_mgmt_data_rset bss_basic_rset;
u8 operational_rate_set[10]; struct iw_mgmt_data_rset operational_rset;
u8 cf_pset[8]; struct iw_mgmt_cf_pset cf_pset;
u8 phy_pset[3]; struct iw_mgmt_ds_pset ds_pset;
u8 ibss_pset[4]; struct iw_mgmt_ibss_pset ibss_pset;
}; };
struct wl3501_assoc_req { struct wl3501_assoc_req {
...@@ -317,25 +379,25 @@ struct wl3501_get_confirm { ...@@ -317,25 +379,25 @@ struct wl3501_get_confirm {
}; };
struct wl3501_join_req { struct wl3501_join_req {
u16 next_blk; u16 next_blk;
u8 sig_id; u8 sig_id;
u8 reserved; u8 reserved;
u8 operational_rate_set[10]; struct iw_mgmt_data_rset operational_rset;
u16 reserved2; u16 reserved2;
u16 timeout; u16 timeout;
u16 probe_delay; u16 probe_delay;
u8 timestamp[8]; u8 timestamp[8];
u8 local_time[8]; u8 local_time[8];
u16 beacon_period; u16 beacon_period;
u16 dtim_period; u16 dtim_period;
u16 cap_info; u16 cap_info;
u8 bss_type; u8 bss_type;
u8 bssid[ETH_ALEN]; u8 bssid[ETH_ALEN];
char ssid[WL3501_ESSID_MAX_LEN]; struct iw_mgmt_essid_pset ssid;
u8 phy_pset[3]; struct iw_mgmt_ds_pset ds_pset;
u8 cf_pset[8]; struct iw_mgmt_cf_pset cf_pset;
u8 ibss_pset[4]; struct iw_mgmt_ibss_pset ibss_pset;
u8 bss_basic_rate_set[10]; struct iw_mgmt_data_rset bss_basic_rset;
}; };
struct wl3501_join_confirm { struct wl3501_join_confirm {
...@@ -361,36 +423,36 @@ struct wl3501_pwr_mgmt_confirm { ...@@ -361,36 +423,36 @@ struct wl3501_pwr_mgmt_confirm {
}; };
struct wl3501_scan_req { struct wl3501_scan_req {
u16 next_blk; u16 next_blk;
u8 sig_id; u8 sig_id;
u8 bss_type; u8 bss_type;
u16 probe_delay; u16 probe_delay;
u16 min_chan_time; u16 min_chan_time;
u16 max_chan_time; u16 max_chan_time;
u8 chan_list[14]; u8 chan_list[14];
u8 bssid[ETH_ALEN]; u8 bssid[ETH_ALEN];
char ssid[WL3501_ESSID_MAX_LEN]; struct iw_mgmt_essid_pset ssid;
enum wl3501_scan_type scan_type; enum wl3501_scan_type scan_type;
}; };
struct wl3501_scan_confirm { struct wl3501_scan_confirm {
u16 next_blk; u16 next_blk;
u8 sig_id; u8 sig_id;
u8 reserved; u8 reserved;
u16 status; u16 status;
char timestamp[8]; char timestamp[8];
char localtime[8]; char localtime[8];
u16 beacon_period; u16 beacon_period;
u16 dtim_period; u16 dtim_period;
u16 cap_info; u16 cap_info;
u8 bss_type; u8 bss_type;
u8 bssid[ETH_ALEN]; u8 bssid[ETH_ALEN];
char ssid[WL3501_ESSID_MAX_LEN]; struct iw_mgmt_essid_pset ssid;
u8 phy_pset[3]; struct iw_mgmt_ds_pset ds_pset;
u8 cf_pset[8]; struct iw_mgmt_cf_pset cf_pset;
u8 ibss_pset[4]; struct iw_mgmt_ibss_pset ibss_pset;
u8 bss_basic_rate_set[10]; struct iw_mgmt_data_rset bss_basic_rset;
u8 rssi; u8 rssi;
}; };
struct wl3501_start_confirm { struct wl3501_start_confirm {
...@@ -527,10 +589,10 @@ struct wl3501_card { ...@@ -527,10 +589,10 @@ struct wl3501_card {
u16 esbq_confirm_start; u16 esbq_confirm_start;
u16 esbq_confirm_end; u16 esbq_confirm_end;
u16 esbq_confirm; u16 esbq_confirm;
u8 essid[WL3501_ESSID_MAX_LEN]; struct iw_mgmt_essid_pset essid;
struct iw_mgmt_essid_pset keep_essid;
u8 bssid[ETH_ALEN]; u8 bssid[ETH_ALEN];
int net_type; int net_type;
u8 keep_essid[WL3501_ESSID_MAX_LEN];
char nick[32]; char nick[32];
char card_name[32]; char card_name[32];
char firmware_date[32]; char firmware_date[32];
......
...@@ -220,6 +220,21 @@ static int iw_default_channel(int reg_domain) ...@@ -220,6 +220,21 @@ static int iw_default_channel(int reg_domain)
return rc; return rc;
} }
static void iw_set_mgmt_info_element(enum iw_mgmt_info_element_ids id,
struct iw_mgmt_info_element *el,
void *value, int len)
{
el->id = id;
el->len = len;
memcpy(el->data, value, len);
}
static void iw_copy_mgmt_info_element(struct iw_mgmt_info_element *to,
struct iw_mgmt_info_element *from)
{
iw_set_mgmt_info_element(from->id, to, from->data, from->len);
}
/* /*
* A linked list of "instances" of the wl24 device. Each actual PCMCIA card * A linked list of "instances" of the wl24 device. Each actual PCMCIA card
* corresponds to one device instance, and is described by one dev_link_t * corresponds to one device instance, and is described by one dev_link_t
...@@ -621,10 +636,12 @@ static int wl3501_mgmt_scan(struct wl3501_card *this, u16 chan_time) ...@@ -621,10 +636,12 @@ static int wl3501_mgmt_scan(struct wl3501_card *this, u16 chan_time)
static int wl3501_mgmt_join(struct wl3501_card *this, u16 stas) static int wl3501_mgmt_join(struct wl3501_card *this, u16 stas)
{ {
struct wl3501_join_req sig = { struct wl3501_join_req sig = {
.sig_id = WL3501_SIG_JOIN_REQ, .sig_id = WL3501_SIG_JOIN_REQ,
.timeout = 10, .timeout = 10,
.phy_pset = { .ds_pset = {
[2] = this->chan, .el.id = IW_MGMT_INFO_ELEMENT_DS_PARAMETER_SET,
.el.len = 1,
.chan = this->chan,
}, },
}; };
...@@ -638,24 +655,42 @@ static int wl3501_mgmt_start(struct wl3501_card *this) ...@@ -638,24 +655,42 @@ static int wl3501_mgmt_start(struct wl3501_card *this)
.sig_id = WL3501_SIG_START_REQ, .sig_id = WL3501_SIG_START_REQ,
.beacon_period = 400, .beacon_period = 400,
.dtim_period = 1, .dtim_period = 1,
.phy_pset = { .ds_pset = {
[0] = 3, [1] = 1, [2] = this->chan, .el.id = IW_MGMT_INFO_ELEMENT_DS_PARAMETER_SET,
.el.len = 1,
.chan = this->chan,
}, },
.bss_basic_rate_set = { .bss_basic_rset = {
[0] = 0x01, [1] = 0x02, [2] = 0x82, [3] = 0x84, .el.id = IW_MGMT_INFO_ELEMENT_SUPPORTED_RATES,
.el.len = 2,
.data_rate_labels = {
[0] = IW_MGMT_RATE_LABEL_MANDATORY |
IW_MGMT_RATE_LABEL_1MBIT,
[1] = IW_MGMT_RATE_LABEL_MANDATORY |
IW_MGMT_RATE_LABEL_2MBIT,
},
}, },
.operational_rate_set = { .operational_rset = {
[0] = 0x01, [1] = 0x02, [2] = 0x82, [3] = 0x84, .el.id = IW_MGMT_INFO_ELEMENT_SUPPORTED_RATES,
.el.len = 2,
.data_rate_labels = {
[0] = IW_MGMT_RATE_LABEL_MANDATORY |
IW_MGMT_RATE_LABEL_1MBIT,
[1] = IW_MGMT_RATE_LABEL_MANDATORY |
IW_MGMT_RATE_LABEL_2MBIT,
},
}, },
.ibss_pset = { .ibss_pset = {
[0] = 6, [1] = 2, [2] = 10, .el.id = IW_MGMT_INFO_ELEMENT_IBSS_PARAMETER_SET,
.el.len = 2,
.atim_window = 10,
}, },
.bss_type = wl3501_fw_bss_type(this), .bss_type = wl3501_fw_bss_type(this),
.cap_info = wl3501_fw_cap_info(this), .cap_info = wl3501_fw_cap_info(this),
}; };
memcpy(sig.ssid, this->essid, WL3501_ESSID_MAX_LEN); iw_copy_mgmt_info_element(&sig.ssid.el, &this->essid.el);
memcpy(this->keep_essid, this->essid, WL3501_ESSID_MAX_LEN); iw_copy_mgmt_info_element(&this->keep_essid.el, &this->essid.el);
return wl3501_esbq_exec(this, &sig, sizeof(sig)); return wl3501_esbq_exec(this, &sig, sizeof(sig));
} }
...@@ -674,15 +709,15 @@ static void wl3501_mgmt_scan_confirm(struct wl3501_card *this, u16 addr) ...@@ -674,15 +709,15 @@ static void wl3501_mgmt_scan_confirm(struct wl3501_card *this, u16 addr)
(this->net_type == IW_MODE_ADHOC && (this->net_type == IW_MODE_ADHOC &&
(sig.cap_info & WL3501_MGMT_CAPABILITY_IBSS)) || (sig.cap_info & WL3501_MGMT_CAPABILITY_IBSS)) ||
this->net_type == IW_MODE_AUTO) { this->net_type == IW_MODE_AUTO) {
if (!this->essid[1]) if (!this->essid.el.len)
matchflag = 1; matchflag = 1;
else if (this->essid[1] == 3 && else if (this->essid.el.len == 3 &&
!strncmp((char *)&this->essid[2], "ANY", 3)) !memcmp(this->essid.essid, "ANY", 3))
matchflag = 1; matchflag = 1;
else if (this->essid[1] != sig.ssid[1]) else if (this->essid.el.len != sig.ssid.el.len)
matchflag = 0; matchflag = 0;
else if (memcmp(&this->essid[2], &sig.ssid[2], else if (memcmp(this->essid.essid, sig.ssid.essid,
this->essid[1])) this->essid.el.len))
matchflag = 0; matchflag = 0;
else else
matchflag = 1; matchflag = 1;
...@@ -894,17 +929,18 @@ static void wl3501_mgmt_join_confirm(struct net_device *dev, u16 addr) ...@@ -894,17 +929,18 @@ static void wl3501_mgmt_join_confirm(struct net_device *dev, u16 addr)
const int i = this->join_sta_bss; const int i = this->join_sta_bss;
memcpy(this->bssid, memcpy(this->bssid,
this->bss_set[i].bssid, ETH_ALEN); this->bss_set[i].bssid, ETH_ALEN);
this->chan = this->bss_set[i].phy_pset[2]; this->chan = this->bss_set[i].ds_pset.chan;
memcpy(this->keep_essid, this->bss_set[i].ssid, iw_copy_mgmt_info_element(&this->keep_essid.el,
WL3501_ESSID_MAX_LEN); &this->bss_set[i].ssid.el);
wl3501_mgmt_auth(this); wl3501_mgmt_auth(this);
} }
} else { } else {
const int i = this->join_sta_bss; const int i = this->join_sta_bss;
memcpy(this->bssid, this->bss_set[i].bssid, ETH_ALEN);
this->chan = this->bss_set[i].phy_pset[2]; memcpy(&this->bssid, &this->bss_set[i].bssid, ETH_ALEN);
memcpy(this->keep_essid, this->chan = this->bss_set[i].ds_pset.chan;
this->bss_set[i].ssid, WL3501_ESSID_MAX_LEN); iw_copy_mgmt_info_element(&this->keep_essid.el,
&this->bss_set[i].ssid.el);
wl3501_online(dev); wl3501_online(dev);
} }
} else { } else {
...@@ -1688,19 +1724,79 @@ static int wl3501_get_wap(struct net_device *dev, struct iw_request_info *info, ...@@ -1688,19 +1724,79 @@ static int wl3501_get_wap(struct net_device *dev, struct iw_request_info *info,
return 0; return 0;
} }
static int wl3501_set_scan(struct net_device *dev, struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
/*
* FIXME: trigger scanning with a reset, yes, I'm lazy
*/
return wl3501_reset(dev);
}
static int wl3501_get_scan(struct net_device *dev, struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
struct wl3501_card *this = dev->priv;
int i;
char *current_ev = extra;
struct iw_event iwe;
for (i = 0; i < this->bss_cnt; ++i) {
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, this->bss_set[i].bssid, ETH_ALEN);
current_ev = iwe_stream_add_event(current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, IW_EV_ADDR_LEN);
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
iwe.u.data.length = this->bss_set[i].ssid.el.len;
current_ev = iwe_stream_add_point(current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe,
this->bss_set[i].ssid.essid);
iwe.cmd = SIOCGIWMODE;
iwe.u.mode = this->bss_set[i].bss_type;
current_ev = iwe_stream_add_event(current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, IW_EV_UINT_LEN);
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = this->bss_set[i].ds_pset.chan;
iwe.u.freq.e = 0;
current_ev = iwe_stream_add_event(current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, IW_EV_FREQ_LEN);
iwe.cmd = SIOCGIWENCODE;
if (this->bss_set[i].cap_info & WL3501_MGMT_CAPABILITY_PRIVACY)
iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
current_ev = iwe_stream_add_point(current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, NULL);
}
/* Length of data */
wrqu->data.length = (current_ev - extra);
wrqu->data.flags = 0; /* FIXME: set properly these flags */
return 0;
}
static int wl3501_set_essid(struct net_device *dev, static int wl3501_set_essid(struct net_device *dev,
struct iw_request_info *info, struct iw_request_info *info,
union iwreq_data *wrqu, char *extra) union iwreq_data *wrqu, char *extra)
{ {
struct wl3501_card *this = dev->priv; struct wl3501_card *this = dev->priv;
int rc = 0;
if (wrqu->data.flags) { if (wrqu->data.flags) {
strlcpy(this->essid + 2, extra, min_t(u16, wrqu->data.length, iw_set_mgmt_info_element(IW_MGMT_INFO_ELEMENT_SSID,
IW_ESSID_MAX_SIZE)); &this->essid.el,
rc = wl3501_reset(dev); extra, wrqu->data.length);
} else { /* We accept any ESSID */
iw_set_mgmt_info_element(IW_MGMT_INFO_ELEMENT_SSID,
&this->essid.el, "ANY", 3);
} }
return rc; return wl3501_reset(dev);
} }
static int wl3501_get_essid(struct net_device *dev, static int wl3501_get_essid(struct net_device *dev,
...@@ -1712,8 +1808,8 @@ static int wl3501_get_essid(struct net_device *dev, ...@@ -1712,8 +1808,8 @@ static int wl3501_get_essid(struct net_device *dev,
spin_lock_irqsave(&this->lock, flags); spin_lock_irqsave(&this->lock, flags);
wrqu->essid.flags = 1; wrqu->essid.flags = 1;
wrqu->essid.length = IW_ESSID_MAX_SIZE; wrqu->essid.length = this->essid.el.len;
strlcpy(extra, this->essid + 2, IW_ESSID_MAX_SIZE); memcpy(extra, this->essid.essid, this->essid.el.len);
spin_unlock_irqrestore(&this->lock, flags); spin_unlock_irqrestore(&this->lock, flags);
return 0; return 0;
} }
...@@ -1902,6 +1998,8 @@ static const iw_handler wl3501_handler[] = { ...@@ -1902,6 +1998,8 @@ static const iw_handler wl3501_handler[] = {
[SIOCGIWTHRSPY - SIOCIWFIRST] = iw_handler_get_thrspy, [SIOCGIWTHRSPY - SIOCIWFIRST] = iw_handler_get_thrspy,
[SIOCSIWAP - SIOCIWFIRST] = wl3501_set_wap, [SIOCSIWAP - SIOCIWFIRST] = wl3501_set_wap,
[SIOCGIWAP - SIOCIWFIRST] = wl3501_get_wap, [SIOCGIWAP - SIOCIWFIRST] = wl3501_get_wap,
[SIOCSIWSCAN - SIOCIWFIRST] = wl3501_set_scan,
[SIOCGIWSCAN - SIOCIWFIRST] = wl3501_get_scan,
[SIOCSIWESSID - SIOCIWFIRST] = wl3501_set_essid, [SIOCSIWESSID - SIOCIWFIRST] = wl3501_set_essid,
[SIOCGIWESSID - SIOCIWFIRST] = wl3501_get_essid, [SIOCGIWESSID - SIOCIWFIRST] = wl3501_get_essid,
[SIOCSIWNICKN - SIOCIWFIRST] = wl3501_set_nick, [SIOCSIWNICKN - SIOCIWFIRST] = wl3501_set_nick,
...@@ -2118,11 +2216,8 @@ static void wl3501_config(dev_link_t *link) ...@@ -2118,11 +2216,8 @@ static void wl3501_config(dev_link_t *link)
this->bss_cnt = 0; this->bss_cnt = 0;
this->join_sta_bss = 0; this->join_sta_bss = 0;
this->adhoc_times = 0; this->adhoc_times = 0;
this->essid[0] = 0; iw_set_mgmt_info_element(IW_MGMT_INFO_ELEMENT_SSID, &this->essid.el,
this->essid[1] = 3; "ANY", 3);
this->essid[2] = 'A';
this->essid[3] = 'N';
this->essid[4] = 'Y';
this->card_name[0] = '\0'; this->card_name[0] = '\0';
this->firmware_date[0] = '\0'; this->firmware_date[0] = '\0';
this->rssi = 255; this->rssi = 255;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment