#define DRIVER_NAME "orinoco"
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
+#include <linux/if_arp.h>
#include <linux/wireless.h>
#include <net/iw_handler.h>
#include <net/ieee80211.h>
#define MAX_RID_LEN 1024
static const struct iw_handler_def orinoco_handler_def;
-static struct ethtool_ops orinoco_ethtool_ops;
+static const struct ethtool_ops orinoco_ethtool_ops;
/********************************************************************/
/* Data tables */
/* Note : gcc will optimise the whole section away if
* WIRELESS_SPY is not defined... - Jean II */
if (SPY_NUMBER(priv)) {
- orinoco_spy_gather(dev, skb->mac.raw + ETH_ALEN,
+ orinoco_spy_gather(dev, skb_mac_header(skb) + ETH_ALEN,
desc->signal, desc->silence);
}
}
/* Copy the 802.11 header to the skb */
memcpy(skb_put(skb, hdrlen), &(desc->frame_ctl), hdrlen);
- skb->mac.raw = skb->data;
+ skb_reset_mac_header(skb);
/* If any, copy the data from the card to the skb */
if (datalen > 0) {
memcpy(hdr->h_source, desc.addr2, ETH_ALEN);
dev->last_rx = jiffies;
- skb->dev = dev;
skb->protocol = eth_type_trans(skb, dev);
skb->ip_summed = CHECKSUM_NONE;
if (fc & IEEE80211_FCTL_TODS)
}
/* Search scan results for requested BSSID, join it if found */
-static void orinoco_join_ap(struct net_device *dev)
+static void orinoco_join_ap(struct work_struct *work)
{
- struct orinoco_private *priv = netdev_priv(dev);
+ struct orinoco_private *priv =
+ container_of(work, struct orinoco_private, join_work);
+ struct net_device *dev = priv->ndev;
struct hermes *hw = &priv->hw;
int err;
unsigned long flags;
}
/* Send new BSSID to userspace */
-static void orinoco_send_wevents(struct net_device *dev)
+static void orinoco_send_wevents(struct work_struct *work)
{
- struct orinoco_private *priv = netdev_priv(dev);
+ struct orinoco_private *priv =
+ container_of(work, struct orinoco_private, wevent_work);
+ struct net_device *dev = priv->ndev;
struct hermes *hw = &priv->hw;
union iwreq_data wrqu;
int err;
/* Set promiscuity / multicast*/
priv->promiscuous = 0;
priv->mc_count = 0;
- __orinoco_set_multicast_list(dev); /* FIXME: what about the xmit_lock */
+
+ /* FIXME: what about netif_tx_lock */
+ __orinoco_set_multicast_list(dev);
return 0;
}
/* This must be called from user context, without locks held - use
* schedule_work() */
-static void orinoco_reset(struct net_device *dev)
+static void orinoco_reset(struct work_struct *work)
{
- struct orinoco_private *priv = netdev_priv(dev);
+ struct orinoco_private *priv =
+ container_of(work, struct orinoco_private, reset_work);
+ struct net_device *dev = priv->ndev;
struct hermes *hw = &priv->hw;
int err;
unsigned long flags;
dev->name);
}
-irqreturn_t orinoco_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t orinoco_interrupt(int irq, void *dev_id)
{
- struct net_device *dev = (struct net_device *)dev_id;
+ struct net_device *dev = dev_id;
struct orinoco_private *priv = netdev_priv(dev);
hermes_t *hw = &priv->hw;
int count = MAX_IRQLOOPS_PER_IRQ;
int err;
struct comp_id nic_id, sta_id;
unsigned int firmver;
- char tmp[SYMBOL_MAX_VER_LEN+1];
+ char tmp[SYMBOL_MAX_VER_LEN+1] __attribute__((aligned(2)));
/* Get the hardware version */
err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id);
struct hermes_idstring nickbuf;
u16 reclen;
int len;
+ DECLARE_MAC_BUF(mac);
/* No need to lock, the hw_unavailable flag is already set in
* alloc_orinocodev() */
goto out;
}
- printk(KERN_DEBUG "%s: MAC address %02X:%02X:%02X:%02X:%02X:%02X\n",
- dev->name, dev->dev_addr[0], dev->dev_addr[1],
- dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4],
- dev->dev_addr[5]);
+ printk(KERN_DEBUG "%s: MAC address %s\n",
+ dev->name, print_mac(mac, dev->dev_addr));
/* Get the station name */
err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
priv->hw_unavailable = 1; /* orinoco_init() must clear this
* before anything else touches the
* hardware */
- INIT_WORK(&priv->reset_work, (void (*)(void *))orinoco_reset, dev);
- INIT_WORK(&priv->join_work, (void (*)(void *))orinoco_join_ap, dev);
- INIT_WORK(&priv->wevent_work, (void (*)(void *))orinoco_send_wevents, dev);
+ INIT_WORK(&priv->reset_work, orinoco_reset);
+ INIT_WORK(&priv->join_work, orinoco_join_ap);
+ INIT_WORK(&priv->wevent_work, orinoco_send_wevents);
netif_carrier_off(dev);
priv->last_linkstatus = 0xffff;
/* Wireless extensions */
/********************************************************************/
+/* Return : < 0 -> error code ; >= 0 -> length */
static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
char buf[IW_ESSID_MAX_SIZE+1])
{
len = le16_to_cpu(essidbuf.len);
BUG_ON(len > IW_ESSID_MAX_SIZE);
- memset(buf, 0, IW_ESSID_MAX_SIZE+1);
+ memset(buf, 0, IW_ESSID_MAX_SIZE);
memcpy(buf, p, len);
- buf[len] = '\0';
+ err = len;
fail_unlock:
orinoco_unlock(priv, &flags);
if (orinoco_lock(priv, &flags) != 0)
return -EBUSY;
- if (erq->pointer) {
+ if (erq->length > 0) {
if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
index = priv->tx_key;
if (erq->flags & IW_ENCODE_RESTRICTED)
restricted = 1;
- if (erq->pointer) {
+ if (erq->pointer && erq->length > 0) {
priv->keys[index].len = cpu_to_le16(xlen);
memset(priv->keys[index].data, 0,
sizeof(priv->keys[index].data));
if (netif_running(dev)) {
err = orinoco_hw_get_essid(priv, &active, essidbuf);
- if (err)
+ if (err < 0)
return err;
+ erq->length = err;
} else {
if (orinoco_lock(priv, &flags) != 0)
return -EBUSY;
- memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE + 1);
+ memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE);
+ erq->length = strlen(priv->desired_essid);
orinoco_unlock(priv, &flags);
}
erq->flags = 1;
- erq->length = strlen(essidbuf) + 1;
return 0;
}
if (orinoco_lock(priv, &flags) != 0)
return -EBUSY;
- memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1);
+ memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE);
orinoco_unlock(priv, &flags);
- nrq->length = strlen(nickbuf)+1;
+ nrq->length = strlen(priv->nick);
return 0;
}
rrq->value = lifetime * 1000; /* ??? */
} else {
/* By default, display the min number */
- if ((rrq->flags & IW_RETRY_MAX)) {
- rrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
+ if ((rrq->flags & IW_RETRY_LONG)) {
+ rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
rrq->value = long_limit;
} else {
rrq->flags = IW_RETRY_LIMIT;
rrq->value = short_limit;
if(short_limit != long_limit)
- rrq->flags |= IW_RETRY_MIN;
+ rrq->flags |= IW_RETRY_SHORT;
}
}
printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name);
/* Firmware reset */
- orinoco_reset(dev);
+ orinoco_reset(&priv->reset_work);
} else {
printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
return 0;
if (priv->broken_disableport) {
- orinoco_reset(dev);
+ orinoco_reset(&priv->reset_work);
return 0;
}
strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1);
strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
strncpy(info->fw_version, priv->fw_name, sizeof(info->fw_version) - 1);
- if (dev->class_dev.dev)
- strncpy(info->bus_info, dev->class_dev.dev->bus_id,
+ if (dev->dev.parent)
+ strncpy(info->bus_info, dev->dev.parent->bus_id,
sizeof(info->bus_info) - 1);
else
snprintf(info->bus_info, sizeof(info->bus_info) - 1,
"PCMCIA %p", priv->hw.iobase);
}
-static struct ethtool_ops orinoco_ethtool_ops = {
+static const struct ethtool_ops orinoco_ethtool_ops = {
.get_drvinfo = orinoco_get_drvinfo,
.get_link = ethtool_op_get_link,
};