Commit cb3126e6 authored by Karl Relton's avatar Karl Relton Committed by Greg Kroah-Hartman

Staging: wlan-ng: Switch from wext to cfg80211

Switch driver over from wext to cfg80211 interface.

Some Notes:

- This patch moves the driver wholesale from wext to cfg80211. Wext
support is still provided through the cfg80211 provided wext
compatability layer.

- Currently only infrastructure mode is implemented. Ad hoc mode is not
yet implemented, but can be added.

- It does not support connecting to a specified bssid, instead roaming
is handled by the card itself. This matches the behaviour of the
existing driver.

- It has been tested using NetworkManager (via wpa_supplicant)
configured to use the wext compatability layer, and then again with the
native nl80211 layer.
Signed-off-by: default avatarKarl Relton <karllinuxtest.relton@ntlworld.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 9c770f3b
...@@ -4,5 +4,4 @@ prism2_usb-objs := prism2usb.o \ ...@@ -4,5 +4,4 @@ prism2_usb-objs := prism2usb.o \
p80211conv.o \ p80211conv.o \
p80211req.o \ p80211req.o \
p80211wep.o \ p80211wep.o \
p80211wext.o \
p80211netdev.o p80211netdev.o
This diff is collapsed.
...@@ -1284,6 +1284,8 @@ typedef struct hfa384x { ...@@ -1284,6 +1284,8 @@ typedef struct hfa384x {
u16 link_status_new; u16 link_status_new;
struct sk_buff_head authq; struct sk_buff_head authq;
u32 txrate;
/* And here we have stuff that used to be in priv */ /* And here we have stuff that used to be in priv */
/* State variables */ /* State variables */
......
...@@ -113,6 +113,7 @@ typedef struct p80211msg_dot11req_scan_results { ...@@ -113,6 +113,7 @@ typedef struct p80211msg_dot11req_scan_results {
p80211item_uint32_t cfpollable; p80211item_uint32_t cfpollable;
p80211item_uint32_t cfpollreq; p80211item_uint32_t cfpollreq;
p80211item_uint32_t privacy; p80211item_uint32_t privacy;
p80211item_uint32_t capinfo;
p80211item_uint32_t basicrate1; p80211item_uint32_t basicrate1;
p80211item_uint32_t basicrate2; p80211item_uint32_t basicrate2;
p80211item_uint32_t basicrate3; p80211item_uint32_t basicrate3;
...@@ -209,6 +210,7 @@ typedef struct p80211msg_lnxreq_commsquality { ...@@ -209,6 +210,7 @@ typedef struct p80211msg_lnxreq_commsquality {
p80211item_uint32_t link; p80211item_uint32_t link;
p80211item_uint32_t level; p80211item_uint32_t level;
p80211item_uint32_t noise; p80211item_uint32_t noise;
p80211item_uint32_t txrate;
} __attribute__ ((packed)) p80211msg_lnxreq_commsquality_t; } __attribute__ ((packed)) p80211msg_lnxreq_commsquality_t;
typedef struct p80211msg_lnxreq_autojoin { typedef struct p80211msg_lnxreq_autojoin {
......
...@@ -75,6 +75,7 @@ ...@@ -75,6 +75,7 @@
#include <net/iw_handler.h> #include <net/iw_handler.h>
#include <net/net_namespace.h> #include <net/net_namespace.h>
#include <net/cfg80211.h>
#include "p80211types.h" #include "p80211types.h"
#include "p80211hdr.h" #include "p80211hdr.h"
...@@ -87,6 +88,8 @@ ...@@ -87,6 +88,8 @@
#include "p80211metastruct.h" #include "p80211metastruct.h"
#include "p80211metadef.h" #include "p80211metadef.h"
#include "cfg80211.c"
/* Support functions */ /* Support functions */
static void p80211netdev_rx_bh(unsigned long arg); static void p80211netdev_rx_bh(unsigned long arg);
...@@ -732,6 +735,7 @@ static const struct net_device_ops p80211_netdev_ops = { ...@@ -732,6 +735,7 @@ static const struct net_device_ops p80211_netdev_ops = {
* Arguments: * Arguments:
* wlandev ptr to the wlandev structure for the * wlandev ptr to the wlandev structure for the
* interface. * interface.
* physdev ptr to usb device
* Returns: * Returns:
* zero on success, non-zero otherwise. * zero on success, non-zero otherwise.
* Call Context: * Call Context:
...@@ -740,10 +744,12 @@ static const struct net_device_ops p80211_netdev_ops = { ...@@ -740,10 +744,12 @@ static const struct net_device_ops p80211_netdev_ops = {
* compiled drivers, this function will be called in the * compiled drivers, this function will be called in the
* context of the kernel startup code. * context of the kernel startup code.
----------------------------------------------------------------*/ ----------------------------------------------------------------*/
int wlan_setup(wlandevice_t *wlandev) int wlan_setup(wlandevice_t *wlandev, struct device *physdev)
{ {
int result = 0; int result = 0;
netdevice_t *dev; netdevice_t *netdev;
struct wiphy *wiphy;
struct wireless_dev *wdev;
/* Set up the wlandev */ /* Set up the wlandev */
wlandev->state = WLAN_DEVICE_CLOSED; wlandev->state = WLAN_DEVICE_CLOSED;
...@@ -755,20 +761,30 @@ int wlan_setup(wlandevice_t *wlandev) ...@@ -755,20 +761,30 @@ int wlan_setup(wlandevice_t *wlandev)
tasklet_init(&wlandev->rx_bh, tasklet_init(&wlandev->rx_bh,
p80211netdev_rx_bh, (unsigned long)wlandev); p80211netdev_rx_bh, (unsigned long)wlandev);
/* Allocate and initialize the wiphy struct */
wiphy = wlan_create_wiphy(physdev, wlandev);
if (wiphy == NULL) {
printk(KERN_ERR "Failed to alloc wiphy.\n");
return 1;
}
/* Allocate and initialize the struct device */ /* Allocate and initialize the struct device */
dev = alloc_netdev(0, "wlan%d", ether_setup); netdev = alloc_netdev(sizeof(struct wireless_dev), "wlan%d", ether_setup);
if (dev == NULL) { if (netdev == NULL) {
printk(KERN_ERR "Failed to alloc netdev.\n"); printk(KERN_ERR "Failed to alloc netdev.\n");
wlan_free_wiphy(wiphy);
result = 1; result = 1;
} else { } else {
wlandev->netdev = dev; wlandev->netdev = netdev;
dev->ml_priv = wlandev; netdev->ml_priv = wlandev;
dev->netdev_ops = &p80211_netdev_ops; netdev->netdev_ops = &p80211_netdev_ops;
wdev = netdev_priv(netdev);
dev->wireless_handlers = &p80211wext_handler_def; wdev->wiphy = wiphy;
wdev->iftype = NL80211_IFTYPE_STATION;
netif_stop_queue(dev); netdev->ieee80211_ptr = wdev;
netif_carrier_off(dev);
netif_stop_queue(netdev);
netif_carrier_off(netdev);
} }
return result; return result;
...@@ -797,14 +813,13 @@ int wlan_setup(wlandevice_t *wlandev) ...@@ -797,14 +813,13 @@ int wlan_setup(wlandevice_t *wlandev)
----------------------------------------------------------------*/ ----------------------------------------------------------------*/
int wlan_unsetup(wlandevice_t *wlandev) int wlan_unsetup(wlandevice_t *wlandev)
{ {
int result = 0; struct wireless_dev *wdev;
tasklet_kill(&wlandev->rx_bh); tasklet_kill(&wlandev->rx_bh);
if (wlandev->netdev == NULL) { if (wlandev->netdev) {
printk(KERN_ERR "called without wlandev->netdev set.\n"); wdev = netdev_priv(wlandev->netdev);
result = 1; if(wdev->wiphy) wlan_free_wiphy(wdev->wiphy);
} else {
free_netdev(wlandev->netdev); free_netdev(wlandev->netdev);
wlandev->netdev = NULL; wlandev->netdev = NULL;
} }
......
...@@ -148,6 +148,7 @@ int p80211wext_event_associated(struct wlandevice *wlandev, int assoc); ...@@ -148,6 +148,7 @@ int p80211wext_event_associated(struct wlandevice *wlandev, int assoc);
#define MAX_KEYLEN 32 #define MAX_KEYLEN 32
#define HOSTWEP_DEFAULTKEY_MASK (BIT(1)|BIT(0)) #define HOSTWEP_DEFAULTKEY_MASK (BIT(1)|BIT(0))
#define HOSTWEP_SHAREDKEY BIT(3)
#define HOSTWEP_DECRYPT BIT(4) #define HOSTWEP_DECRYPT BIT(4)
#define HOSTWEP_ENCRYPT BIT(5) #define HOSTWEP_ENCRYPT BIT(5)
#define HOSTWEP_PRIVACYINVOKED BIT(6) #define HOSTWEP_PRIVACYINVOKED BIT(6)
...@@ -233,7 +234,7 @@ int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override, ...@@ -233,7 +234,7 @@ int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override,
int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum, int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum,
u8 *iv, u8 *icv); u8 *iv, u8 *icv);
int wlan_setup(wlandevice_t *wlandev); int wlan_setup(wlandevice_t *wlandev, struct device *physdev);
int wlan_unsetup(wlandevice_t *wlandev); int wlan_unsetup(wlandevice_t *wlandev);
int register_wlandev(wlandevice_t *wlandev); int register_wlandev(wlandevice_t *wlandev);
int unregister_wlandev(wlandevice_t *wlandev); int unregister_wlandev(wlandevice_t *wlandev);
......
This diff is collapsed.
...@@ -463,6 +463,8 @@ int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp) ...@@ -463,6 +463,8 @@ int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
/* capinfo bits */ /* capinfo bits */
count = le16_to_cpu(item->capinfo); count = le16_to_cpu(item->capinfo);
req->capinfo.status = P80211ENUM_msgitem_status_data_ok;
req->capinfo.data = count;
/* privacy flag */ /* privacy flag */
req->privacy.status = P80211ENUM_msgitem_status_data_ok; req->privacy.status = P80211ENUM_msgitem_status_data_ok;
......
...@@ -124,6 +124,10 @@ MODULE_PARM_DESC(prism2_reset_settletime, "reset settle time in ms"); ...@@ -124,6 +124,10 @@ MODULE_PARM_DESC(prism2_reset_settletime, "reset settle time in ms");
MODULE_LICENSE("Dual MPL/GPL"); MODULE_LICENSE("Dual MPL/GPL");
void prism2_connect_result(wlandevice_t *wlandev, u8 failed);
void prism2_disconnected(wlandevice_t *wlandev);
void prism2_roamed(wlandevice_t *wlandev);
static int prism2sta_open(wlandevice_t *wlandev); static int prism2sta_open(wlandevice_t *wlandev);
static int prism2sta_close(wlandevice_t *wlandev); static int prism2sta_close(wlandevice_t *wlandev);
static void prism2sta_reset(wlandevice_t *wlandev); static void prism2sta_reset(wlandevice_t *wlandev);
...@@ -401,6 +405,7 @@ static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg) ...@@ -401,6 +405,7 @@ static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg)
qualmsg->link.data = le16_to_cpu(hw->qual.CQ_currBSS); qualmsg->link.data = le16_to_cpu(hw->qual.CQ_currBSS);
qualmsg->level.data = le16_to_cpu(hw->qual.ASL_currBSS); qualmsg->level.data = le16_to_cpu(hw->qual.ASL_currBSS);
qualmsg->noise.data = le16_to_cpu(hw->qual.ANL_currFC); qualmsg->noise.data = le16_to_cpu(hw->qual.ANL_currFC);
qualmsg->txrate.data = hw->txrate;
break; break;
} }
...@@ -1300,6 +1305,9 @@ void prism2sta_processing_defer(struct work_struct *data) ...@@ -1300,6 +1305,9 @@ void prism2sta_processing_defer(struct work_struct *data)
(portstatus == HFA384x_PSTATUS_CONN_IBSS) ? (portstatus == HFA384x_PSTATUS_CONN_IBSS) ?
WLAN_MACMODE_IBSS_STA : WLAN_MACMODE_ESS_STA; WLAN_MACMODE_IBSS_STA : WLAN_MACMODE_ESS_STA;
/* signal back up to cfg80211 layer */
prism2_connect_result(wlandev, P80211ENUM_truth_false);
/* Get the ball rolling on the comms quality stuff */ /* Get the ball rolling on the comms quality stuff */
prism2sta_commsqual_defer(&hw->commsqual_bh); prism2sta_commsqual_defer(&hw->commsqual_bh);
} }
...@@ -1315,25 +1323,16 @@ void prism2sta_processing_defer(struct work_struct *data) ...@@ -1315,25 +1323,16 @@ void prism2sta_processing_defer(struct work_struct *data)
* Indicate Deauthentication * Indicate Deauthentication
* Block Transmits, Ignore receives of data frames * Block Transmits, Ignore receives of data frames
*/ */
if (hw->join_ap == 2) { if (wlandev->netdev->type == ARPHRD_ETHER)
hfa384x_JoinRequest_data_t joinreq;
joinreq = hw->joinreq;
/* Send the join request */
hfa384x_drvr_setconfig(hw,
HFA384x_RID_JOINREQUEST,
&joinreq,
HFA384x_RID_JOINREQUEST_LEN);
printk(KERN_INFO printk(KERN_INFO
"linkstatus=DISCONNECTED (re-submitting join)\n"); "linkstatus=DISCONNECTED (unhandled)\n");
} else {
if (wlandev->netdev->type == ARPHRD_ETHER)
printk(KERN_INFO
"linkstatus=DISCONNECTED (unhandled)\n");
}
wlandev->macmode = WLAN_MACMODE_NONE; wlandev->macmode = WLAN_MACMODE_NONE;
netif_carrier_off(wlandev->netdev); netif_carrier_off(wlandev->netdev);
/* signal back up to cfg80211 layer */
prism2_disconnected(wlandev);
break; break;
case HFA384x_LINK_AP_CHANGE: case HFA384x_LINK_AP_CHANGE:
...@@ -1376,6 +1375,9 @@ void prism2sta_processing_defer(struct work_struct *data) ...@@ -1376,6 +1375,9 @@ void prism2sta_processing_defer(struct work_struct *data)
hw->link_status = HFA384x_LINK_CONNECTED; hw->link_status = HFA384x_LINK_CONNECTED;
netif_carrier_on(wlandev->netdev); netif_carrier_on(wlandev->netdev);
/* signal back up to cfg80211 layer */
prism2_roamed(wlandev);
break; break;
case HFA384x_LINK_AP_OUTOFRANGE: case HFA384x_LINK_AP_OUTOFRANGE:
...@@ -1435,6 +1437,9 @@ void prism2sta_processing_defer(struct work_struct *data) ...@@ -1435,6 +1437,9 @@ void prism2sta_processing_defer(struct work_struct *data)
netif_carrier_off(wlandev->netdev); netif_carrier_off(wlandev->netdev);
/* signal back up to cfg80211 layer */
prism2_connect_result(wlandev, P80211ENUM_truth_true);
break; break;
default: default:
...@@ -1446,7 +1451,6 @@ void prism2sta_processing_defer(struct work_struct *data) ...@@ -1446,7 +1451,6 @@ void prism2sta_processing_defer(struct work_struct *data)
} }
wlandev->linkstatus = (hw->link_status == HFA384x_LINK_CONNECTED); wlandev->linkstatus = (hw->link_status == HFA384x_LINK_CONNECTED);
p80211wext_event_associated(wlandev, wlandev->linkstatus);
failed: failed:
return; return;
...@@ -1985,6 +1989,8 @@ void prism2sta_commsqual_defer(struct work_struct *data) ...@@ -1985,6 +1989,8 @@ void prism2sta_commsqual_defer(struct work_struct *data)
hfa384x_t *hw = container_of(data, struct hfa384x, commsqual_bh); hfa384x_t *hw = container_of(data, struct hfa384x, commsqual_bh);
wlandevice_t *wlandev = hw->wlandev; wlandevice_t *wlandev = hw->wlandev;
hfa384x_bytestr32_t ssid; hfa384x_bytestr32_t ssid;
p80211msg_dot11req_mibget_t msg;
p80211item_uint32_t *mibitem = (p80211item_uint32_t *) &msg.mibattribute.data;
int result = 0; int result = 0;
if (hw->wlandev->hwremoved) if (hw->wlandev->hwremoved)
...@@ -2013,6 +2019,34 @@ void prism2sta_commsqual_defer(struct work_struct *data) ...@@ -2013,6 +2019,34 @@ void prism2sta_commsqual_defer(struct work_struct *data)
le16_to_cpu(hw->qual.ANL_currFC)); le16_to_cpu(hw->qual.ANL_currFC));
} }
/* Get the signal rate */
msg.msgcode = DIDmsg_dot11req_mibget;
mibitem->did = DIDmib_p2_p2MAC_p2CurrentTxRate;
result = p80211req_dorequest(wlandev, (u8 *) & msg);
if (result) {
pr_debug("get signal rate failed, result = %d\n",
result);
goto done;
}
switch (mibitem->data) {
case HFA384x_RATEBIT_1:
hw->txrate = 10;
break;
case HFA384x_RATEBIT_2:
hw->txrate = 20;
break;
case HFA384x_RATEBIT_5dot5:
hw->txrate = 55;
break;
case HFA384x_RATEBIT_11:
hw->txrate = 110;
break;
default:
pr_debug("Bad ratebit (%d)\n", mibitem->data);
}
/* Lastly, we need to make sure the BSSID didn't change on us */ /* Lastly, we need to make sure the BSSID didn't change on us */
result = hfa384x_drvr_getconfig(hw, result = hfa384x_drvr_getconfig(hw,
HFA384x_RID_CURRENTBSSID, HFA384x_RID_CURRENTBSSID,
......
...@@ -119,7 +119,7 @@ static int prism2sta_probe_usb(struct usb_interface *interface, ...@@ -119,7 +119,7 @@ static int prism2sta_probe_usb(struct usb_interface *interface,
} }
hw = wlandev->priv; hw = wlandev->priv;
if (wlan_setup(wlandev) != 0) { if (wlan_setup(wlandev, &(interface->dev)) != 0) {
printk(KERN_ERR "%s: wlan_setup() failed.\n", dev_info); printk(KERN_ERR "%s: wlan_setup() failed.\n", dev_info);
result = -EIO; result = -EIO;
goto failed; goto failed;
......
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