aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/wireless/p54/fwio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/p54/fwio.c')
-rw-r--r--drivers/net/wireless/p54/fwio.c120
1 files changed, 83 insertions, 37 deletions
diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c
index e7b9e9cb39f..bc065e8e348 100644
--- a/drivers/net/wireless/p54/fwio.c
+++ b/drivers/net/wireless/p54/fwio.c
@@ -16,9 +16,10 @@
* published by the Free Software Foundation.
*/
-#include <linux/init.h>
+#include <linux/slab.h>
#include <linux/firmware.h>
#include <linux/etherdevice.h>
+#include <linux/export.h>
#include <net/mac80211.h>
@@ -61,16 +62,15 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
case FW_LM20:
case FW_LM87: {
char *iftype = (char *)bootrec->data;
- printk(KERN_INFO "%s: p54 detected a LM%c%c "
- "firmware\n",
- wiphy_name(priv->hw->wiphy),
- iftype[2], iftype[3]);
+ wiphy_info(priv->hw->wiphy,
+ "p54 detected a LM%c%c firmware\n",
+ iftype[2], iftype[3]);
break;
}
case FW_FMAC:
default:
- printk(KERN_ERR "%s: unsupported firmware\n",
- wiphy_name(priv->hw->wiphy));
+ wiphy_err(priv->hw->wiphy,
+ "unsupported firmware\n");
return -ENODEV;
}
break;
@@ -123,16 +123,20 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
bootrec = (struct bootrec *)&bootrec->data[len];
}
- if (fw_version)
- printk(KERN_INFO "%s: FW rev %s - Softmac protocol %x.%x\n",
- wiphy_name(priv->hw->wiphy), fw_version,
- priv->fw_var >> 8, priv->fw_var & 0xff);
+ if (fw_version) {
+ wiphy_info(priv->hw->wiphy,
+ "FW rev %s - Softmac protocol %x.%x\n",
+ fw_version, priv->fw_var >> 8, priv->fw_var & 0xff);
+ snprintf(dev->wiphy->fw_version, sizeof(dev->wiphy->fw_version),
+ "%s - %x.%x", fw_version,
+ priv->fw_var >> 8, priv->fw_var & 0xff);
+ }
if (priv->fw_var < 0x500)
- printk(KERN_INFO "%s: you are using an obsolete firmware. "
- "visit http://wireless.kernel.org/en/users/Drivers/p54 "
- "and grab one for \"kernel >= 2.6.28\"!\n",
- wiphy_name(priv->hw->wiphy));
+ wiphy_info(priv->hw->wiphy,
+ "you are using an obsolete firmware. "
+ "visit http://wireless.kernel.org/en/users/Drivers/p54 "
+ "and grab one for \"kernel >= 2.6.28\"!\n");
if (priv->fw_var >= 0x300) {
/* Firmware supports QoS, use it! */
@@ -151,13 +155,14 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
priv->hw->queues = P54_QUEUE_AC_NUM;
}
- printk(KERN_INFO "%s: cryptographic accelerator "
- "WEP:%s, TKIP:%s, CCMP:%s\n", wiphy_name(priv->hw->wiphy),
- (priv->privacy_caps & BR_DESC_PRIV_CAP_WEP) ? "YES" :
- "no", (priv->privacy_caps & (BR_DESC_PRIV_CAP_TKIP |
- BR_DESC_PRIV_CAP_MICHAEL)) ? "YES" : "no",
- (priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP) ?
- "YES" : "no");
+ wiphy_info(priv->hw->wiphy,
+ "cryptographic accelerator WEP:%s, TKIP:%s, CCMP:%s\n",
+ (priv->privacy_caps & BR_DESC_PRIV_CAP_WEP) ? "YES" : "no",
+ (priv->privacy_caps &
+ (BR_DESC_PRIV_CAP_TKIP | BR_DESC_PRIV_CAP_MICHAEL))
+ ? "YES" : "no",
+ (priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP)
+ ? "YES" : "no");
if (priv->rx_keycache_size) {
/*
@@ -246,8 +251,7 @@ int p54_download_eeprom(struct p54_common *priv, void *buf,
if (!wait_for_completion_interruptible_timeout(
&priv->eeprom_comp, HZ)) {
- printk(KERN_ERR "%s: device does not respond!\n",
- wiphy_name(priv->hw->wiphy));
+ wiphy_err(priv->hw->wiphy, "device does not respond!\n");
ret = -EBUSY;
}
priv->eeprom = NULL;
@@ -381,6 +385,7 @@ int p54_setup_mac(struct p54_common *priv)
setup->v2.osc_start_delay = cpu_to_le16(65535);
}
p54_tx(priv, skb);
+ priv->phy_idle = mode == P54_FILTER_TYPE_HIBERNATE;
return 0;
}
@@ -393,10 +398,10 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell)
union p54_scan_body_union *body;
struct p54_scan_tail_rate *rate;
struct pda_rssi_cal_entry *rssi;
+ struct p54_rssi_db_entry *rssi_data;
unsigned int i;
void *entry;
- int band = priv->hw->conf.channel->band;
- __le16 freq = cpu_to_le16(priv->hw->conf.channel->center_freq);
+ __le16 freq = cpu_to_le16(priv->hw->conf.chandef.chan->center_freq);
skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*head) +
2 + sizeof(*iq_autocal) + sizeof(*body) +
@@ -472,7 +477,7 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell)
if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
memcpy(&body->longbow.curve_data,
- (void *) entry + sizeof(__le16),
+ entry + sizeof(__le16),
priv->curve_data->entry_size);
} else {
struct p54_scan_body *chan = &body->normal;
@@ -499,13 +504,14 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell)
}
rssi = (struct pda_rssi_cal_entry *) skb_put(skb, sizeof(*rssi));
- rssi->mul = cpu_to_le16(priv->rssical_db[band].mul);
- rssi->add = cpu_to_le16(priv->rssical_db[band].add);
+ rssi_data = p54_rssi_find(priv, le16_to_cpu(freq));
+ rssi->mul = cpu_to_le16(rssi_data->mul);
+ rssi->add = cpu_to_le16(rssi_data->add);
if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
/* Longbow frontend needs ever more */
rssi = (void *) skb_put(skb, sizeof(*rssi));
- rssi->mul = cpu_to_le16(priv->rssical_db[band].longbow_unkn);
- rssi->add = cpu_to_le16(priv->rssical_db[band].longbow_unk2);
+ rssi->mul = cpu_to_le16(rssi_data->longbow_unkn);
+ rssi->add = cpu_to_le16(rssi_data->longbow_unk2);
}
if (priv->fw_var >= 0x509) {
@@ -519,12 +525,13 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell)
hdr->len = cpu_to_le16(skb->len - sizeof(*hdr));
p54_tx(priv, skb);
+ priv->cur_rssi = rssi_data;
return 0;
err:
- printk(KERN_ERR "%s: frequency change to channel %d failed.\n",
- wiphy_name(priv->hw->wiphy), ieee80211_frequency_to_channel(
- priv->hw->conf.channel->center_freq));
+ wiphy_err(priv->hw->wiphy, "frequency change to channel %d failed.\n",
+ ieee80211_frequency_to_channel(
+ priv->hw->conf.chandef.chan->center_freq));
dev_kfree_skb_any(skb);
return -EINVAL;
@@ -553,6 +560,7 @@ int p54_set_edcf(struct p54_common *priv)
{
struct sk_buff *skb;
struct p54_edcf *edcf;
+ u8 rtd;
skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*edcf),
P54_CONTROL_TYPE_DCFINIT, GFP_ATOMIC);
@@ -569,9 +577,15 @@ int p54_set_edcf(struct p54_common *priv)
edcf->sifs = 0x0a;
edcf->eofpad = 0x06;
}
+ /*
+ * calculate the extra round trip delay according to the
+ * formula from 802.11-2007 17.3.8.6.
+ */
+ rtd = 3 * priv->coverage_class;
+ edcf->slottime += rtd;
+ edcf->round_trip_delay = cpu_to_le16(rtd);
/* (see prism54/isl_oid.h for further details) */
edcf->frameburst = cpu_to_le16(0);
- edcf->round_trip_delay = cpu_to_le16(0);
edcf->flags = 0;
memset(edcf->mapping, 0, sizeof(edcf->mapping));
memcpy(edcf->queue, priv->qos_params, sizeof(edcf->queue));
@@ -613,6 +627,7 @@ int p54_set_ps(struct p54_common *priv)
psm->exclude[0] = WLAN_EID_TIM;
p54_tx(priv, skb);
+ priv->phy_ps = mode != P54_PSM_CAM;
return 0;
}
@@ -675,8 +690,8 @@ int p54_upload_key(struct p54_common *priv, u8 algo, int slot, u8 idx, u8 len,
break;
default:
- printk(KERN_ERR "%s: invalid cryptographic algorithm: %d\n",
- wiphy_name(priv->hw->wiphy), algo);
+ wiphy_err(priv->hw->wiphy,
+ "invalid cryptographic algorithm: %d\n", algo);
dev_kfree_skb(skb);
return -EINVAL;
}
@@ -714,3 +729,34 @@ int p54_fetch_statistics(struct p54_common *priv)
p54_tx(priv, skb);
return 0;
}
+
+int p54_set_groupfilter(struct p54_common *priv)
+{
+ struct p54_group_address_table *grp;
+ struct sk_buff *skb;
+ bool on = false;
+
+ skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*grp),
+ P54_CONTROL_TYPE_GROUP_ADDRESS_TABLE, GFP_KERNEL);
+ if (!skb)
+ return -ENOMEM;
+
+ grp = (struct p54_group_address_table *)skb_put(skb, sizeof(*grp));
+
+ on = !(priv->filter_flags & FIF_ALLMULTI) &&
+ (priv->mc_maclist_num > 0 &&
+ priv->mc_maclist_num <= MC_FILTER_ADDRESS_NUM);
+
+ if (on) {
+ grp->filter_enable = cpu_to_le16(1);
+ grp->num_address = cpu_to_le16(priv->mc_maclist_num);
+ memcpy(grp->mac_list, priv->mc_maclist, sizeof(grp->mac_list));
+ } else {
+ grp->filter_enable = cpu_to_le16(0);
+ grp->num_address = cpu_to_le16(0);
+ memset(grp->mac_list, 0, sizeof(grp->mac_list));
+ }
+
+ p54_tx(priv, skb);
+ return 0;
+}