diff options
Diffstat (limited to 'drivers/net/wireless/libertas/ethtool.c')
| -rw-r--r-- | drivers/net/wireless/libertas/ethtool.c | 234 |
1 files changed, 85 insertions, 149 deletions
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c index 0064de54296..f955b2d66ed 100644 --- a/drivers/net/wireless/libertas/ethtool.c +++ b/drivers/net/wireless/libertas/ethtool.c @@ -1,184 +1,120 @@ - +#include <linux/hardirq.h> #include <linux/netdevice.h> #include <linux/ethtool.h> #include <linux/delay.h> -#include "host.h" -#include "sbi.h" #include "decl.h" -#include "defs.h" -#include "dev.h" -#include "join.h" -#include "wext.h" -static const char * mesh_stat_strings[]= { - "drop_duplicate_bcast", - "drop_ttl_zero", - "drop_no_fwd_route", - "drop_no_buffers", - "fwded_unicast_cnt", - "fwded_bcast_cnt", - "drop_blind_table" -}; +#include "cmd.h" +#include "mesh.h" + -static void libertas_ethtool_get_drvinfo(struct net_device *dev, +static void lbs_ethtool_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - wlan_private *priv = (wlan_private *) dev->priv; - char fwver[32]; - - libertas_get_fwversion(priv->adapter, fwver, sizeof(fwver) - 1); - - strcpy(info->driver, "libertas"); - strcpy(info->version, libertas_driver_version); - strcpy(info->fw_version, fwver); + struct lbs_private *priv = dev->ml_priv; + + snprintf(info->fw_version, sizeof(info->fw_version), + "%u.%u.%u.p%u", + priv->fwrelease >> 24 & 0xff, + priv->fwrelease >> 16 & 0xff, + priv->fwrelease >> 8 & 0xff, + priv->fwrelease & 0xff); + strlcpy(info->driver, "libertas", sizeof(info->driver)); + strlcpy(info->version, lbs_driver_version, sizeof(info->version)); } -/* All 8388 parts have 16KiB EEPROM size at the time of writing. +/* + * All 8388 parts have 16KiB EEPROM size at the time of writing. * In case that changes this needs fixing. */ -#define LIBERTAS_EEPROM_LEN 16384 +#define LBS_EEPROM_LEN 16384 -static int libertas_ethtool_get_eeprom_len(struct net_device *dev) +static int lbs_ethtool_get_eeprom_len(struct net_device *dev) { - return LIBERTAS_EEPROM_LEN; + return LBS_EEPROM_LEN; } -static int libertas_ethtool_get_eeprom(struct net_device *dev, +static int lbs_ethtool_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 * bytes) { - wlan_private *priv = (wlan_private *) dev->priv; - wlan_adapter *adapter = priv->adapter; - struct wlan_ioctl_regrdwr regctrl; - char *ptr; + struct lbs_private *priv = dev->ml_priv; + struct cmd_ds_802_11_eeprom_access cmd; int ret; - regctrl.action = 0; - regctrl.offset = eeprom->offset; - regctrl.NOB = eeprom->len; - - if (eeprom->offset + eeprom->len > LIBERTAS_EEPROM_LEN) - return -EINVAL; - -// mutex_lock(&priv->mutex); - - adapter->prdeeprom = - (char *)kmalloc(eeprom->len+sizeof(regctrl), GFP_KERNEL); - if (!adapter->prdeeprom) - return -ENOMEM; - memcpy(adapter->prdeeprom, ®ctrl, sizeof(regctrl)); - - /* +14 is for action, offset, and NOB in - * response */ - lbs_pr_debug(1, "action:%d offset: %x NOB: %02x\n", - regctrl.action, regctrl.offset, regctrl.NOB); - - ret = libertas_prepare_and_send_command(priv, - cmd_802_11_eeprom_access, - regctrl.action, - cmd_option_waitforrsp, 0, - ®ctrl); - - if (ret) { - if (adapter->prdeeprom) - kfree(adapter->prdeeprom); - LEAVE(); - return ret; - } - - mdelay(10); - - ptr = (char *)adapter->prdeeprom; - - /* skip the command header, but include the "value" u32 variable */ - ptr = ptr + sizeof(struct wlan_ioctl_regrdwr) - 4; - - /* - * Return the result back to the user - */ - memcpy(bytes, ptr, eeprom->len); + lbs_deb_enter(LBS_DEB_ETHTOOL); - if (adapter->prdeeprom) - kfree(adapter->prdeeprom); -// mutex_unlock(&priv->mutex); + if (eeprom->offset + eeprom->len > LBS_EEPROM_LEN || + eeprom->len > LBS_EEPROM_READ_LEN) { + ret = -EINVAL; + goto out; + } - return 0; + cmd.hdr.size = cpu_to_le16(sizeof(struct cmd_ds_802_11_eeprom_access) - + LBS_EEPROM_READ_LEN + eeprom->len); + cmd.action = cpu_to_le16(CMD_ACT_GET); + cmd.offset = cpu_to_le16(eeprom->offset); + cmd.len = cpu_to_le16(eeprom->len); + ret = lbs_cmd_with_response(priv, CMD_802_11_EEPROM_ACCESS, &cmd); + if (!ret) + memcpy(bytes, cmd.value, eeprom->len); + +out: + lbs_deb_leave_args(LBS_DEB_ETHTOOL, "ret %d", ret); + return ret; } -static void libertas_ethtool_get_stats(struct net_device * dev, - struct ethtool_stats * stats, u64 * data) +static void lbs_ethtool_get_wol(struct net_device *dev, + struct ethtool_wolinfo *wol) { - wlan_private *priv = dev->priv; - - ENTER(); - - stats->cmd = ETHTOOL_GSTATS; - BUG_ON(stats->n_stats != MESH_STATS_NUM); + struct lbs_private *priv = dev->ml_priv; - data[0] = priv->mstats.fwd_drop_rbt; - data[1] = priv->mstats.fwd_drop_ttl; - data[2] = priv->mstats.fwd_drop_noroute; - data[3] = priv->mstats.fwd_drop_nobuf; - data[4] = priv->mstats.fwd_unicast_cnt; - data[5] = priv->mstats.fwd_bcast_cnt; - data[6] = priv->mstats.drop_blind; - - LEAVE(); -} - -static int libertas_ethtool_get_stats_count(struct net_device * dev) -{ - int ret; - wlan_private *priv = dev->priv; - struct cmd_ds_mesh_access mesh_access; - - ENTER(); - /* Get Mesh Statistics */ - ret = libertas_prepare_and_send_command(priv, - cmd_mesh_access, cmd_act_mesh_get_stats, - cmd_option_waitforrsp, 0, &mesh_access); - - if (ret) { - LEAVE(); - return 0; - } + wol->supported = WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY; - priv->mstats.fwd_drop_rbt = mesh_access.data[0]; - priv->mstats.fwd_drop_ttl = mesh_access.data[1]; - priv->mstats.fwd_drop_noroute = mesh_access.data[2]; - priv->mstats.fwd_drop_nobuf = mesh_access.data[3]; - priv->mstats.fwd_unicast_cnt = mesh_access.data[4]; - priv->mstats.fwd_bcast_cnt = mesh_access.data[5]; - priv->mstats.drop_blind = mesh_access.data[6]; + if (priv->wol_criteria == EHS_REMOVE_WAKEUP) + return; - LEAVE(); - return MESH_STATS_NUM; + if (priv->wol_criteria & EHS_WAKE_ON_UNICAST_DATA) + wol->wolopts |= WAKE_UCAST; + if (priv->wol_criteria & EHS_WAKE_ON_MULTICAST_DATA) + wol->wolopts |= WAKE_MCAST; + if (priv->wol_criteria & EHS_WAKE_ON_BROADCAST_DATA) + wol->wolopts |= WAKE_BCAST; + if (priv->wol_criteria & EHS_WAKE_ON_MAC_EVENT) + wol->wolopts |= WAKE_PHY; } -static void libertas_ethtool_get_strings (struct net_device * dev, - u32 stringset, - u8 * s) +static int lbs_ethtool_set_wol(struct net_device *dev, + struct ethtool_wolinfo *wol) { - int i; - - ENTER(); - switch (stringset) { - case ETH_SS_STATS: - for (i=0; i < MESH_STATS_NUM; i++) { - memcpy(s + i * ETH_GSTRING_LEN, - mesh_stat_strings[i], - ETH_GSTRING_LEN); - } - break; - } - LEAVE(); + struct lbs_private *priv = dev->ml_priv; + + if (wol->wolopts & ~(WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY)) + return -EOPNOTSUPP; + + priv->wol_criteria = 0; + if (wol->wolopts & WAKE_UCAST) + priv->wol_criteria |= EHS_WAKE_ON_UNICAST_DATA; + if (wol->wolopts & WAKE_MCAST) + priv->wol_criteria |= EHS_WAKE_ON_MULTICAST_DATA; + if (wol->wolopts & WAKE_BCAST) + priv->wol_criteria |= EHS_WAKE_ON_BROADCAST_DATA; + if (wol->wolopts & WAKE_PHY) + priv->wol_criteria |= EHS_WAKE_ON_MAC_EVENT; + if (wol->wolopts == 0) + priv->wol_criteria |= EHS_REMOVE_WAKEUP; + return 0; } -struct ethtool_ops libertas_ethtool_ops = { - .get_drvinfo = libertas_ethtool_get_drvinfo, - .get_eeprom = libertas_ethtool_get_eeprom, - .get_eeprom_len = libertas_ethtool_get_eeprom_len, - .get_stats_count = libertas_ethtool_get_stats_count, - .get_ethtool_stats = libertas_ethtool_get_stats, - .get_strings = libertas_ethtool_get_strings, +const struct ethtool_ops lbs_ethtool_ops = { + .get_drvinfo = lbs_ethtool_get_drvinfo, + .get_eeprom = lbs_ethtool_get_eeprom, + .get_eeprom_len = lbs_ethtool_get_eeprom_len, +#ifdef CONFIG_LIBERTAS_MESH + .get_sset_count = lbs_mesh_ethtool_get_sset_count, + .get_ethtool_stats = lbs_mesh_ethtool_get_stats, + .get_strings = lbs_mesh_ethtool_get_strings, +#endif + .get_wol = lbs_ethtool_get_wol, + .set_wol = lbs_ethtool_set_wol, }; |
