return 0;
error:
- if (txq->txb) {
- kfree(txq->txb);
- txq->txb = NULL;
- }
+ kfree(txq->txb);
+ txq->txb = NULL;
return -ENOMEM;
}
txq->q.n_bd, txq->bd, txq->q.dma_addr);
/* De-alloc array of per-TFD driver data */
- if (txq->txb) {
- kfree(txq->txb);
- txq->txb = NULL;
- }
+ kfree(txq->txb);
+ txq->txb = NULL;
/* 0-fill queue descriptor structure */
memset(txq, 0, sizeof(*txq));
return test_bit(STATUS_INIT, &priv->status);
}
+static inline int iwl3945_is_rfkill_sw(struct iwl3945_priv *priv)
+{
+ return test_bit(STATUS_RF_KILL_SW, &priv->status);
+}
+
+static inline int iwl3945_is_rfkill_hw(struct iwl3945_priv *priv)
+{
+ return test_bit(STATUS_RF_KILL_HW, &priv->status);
+}
+
static inline int iwl3945_is_rfkill(struct iwl3945_priv *priv)
{
- return test_bit(STATUS_RF_KILL_HW, &priv->status) ||
- test_bit(STATUS_RF_KILL_SW, &priv->status);
+ return iwl3945_is_rfkill_hw(priv) ||
+ iwl3945_is_rfkill_sw(priv);
}
static inline int iwl3945_is_ready_rf(struct iwl3945_priv *priv)
return rc;
}
-int iwl3945_is_network_packet(struct iwl3945_priv *priv, struct ieee80211_hdr *header)
-{
- /* Filter incoming packets to determine if they are targeted toward
- * this network, discarding packets coming from ourselves */
- switch (priv->iw_mode) {
- case IEEE80211_IF_TYPE_IBSS: /* Header: Dest. | Source | BSSID */
- /* packets from our adapter are dropped (echo) */
- if (!compare_ether_addr(header->addr2, priv->mac_addr))
- return 0;
- /* {broad,multi}cast packets to our IBSS go through */
- if (is_multicast_ether_addr(header->addr1))
- return !compare_ether_addr(header->addr3, priv->bssid);
- /* packets to our adapter go through */
- return !compare_ether_addr(header->addr1, priv->mac_addr);
- case IEEE80211_IF_TYPE_STA: /* Header: Dest. | AP{BSSID} | Source */
- /* packets from our adapter are dropped (echo) */
- if (!compare_ether_addr(header->addr3, priv->mac_addr))
- return 0;
- /* {broad,multi}cast packets to our BSS go through */
- if (is_multicast_ether_addr(header->addr1))
- return !compare_ether_addr(header->addr2, priv->bssid);
- /* packets to our adapter go through */
- return !compare_ether_addr(header->addr1, priv->mac_addr);
- default:
- return 1;
- }
-
- return 1;
-}
-
/**
* iwl3945_scan_cancel - Cancel any currently executing HW scan
*
return ret;
}
-static void iwl3945_sequence_reset(struct iwl3945_priv *priv)
-{
- /* Reset ieee stats */
-
- /* We don't reset the net_device_stats (ieee->stats) on
- * re-association */
-
- priv->last_seq_num = -1;
- priv->last_frag_num = -1;
- priv->last_packet_time = 0;
-
- iwl3945_scan_cancel(priv);
-}
-
#define MAX_UCODE_BEACON_INTERVAL 1024
#define INTEL_CONN_LISTEN_INTERVAL __constant_cpu_to_le16(0xA)
* first entry */
iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len);
- if (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT))
+ if (info->control.hw_key)
iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, 0);
/* Set up TFD's 2nd entry to point directly to remainder of skb,
if (!ieee80211_has_morefrags(hdr->frame_control)) {
txq->need_update = 1;
- if (qc) {
+ if (qc)
priv->stations[sta_id].tid[tid].seq_number = seq_number;
- }
} else {
wait_write_ptr = 1;
txq->need_update = 0;
}
}
-#define IWL_PACKET_RETRY_TIME HZ
-
-int iwl3945_is_duplicate_packet(struct iwl3945_priv *priv, struct ieee80211_hdr *header)
-{
- u16 sc = le16_to_cpu(header->seq_ctrl);
- u16 seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
- u16 frag = sc & IEEE80211_SCTL_FRAG;
- u16 *last_seq, *last_frag;
- unsigned long *last_time;
-
- switch (priv->iw_mode) {
- case IEEE80211_IF_TYPE_IBSS:{
- struct list_head *p;
- struct iwl3945_ibss_seq *entry = NULL;
- u8 *mac = header->addr2;
- int index = mac[5] & (IWL_IBSS_MAC_HASH_SIZE - 1);
-
- __list_for_each(p, &priv->ibss_mac_hash[index]) {
- entry = list_entry(p, struct iwl3945_ibss_seq, list);
- if (!compare_ether_addr(entry->mac, mac))
- break;
- }
- if (p == &priv->ibss_mac_hash[index]) {
- entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
- if (!entry) {
- IWL_ERROR("Cannot malloc new mac entry\n");
- return 0;
- }
- memcpy(entry->mac, mac, ETH_ALEN);
- entry->seq_num = seq;
- entry->frag_num = frag;
- entry->packet_time = jiffies;
- list_add(&entry->list, &priv->ibss_mac_hash[index]);
- return 0;
- }
- last_seq = &entry->seq_num;
- last_frag = &entry->frag_num;
- last_time = &entry->packet_time;
- break;
- }
- case IEEE80211_IF_TYPE_STA:
- last_seq = &priv->last_seq_num;
- last_frag = &priv->last_frag_num;
- last_time = &priv->last_packet_time;
- break;
- default:
- return 0;
- }
- if ((*last_seq == seq) &&
- time_after(*last_time + IWL_PACKET_RETRY_TIME, jiffies)) {
- if (*last_frag == frag)
- goto drop;
- if (*last_frag + 1 != frag)
- /* out-of-order fragment */
- goto drop;
- } else
- *last_seq = seq;
-
- *last_frag = frag;
- *last_time = jiffies;
- return 0;
-
- drop:
- return 1;
-}
-
#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
#include "iwl-spectrum.h"
/* 100:1 or higher, divide by 10 and use table,
* add 20 dB to make up for divide by 10 */
if (sig_ratio >= 100)
- return (20 + (int)ratio2dB[sig_ratio/10]);
+ return 20 + (int)ratio2dB[sig_ratio/10];
/* We shouldn't see this */
if (sig_ratio < 1)
* iwl3945_verify_inst_full - verify runtime uCode image in card vs. host,
* looking at all data.
*/
-static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 * image, u32 len)
+static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 *image, u32 len)
{
u32 val;
u32 save_len = len;
val = iwl3945_read_prph(priv, BSM_WR_DWCOUNT_REG);
for (reg = BSM_SRAM_LOWER_BOUND;
reg < BSM_SRAM_LOWER_BOUND + len;
- reg += sizeof(u32), image ++) {
+ reg += sizeof(u32), image++) {
val = iwl3945_read_prph(priv, reg);
if (val != le32_to_cpu(*image)) {
IWL_ERROR("BSM uCode verification failed at "
else {
set_bit(STATUS_RF_KILL_HW, &priv->status);
if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) {
- iwl3945_rfkill_set_hw_state(priv);
IWL_WARNING("Radio disabled by HW RF Kill switch\n");
return -ENODEV;
}
}
- iwl3945_rfkill_set_hw_state(priv);
+
iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF);
rc = iwl3945_hw_nic_init(priv);
"wireless networking to work.\n");
}
- iwl3945_rfkill_set_hw_state(priv);
mutex_unlock(&priv->mutex);
+ iwl3945_rfkill_set_hw_state(priv);
}
static void iwl3945_bg_set_monitor(struct work_struct *work)
mutex_lock(&priv->mutex);
__iwl3945_up(priv);
mutex_unlock(&priv->mutex);
+ iwl3945_rfkill_set_hw_state(priv);
}
static void iwl3945_bg_restart(struct work_struct *data)
DECLARE_MAC_BUF(mac);
if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
- IWL_ERROR("%s Should not be called in AP mode\n", __FUNCTION__);
+ IWL_ERROR("%s Should not be called in AP mode\n", __func__);
return;
}
default:
IWL_ERROR("%s Should not be called in %d mode\n",
- __FUNCTION__, priv->iw_mode);
+ __func__, priv->iw_mode);
break;
}
- iwl3945_sequence_reset(priv);
-
iwl3945_activate_qos(priv, 0);
/* we have just associated, don't start scan too early */
mutex_unlock(&priv->mutex);
+ iwl3945_rfkill_set_hw_state(priv);
+
if (ret)
goto out_release_irq;
IWL_DEBUG_MAC80211("enter\n");
+ if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
+ IWL_DEBUG_MAC80211("leave - monitor\n");
+ dev_kfree_skb_any(skb);
+ return 0;
+ }
+
IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
* clear sta table, add BCAST sta... */
}
+/* temporary */
+static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
+
static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_if_conf *conf)
return 0;
}
+ /* handle this temporarily here */
+ if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS &&
+ conf->changed & IEEE80211_IFCC_BEACON) {
+ struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
+ if (!beacon)
+ return -ENOMEM;
+ rc = iwl3945_mac_beacon_update(hw, beacon);
+ if (rc)
+ return rc;
+ }
+
/* XXX: this MUST use conf->mac_addr */
if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) &&
- (!conf->beacon || !conf->ssid_len)) {
+ (!conf->ssid_len)) {
IWL_DEBUG_MAC80211
("Leaving in AP mode because HostAPD is not ready.\n");
return 0;
if (priv->ibss_beacon)
dev_kfree_skb(priv->ibss_beacon);
- priv->ibss_beacon = conf->beacon;
+ priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
}
if (iwl3945_is_rfkill(priv))
struct iwl3945_priv *priv = dev_get_drvdata(d);
struct iwl3945_spectrum_notification measure_report;
u32 size = sizeof(measure_report), len = 0, ofs = 0;
- u8 *data = (u8 *) & measure_report;
+ u8 *data = (u8 *)&measure_report;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
else
p += sprintf(p, " \n");
- return (p - buf + 1);
+ return p - buf + 1;
}
struct iwl3945_priv *priv = dev_get_drvdata(d);
u32 size = sizeof(struct iwl3945_notif_statistics);
u32 len = 0, ofs = 0;
- u8 *data = (u8 *) & priv->statistics;
+ u8 *data = (u8 *)&priv->statistics;
int rc = 0;
if (!iwl3945_is_alive(priv))
.conf_tx = iwl3945_mac_conf_tx,
.get_tsf = iwl3945_mac_get_tsf,
.reset_tsf = iwl3945_mac_reset_tsf,
- .beacon_update = iwl3945_mac_beacon_update,
.hw_scan = iwl3945_mac_hw_scan
};
struct iwl3945_priv *priv;
struct ieee80211_hw *hw;
struct iwl_3945_cfg *cfg = (struct iwl_3945_cfg *)(ent->driver_data);
- int i;
unsigned long flags;
DECLARE_MAC_BUF(mac);
priv->ibss_beacon = NULL;
/* Tell mac80211 our characteristics */
- hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
- IEEE80211_HW_SIGNAL_DBM |
+ hw->flags = IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_NOISE_DBM;
/* 4 EDCA QOS priorities */
spin_lock_init(&priv->sta_lock);
spin_lock_init(&priv->hcmd_lock);
- for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++)
- INIT_LIST_HEAD(&priv->ibss_mac_hash[i]);
-
INIT_LIST_HEAD(&priv->free_frames);
mutex_init(&priv->mutex);
/* nic init */
iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS,
- CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
-
- iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
- err = iwl3945_poll_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
- if (err < 0) {
- IWL_DEBUG_INFO("Failed to init the card\n");
+ CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
+
+ iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+ err = iwl3945_poll_bit(priv, CSR_GP_CNTRL,
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+ CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+ if (err < 0) {
+ IWL_DEBUG_INFO("Failed to init the card\n");
goto out_remove_sysfs;
- }
+ }
/* Read the EEPROM */
err = iwl3945_eeprom_init(priv);
if (err) {
static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
{
struct iwl3945_priv *priv = pci_get_drvdata(pdev);
- struct list_head *p, *q;
- int i;
unsigned long flags;
if (!priv)
iwl_synchronize_irq(priv);
- /* Free MAC hash list for ADHOC */
- for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) {
- list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) {
- list_del(p);
- kfree(list_entry(p, struct iwl3945_ibss_seq, list));
- }
- }
-
sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
iwl3945_rfkill_unregister(priv);
iwl3945_unset_hw_setting(priv);
iwl3945_clear_stations_table(priv);
- if (priv->mac80211_registered) {
+ if (priv->mac80211_registered)
ieee80211_unregister_hw(priv->hw);
- }
/*netif_stop_queue(dev); */
flush_workqueue(priv->workqueue);
#endif /* CONFIG_PM */
/*************** RFKILL FUNCTIONS **********/
-#ifdef CONFIG_IWLWIFI_RFKILL
+#ifdef CONFIG_IWL3945_RFKILL
/* software rf-kill from user */
static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
{
struct iwl3945_priv *priv = data;
int err = 0;
- if (!priv->rfkill_mngr.rfkill)
+ if (!priv->rfkill)
return 0;
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
switch (state) {
case RFKILL_STATE_UNBLOCKED:
- iwl3945_radio_kill_sw(priv, 0);
- /* if HW rf-kill is set dont allow ON state */
- if (iwl3945_is_rfkill(priv))
+ if (iwl3945_is_rfkill_hw(priv)) {
err = -EBUSY;
+ goto out_unlock;
+ }
+ iwl3945_radio_kill_sw(priv, 0);
break;
case RFKILL_STATE_SOFT_BLOCKED:
iwl3945_radio_kill_sw(priv, 1);
- if (!iwl3945_is_rfkill(priv))
- err = -EBUSY;
break;
default:
IWL_WARNING("we recieved unexpected RFKILL state %d\n", state);
break;
}
+out_unlock:
mutex_unlock(&priv->mutex);
return err;
BUG_ON(device == NULL);
IWL_DEBUG_RF_KILL("Initializing RFKILL.\n");
- priv->rfkill_mngr.rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
- if (!priv->rfkill_mngr.rfkill) {
+ priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
+ if (!priv->rfkill) {
IWL_ERROR("Unable to allocate rfkill device.\n");
ret = -ENOMEM;
goto error;
}
- priv->rfkill_mngr.rfkill->name = priv->cfg->name;
- priv->rfkill_mngr.rfkill->data = priv;
- priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON;
- priv->rfkill_mngr.rfkill->toggle_radio = iwl3945_rfkill_soft_rf_kill;
- priv->rfkill_mngr.rfkill->user_claim_unsupported = 1;
-
- priv->rfkill_mngr.rfkill->dev.class->suspend = NULL;
- priv->rfkill_mngr.rfkill->dev.class->resume = NULL;
-
- priv->rfkill_mngr.input_dev = input_allocate_device();
- if (!priv->rfkill_mngr.input_dev) {
- IWL_ERROR("Unable to allocate rfkill input device.\n");
- ret = -ENOMEM;
- goto freed_rfkill;
- }
+ priv->rfkill->name = priv->cfg->name;
+ priv->rfkill->data = priv;
+ priv->rfkill->state = RFKILL_STATE_UNBLOCKED;
+ priv->rfkill->toggle_radio = iwl3945_rfkill_soft_rf_kill;
+ priv->rfkill->user_claim_unsupported = 1;
- priv->rfkill_mngr.input_dev->name = priv->cfg->name;
- priv->rfkill_mngr.input_dev->phys = wiphy_name(priv->hw->wiphy);
- priv->rfkill_mngr.input_dev->id.bustype = BUS_HOST;
- priv->rfkill_mngr.input_dev->id.vendor = priv->pci_dev->vendor;
- priv->rfkill_mngr.input_dev->dev.parent = device;
- priv->rfkill_mngr.input_dev->evbit[0] = BIT(EV_KEY);
- set_bit(KEY_WLAN, priv->rfkill_mngr.input_dev->keybit);
+ priv->rfkill->dev.class->suspend = NULL;
+ priv->rfkill->dev.class->resume = NULL;
- ret = rfkill_register(priv->rfkill_mngr.rfkill);
+ ret = rfkill_register(priv->rfkill);
if (ret) {
IWL_ERROR("Unable to register rfkill: %d\n", ret);
- goto free_input_dev;
- }
-
- ret = input_register_device(priv->rfkill_mngr.input_dev);
- if (ret) {
- IWL_ERROR("Unable to register rfkill input device: %d\n", ret);
- goto unregister_rfkill;
+ goto freed_rfkill;
}
IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
return ret;
-unregister_rfkill:
- rfkill_unregister(priv->rfkill_mngr.rfkill);
- priv->rfkill_mngr.rfkill = NULL;
-
-free_input_dev:
- input_free_device(priv->rfkill_mngr.input_dev);
- priv->rfkill_mngr.input_dev = NULL;
-
freed_rfkill:
- if (priv->rfkill_mngr.rfkill != NULL)
- rfkill_free(priv->rfkill_mngr.rfkill);
- priv->rfkill_mngr.rfkill = NULL;
+ if (priv->rfkill != NULL)
+ rfkill_free(priv->rfkill);
+ priv->rfkill = NULL;
error:
IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n");
void iwl3945_rfkill_unregister(struct iwl3945_priv *priv)
{
+ if (priv->rfkill)
+ rfkill_unregister(priv->rfkill);
- if (priv->rfkill_mngr.input_dev)
- input_unregister_device(priv->rfkill_mngr.input_dev);
-
- if (priv->rfkill_mngr.rfkill)
- rfkill_unregister(priv->rfkill_mngr.rfkill);
-
- priv->rfkill_mngr.input_dev = NULL;
- priv->rfkill_mngr.rfkill = NULL;
+ priv->rfkill = NULL;
}
/* set rf-kill to the right state. */
void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv)
{
- if (!priv->rfkill_mngr.rfkill)
+ if (!priv->rfkill)
return;
- if (!iwl3945_is_rfkill(priv))
- priv->rfkill_mngr.rfkill->state = RFKILL_STATE_ON;
+ if (iwl3945_is_rfkill_hw(priv)) {
+ rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED);
+ return;
+ }
+
+ if (!iwl3945_is_rfkill_sw(priv))
+ rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED);
else
- priv->rfkill_mngr.rfkill->state = RFKILL_STATE_OFF;
+ rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED);
}
#endif