From 88787d2842b6e6ff9bdc218445209c5e3c84d6fa Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 13 May 2008 21:05:50 -0700 Subject: wireless: fix "iwlwifi: unify init driver flow" drivers/net/wireless/iwlwifi/iwl-core.c: In function 'iwlcore_init_geos': drivers/net/wireless/iwlwifi/iwl-core.c:323: error: implicit declaration of function 'iwlcore_init_ht_hw_capab' This (or something like it) should be folded into the base patch to avoid breaking bisection, please. Cc: Ron Rindjunsky Cc: Tomas Winkler Cc: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index c4b5c1a100f..55e3d139f42 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -259,6 +259,12 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, if (priv->hw_params.tx_chains_num >= 3) ht_info->supp_mcs_set[2] = 0xFF; } +#else +static inline void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, + struct ieee80211_ht_info *ht_info, + enum ieee80211_band band) +{ +} #endif /* CONFIG_IWL4965_HT */ static void iwlcore_init_hw_rates(struct iwl_priv *priv, -- cgit v1.2.3 From cdbf0846e2dd5f122f3910d0e2a305fab337744b Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 2 May 2008 13:47:48 -0700 Subject: b43: replace limit_value macro with clamp_val kernel-provided clamp_val is identical, delete the private limit_value helper. Signed-off-by: Harvey Harrison Cc: Michael Buesch Cc: "John W. Linville" Signed-off-by: Andrew Morton Signed-off-by: John W. Linville --- drivers/net/wireless/b43/b43.h | 16 ---------------- drivers/net/wireless/b43/lo.c | 4 ++-- drivers/net/wireless/b43/main.c | 8 ++++---- drivers/net/wireless/b43/phy.c | 24 ++++++++++++------------ 4 files changed, 18 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 7d034df250b..0c2bc061e8f 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -939,22 +939,6 @@ static inline bool __b43_warn_on_dummy(bool x) { return x; } # define B43_WARN_ON(x) __b43_warn_on_dummy(unlikely(!!(x))) #endif -/** Limit a value between two limits */ -#ifdef limit_value -# undef limit_value -#endif -#define limit_value(value, min, max) \ - ({ \ - typeof(value) __value = (value); \ - typeof(value) __min = (min); \ - typeof(value) __max = (max); \ - if (__value < __min) \ - __value = __min; \ - else if (__value > __max) \ - __value = __max; \ - __value; \ - }) - /* Convert an integer to a Q5.2 value */ #define INT_TO_Q52(i) ((i) << 2) /* Convert a Q5.2 value to an integer (precision loss!) */ diff --git a/drivers/net/wireless/b43/lo.c b/drivers/net/wireless/b43/lo.c index 4ce1e356120..9c854d6aae3 100644 --- a/drivers/net/wireless/b43/lo.c +++ b/drivers/net/wireless/b43/lo.c @@ -199,7 +199,7 @@ static void lo_measure_txctl_values(struct b43_wldev *dev) if (lb_gain > 10) { radio_pctl_reg = 0; pga = abs(10 - lb_gain) / 6; - pga = limit_value(pga, 0, 15); + pga = clamp_val(pga, 0, 15); } else { int cmp_val; int tmp; @@ -321,7 +321,7 @@ static void lo_measure_gain_values(struct b43_wldev *dev, phy->lna_lod_gain = 1; trsw_rx_gain -= 8; } - trsw_rx_gain = limit_value(trsw_rx_gain, 0, 0x2D); + trsw_rx_gain = clamp_val(trsw_rx_gain, 0, 0x2D); phy->pga_gain = trsw_rx_gain / 3; if (phy->pga_gain >= 5) { phy->pga_gain -= 5; diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index c6e79a15d3c..7c23aa8705c 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1182,10 +1182,10 @@ static void handle_irq_noise(struct b43_wldev *dev) /* Get the noise samples. */ B43_WARN_ON(dev->noisecalc.nr_samples >= 8); i = dev->noisecalc.nr_samples; - noise[0] = limit_value(noise[0], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); - noise[1] = limit_value(noise[1], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); - noise[2] = limit_value(noise[2], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); - noise[3] = limit_value(noise[3], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); + noise[0] = clamp_val(noise[0], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); + noise[1] = clamp_val(noise[1], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); + noise[2] = clamp_val(noise[2], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); + noise[3] = clamp_val(noise[3], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); dev->noisecalc.samples[i][0] = phy->nrssi_lt[noise[0]]; dev->noisecalc.samples[i][1] = phy->nrssi_lt[noise[1]]; dev->noisecalc.samples[i][2] = phy->nrssi_lt[noise[2]]; diff --git a/drivers/net/wireless/b43/phy.c b/drivers/net/wireless/b43/phy.c index 8b3c24da8db..6378c266549 100644 --- a/drivers/net/wireless/b43/phy.c +++ b/drivers/net/wireless/b43/phy.c @@ -1415,7 +1415,7 @@ static void b43_phy_initg(struct b43_wldev *dev) * the value 0x7FFFFFFF here. I think that is some weird * compiler optimization in the original driver. * Essentially, what we do here is resetting all NRSSI LT - * entries to -32 (see the limit_value() in nrssi_hw_update()) + * entries to -32 (see the clamp_val() in nrssi_hw_update()) */ b43_nrssi_hw_update(dev, 0xFFFF); //FIXME? b43_calc_nrssi_threshold(dev); @@ -1477,13 +1477,13 @@ static s8 b43_phy_estimate_power_out(struct b43_wldev *dev, s8 tssi) switch (phy->type) { case B43_PHYTYPE_A: tmp += 0x80; - tmp = limit_value(tmp, 0x00, 0xFF); + tmp = clamp_val(tmp, 0x00, 0xFF); dbm = phy->tssi2dbm[tmp]; //TODO: There's a FIXME on the specs break; case B43_PHYTYPE_B: case B43_PHYTYPE_G: - tmp = limit_value(tmp, 0x00, 0x3F); + tmp = clamp_val(tmp, 0x00, 0x3F); dbm = phy->tssi2dbm[tmp]; break; default: @@ -1542,8 +1542,8 @@ void b43_put_attenuation_into_ranges(struct b43_wldev *dev, break; } - *_rfatt = limit_value(rfatt, rf_min, rf_max); - *_bbatt = limit_value(bbatt, bb_min, bb_max); + *_rfatt = clamp_val(rfatt, rf_min, rf_max); + *_bbatt = clamp_val(bbatt, bb_min, bb_max); } /* http://bcm-specs.sipsolutions.net/RecalculateTransmissionPower */ @@ -1638,7 +1638,7 @@ void b43_phy_xmitpower(struct b43_wldev *dev) /* Get desired power (in Q5.2) */ desired_pwr = INT_TO_Q52(phy->power_level); /* And limit it. max_pwr already is Q5.2 */ - desired_pwr = limit_value(desired_pwr, 0, max_pwr); + desired_pwr = clamp_val(desired_pwr, 0, max_pwr); if (b43_debug(dev, B43_DBG_XMITPOWER)) { b43dbg(dev->wl, "Current TX power output: " Q52_FMT @@ -1748,7 +1748,7 @@ static inline f = q; i++; } while (delta >= 2); - entry[index] = limit_value(b43_tssi2dbm_ad(m1 * f, 8192), -127, 128); + entry[index] = clamp_val(b43_tssi2dbm_ad(m1 * f, 8192), -127, 128); return 0; } @@ -2274,7 +2274,7 @@ void b43_nrssi_hw_update(struct b43_wldev *dev, u16 val) for (i = 0; i < 64; i++) { tmp = b43_nrssi_hw_read(dev, i); tmp -= val; - tmp = limit_value(tmp, -32, 31); + tmp = clamp_val(tmp, -32, 31); b43_nrssi_hw_write(dev, i, tmp); } } @@ -2291,7 +2291,7 @@ void b43_nrssi_mem_update(struct b43_wldev *dev) tmp = (i - delta) * phy->nrssislope; tmp /= 0x10000; tmp += 0x3A; - tmp = limit_value(tmp, 0, 0x3F); + tmp = clamp_val(tmp, 0, 0x3F); phy->nrssi_lt[i] = tmp; } } @@ -2728,7 +2728,7 @@ void b43_calc_nrssi_threshold(struct b43_wldev *dev) } else threshold = phy->nrssi[1] - 5; - threshold = limit_value(threshold, 0, 0x3E); + threshold = clamp_val(threshold, 0, 0x3E); b43_phy_read(dev, 0x0020); /* dummy read */ b43_phy_write(dev, 0x0020, (((u16) threshold) << 8) | 0x001C); @@ -2779,7 +2779,7 @@ void b43_calc_nrssi_threshold(struct b43_wldev *dev) else a += 32; a = a >> 6; - a = limit_value(a, -31, 31); + a = clamp_val(a, -31, 31); b = b * (phy->nrssi[1] - phy->nrssi[0]); b += (phy->nrssi[0] << 6); @@ -2788,7 +2788,7 @@ void b43_calc_nrssi_threshold(struct b43_wldev *dev) else b += 32; b = b >> 6; - b = limit_value(b, -31, 31); + b = clamp_val(b, -31, 31); tmp_u16 = b43_phy_read(dev, 0x048A) & 0xF000; tmp_u16 |= ((u32) b & 0x0000003F); -- cgit v1.2.3 From ca21614d4c7a176d3723ac211873020b3722dbda Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 2 May 2008 13:47:49 -0700 Subject: b43legacy: replace limit_value macro with clamp_val kernel-provided clamp_val is identical, delete the private limit_value helper. Signed-off-by: Harvey Harrison Cc: Michael Buesch Cc: "John W. Linville" Signed-off-by: Andrew Morton Signed-off-by: John W. Linville --- drivers/net/wireless/b43legacy/b43legacy.h | 17 ----------------- drivers/net/wireless/b43legacy/main.c | 8 ++++---- drivers/net/wireless/b43legacy/phy.c | 14 +++++++------- drivers/net/wireless/b43legacy/radio.c | 12 ++++++------ 4 files changed, 17 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index ded3cd31b3d..c40078e1fff 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h @@ -823,23 +823,6 @@ void b43legacydbg(struct b43legacy_wl *wl, const char *fmt, ...) # define b43legacydbg(wl, fmt...) do { /* nothing */ } while (0) #endif /* DEBUG */ - -/** Limit a value between two limits */ -#ifdef limit_value -# undef limit_value -#endif -#define limit_value(value, min, max) \ - ({ \ - typeof(value) __value = (value); \ - typeof(value) __min = (min); \ - typeof(value) __max = (max); \ - if (__value < __min) \ - __value = __min; \ - else if (__value > __max) \ - __value = __max; \ - __value; \ - }) - /* Macros for printing a value in Q5.2 format */ #define Q52_FMT "%u.%u" #define Q52_ARG(q52) ((q52) / 4), (((q52) & 3) * 100 / 4) diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 1ccc51e90a8..d3820dce3c4 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -846,10 +846,10 @@ static void handle_irq_noise(struct b43legacy_wldev *dev) /* Get the noise samples. */ B43legacy_WARN_ON(dev->noisecalc.nr_samples >= 8); i = dev->noisecalc.nr_samples; - noise[0] = limit_value(noise[0], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); - noise[1] = limit_value(noise[1], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); - noise[2] = limit_value(noise[2], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); - noise[3] = limit_value(noise[3], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); + noise[0] = clamp_val(noise[0], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); + noise[1] = clamp_val(noise[1], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); + noise[2] = clamp_val(noise[2], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); + noise[3] = clamp_val(noise[3], 0, ARRAY_SIZE(phy->nrssi_lt) - 1); dev->noisecalc.samples[i][0] = phy->nrssi_lt[noise[0]]; dev->noisecalc.samples[i][1] = phy->nrssi_lt[noise[1]]; dev->noisecalc.samples[i][2] = phy->nrssi_lt[noise[2]]; diff --git a/drivers/net/wireless/b43legacy/phy.c b/drivers/net/wireless/b43legacy/phy.c index 8e5c09b8187..768cccb9b1b 100644 --- a/drivers/net/wireless/b43legacy/phy.c +++ b/drivers/net/wireless/b43legacy/phy.c @@ -1088,7 +1088,7 @@ static void b43legacy_phy_initg(struct b43legacy_wldev *dev) * the value 0x7FFFFFFF here. I think that is some weird * compiler optimization in the original driver. * Essentially, what we do here is resetting all NRSSI LT - * entries to -32 (see the limit_value() in nrssi_hw_update()) + * entries to -32 (see the clamp_val() in nrssi_hw_update()) */ b43legacy_nrssi_hw_update(dev, 0xFFFF); b43legacy_calc_nrssi_threshold(dev); @@ -1756,7 +1756,7 @@ static s8 b43legacy_phy_estimate_power_out(struct b43legacy_wldev *dev, s8 tssi) switch (phy->type) { case B43legacy_PHYTYPE_B: case B43legacy_PHYTYPE_G: - tmp = limit_value(tmp, 0x00, 0x3F); + tmp = clamp_val(tmp, 0x00, 0x3F); dbm = phy->tssi2dbm[tmp]; break; default: @@ -1859,7 +1859,7 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev) /* find the desired power in Q5.2 - power_level is in dBm * and limit it - max_pwr is already in Q5.2 */ - desired_pwr = limit_value(phy->power_level << 2, 0, max_pwr); + desired_pwr = clamp_val(phy->power_level << 2, 0, max_pwr); if (b43legacy_debug(dev, B43legacy_DBG_XMITPOWER)) b43legacydbg(dev->wl, "Current TX power output: " Q52_FMT " dBm, Desired TX power output: " Q52_FMT @@ -1905,7 +1905,7 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev) radio_attenuation++; } } - baseband_attenuation = limit_value(baseband_attenuation, 0, 11); + baseband_attenuation = clamp_val(baseband_attenuation, 0, 11); txpower = phy->txctl1; if ((phy->radio_ver == 0x2050) && (phy->radio_rev == 2)) { @@ -1933,8 +1933,8 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev) } /* Save the control values */ phy->txctl1 = txpower; - baseband_attenuation = limit_value(baseband_attenuation, 0, 11); - radio_attenuation = limit_value(radio_attenuation, 0, 9); + baseband_attenuation = clamp_val(baseband_attenuation, 0, 11); + radio_attenuation = clamp_val(radio_attenuation, 0, 9); phy->rfatt = radio_attenuation; phy->bbatt = baseband_attenuation; @@ -1979,7 +1979,7 @@ s8 b43legacy_tssi2dbm_entry(s8 entry [], u8 index, s16 pab0, s16 pab1, s16 pab2) f = q; i++; } while (delta >= 2); - entry[index] = limit_value(b43legacy_tssi2dbm_ad(m1 * f, 8192), + entry[index] = clamp_val(b43legacy_tssi2dbm_ad(m1 * f, 8192), -127, 128); return 0; } diff --git a/drivers/net/wireless/b43legacy/radio.c b/drivers/net/wireless/b43legacy/radio.c index 955832e8654..2df545cfad1 100644 --- a/drivers/net/wireless/b43legacy/radio.c +++ b/drivers/net/wireless/b43legacy/radio.c @@ -357,7 +357,7 @@ void b43legacy_nrssi_hw_update(struct b43legacy_wldev *dev, u16 val) for (i = 0; i < 64; i++) { tmp = b43legacy_nrssi_hw_read(dev, i); tmp -= val; - tmp = limit_value(tmp, -32, 31); + tmp = clamp_val(tmp, -32, 31); b43legacy_nrssi_hw_write(dev, i, tmp); } } @@ -375,7 +375,7 @@ void b43legacy_nrssi_mem_update(struct b43legacy_wldev *dev) tmp = (i - delta) * phy->nrssislope; tmp /= 0x10000; tmp += 0x3A; - tmp = limit_value(tmp, 0, 0x3F); + tmp = clamp_val(tmp, 0, 0x3F); phy->nrssi_lt[i] = tmp; } } @@ -839,7 +839,7 @@ void b43legacy_calc_nrssi_threshold(struct b43legacy_wldev *dev) } else threshold = phy->nrssi[1] - 5; - threshold = limit_value(threshold, 0, 0x3E); + threshold = clamp_val(threshold, 0, 0x3E); b43legacy_phy_read(dev, 0x0020); /* dummy read */ b43legacy_phy_write(dev, 0x0020, (((u16)threshold) << 8) | 0x001C); @@ -892,7 +892,7 @@ void b43legacy_calc_nrssi_threshold(struct b43legacy_wldev *dev) else a += 32; a = a >> 6; - a = limit_value(a, -31, 31); + a = clamp_val(a, -31, 31); b = b * (phy->nrssi[1] - phy->nrssi[0]); b += (phy->nrssi[0] << 6); @@ -901,7 +901,7 @@ void b43legacy_calc_nrssi_threshold(struct b43legacy_wldev *dev) else b += 32; b = b >> 6; - b = limit_value(b, -31, 31); + b = clamp_val(b, -31, 31); tmp_u16 = b43legacy_phy_read(dev, 0x048A) & 0xF000; tmp_u16 |= ((u32)b & 0x0000003F); @@ -1905,7 +1905,7 @@ void b43legacy_radio_set_txpower_a(struct b43legacy_wldev *dev, u16 txpower) u16 dac; u16 ilt; - txpower = limit_value(txpower, 0, 63); + txpower = clamp_val(txpower, 0, 63); pamp = b43legacy_get_txgain_freq_power_amp(txpower); pamp <<= 5; -- cgit v1.2.3 From 07346f81e87d6e4cca7ae9adfa711d0c61c87b56 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 3 May 2008 01:02:02 +0200 Subject: mac80211: proper STA info locking As discussed earlier, we can unify locking in struct sta_info and use just a single spinlock protecting all members of the structure that need protection. Many don't, but one of the especially bad ones is the 'flags' member that can currently be clobbered when RX and TX is being processed on different CPUs at the same time. Because having four spinlocks for different, mostly exclusive parts of a single structure is overkill, this patch also kills the ampdu and mesh plink spinlocks and uses just a single one for everything. Because none of the spinlocks are nested, this is safe. It remains to be seen whether or not we should make the sta flags use atomic bit operations instead, for now though this is a safe thing and using atomic operations instead will be very simple using the new static inline functions this patch introduces for accessing sta->flags. Since spin_lock_bh() is used with this lock, there shouldn't be any contention even if aggregation is enabled at around the same time as both requires frame transmission/reception which is in a bh context. Signed-off-by: Johannes Berg Cc: Tomas Winkler Cc: Ron Rindjunsky Cc: Luis Carlos Cobo Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-4965-rs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index 67356d9a0c5..e3444c4ea1a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c @@ -360,9 +360,9 @@ static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, unsigned long state; DECLARE_MAC_BUF(mac); - spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); + spin_lock_bh(&sta->lock); state = sta->ampdu_mlme.tid_state_tx[tid]; - spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); + spin_unlock_bh(&sta->lock); if (state == HT_AGG_STATE_IDLE && rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { -- cgit v1.2.3 From 0d0b2c1c49814ee54f1b4efd2c715a7465219ede Mon Sep 17 00:00:00 2001 From: Ron Rindjunsky Date: Sun, 4 May 2008 14:48:18 +0300 Subject: iwlwifi: map A-MPDU HW queue to mac80211 A-MPDU SW queue This patch maps A-MPDU HW queue to mac80211 SW queue scheme (as introduced in patch "mac80211: QoS related cleanups"), when trying to perform ieee80211_wake_queue. Signed-off-by: Ron Rindjunsky Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-4965.c | 5 ++++- drivers/net/wireless/iwlwifi/iwl4965-base.c | 23 +++++++++++------------ 2 files changed, 15 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 9546582e983..70c0455b622 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -3547,13 +3547,16 @@ static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv, * block-ack window (we assume that they've been successfully * transmitted ... if not, it's too late anyway). */ if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) { + /* calculate mac80211 ampdu sw queue to wake */ + int ampdu_q = + scd_flow - IWL_BACK_QUEUE_FIRST_ID + priv->hw->queues; int freed = iwl4965_tx_queue_reclaim(priv, scd_flow, index); priv->stations[ba_resp->sta_id]. tid[ba_resp->tid].tfds_in_queue -= freed; if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && priv->mac80211_registered && agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) - ieee80211_wake_queue(priv->hw, scd_flow); + ieee80211_wake_queue(priv->hw, ampdu_q); iwl4965_check_empty_hw_queue(priv, ba_resp->sta_id, ba_resp->tid, scd_flow); } diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 4406fc72d88..54534270d46 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -2568,12 +2568,6 @@ int iwl4965_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) nfreed++; } -/* if (iwl4965_queue_space(q) > q->low_mark && (txq_id >= 0) && - (txq_id != IWL_CMD_QUEUE_NUM) && - priv->mac80211_registered) - ieee80211_wake_queue(priv->hw, txq_id); */ - - return nfreed; } @@ -2797,7 +2791,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, } if (txq->q.read_ptr != (scd_ssn & 0xff)) { - int freed; + int freed, ampdu_q; index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn " "%d index %d\n", scd_ssn , index); @@ -2806,9 +2800,15 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && txq_id >= 0 && priv->mac80211_registered && - agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) - ieee80211_wake_queue(priv->hw, txq_id); - + agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) { + /* calculate mac80211 ampdu sw queue to wake */ + ampdu_q = txq_id - IWL_BACK_QUEUE_FIRST_ID + + priv->hw->queues; + if (agg->state == IWL_AGG_OFF) + ieee80211_wake_queue(priv->hw, txq_id); + else + ieee80211_wake_queue(priv->hw, ampdu_q); + } iwl4965_check_empty_hw_queue(priv, sta_id, tid, txq_id); } } else { @@ -2833,8 +2833,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, if (tid != MAX_TID_COUNT) priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && - (txq_id >= 0) && - priv->mac80211_registered) + (txq_id >= 0) && priv->mac80211_registered) ieee80211_wake_queue(priv->hw, txq_id); if (tid != MAX_TID_COUNT) iwl4965_check_empty_hw_queue(priv, sta_id, tid, txq_id); -- cgit v1.2.3 From a55360e458551b0add4ec147ef786d71e163bf50 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 5 May 2008 10:22:28 +0800 Subject: iwlwifi: move RX code to iwl-rx.c This patch moves partialy rx code into iwl-rx.c as part of iwlcore. The second part of the code can be merged only with moving of tx code as well. Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Makefile | 1 + drivers/net/wireless/iwlwifi/iwl-4965.c | 25 +- drivers/net/wireless/iwlwifi/iwl-core.h | 16 + drivers/net/wireless/iwlwifi/iwl-dev.h | 26 +- drivers/net/wireless/iwlwifi/iwl-rx.c | 371 +++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl4965-base.c | 545 ++++++---------------------- 6 files changed, 517 insertions(+), 467 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/iwl-rx.c (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index b0b2b5ebfa6..0211a7f7147 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_IWLCORE) += iwlcore.o iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o +iwlcore-objs += iwl-rx.o iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 70c0455b622..773bb3229cf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -372,7 +372,7 @@ int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src) return ret; } -static int iwl4965_rx_init(struct iwl_priv *priv, struct iwl4965_rx_queue *rxq) +static int iwl4965_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) { int ret; unsigned long flags; @@ -625,7 +625,7 @@ static void iwl4965_nic_config(struct iwl_priv *priv) int iwl4965_hw_nic_init(struct iwl_priv *priv) { unsigned long flags; - struct iwl4965_rx_queue *rxq = &priv->rxq; + struct iwl_rx_queue *rxq = &priv->rxq; int ret; /* nic_init */ @@ -645,22 +645,22 @@ int iwl4965_hw_nic_init(struct iwl_priv *priv) /* Allocate the RX queue, or reset if it is already allocated */ if (!rxq->bd) { - ret = iwl4965_rx_queue_alloc(priv); + ret = iwl_rx_queue_alloc(priv); if (ret) { IWL_ERROR("Unable to initialize Rx queue\n"); return -ENOMEM; } } else - iwl4965_rx_queue_reset(priv, rxq); + iwl_rx_queue_reset(priv, rxq); - iwl4965_rx_replenish(priv); + iwl_rx_replenish(priv); iwl4965_rx_init(priv, rxq); spin_lock_irqsave(&priv->lock, flags); rxq->need_update = 1; - iwl4965_rx_queue_update_write_ptr(priv, rxq); + iwl_rx_queue_update_write_ptr(priv, rxq); spin_unlock_irqrestore(&priv->lock, flags); @@ -2516,7 +2516,8 @@ static void iwl4965_rx_calc_noise(struct iwl_priv *priv) priv->last_rx_noise); } -void iwl4965_hw_rx_statistics(struct iwl_priv *priv, struct iwl4965_rx_mem_buffer *rxb) +void iwl4965_hw_rx_statistics(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) { struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; int change; @@ -2803,7 +2804,7 @@ static u32 iwl4965_translate_rx_status(u32 decrypt_in) static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data, int include_phy, - struct iwl4965_rx_mem_buffer *rxb, + struct iwl_rx_mem_buffer *rxb, struct ieee80211_rx_status *stats) { struct iwl4965_rx_packet *pkt = (struct iwl4965_rx_packet *)rxb->skb->data; @@ -3109,7 +3110,7 @@ static inline void iwl4965_dbg_report_frame(struct iwl_priv *priv, /* Called for REPLY_RX (legacy ABG frames), or * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, - struct iwl4965_rx_mem_buffer *rxb) + struct iwl_rx_mem_buffer *rxb) { struct ieee80211_hdr *header; struct ieee80211_rx_status rx_status; @@ -3278,7 +3279,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). * This will be used later in iwl4965_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ static void iwl4965_rx_reply_rx_phy(struct iwl_priv *priv, - struct iwl4965_rx_mem_buffer *rxb) + struct iwl_rx_mem_buffer *rxb) { struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; priv->last_phy_res[0] = 1; @@ -3286,7 +3287,7 @@ static void iwl4965_rx_reply_rx_phy(struct iwl_priv *priv, sizeof(struct iwl4965_rx_phy_res)); } static void iwl4965_rx_missed_beacon_notif(struct iwl_priv *priv, - struct iwl4965_rx_mem_buffer *rxb) + struct iwl_rx_mem_buffer *rxb) { #ifdef CONFIG_IWL4965_RUN_TIME_CALIB @@ -3495,7 +3496,7 @@ static inline int iwl4965_queue_dec_wrap(int index, int n_bd) * of frames sent via aggregation. */ static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv, - struct iwl4965_rx_mem_buffer *rxb) + struct iwl_rx_mem_buffer *rxb) { struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; struct iwl4965_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 369f1821584..2356cadc1de 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -173,6 +173,21 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, void iwlcore_free_geos(struct iwl_priv *priv); int iwl_setup(struct iwl_priv *priv); +/***************************************************** +* RX +******************************************************/ +void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq); +int iwl_rx_queue_alloc(struct iwl_priv *priv); +void iwl_rx_handle(struct iwl_priv *priv); +int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, + struct iwl_rx_queue *q); +void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); +void iwl_rx_replenish(struct iwl_priv *priv); +/* FIXME: remove when TX is moved to iwl core */ +int iwl_rx_queue_restock(struct iwl_priv *priv); +int iwl_rx_queue_space(const struct iwl_rx_queue *q); +void iwl_rx_allocate(struct iwl_priv *priv); + /***************************************************** * S e n d i n g H o s t C o m m a n d s * *****************************************************/ @@ -265,4 +280,5 @@ static inline int iwl_send_rxon_assoc(struct iwl_priv *priv) return priv->cfg->ops->hcmd->rxon_assoc(priv); } + #endif /* __iwl_core_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 78aba21bc18..1d80ad79114 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -91,7 +91,7 @@ extern struct iwl_cfg iwl5350_agn_cfg; #define DEFAULT_SHORT_RETRY_LIMIT 7U #define DEFAULT_LONG_RETRY_LIMIT 4U -struct iwl4965_rx_mem_buffer { +struct iwl_rx_mem_buffer { dma_addr_t dma_addr; struct sk_buff *skb; struct list_head list; @@ -358,7 +358,7 @@ struct iwl_host_cmd { #define SUP_RATE_11G_MAX_NUM_CHANNELS 12 /** - * struct iwl4965_rx_queue - Rx queue + * struct iwl_rx_queue - Rx queue * @processed: Internal index to last handled Rx packet * @read: Shared index to newest available Rx buffer * @write: Shared index to oldest written Rx packet @@ -367,13 +367,13 @@ struct iwl_host_cmd { * @rx_used: List of Rx buffers with no SKB * @need_update: flag to indicate we need to update read/write index * - * NOTE: rx_free and rx_used are used as a FIFO for iwl4965_rx_mem_buffers + * NOTE: rx_free and rx_used are used as a FIFO for iwl_rx_mem_buffers */ -struct iwl4965_rx_queue { +struct iwl_rx_queue { __le32 *bd; dma_addr_t dma_addr; - struct iwl4965_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS]; - struct iwl4965_rx_mem_buffer *queue[RX_QUEUE_SIZE]; + struct iwl_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS]; + struct iwl_rx_mem_buffer *queue[RX_QUEUE_SIZE]; u32 processed; u32 read; u32 write; @@ -643,26 +643,20 @@ extern int iwl4965_is_network_packet(struct iwl_priv *priv, struct ieee80211_hdr *header); extern int iwl4965_power_init_handle(struct iwl_priv *priv); extern void iwl4965_handle_data_packet_monitor(struct iwl_priv *priv, - struct iwl4965_rx_mem_buffer *rxb, + struct iwl_rx_mem_buffer *rxb, void *data, short len, struct ieee80211_rx_status *stats, u16 phy_flags); extern int iwl4965_is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header); -extern int iwl4965_rx_queue_alloc(struct iwl_priv *priv); -extern void iwl4965_rx_queue_reset(struct iwl_priv *priv, - struct iwl4965_rx_queue *rxq); extern int iwl4965_calc_db_from_ratio(int sig_ratio); extern int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm); extern int iwl4965_tx_queue_init(struct iwl_priv *priv, struct iwl4965_tx_queue *txq, int count, u32 id); -extern void iwl4965_rx_replenish(void *data); extern void iwl4965_tx_queue_free(struct iwl_priv *priv, struct iwl4965_tx_queue *txq); extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv, struct ieee80211_hdr *hdr, const u8 *dest, int left); -extern int iwl4965_rx_queue_update_write_ptr(struct iwl_priv *priv, - struct iwl4965_rx_queue *q); extern __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr); extern void iwl4965_update_chain_flags(struct iwl_priv *priv); int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src); @@ -722,7 +716,7 @@ extern void iwl4965_hw_build_tx_cmd_rate(struct iwl_priv *priv, extern int iwl4965_hw_reg_send_txpower(struct iwl_priv *priv); extern int iwl4965_hw_reg_set_txpower(struct iwl_priv *priv, s8 power); extern void iwl4965_hw_rx_statistics(struct iwl_priv *priv, - struct iwl4965_rx_mem_buffer *rxb); + struct iwl_rx_mem_buffer *rxb); extern void iwl4965_disable_events(struct iwl_priv *priv); extern int iwl4965_get_temperature(const struct iwl_priv *priv); @@ -960,7 +954,7 @@ struct iwl_priv { bool add_radiotap; void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, - struct iwl4965_rx_mem_buffer *rxb); + struct iwl_rx_mem_buffer *rxb); struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; @@ -1077,7 +1071,7 @@ struct iwl_priv { int activity_timer_active; /* Rx and Tx DMA processing queues */ - struct iwl4965_rx_queue rxq; + struct iwl_rx_queue rxq; struct iwl4965_tx_queue txq[IWL_MAX_NUM_QUEUES]; unsigned long txq_ctx_active_msk; struct iwl4965_kw kw; /* keep warm address */ diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c new file mode 100644 index 00000000000..667b592e6ad --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -0,0 +1,371 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * James P. Ketrenos + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include "iwl-eeprom.h" +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-sta.h" +#include "iwl-io.h" +#include "iwl-helpers.h" +/************************** RX-FUNCTIONS ****************************/ +/* + * Rx theory of operation + * + * Driver allocates a circular buffer of Receive Buffer Descriptors (RBDs), + * each of which point to Receive Buffers to be filled by the NIC. These get + * used not only for Rx frames, but for any command response or notification + * from the NIC. The driver and NIC manage the Rx buffers by means + * of indexes into the circular buffer. + * + * Rx Queue Indexes + * The host/firmware share two index registers for managing the Rx buffers. + * + * The READ index maps to the first position that the firmware may be writing + * to -- the driver can read up to (but not including) this position and get + * good data. + * The READ index is managed by the firmware once the card is enabled. + * + * The WRITE index maps to the last position the driver has read from -- the + * position preceding WRITE is the last slot the firmware can place a packet. + * + * The queue is empty (no good data) if WRITE = READ - 1, and is full if + * WRITE = READ. + * + * During initialization, the host sets up the READ queue position to the first + * INDEX position, and WRITE to the last (READ - 1 wrapped) + * + * When the firmware places a packet in a buffer, it will advance the READ index + * and fire the RX interrupt. The driver can then query the READ index and + * process as many packets as possible, moving the WRITE index forward as it + * resets the Rx queue buffers with new memory. + * + * The management in the driver is as follows: + * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free. When + * iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled + * to replenish the iwl->rxq->rx_free. + * + In iwl_rx_replenish (scheduled) if 'processed' != 'read' then the + * iwl->rxq is replenished and the READ INDEX is updated (updating the + * 'processed' and 'read' driver indexes as well) + * + A received packet is processed and handed to the kernel network stack, + * detached from the iwl->rxq. The driver 'processed' index is updated. + * + The Host/Firmware iwl->rxq is replenished at tasklet time from the rx_free + * list. If there are no allocated buffers in iwl->rxq->rx_free, the READ + * INDEX is not incremented and iwl->status(RX_STALLED) is set. If there + * were enough free buffers and RX_STALLED is set it is cleared. + * + * + * Driver sequence: + * + * iwl_rx_queue_alloc() Allocates rx_free + * iwl_rx_replenish() Replenishes rx_free list from rx_used, and calls + * iwl_rx_queue_restock + * iwl_rx_queue_restock() Moves available buffers from rx_free into Rx + * queue, updates firmware pointers, and updates + * the WRITE index. If insufficient rx_free buffers + * are available, schedules iwl_rx_replenish + * + * -- enable interrupts -- + * ISR - iwl_rx() Detach iwl_rx_mem_buffers from pool up to the + * READ INDEX, detaching the SKB from the pool. + * Moves the packet buffer from queue to rx_used. + * Calls iwl_rx_queue_restock to refill any empty + * slots. + * ... + * + */ + +/** + * iwl_rx_queue_space - Return number of free slots available in queue. + */ +int iwl_rx_queue_space(const struct iwl_rx_queue *q) +{ + int s = q->read - q->write; + if (s <= 0) + s += RX_QUEUE_SIZE; + /* keep some buffer to not confuse full and empty queue */ + s -= 2; + if (s < 0) + s = 0; + return s; +} +EXPORT_SYMBOL(iwl_rx_queue_space); + +/** + * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue + */ +int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q) +{ + u32 reg = 0; + int ret = 0; + unsigned long flags; + + spin_lock_irqsave(&q->lock, flags); + + if (q->need_update == 0) + goto exit_unlock; + + /* If power-saving is in use, make sure device is awake */ + if (test_bit(STATUS_POWER_PMI, &priv->status)) { + reg = iwl_read32(priv, CSR_UCODE_DRV_GP1); + + if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { + iwl_set_bit(priv, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + goto exit_unlock; + } + + ret = iwl_grab_nic_access(priv); + if (ret) + goto exit_unlock; + + /* Device expects a multiple of 8 */ + iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR, + q->write & ~0x7); + iwl_release_nic_access(priv); + + /* Else device is assumed to be awake */ + } else + /* Device expects a multiple of 8 */ + iwl_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7); + + + q->need_update = 0; + + exit_unlock: + spin_unlock_irqrestore(&q->lock, flags); + return ret; +} +EXPORT_SYMBOL(iwl_rx_queue_update_write_ptr); +/** + * iwl_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr + */ +static inline __le32 iwl_dma_addr2rbd_ptr(struct iwl_priv *priv, + dma_addr_t dma_addr) +{ + return cpu_to_le32((u32)(dma_addr >> 8)); +} + +/** + * iwl_rx_queue_restock - refill RX queue from pre-allocated pool + * + * If there are slots in the RX queue that need to be restocked, + * and we have free pre-allocated buffers, fill the ranks as much + * as we can, pulling from rx_free. + * + * This moves the 'write' index forward to catch up with 'processed', and + * also updates the memory address in the firmware to reference the new + * target buffer. + */ +int iwl_rx_queue_restock(struct iwl_priv *priv) +{ + struct iwl_rx_queue *rxq = &priv->rxq; + struct list_head *element; + struct iwl_rx_mem_buffer *rxb; + unsigned long flags; + int write; + int ret = 0; + + spin_lock_irqsave(&rxq->lock, flags); + write = rxq->write & ~0x7; + while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) { + /* Get next free Rx buffer, remove from free list */ + element = rxq->rx_free.next; + rxb = list_entry(element, struct iwl_rx_mem_buffer, list); + list_del(element); + + /* Point to Rx buffer via next RBD in circular buffer */ + rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(priv, rxb->dma_addr); + rxq->queue[rxq->write] = rxb; + rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; + rxq->free_count--; + } + spin_unlock_irqrestore(&rxq->lock, flags); + /* If the pre-allocated buffer pool is dropping low, schedule to + * refill it */ + if (rxq->free_count <= RX_LOW_WATERMARK) + queue_work(priv->workqueue, &priv->rx_replenish); + + + /* If we've added more space for the firmware to place data, tell it. + * Increment device's write pointer in multiples of 8. */ + if ((write != (rxq->write & ~0x7)) + || (abs(rxq->write - rxq->read) > 7)) { + spin_lock_irqsave(&rxq->lock, flags); + rxq->need_update = 1; + spin_unlock_irqrestore(&rxq->lock, flags); + ret = iwl_rx_queue_update_write_ptr(priv, rxq); + } + + return ret; +} +EXPORT_SYMBOL(iwl_rx_queue_restock); + + +/** + * iwl_rx_replenish - Move all used packet from rx_used to rx_free + * + * When moving to rx_free an SKB is allocated for the slot. + * + * Also restock the Rx queue via iwl_rx_queue_restock. + * This is called as a scheduled work item (except for during initialization) + */ +void iwl_rx_allocate(struct iwl_priv *priv) +{ + struct iwl_rx_queue *rxq = &priv->rxq; + struct list_head *element; + struct iwl_rx_mem_buffer *rxb; + unsigned long flags; + spin_lock_irqsave(&rxq->lock, flags); + while (!list_empty(&rxq->rx_used)) { + element = rxq->rx_used.next; + rxb = list_entry(element, struct iwl_rx_mem_buffer, list); + + /* Alloc a new receive buffer */ + rxb->skb = alloc_skb(priv->hw_params.rx_buf_size, + __GFP_NOWARN | GFP_ATOMIC); + if (!rxb->skb) { + if (net_ratelimit()) + printk(KERN_CRIT DRV_NAME + ": Can not allocate SKB buffers\n"); + /* We don't reschedule replenish work here -- we will + * call the restock method and if it still needs + * more buffers it will schedule replenish */ + break; + } + priv->alloc_rxb_skb++; + list_del(element); + + /* Get physical address of RB/SKB */ + rxb->dma_addr = + pci_map_single(priv->pci_dev, rxb->skb->data, + priv->hw_params.rx_buf_size, PCI_DMA_FROMDEVICE); + list_add_tail(&rxb->list, &rxq->rx_free); + rxq->free_count++; + } + spin_unlock_irqrestore(&rxq->lock, flags); +} +EXPORT_SYMBOL(iwl_rx_allocate); + +void iwl_rx_replenish(struct iwl_priv *priv) +{ + unsigned long flags; + + iwl_rx_allocate(priv); + + spin_lock_irqsave(&priv->lock, flags); + iwl_rx_queue_restock(priv); + spin_unlock_irqrestore(&priv->lock, flags); +} +EXPORT_SYMBOL(iwl_rx_replenish); + + +/* Assumes that the skb field of the buffers in 'pool' is kept accurate. + * If an SKB has been detached, the POOL needs to have its SKB set to NULL + * This free routine walks the list of POOL entries and if SKB is set to + * non NULL it is unmapped and freed + */ +void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) +{ + int i; + for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { + if (rxq->pool[i].skb != NULL) { + pci_unmap_single(priv->pci_dev, + rxq->pool[i].dma_addr, + priv->hw_params.rx_buf_size, + PCI_DMA_FROMDEVICE); + dev_kfree_skb(rxq->pool[i].skb); + } + } + + pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd, + rxq->dma_addr); + rxq->bd = NULL; +} +EXPORT_SYMBOL(iwl_rx_queue_free); + +int iwl_rx_queue_alloc(struct iwl_priv *priv) +{ + struct iwl_rx_queue *rxq = &priv->rxq; + struct pci_dev *dev = priv->pci_dev; + int i; + + spin_lock_init(&rxq->lock); + INIT_LIST_HEAD(&rxq->rx_free); + INIT_LIST_HEAD(&rxq->rx_used); + + /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */ + rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr); + if (!rxq->bd) + return -ENOMEM; + + /* Fill the rx_used queue with _all_ of the Rx buffers */ + for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) + list_add_tail(&rxq->pool[i].list, &rxq->rx_used); + + /* Set us so that we have processed and used all buffers, but have + * not restocked the Rx queue with fresh buffers */ + rxq->read = rxq->write = 0; + rxq->free_count = 0; + rxq->need_update = 0; + return 0; +} +EXPORT_SYMBOL(iwl_rx_queue_alloc); + +void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) +{ + unsigned long flags; + int i; + spin_lock_irqsave(&rxq->lock, flags); + INIT_LIST_HEAD(&rxq->rx_free); + INIT_LIST_HEAD(&rxq->rx_used); + /* Fill the rx_used queue with _all_ of the Rx buffers */ + for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { + /* In the reset function, these buffers may have been allocated + * to an SKB, so we need to unmap and free potential storage */ + if (rxq->pool[i].skb != NULL) { + pci_unmap_single(priv->pci_dev, + rxq->pool[i].dma_addr, + priv->hw_params.rx_buf_size, + PCI_DMA_FROMDEVICE); + priv->alloc_rxb_skb--; + dev_kfree_skb(rxq->pool[i].skb); + rxq->pool[i].skb = NULL; + } + list_add_tail(&rxq->pool[i].list, &rxq->rx_used); + } + + /* Set us so that we have processed and used all buffers, but have + * not restocked the Rx queue with fresh buffers */ + rxq->read = rxq->write = 0; + rxq->free_count = 0; + spin_unlock_irqrestore(&rxq->lock, flags); +} +EXPORT_SYMBOL(iwl_rx_queue_reset); + diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 54534270d46..aa0393589da 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -2736,7 +2736,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response */ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, - struct iwl4965_rx_mem_buffer *rxb) + struct iwl_rx_mem_buffer *rxb) { struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; u16 sequence = le16_to_cpu(pkt->hdr.sequence); @@ -2849,7 +2849,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, static void iwl4965_rx_reply_alive(struct iwl_priv *priv, - struct iwl4965_rx_mem_buffer *rxb) + struct iwl_rx_mem_buffer *rxb) { struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; struct iwl4965_alive_resp *palive; @@ -2885,7 +2885,7 @@ static void iwl4965_rx_reply_alive(struct iwl_priv *priv, } static void iwl4965_rx_reply_add_sta(struct iwl_priv *priv, - struct iwl4965_rx_mem_buffer *rxb) + struct iwl_rx_mem_buffer *rxb) { struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; @@ -2894,7 +2894,7 @@ static void iwl4965_rx_reply_add_sta(struct iwl_priv *priv, } static void iwl4965_rx_reply_error(struct iwl_priv *priv, - struct iwl4965_rx_mem_buffer *rxb) + struct iwl_rx_mem_buffer *rxb) { struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; @@ -2909,7 +2909,7 @@ static void iwl4965_rx_reply_error(struct iwl_priv *priv, #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x -static void iwl4965_rx_csa(struct iwl_priv *priv, struct iwl4965_rx_mem_buffer *rxb) +static void iwl4965_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; struct iwl4965_rxon_cmd *rxon = (void *)&priv->active_rxon; @@ -2921,7 +2921,7 @@ static void iwl4965_rx_csa(struct iwl_priv *priv, struct iwl4965_rx_mem_buffer * } static void iwl4965_rx_spectrum_measure_notif(struct iwl_priv *priv, - struct iwl4965_rx_mem_buffer *rxb) + struct iwl_rx_mem_buffer *rxb) { #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; @@ -2939,7 +2939,7 @@ static void iwl4965_rx_spectrum_measure_notif(struct iwl_priv *priv, } static void iwl4965_rx_pm_sleep_notif(struct iwl_priv *priv, - struct iwl4965_rx_mem_buffer *rxb) + struct iwl_rx_mem_buffer *rxb) { #ifdef CONFIG_IWLWIFI_DEBUG struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; @@ -2950,7 +2950,7 @@ static void iwl4965_rx_pm_sleep_notif(struct iwl_priv *priv, } static void iwl4965_rx_pm_debug_statistics_notif(struct iwl_priv *priv, - struct iwl4965_rx_mem_buffer *rxb) + struct iwl_rx_mem_buffer *rxb) { struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; IWL_DEBUG_RADIO("Dumping %d bytes of unhandled " @@ -2985,7 +2985,7 @@ static void iwl4965_bg_beacon_update(struct work_struct *work) } static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, - struct iwl4965_rx_mem_buffer *rxb) + struct iwl_rx_mem_buffer *rxb) { #ifdef CONFIG_IWLWIFI_DEBUG struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; @@ -3008,7 +3008,7 @@ static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, /* Service response to REPLY_SCAN_CMD (0x80) */ static void iwl4965_rx_reply_scan(struct iwl_priv *priv, - struct iwl4965_rx_mem_buffer *rxb) + struct iwl_rx_mem_buffer *rxb) { #ifdef CONFIG_IWLWIFI_DEBUG struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; @@ -3021,7 +3021,7 @@ static void iwl4965_rx_reply_scan(struct iwl_priv *priv, /* Service SCAN_START_NOTIFICATION (0x82) */ static void iwl4965_rx_scan_start_notif(struct iwl_priv *priv, - struct iwl4965_rx_mem_buffer *rxb) + struct iwl_rx_mem_buffer *rxb) { struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; struct iwl4965_scanstart_notification *notif = @@ -3038,7 +3038,7 @@ static void iwl4965_rx_scan_start_notif(struct iwl_priv *priv, /* Service SCAN_RESULTS_NOTIFICATION (0x83) */ static void iwl4965_rx_scan_results_notif(struct iwl_priv *priv, - struct iwl4965_rx_mem_buffer *rxb) + struct iwl_rx_mem_buffer *rxb) { struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; struct iwl4965_scanresults_notification *notif = @@ -3063,7 +3063,7 @@ static void iwl4965_rx_scan_results_notif(struct iwl_priv *priv, /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ static void iwl4965_rx_scan_complete_notif(struct iwl_priv *priv, - struct iwl4965_rx_mem_buffer *rxb) + struct iwl_rx_mem_buffer *rxb) { struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; struct iwl4965_scancomplete_notification *scan_notif = (void *)pkt->u.raw; @@ -3121,7 +3121,7 @@ reschedule: /* Handle notification from uCode that card's power state is changing * due to software, hardware, or critical temperature RFKILL */ static void iwl4965_rx_card_state_notif(struct iwl_priv *priv, - struct iwl4965_rx_mem_buffer *rxb) + struct iwl_rx_mem_buffer *rxb) { struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); @@ -3241,7 +3241,7 @@ static void iwl4965_setup_rx_handlers(struct iwl_priv *priv) * if the callback returns 1 */ static void iwl4965_tx_cmd_complete(struct iwl_priv *priv, - struct iwl4965_rx_mem_buffer *rxb) + struct iwl_rx_mem_buffer *rxb) { struct iwl4965_rx_packet *pkt = (struct iwl4965_rx_packet *)rxb->skb->data; u16 sequence = le16_to_cpu(pkt->hdr.sequence); @@ -3278,438 +3278,28 @@ static void iwl4965_tx_cmd_complete(struct iwl_priv *priv, } } -/************************** RX-FUNCTIONS ****************************/ -/* - * Rx theory of operation - * - * Driver allocates a circular buffer of Receive Buffer Descriptors (RBDs), - * each of which point to Receive Buffers to be filled by 4965. These get - * used not only for Rx frames, but for any command response or notification - * from the 4965. The driver and 4965 manage the Rx buffers by means - * of indexes into the circular buffer. - * - * Rx Queue Indexes - * The host/firmware share two index registers for managing the Rx buffers. - * - * The READ index maps to the first position that the firmware may be writing - * to -- the driver can read up to (but not including) this position and get - * good data. - * The READ index is managed by the firmware once the card is enabled. - * - * The WRITE index maps to the last position the driver has read from -- the - * position preceding WRITE is the last slot the firmware can place a packet. - * - * The queue is empty (no good data) if WRITE = READ - 1, and is full if - * WRITE = READ. - * - * During initialization, the host sets up the READ queue position to the first - * INDEX position, and WRITE to the last (READ - 1 wrapped) - * - * When the firmware places a packet in a buffer, it will advance the READ index - * and fire the RX interrupt. The driver can then query the READ index and - * process as many packets as possible, moving the WRITE index forward as it - * resets the Rx queue buffers with new memory. - * - * The management in the driver is as follows: - * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free. When - * iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled - * to replenish the iwl->rxq->rx_free. - * + In iwl4965_rx_replenish (scheduled) if 'processed' != 'read' then the - * iwl->rxq is replenished and the READ INDEX is updated (updating the - * 'processed' and 'read' driver indexes as well) - * + A received packet is processed and handed to the kernel network stack, - * detached from the iwl->rxq. The driver 'processed' index is updated. - * + The Host/Firmware iwl->rxq is replenished at tasklet time from the rx_free - * list. If there are no allocated buffers in iwl->rxq->rx_free, the READ - * INDEX is not incremented and iwl->status(RX_STALLED) is set. If there - * were enough free buffers and RX_STALLED is set it is cleared. - * - * - * Driver sequence: - * - * iwl4965_rx_queue_alloc() Allocates rx_free - * iwl4965_rx_replenish() Replenishes rx_free list from rx_used, and calls - * iwl4965_rx_queue_restock - * iwl4965_rx_queue_restock() Moves available buffers from rx_free into Rx - * queue, updates firmware pointers, and updates - * the WRITE index. If insufficient rx_free buffers - * are available, schedules iwl4965_rx_replenish - * - * -- enable interrupts -- - * ISR - iwl4965_rx() Detach iwl4965_rx_mem_buffers from pool up to the - * READ INDEX, detaching the SKB from the pool. - * Moves the packet buffer from queue to rx_used. - * Calls iwl4965_rx_queue_restock to refill any empty - * slots. - * ... - * - */ - -/** - * iwl4965_rx_queue_space - Return number of free slots available in queue. - */ -static int iwl4965_rx_queue_space(const struct iwl4965_rx_queue *q) -{ - int s = q->read - q->write; - if (s <= 0) - s += RX_QUEUE_SIZE; - /* keep some buffer to not confuse full and empty queue */ - s -= 2; - if (s < 0) - s = 0; - return s; -} - -/** - * iwl4965_rx_queue_update_write_ptr - Update the write pointer for the RX queue - */ -int iwl4965_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl4965_rx_queue *q) -{ - u32 reg = 0; - int rc = 0; - unsigned long flags; - - spin_lock_irqsave(&q->lock, flags); - - if (q->need_update == 0) - goto exit_unlock; - - /* If power-saving is in use, make sure device is awake */ - if (test_bit(STATUS_POWER_PMI, &priv->status)) { - reg = iwl_read32(priv, CSR_UCODE_DRV_GP1); - - if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { - iwl_set_bit(priv, CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); - goto exit_unlock; - } - - rc = iwl_grab_nic_access(priv); - if (rc) - goto exit_unlock; - - /* Device expects a multiple of 8 */ - iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR, - q->write & ~0x7); - iwl_release_nic_access(priv); - - /* Else device is assumed to be awake */ - } else - /* Device expects a multiple of 8 */ - iwl_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7); - - - q->need_update = 0; - - exit_unlock: - spin_unlock_irqrestore(&q->lock, flags); - return rc; -} - -/** - * iwl4965_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr - */ -static inline __le32 iwl4965_dma_addr2rbd_ptr(struct iwl_priv *priv, - dma_addr_t dma_addr) -{ - return cpu_to_le32((u32)(dma_addr >> 8)); -} - - -/** - * iwl4965_rx_queue_restock - refill RX queue from pre-allocated pool - * - * If there are slots in the RX queue that need to be restocked, - * and we have free pre-allocated buffers, fill the ranks as much - * as we can, pulling from rx_free. - * - * This moves the 'write' index forward to catch up with 'processed', and - * also updates the memory address in the firmware to reference the new - * target buffer. - */ -static int iwl4965_rx_queue_restock(struct iwl_priv *priv) -{ - struct iwl4965_rx_queue *rxq = &priv->rxq; - struct list_head *element; - struct iwl4965_rx_mem_buffer *rxb; - unsigned long flags; - int write, rc; - - spin_lock_irqsave(&rxq->lock, flags); - write = rxq->write & ~0x7; - while ((iwl4965_rx_queue_space(rxq) > 0) && (rxq->free_count)) { - /* Get next free Rx buffer, remove from free list */ - element = rxq->rx_free.next; - rxb = list_entry(element, struct iwl4965_rx_mem_buffer, list); - list_del(element); - - /* Point to Rx buffer via next RBD in circular buffer */ - rxq->bd[rxq->write] = iwl4965_dma_addr2rbd_ptr(priv, rxb->dma_addr); - rxq->queue[rxq->write] = rxb; - rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; - rxq->free_count--; - } - spin_unlock_irqrestore(&rxq->lock, flags); - /* If the pre-allocated buffer pool is dropping low, schedule to - * refill it */ - if (rxq->free_count <= RX_LOW_WATERMARK) - queue_work(priv->workqueue, &priv->rx_replenish); - - - /* If we've added more space for the firmware to place data, tell it. - * Increment device's write pointer in multiples of 8. */ - if ((write != (rxq->write & ~0x7)) - || (abs(rxq->write - rxq->read) > 7)) { - spin_lock_irqsave(&rxq->lock, flags); - rxq->need_update = 1; - spin_unlock_irqrestore(&rxq->lock, flags); - rc = iwl4965_rx_queue_update_write_ptr(priv, rxq); - if (rc) - return rc; - } - - return 0; -} - -/** - * iwl4965_rx_replenish - Move all used packet from rx_used to rx_free - * - * When moving to rx_free an SKB is allocated for the slot. - * - * Also restock the Rx queue via iwl4965_rx_queue_restock. - * This is called as a scheduled work item (except for during initialization) - */ -static void iwl4965_rx_allocate(struct iwl_priv *priv) -{ - struct iwl4965_rx_queue *rxq = &priv->rxq; - struct list_head *element; - struct iwl4965_rx_mem_buffer *rxb; - unsigned long flags; - spin_lock_irqsave(&rxq->lock, flags); - while (!list_empty(&rxq->rx_used)) { - element = rxq->rx_used.next; - rxb = list_entry(element, struct iwl4965_rx_mem_buffer, list); - - /* Alloc a new receive buffer */ - rxb->skb = - alloc_skb(priv->hw_params.rx_buf_size, - __GFP_NOWARN | GFP_ATOMIC); - if (!rxb->skb) { - if (net_ratelimit()) - printk(KERN_CRIT DRV_NAME - ": Can not allocate SKB buffers\n"); - /* We don't reschedule replenish work here -- we will - * call the restock method and if it still needs - * more buffers it will schedule replenish */ - break; - } - priv->alloc_rxb_skb++; - list_del(element); - - /* Get physical address of RB/SKB */ - rxb->dma_addr = - pci_map_single(priv->pci_dev, rxb->skb->data, - priv->hw_params.rx_buf_size, PCI_DMA_FROMDEVICE); - list_add_tail(&rxb->list, &rxq->rx_free); - rxq->free_count++; - } - spin_unlock_irqrestore(&rxq->lock, flags); -} - /* * this should be called while priv->lock is locked */ -static void __iwl4965_rx_replenish(void *data) -{ - struct iwl_priv *priv = data; - - iwl4965_rx_allocate(priv); - iwl4965_rx_queue_restock(priv); -} - - -void iwl4965_rx_replenish(void *data) -{ - struct iwl_priv *priv = data; - unsigned long flags; - - iwl4965_rx_allocate(priv); - - spin_lock_irqsave(&priv->lock, flags); - iwl4965_rx_queue_restock(priv); - spin_unlock_irqrestore(&priv->lock, flags); -} - -/* Assumes that the skb field of the buffers in 'pool' is kept accurate. - * If an SKB has been detached, the POOL needs to have its SKB set to NULL - * This free routine walks the list of POOL entries and if SKB is set to - * non NULL it is unmapped and freed - */ -static void iwl4965_rx_queue_free(struct iwl_priv *priv, struct iwl4965_rx_queue *rxq) -{ - int i; - for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { - if (rxq->pool[i].skb != NULL) { - pci_unmap_single(priv->pci_dev, - rxq->pool[i].dma_addr, - priv->hw_params.rx_buf_size, - PCI_DMA_FROMDEVICE); - dev_kfree_skb(rxq->pool[i].skb); - } - } - - pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd, - rxq->dma_addr); - rxq->bd = NULL; -} - -int iwl4965_rx_queue_alloc(struct iwl_priv *priv) -{ - struct iwl4965_rx_queue *rxq = &priv->rxq; - struct pci_dev *dev = priv->pci_dev; - int i; - - spin_lock_init(&rxq->lock); - INIT_LIST_HEAD(&rxq->rx_free); - INIT_LIST_HEAD(&rxq->rx_used); - - /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */ - rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr); - if (!rxq->bd) - return -ENOMEM; - - /* Fill the rx_used queue with _all_ of the Rx buffers */ - for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) - list_add_tail(&rxq->pool[i].list, &rxq->rx_used); - - /* Set us so that we have processed and used all buffers, but have - * not restocked the Rx queue with fresh buffers */ - rxq->read = rxq->write = 0; - rxq->free_count = 0; - rxq->need_update = 0; - return 0; -} - -void iwl4965_rx_queue_reset(struct iwl_priv *priv, struct iwl4965_rx_queue *rxq) -{ - unsigned long flags; - int i; - spin_lock_irqsave(&rxq->lock, flags); - INIT_LIST_HEAD(&rxq->rx_free); - INIT_LIST_HEAD(&rxq->rx_used); - /* Fill the rx_used queue with _all_ of the Rx buffers */ - for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { - /* In the reset function, these buffers may have been allocated - * to an SKB, so we need to unmap and free potential storage */ - if (rxq->pool[i].skb != NULL) { - pci_unmap_single(priv->pci_dev, - rxq->pool[i].dma_addr, - priv->hw_params.rx_buf_size, - PCI_DMA_FROMDEVICE); - priv->alloc_rxb_skb--; - dev_kfree_skb(rxq->pool[i].skb); - rxq->pool[i].skb = NULL; - } - list_add_tail(&rxq->pool[i].list, &rxq->rx_used); - } - - /* Set us so that we have processed and used all buffers, but have - * not restocked the Rx queue with fresh buffers */ - rxq->read = rxq->write = 0; - rxq->free_count = 0; - spin_unlock_irqrestore(&rxq->lock, flags); -} - -/* Convert linear signal-to-noise ratio into dB */ -static u8 ratio2dB[100] = { -/* 0 1 2 3 4 5 6 7 8 9 */ - 0, 0, 6, 10, 12, 14, 16, 17, 18, 19, /* 00 - 09 */ - 20, 21, 22, 22, 23, 23, 24, 25, 26, 26, /* 10 - 19 */ - 26, 26, 26, 27, 27, 28, 28, 28, 29, 29, /* 20 - 29 */ - 29, 30, 30, 30, 31, 31, 31, 31, 32, 32, /* 30 - 39 */ - 32, 32, 32, 33, 33, 33, 33, 33, 34, 34, /* 40 - 49 */ - 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, /* 50 - 59 */ - 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, /* 60 - 69 */ - 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, /* 70 - 79 */ - 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, /* 80 - 89 */ - 39, 39, 39, 39, 39, 40, 40, 40, 40, 40 /* 90 - 99 */ -}; - -/* Calculates a relative dB value from a ratio of linear - * (i.e. not dB) signal levels. - * Conversion assumes that levels are voltages (20*log), not powers (10*log). */ -int iwl4965_calc_db_from_ratio(int sig_ratio) +static void __iwl_rx_replenish(struct iwl_priv *priv) { - /* 1000:1 or higher just report as 60 dB */ - if (sig_ratio >= 1000) - return 60; - - /* 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]); - - /* We shouldn't see this */ - if (sig_ratio < 1) - return 0; - - /* Use table for ratios 1:1 - 99:1 */ - return (int)ratio2dB[sig_ratio]; + iwl_rx_allocate(priv); + iwl_rx_queue_restock(priv); } -#define PERFECT_RSSI (-20) /* dBm */ -#define WORST_RSSI (-95) /* dBm */ -#define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI) - -/* Calculate an indication of rx signal quality (a percentage, not dBm!). - * See http://www.ces.clemson.edu/linux/signal_quality.shtml for info - * about formulas used below. */ -int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm) -{ - int sig_qual; - int degradation = PERFECT_RSSI - rssi_dbm; - - /* If we get a noise measurement, use signal-to-noise ratio (SNR) - * as indicator; formula is (signal dbm - noise dbm). - * SNR at or above 40 is a great signal (100%). - * Below that, scale to fit SNR of 0 - 40 dB within 0 - 100% indicator. - * Weakest usable signal is usually 10 - 15 dB SNR. */ - if (noise_dbm) { - if (rssi_dbm - noise_dbm >= 40) - return 100; - else if (rssi_dbm < noise_dbm) - return 0; - sig_qual = ((rssi_dbm - noise_dbm) * 5) / 2; - - /* Else use just the signal level. - * This formula is a least squares fit of data points collected and - * compared with a reference system that had a percentage (%) display - * for signal quality. */ - } else - sig_qual = (100 * (RSSI_RANGE * RSSI_RANGE) - degradation * - (15 * RSSI_RANGE + 62 * degradation)) / - (RSSI_RANGE * RSSI_RANGE); - - if (sig_qual > 100) - sig_qual = 100; - else if (sig_qual < 1) - sig_qual = 0; - - return sig_qual; -} /** - * iwl4965_rx_handle - Main entry function for receiving responses from uCode + * iwl_rx_handle - Main entry function for receiving responses from uCode * * Uses the priv->rx_handlers callback function array to invoke * the appropriate handlers, including command responses, * frame-received notifications, and other notifications. */ -static void iwl4965_rx_handle(struct iwl_priv *priv) +void iwl_rx_handle(struct iwl_priv *priv) { - struct iwl4965_rx_mem_buffer *rxb; + struct iwl_rx_mem_buffer *rxb; struct iwl4965_rx_packet *pkt; - struct iwl4965_rx_queue *rxq = &priv->rxq; + struct iwl_rx_queue *rxq = &priv->rxq; u32 r, i; int reclaim; unsigned long flags; @@ -3725,7 +3315,7 @@ static void iwl4965_rx_handle(struct iwl_priv *priv) if (i == r) IWL_DEBUG(IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d\n", r, i); - if (iwl4965_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2)) + if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2)) fill_rx = 1; while (i != r) { @@ -3804,7 +3394,7 @@ static void iwl4965_rx_handle(struct iwl_priv *priv) count++; if (count >= 8) { priv->rxq.read = i; - __iwl4965_rx_replenish(priv); + __iwl_rx_replenish(priv); count = 0; } } @@ -3812,7 +3402,84 @@ static void iwl4965_rx_handle(struct iwl_priv *priv) /* Backtrack one entry */ priv->rxq.read = i; - iwl4965_rx_queue_restock(priv); + iwl_rx_queue_restock(priv); +} +/* Convert linear signal-to-noise ratio into dB */ +static u8 ratio2dB[100] = { +/* 0 1 2 3 4 5 6 7 8 9 */ + 0, 0, 6, 10, 12, 14, 16, 17, 18, 19, /* 00 - 09 */ + 20, 21, 22, 22, 23, 23, 24, 25, 26, 26, /* 10 - 19 */ + 26, 26, 26, 27, 27, 28, 28, 28, 29, 29, /* 20 - 29 */ + 29, 30, 30, 30, 31, 31, 31, 31, 32, 32, /* 30 - 39 */ + 32, 32, 32, 33, 33, 33, 33, 33, 34, 34, /* 40 - 49 */ + 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, /* 50 - 59 */ + 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, /* 60 - 69 */ + 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, /* 70 - 79 */ + 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, /* 80 - 89 */ + 39, 39, 39, 39, 39, 40, 40, 40, 40, 40 /* 90 - 99 */ +}; + +/* Calculates a relative dB value from a ratio of linear + * (i.e. not dB) signal levels. + * Conversion assumes that levels are voltages (20*log), not powers (10*log). */ +int iwl4965_calc_db_from_ratio(int sig_ratio) +{ + /* 1000:1 or higher just report as 60 dB */ + if (sig_ratio >= 1000) + return 60; + + /* 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]); + + /* We shouldn't see this */ + if (sig_ratio < 1) + return 0; + + /* Use table for ratios 1:1 - 99:1 */ + return (int)ratio2dB[sig_ratio]; +} + +#define PERFECT_RSSI (-20) /* dBm */ +#define WORST_RSSI (-95) /* dBm */ +#define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI) + +/* Calculate an indication of rx signal quality (a percentage, not dBm!). + * See http://www.ces.clemson.edu/linux/signal_quality.shtml for info + * about formulas used below. */ +int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm) +{ + int sig_qual; + int degradation = PERFECT_RSSI - rssi_dbm; + + /* If we get a noise measurement, use signal-to-noise ratio (SNR) + * as indicator; formula is (signal dbm - noise dbm). + * SNR at or above 40 is a great signal (100%). + * Below that, scale to fit SNR of 0 - 40 dB within 0 - 100% indicator. + * Weakest usable signal is usually 10 - 15 dB SNR. */ + if (noise_dbm) { + if (rssi_dbm - noise_dbm >= 40) + return 100; + else if (rssi_dbm < noise_dbm) + return 0; + sig_qual = ((rssi_dbm - noise_dbm) * 5) / 2; + + /* Else use just the signal level. + * This formula is a least squares fit of data points collected and + * compared with a reference system that had a percentage (%) display + * for signal quality. */ + } else + sig_qual = (100 * (RSSI_RANGE * RSSI_RANGE) - degradation * + (15 * RSSI_RANGE + 62 * degradation)) / + (RSSI_RANGE * RSSI_RANGE); + + if (sig_qual > 100) + sig_qual = 100; + else if (sig_qual < 1) + sig_qual = 0; + + return sig_qual; } /** @@ -4248,7 +3915,7 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv) /* uCode wakes up after power-down sleep */ if (inta & CSR_INT_BIT_WAKEUP) { IWL_DEBUG_ISR("Wakeup interrupt\n"); - iwl4965_rx_queue_update_write_ptr(priv, &priv->rxq); + iwl_rx_queue_update_write_ptr(priv, &priv->rxq); iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[0]); iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[1]); iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[2]); @@ -4263,7 +3930,7 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv) * Rx "responses" (frame-received notification), and other * notifications from uCode come through here*/ if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { - iwl4965_rx_handle(priv); + iwl_rx_handle(priv); handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); } @@ -5452,7 +5119,7 @@ static void iwl4965_bg_rx_replenish(struct work_struct *data) return; mutex_lock(&priv->mutex); - iwl4965_rx_replenish(priv); + iwl_rx_replenish(priv); mutex_unlock(&priv->mutex); } @@ -7309,7 +6976,7 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) iwl4965_dealloc_ucode_pci(priv); if (priv->rxq.bd) - iwl4965_rx_queue_free(priv, &priv->rxq); + iwl_rx_queue_free(priv, &priv->rxq); iwl4965_hw_txq_ctx_free(priv); iwlcore_clear_stations_table(priv); -- cgit v1.2.3 From 5a835353fb3c68a3da3badcc485614cdfc6e6109 Mon Sep 17 00:00:00 2001 From: Ron Rindjunsky Date: Mon, 5 May 2008 10:22:29 +0800 Subject: iwlwifi-5000: rename iwl5000_init_nic to iwl5000_init_config Signed-off-by: Ron Rindjunsky Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-5000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 0d8ef63f871..83ed69dfac6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -86,7 +86,7 @@ static int iwl5000_apm_init(struct iwl_priv *priv) return ret; } -static void iwl5000_nic_init(struct iwl_priv *priv) +static void iwl5000_nic_config(struct iwl_priv *priv) { unsigned long flags; u16 radio_cfg; @@ -439,7 +439,7 @@ static struct iwl_lib_ops iwl5000_lib = { .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, .apm_ops = { .init = iwl5000_apm_init, - .config = iwl5000_nic_init, + .config = iwl5000_nic_config, .set_pwr_src = iwl4965_set_pwr_src, }, .eeprom_ops = { -- cgit v1.2.3 From 6b9b34389c2fdb8618fe2c686b6872d26562fd07 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 5 May 2008 10:22:30 +0800 Subject: iwlwifi: don't override association channel with control channel This patch fixes override of association channel with HT control channel. The scenario is currently happening because disassociation flow doesn't clean previous association information (such as is_ht and control channel). Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-4965.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 773bb3229cf..6eca75717f3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -3775,10 +3775,10 @@ void iwl4965_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info) RXON_FLG_CHANNEL_MODE_PURE_40_MSK); if (le16_to_cpu(rxon->channel) != ht_info->control_channel) { - IWL_DEBUG_ASSOC("control diff than current %d %d\n", + IWL_ERROR("control diff than current %d %d\n", le16_to_cpu(rxon->channel), ht_info->control_channel); - rxon->channel = cpu_to_le16(ht_info->control_channel); + WARN_ON(1); return; } -- cgit v1.2.3 From 6def9761f72501e638e79eebcd70afea12a3a93d Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 5 May 2008 10:22:31 +0800 Subject: iwlwifi: remove 4965 from station_entry This patch removes 4965 mark form the station entry structure. Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-4965.c | 10 +++++----- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 2 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 18 +++++++++--------- drivers/net/wireless/iwlwifi/iwl-sta.c | 2 +- drivers/net/wireless/iwlwifi/iwl4965-base.c | 8 ++++---- 5 files changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 6eca75717f3..bd9d5ff7392 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -3333,7 +3333,7 @@ static void iwl4965_sta_modify_enable_tid_tx(struct iwl_priv *priv, * ACK vs. not. This gets sent to mac80211, then to rate scaling algo. */ static int iwl4965_tx_status_reply_compressed_ba(struct iwl_priv *priv, - struct iwl4965_ht_agg *agg, + struct iwl_ht_agg *agg, struct iwl4965_compressed_ba_resp* ba_resp) @@ -3450,7 +3450,7 @@ int iwl4965_check_empty_hw_queue(struct iwl_priv *priv, int sta_id, { struct iwl4965_queue *q = &priv->txq[txq_id].q; u8 *addr = priv->stations[sta_id].sta.sta.addr; - struct iwl4965_tid_data *tid_data = &priv->stations[sta_id].tid[tid]; + struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid]; switch (priv->stations[sta_id].tid[tid].agg.state) { case IWL_EMPTYING_HW_QUEUE_DELBA: @@ -3502,7 +3502,7 @@ static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv, struct iwl4965_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; int index; struct iwl4965_tx_queue *txq = NULL; - struct iwl4965_ht_agg *agg; + struct iwl_ht_agg *agg; DECLARE_MAC_BUF(mac); /* "flow" corresponds to Tx queue */ @@ -3929,7 +3929,7 @@ static int iwl4965_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra, int ssn = -1; int ret = 0; unsigned long flags; - struct iwl4965_tid_data *tid_data; + struct iwl_tid_data *tid_data; DECLARE_MAC_BUF(mac); if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo))) @@ -3982,7 +3982,7 @@ static int iwl4965_tx_agg_stop(struct ieee80211_hw *hw, const u8 *ra, u16 tid) { struct iwl_priv *priv = hw->priv; int tx_fifo_id, txq_id, sta_id, ssn = -1; - struct iwl4965_tid_data *tid_data; + struct iwl_tid_data *tid_data; int ret, write_ptr, read_ptr; unsigned long flags; DECLARE_MAC_BUF(mac); diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 30914453de1..37b52e63739 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -206,7 +206,7 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct iwl_priv *priv = (struct iwl_priv *)file->private_data; - struct iwl4965_station_entry *station; + struct iwl_station_entry *station; int max_sta = priv->hw_params.max_stations; char *buf; int i, j, pos = 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 1d80ad79114..07eff75786b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -401,7 +401,7 @@ struct iwl_rx_queue { #ifdef CONFIG_IWL4965_HT /** - * struct iwl4965_ht_agg -- aggregation status while waiting for block-ack + * struct iwl_ht_agg -- aggregation status while waiting for block-ack * @txq_id: Tx queue used for Tx attempt * @frame_count: # frames attempted by Tx command * @wait_for_ba: Expect block-ack before next Tx reply @@ -414,7 +414,7 @@ struct iwl_rx_queue { * for block ack (REPLY_COMPRESSED_BA). This struct stores tx reply info * until block ack arrives. */ -struct iwl4965_ht_agg { +struct iwl_ht_agg { u16 txq_id; u16 frame_count; u16 wait_for_ba; @@ -430,15 +430,15 @@ struct iwl4965_ht_agg { #endif /* CONFIG_IWL4965_HT */ -struct iwl4965_tid_data { +struct iwl_tid_data { u16 seq_number; u16 tfds_in_queue; #ifdef CONFIG_IWL4965_HT - struct iwl4965_ht_agg agg; + struct iwl_ht_agg agg; #endif /* CONFIG_IWL4965_HT */ }; -struct iwl4965_hw_key { +struct iwl_hw_key { enum ieee80211_key_alg alg; int keylen; u8 keyidx; @@ -510,12 +510,12 @@ struct iwl4965_qos_info { #define STA_PS_STATUS_WAKE 0 #define STA_PS_STATUS_SLEEP 1 -struct iwl4965_station_entry { +struct iwl_station_entry { struct iwl4965_addsta_cmd sta; - struct iwl4965_tid_data tid[MAX_TID_COUNT]; + struct iwl_tid_data tid[MAX_TID_COUNT]; u8 used; u8 ps_status; - struct iwl4965_hw_key keyinfo; + struct iwl_hw_key keyinfo; }; /* one for each uCode image (inst/data, boot/init/runtime) */ @@ -1107,7 +1107,7 @@ struct iwl_priv { /*station table variables */ spinlock_t sta_lock; int num_stations; - struct iwl4965_station_entry stations[IWL_STATION_COUNT]; + struct iwl_station_entry stations[IWL_STATION_COUNT]; struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; u8 default_wep_key; u8 key_mapping_key; diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 31b37a1a643..0148d49e0b5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -333,7 +333,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, IWL_ERROR("index %d not used in uCode key table.\n", priv->stations[sta_id].sta.key.key_offset); memset(&priv->stations[sta_id].keyinfo, 0, - sizeof(struct iwl4965_hw_key)); + sizeof(struct iwl_hw_key)); memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl4965_keyinfo)); priv->stations[sta_id].sta.key.key_flags = diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index aa0393589da..50757ff66ba 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -433,7 +433,7 @@ u8 iwl4965_add_station_flags(struct iwl_priv *priv, const u8 *addr, { int i; int index = IWL_INVALID_STATION; - struct iwl4965_station_entry *station; + struct iwl_station_entry *station; unsigned long flags_spin; DECLARE_MAC_BUF(mac); @@ -1783,7 +1783,7 @@ static void iwl4965_build_tx_cmd_hwcrypto(struct iwl_priv *priv, struct sk_buff *skb_frag, int sta_id) { - struct iwl4965_hw_key *keyinfo = &priv->stations[sta_id].keyinfo; + struct iwl_hw_key *keyinfo = &priv->stations[sta_id].keyinfo; struct iwl_wep_key *wepkey; int keyidx = 0; @@ -2617,7 +2617,7 @@ static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp) * iwl4965_tx_status_reply_tx - Handle Tx rspnse for frames in aggregation queue */ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, - struct iwl4965_ht_agg *agg, + struct iwl_ht_agg *agg, struct iwl4965_tx_resp_agg *tx_resp, u16 start_idx) { @@ -2775,7 +2775,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, if (txq->sched_retry) { const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp); - struct iwl4965_ht_agg *agg = NULL; + struct iwl_ht_agg *agg = NULL; if (!qc) return; -- cgit v1.2.3 From 8dd266ef4eb51d034fa1c5f9307a9ff07547d8e6 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 5 May 2008 10:22:32 +0800 Subject: iwlwifi: debugfs EEPROM dump This patch adds EEPROM dump in debugfs. Signed-off-by: Tomas Winkler Signed-off-by: Abhijeet Kolekar Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-debug.h | 1 + drivers/net/wireless/iwlwifi/iwl-debugfs.c | 42 ++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index c60724c21db..7e68d24114f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -57,6 +57,7 @@ struct iwl_debugfs { struct dentry *dir_data; struct dir_data_files{ struct dentry *file_sram; + struct dentry *file_eeprom; struct dentry *file_stations; struct dentry *file_rx_statistics; struct dentry *file_tx_statistics; diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 37b52e63739..ad25806dfaf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -277,8 +277,48 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, return ret; } +static ssize_t iwl_dbgfs_eeprom_read(struct file *file, + char __user *user_buf, + size_t count, + loff_t *ppos) +{ + ssize_t ret; + struct iwl_priv *priv = (struct iwl_priv *)file->private_data; + int pos = 0, ofs = 0, buf_size = 0; + const u8 *ptr; + char *buf; + size_t eeprom_len = priv->cfg->eeprom_size; + buf_size = 4 * eeprom_len + 256; + + if (eeprom_len % 16) { + IWL_ERROR("EEPROM size is not multiple of 16.\n"); + return -ENODATA; + } + + /* 4 characters for byte 0xYY */ + buf = kzalloc(buf_size, GFP_KERNEL); + if (!buf) { + IWL_ERROR("Can not allocate Buffer\n"); + return -ENOMEM; + } + + ptr = priv->eeprom; + for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) { + pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs); + hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos, + buf_size - pos, 0); + pos += strlen(buf); + if (buf_size - pos > 0) + buf[pos++] = '\n'; + } + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} DEBUGFS_READ_WRITE_FILE_OPS(sram); +DEBUGFS_READ_FILE_OPS(eeprom); DEBUGFS_READ_FILE_OPS(stations); DEBUGFS_READ_FILE_OPS(rx_statistics); DEBUGFS_READ_FILE_OPS(tx_statistics); @@ -304,6 +344,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) } DEBUGFS_ADD_DIR(data, dbgfs->dir_drv); + DEBUGFS_ADD_FILE(eeprom, data); DEBUGFS_ADD_FILE(sram, data); DEBUGFS_ADD_FILE(stations, data); DEBUGFS_ADD_FILE(rx_statistics, data); @@ -327,6 +368,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv) if (!(priv->dbgfs)) return; + DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_eeprom); DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_rx_statistics); DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_tx_statistics); DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram); -- cgit v1.2.3 From db11d6343aa14ab61258bfad9178042d4be49333 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 5 May 2008 10:22:33 +0800 Subject: iwlwifi: remove 4965 from rx_packet This patch removes 4965 mark from rx_packet. Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-4965.c | 16 ++++----- drivers/net/wireless/iwlwifi/iwl-commands.h | 2 +- drivers/net/wireless/iwlwifi/iwl-hcmd.c | 4 +-- drivers/net/wireless/iwlwifi/iwl4965-base.c | 56 ++++++++++++++--------------- 4 files changed, 39 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index bd9d5ff7392..f7e267e30ce 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2519,7 +2519,7 @@ static void iwl4965_rx_calc_noise(struct iwl_priv *priv) void iwl4965_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { - struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; int change; s32 temp; @@ -2807,7 +2807,7 @@ static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data, struct iwl_rx_mem_buffer *rxb, struct ieee80211_rx_status *stats) { - struct iwl4965_rx_packet *pkt = (struct iwl4965_rx_packet *)rxb->skb->data; + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; struct iwl4965_rx_phy_res *rx_start = (include_phy) ? (struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) : NULL; struct ieee80211_hdr *hdr; @@ -2964,7 +2964,7 @@ static void iwl4965_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr) * proper operation with 4965. */ static void iwl4965_dbg_report_frame(struct iwl_priv *priv, - struct iwl4965_rx_packet *pkt, + struct iwl_rx_packet *pkt, struct ieee80211_hdr *header, int group100) { u32 to_us; @@ -3098,7 +3098,7 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv, } #else static inline void iwl4965_dbg_report_frame(struct iwl_priv *priv, - struct iwl4965_rx_packet *pkt, + struct iwl_rx_packet *pkt, struct ieee80211_hdr *header, int group100) { @@ -3114,7 +3114,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, { struct ieee80211_hdr *header; struct ieee80211_rx_status rx_status; - struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; /* Use phy data (Rx signal strength, etc.) contained within * this rx packet for legacy frames, * or phy data cached from REPLY_RX_PHY_CMD for HT frames. */ @@ -3281,7 +3281,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, static void iwl4965_rx_reply_rx_phy(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { - struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; priv->last_phy_res[0] = 1; memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]), sizeof(struct iwl4965_rx_phy_res)); @@ -3291,7 +3291,7 @@ static void iwl4965_rx_missed_beacon_notif(struct iwl_priv *priv, { #ifdef CONFIG_IWL4965_RUN_TIME_CALIB - struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; struct iwl4965_missed_beacon_notif *missed_beacon; missed_beacon = &pkt->u.missed_beacon; @@ -3498,7 +3498,7 @@ static inline int iwl4965_queue_dec_wrap(int index, int n_bd) static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { - struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; struct iwl4965_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; int index; struct iwl4965_tx_queue *txq = NULL; diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 5afa7b79b59..e5449b8c335 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2731,7 +2731,7 @@ struct iwl4965_led_cmd { * *****************************************************************************/ -struct iwl4965_rx_packet { +struct iwl_rx_packet { __le32 len; struct iwl_cmd_header hdr; union { diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index acb5a8abd78..0412adf6ef8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -101,7 +101,7 @@ EXPORT_SYMBOL(get_cmd_string); static int iwl_generic_cmd_callback(struct iwl_priv *priv, struct iwl_cmd *cmd, struct sk_buff *skb) { - struct iwl4965_rx_packet *pkt = NULL; + struct iwl_rx_packet *pkt = NULL; if (!skb) { IWL_ERROR("Error: Response NULL in %s.\n", @@ -109,7 +109,7 @@ static int iwl_generic_cmd_callback(struct iwl_priv *priv, return 1; } - pkt = (struct iwl4965_rx_packet *)skb->data; + pkt = (struct iwl_rx_packet *)skb->data; if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { IWL_ERROR("Bad return from %s (0x%08X)\n", get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags); diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 50757ff66ba..5b9cbbd197f 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -902,8 +902,8 @@ static int iwl4965_send_bt_config(struct iwl_priv *priv) static int iwl4965_send_scan_abort(struct iwl_priv *priv) { - int rc = 0; - struct iwl4965_rx_packet *res; + int ret = 0; + struct iwl_rx_packet *res; struct iwl_host_cmd cmd = { .id = REPLY_SCAN_ABORT_CMD, .meta.flags = CMD_WANT_SKB, @@ -917,13 +917,13 @@ static int iwl4965_send_scan_abort(struct iwl_priv *priv) return 0; } - rc = iwl_send_cmd_sync(priv, &cmd); - if (rc) { + ret = iwl_send_cmd_sync(priv, &cmd); + if (ret) { clear_bit(STATUS_SCAN_ABORTING, &priv->status); - return rc; + return ret; } - res = (struct iwl4965_rx_packet *)cmd.meta.u.skb->data; + res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; if (res->u.status != CAN_ABORT_STATUS) { /* The scan abort will return 1 for success or * 2 for "failure". A failure condition can be @@ -938,7 +938,7 @@ static int iwl4965_send_scan_abort(struct iwl_priv *priv) dev_kfree_skb_any(cmd.meta.u.skb); - return rc; + return ret; } /* @@ -966,7 +966,7 @@ static int iwl4965_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_fla int iwl4965_send_add_station(struct iwl_priv *priv, struct iwl4965_addsta_cmd *sta, u8 flags) { - struct iwl4965_rx_packet *res = NULL; + struct iwl_rx_packet *res = NULL; int rc = 0; struct iwl_host_cmd cmd = { .id = REPLY_ADD_STA, @@ -983,7 +983,7 @@ int iwl4965_send_add_station(struct iwl_priv *priv, if (rc || (flags & CMD_ASYNC)) return rc; - res = (struct iwl4965_rx_packet *)cmd.meta.u.skb->data; + res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; if (res->hdr.flags & IWL_CMD_FAILED_MSK) { IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n", res->hdr.flags); @@ -2441,7 +2441,7 @@ static int iwl4965_get_measurement(struct iwl_priv *priv, u8 type) { struct iwl4965_spectrum_cmd spectrum; - struct iwl4965_rx_packet *res; + struct iwl_rx_packet *res; struct iwl_host_cmd cmd = { .id = REPLY_SPECTRUM_MEASUREMENT_CMD, .data = (void *)&spectrum, @@ -2486,7 +2486,7 @@ static int iwl4965_get_measurement(struct iwl_priv *priv, if (rc) return rc; - res = (struct iwl4965_rx_packet *)cmd.meta.u.skb->data; + res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; if (res->hdr.flags & IWL_CMD_FAILED_MSK) { IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n"); rc = -EIO; @@ -2738,7 +2738,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, static void iwl4965_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { - struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; u16 sequence = le16_to_cpu(pkt->hdr.sequence); int txq_id = SEQ_TO_QUEUE(sequence); int index = SEQ_TO_INDEX(sequence); @@ -2851,7 +2851,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, static void iwl4965_rx_reply_alive(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { - struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; struct iwl4965_alive_resp *palive; struct delayed_work *pwork; @@ -2887,7 +2887,7 @@ static void iwl4965_rx_reply_alive(struct iwl_priv *priv, static void iwl4965_rx_reply_add_sta(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { - struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; IWL_DEBUG_RX("Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status); return; @@ -2896,7 +2896,7 @@ static void iwl4965_rx_reply_add_sta(struct iwl_priv *priv, static void iwl4965_rx_reply_error(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { - struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; IWL_ERROR("Error Reply type 0x%08X cmd %s (0x%02X) " "seq 0x%04X ser 0x%08X\n", @@ -2911,7 +2911,7 @@ static void iwl4965_rx_reply_error(struct iwl_priv *priv, static void iwl4965_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { - struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; struct iwl4965_rxon_cmd *rxon = (void *)&priv->active_rxon; struct iwl4965_csa_notification *csa = &(pkt->u.csa_notif); IWL_DEBUG_11H("CSA notif: channel %d, status %d\n", @@ -2924,7 +2924,7 @@ static void iwl4965_rx_spectrum_measure_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT - struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; struct iwl4965_spectrum_notification *report = &(pkt->u.spectrum_notif); if (!report->state) { @@ -2942,7 +2942,7 @@ static void iwl4965_rx_pm_sleep_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { #ifdef CONFIG_IWLWIFI_DEBUG - struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; struct iwl4965_sleep_notification *sleep = &(pkt->u.sleep_notif); IWL_DEBUG_RX("sleep mode: %d, src: %d\n", sleep->pm_sleep_mode, sleep->pm_wakeup_src); @@ -2952,7 +2952,7 @@ static void iwl4965_rx_pm_sleep_notif(struct iwl_priv *priv, static void iwl4965_rx_pm_debug_statistics_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { - struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; IWL_DEBUG_RADIO("Dumping %d bytes of unhandled " "notification for %s:\n", le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd)); @@ -2988,7 +2988,7 @@ static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { #ifdef CONFIG_IWLWIFI_DEBUG - struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; struct iwl4965_beacon_notif *beacon = &(pkt->u.beacon_status); u8 rate = iwl4965_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); @@ -3011,7 +3011,7 @@ static void iwl4965_rx_reply_scan(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { #ifdef CONFIG_IWLWIFI_DEBUG - struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; struct iwl4965_scanreq_notification *notif = (struct iwl4965_scanreq_notification *)pkt->u.raw; @@ -3023,7 +3023,7 @@ static void iwl4965_rx_reply_scan(struct iwl_priv *priv, static void iwl4965_rx_scan_start_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { - struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; struct iwl4965_scanstart_notification *notif = (struct iwl4965_scanstart_notification *)pkt->u.raw; priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); @@ -3040,7 +3040,7 @@ static void iwl4965_rx_scan_start_notif(struct iwl_priv *priv, static void iwl4965_rx_scan_results_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { - struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; struct iwl4965_scanresults_notification *notif = (struct iwl4965_scanresults_notification *)pkt->u.raw; @@ -3065,7 +3065,7 @@ static void iwl4965_rx_scan_results_notif(struct iwl_priv *priv, static void iwl4965_rx_scan_complete_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { - struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; struct iwl4965_scancomplete_notification *scan_notif = (void *)pkt->u.raw; IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", @@ -3123,7 +3123,7 @@ reschedule: static void iwl4965_rx_card_state_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { - struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); unsigned long status = priv->status; @@ -3243,7 +3243,7 @@ static void iwl4965_setup_rx_handlers(struct iwl_priv *priv) static void iwl4965_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { - struct iwl4965_rx_packet *pkt = (struct iwl4965_rx_packet *)rxb->skb->data; + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; u16 sequence = le16_to_cpu(pkt->hdr.sequence); int txq_id = SEQ_TO_QUEUE(sequence); int index = SEQ_TO_INDEX(sequence); @@ -3298,7 +3298,7 @@ static void __iwl_rx_replenish(struct iwl_priv *priv) void iwl_rx_handle(struct iwl_priv *priv) { struct iwl_rx_mem_buffer *rxb; - struct iwl4965_rx_packet *pkt; + struct iwl_rx_packet *pkt; struct iwl_rx_queue *rxq = &priv->rxq; u32 r, i; int reclaim; @@ -3331,7 +3331,7 @@ void iwl_rx_handle(struct iwl_priv *priv) pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr, priv->hw_params.rx_buf_size, PCI_DMA_FROMDEVICE); - pkt = (struct iwl4965_rx_packet *)rxb->skb->data; + pkt = (struct iwl_rx_packet *)rxb->skb->data; /* Reclaim a command buffer only if this packet is a response * to a (driver-originated) command. -- cgit v1.2.3 From 133636deffc86809f59a0c8b768408d13237a9a2 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 5 May 2008 10:22:34 +0800 Subject: iwlwifi: generalize iwl4965_send_add_station function This patch moves iwl4965_send_add_station to iwlcore under new name iwl_send_add_sta. Function uses build command handler in order to support multiple HWs. Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-4965.c | 28 ++++++++++++--- drivers/net/wireless/iwlwifi/iwl-commands.h | 46 ++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 1 + drivers/net/wireless/iwlwifi/iwl-dev.h | 10 +++--- drivers/net/wireless/iwlwifi/iwl-sta.c | 54 ++++++++++++++++++++++++++--- drivers/net/wireless/iwlwifi/iwl4965-base.c | 51 ++------------------------- 6 files changed, 127 insertions(+), 63 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index f7e267e30ce..0644e22fe78 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2931,7 +2931,7 @@ static void iwl4965_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; spin_unlock_irqrestore(&priv->sta_lock, flags); - iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); + iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); } static void iwl4965_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr) @@ -3323,7 +3323,7 @@ static void iwl4965_sta_modify_enable_tid_tx(struct iwl_priv *priv, priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; spin_unlock_irqrestore(&priv->sta_lock, flags); - iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); + iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); } /** @@ -3878,7 +3878,7 @@ static int iwl4965_rx_agg_start(struct iwl_priv *priv, priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; spin_unlock_irqrestore(&priv->sta_lock, flags); - return iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, + return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); } @@ -3899,7 +3899,7 @@ static int iwl4965_rx_agg_stop(struct iwl_priv *priv, priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; spin_unlock_irqrestore(&priv->sta_lock, flags); - return iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, + return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); } @@ -4064,9 +4064,26 @@ int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, } return 0; } - #endif /* CONFIG_IWL4965_HT */ + +static u16 iwl4965_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) +{ + struct iwl4965_addsta_cmd *addsta = (struct iwl4965_addsta_cmd *)data; + addsta->mode = cmd->mode; + memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify)); + memcpy(&addsta->key, &cmd->key, sizeof(struct iwl4965_keyinfo)); + addsta->station_flags = cmd->station_flags; + addsta->station_flags_msk = cmd->station_flags_msk; + addsta->tid_disable_tx = cmd->tid_disable_tx; + addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid; + addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid; + addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn; + addsta->reserved1 = __constant_cpu_to_le16(0); + addsta->reserved2 = __constant_cpu_to_le32(0); + + return (u16)sizeof(struct iwl4965_addsta_cmd); +} /* Set up 4965-specific Rx frame reply handlers */ static void iwl4965_rx_handler_setup(struct iwl_priv *priv) { @@ -4110,6 +4127,7 @@ static struct iwl_hcmd_ops iwl4965_hcmd = { static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { .enqueue_hcmd = iwl4965_enqueue_hcmd, + .build_addsta_hcmd = iwl4965_build_addsta_hcmd, #ifdef CONFIG_IWL4965_RUN_TIME_CALIB .chain_noise_reset = iwl4965_chain_noise_reset, .gain_computation = iwl4965_gain_computation, diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index e5449b8c335..d16a853f376 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -769,6 +769,20 @@ struct iwl4965_keyinfo { u8 key[16]; /* 16-byte unicast decryption key */ } __attribute__ ((packed)); +/* 5000 */ +struct iwl_keyinfo { + __le16 key_flags; + u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */ + u8 reserved1; + __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */ + u8 key_offset; + u8 reserved2; + u8 key[16]; /* 16-byte unicast decryption key */ + __le64 tx_secur_seq_cnt; + __le64 hw_tkip_mic_rx_key; + __le64 hw_tkip_mic_tx_key; +} __attribute__ ((packed)); + /** * struct sta_id_modify * @addr[ETH_ALEN]: station's MAC address @@ -844,6 +858,38 @@ struct iwl4965_addsta_cmd { __le32 reserved2; } __attribute__ ((packed)); +/* 5000 */ +struct iwl_addsta_cmd { + u8 mode; /* 1: modify existing, 0: add new station */ + u8 reserved[3]; + struct sta_id_modify sta; + struct iwl_keyinfo key; + __le32 station_flags; /* STA_FLG_* */ + __le32 station_flags_msk; /* STA_FLG_* */ + + /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID) + * corresponding to bit (e.g. bit 5 controls TID 5). + * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */ + __le16 tid_disable_tx; + + __le16 reserved1; + + /* TID for which to add block-ack support. + * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ + u8 add_immediate_ba_tid; + + /* TID for which to remove block-ack support. + * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */ + u8 remove_immediate_ba_tid; + + /* Starting Sequence Number for added block-ack support. + * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ + __le16 add_immediate_ba_ssn; + + __le32 reserved2; +} __attribute__ ((packed)); + + #define ADD_STA_SUCCESS_MSK 0x1 #define ADD_STA_NO_ROOM_IN_TABLE 0x2 #define ADD_STA_NO_BLOCK_ACK_RESOURCE 0x4 diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 2356cadc1de..df27ee65015 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -87,6 +87,7 @@ struct iwl_hcmd_ops { }; struct iwl_hcmd_utils_ops { int (*enqueue_hcmd)(struct iwl_priv *priv, struct iwl_host_cmd *cmd); + u16 (*build_addsta_hcmd)(const struct iwl_addsta_cmd *cmd, u8 *data); #ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB void (*gain_computation)(struct iwl_priv *priv, u32 *average_noise, diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 07eff75786b..4786194c045 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -319,7 +319,7 @@ struct iwl_cmd { struct iwl_cmd_meta meta; /* driver data */ struct iwl_cmd_header hdr; /* uCode API */ union { - struct iwl4965_addsta_cmd addsta; + struct iwl_addsta_cmd addsta; struct iwl4965_led_cmd led; u32 flags; u8 val8; @@ -511,7 +511,7 @@ struct iwl4965_qos_info { #define STA_PS_STATUS_SLEEP 1 struct iwl_station_entry { - struct iwl4965_addsta_cmd sta; + struct iwl_addsta_cmd sta; struct iwl_tid_data tid[MAX_TID_COUNT]; u8 used; u8 ps_status; @@ -634,9 +634,9 @@ struct iwl_hw_params { * for use by iwl-*.c * *****************************************************************************/ -struct iwl4965_addsta_cmd; -extern int iwl4965_send_add_station(struct iwl_priv *priv, - struct iwl4965_addsta_cmd *sta, u8 flags); +struct iwl_addsta_cmd; +extern int iwl_send_add_sta(struct iwl_priv *priv, + struct iwl_addsta_cmd *sta, u8 flags); extern u8 iwl4965_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags, void *ht_data); extern int iwl4965_is_network_packet(struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 0148d49e0b5..34f54244ed2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -70,6 +70,52 @@ u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr) } EXPORT_SYMBOL(iwl_find_station); +int iwl_send_add_sta(struct iwl_priv *priv, + struct iwl_addsta_cmd *sta, u8 flags) +{ + struct iwl_rx_packet *res = NULL; + int ret = 0; + u8 data[sizeof(*sta)]; + struct iwl_host_cmd cmd = { + .id = REPLY_ADD_STA, + .meta.flags = flags, + .data = data, + }; + + if (!(flags & CMD_ASYNC)) + cmd.meta.flags |= CMD_WANT_SKB; + + cmd.len = priv->cfg->ops->utils->build_addsta_hcmd(sta, data); + ret = iwl_send_cmd(priv, &cmd); + + if (ret || (flags & CMD_ASYNC)) + return ret; + + res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; + if (res->hdr.flags & IWL_CMD_FAILED_MSK) { + IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n", + res->hdr.flags); + ret = -EIO; + } + + if (ret == 0) { + switch (res->u.add_sta.status) { + case ADD_STA_SUCCESS_MSK: + IWL_DEBUG_INFO("REPLY_ADD_STA PASSED\n"); + break; + default: + ret = -EIO; + IWL_WARNING("REPLY_ADD_STA failed\n"); + break; + } + } + + priv->alloc_rxb_skb--; + dev_kfree_skb_any(cmd.meta.u.skb); + + return ret; +} +EXPORT_SYMBOL(iwl_send_add_sta); int iwl_get_free_ucode_key_index(struct iwl_priv *priv) { @@ -216,8 +262,7 @@ static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - ret = iwl4965_send_add_station(priv, - &priv->stations[sta_id].sta, CMD_ASYNC); + ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); spin_unlock_irqrestore(&priv->sta_lock, flags); @@ -265,8 +310,7 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv, spin_unlock_irqrestore(&priv->sta_lock, flags); IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n"); - return iwl4965_send_add_station(priv, - &priv->stations[sta_id].sta, CMD_ASYNC); + return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); } static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, @@ -343,7 +387,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n"); - ret = iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, 0); + ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 0); spin_unlock_irqrestore(&priv->sta_lock, flags); return ret; } diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 5b9cbbd197f..8427bc9a9bb 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -476,7 +476,7 @@ u8 iwl4965_add_station_flags(struct iwl_priv *priv, const u8 *addr, priv->num_stations++; /* Set up the REPLY_ADD_STA command to send to device */ - memset(&station->sta, 0, sizeof(struct iwl4965_addsta_cmd)); + memset(&station->sta, 0, sizeof(struct iwl_addsta_cmd)); memcpy(station->sta.sta.addr, addr, ETH_ALEN); station->sta.mode = 0; station->sta.sta.sta_id = index; @@ -493,7 +493,7 @@ u8 iwl4965_add_station_flags(struct iwl_priv *priv, const u8 *addr, spin_unlock_irqrestore(&priv->sta_lock, flags_spin); /* Add station to device's station table */ - iwl4965_send_add_station(priv, &station->sta, flags); + iwl_send_add_sta(priv, &station->sta, flags); return index; } @@ -963,51 +963,6 @@ static int iwl4965_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_fla return iwl_send_cmd(priv, &cmd); } -int iwl4965_send_add_station(struct iwl_priv *priv, - struct iwl4965_addsta_cmd *sta, u8 flags) -{ - struct iwl_rx_packet *res = NULL; - int rc = 0; - struct iwl_host_cmd cmd = { - .id = REPLY_ADD_STA, - .len = sizeof(struct iwl4965_addsta_cmd), - .meta.flags = flags, - .data = sta, - }; - - if (!(flags & CMD_ASYNC)) - cmd.meta.flags |= CMD_WANT_SKB; - - rc = iwl_send_cmd(priv, &cmd); - - if (rc || (flags & CMD_ASYNC)) - return rc; - - res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; - if (res->hdr.flags & IWL_CMD_FAILED_MSK) { - IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n", - res->hdr.flags); - rc = -EIO; - } - - if (rc == 0) { - switch (res->u.add_sta.status) { - case ADD_STA_SUCCESS_MSK: - IWL_DEBUG_INFO("REPLY_ADD_STA PASSED\n"); - break; - default: - rc = -EIO; - IWL_WARNING("REPLY_ADD_STA failed\n"); - break; - } - } - - priv->alloc_rxb_skb--; - dev_kfree_skb_any(cmd.meta.u.skb); - - return rc; -} - static void iwl4965_clear_free_frames(struct iwl_priv *priv) { struct list_head *element; @@ -5927,7 +5882,7 @@ static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw, priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); + iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); spin_unlock_irqrestore(&priv->sta_lock, flags); -- cgit v1.2.3 From 2469bf2e9938eef3c6ab0951985b050ff1f8c94f Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 5 May 2008 10:22:35 +0800 Subject: iwlwifi-5000: add build_addsta_hcmd handler for 5000 HW This patch adds iwl5000_build_addsta_hcmd handler. Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-5000.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 83ed69dfac6..f9c22741308 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -422,10 +422,19 @@ static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv, } } +static u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) +{ + u16 size = (u16)sizeof(struct iwl_addsta_cmd); + memcpy(data, cmd, size); + return size; +} + + static struct iwl_hcmd_ops iwl5000_hcmd = { }; static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = { + .build_addsta_hcmd = iwl5000_build_addsta_hcmd, #ifdef CONFIG_IWL5000_RUN_TIME_CALIB .gain_computation = iwl5000_gain_computation, .chain_noise_reset = iwl5000_chain_noise_reset, -- cgit v1.2.3 From bf403db8a2f5580a5eb355a109d29b9287ca51e1 Mon Sep 17 00:00:00 2001 From: Ester Kummer Date: Mon, 5 May 2008 10:22:40 +0800 Subject: iwlwifi: move per driverdebug_level to per device This patch ports the debug_level to iwl_priv and changes the format of the debug prints. Signed-off-by: Ester Kummer Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-4965-rs.c | 32 +++++++++++++++++-------- drivers/net/wireless/iwlwifi/iwl-4965.c | 13 ++++++----- drivers/net/wireless/iwlwifi/iwl-debug.h | 20 ++++------------ drivers/net/wireless/iwlwifi/iwl-dev.h | 18 +++++++++++++++ drivers/net/wireless/iwlwifi/iwl4965-base.c | 36 ++++++++++++++++++----------- 5 files changed, 75 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index e3444c4ea1a..5baa000c788 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c @@ -662,7 +662,8 @@ static u16 rs_get_supported_rates(struct iwl4965_lq_sta *lq_sta, } } -static u16 rs_get_adjacent_rate(u8 index, u16 rate_mask, int rate_type) +static u16 rs_get_adjacent_rate(struct iwl_priv *priv, u8 index, u16 rate_mask, + int rate_type) { u8 high = IWL_RATE_INVALID; u8 low = IWL_RATE_INVALID; @@ -763,7 +764,8 @@ static u32 rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta, goto out; } - high_low = rs_get_adjacent_rate(scale_index, rate_mask, tbl->lq_type); + high_low = rs_get_adjacent_rate(lq_sta->drv, scale_index, rate_mask, + tbl->lq_type); low = high_low & 0xff; if (low == IWL_RATE_INVALID) @@ -990,7 +992,7 @@ out: * These control how long we stay using same modulation mode before * searching for a new mode. */ -static void rs_set_stay_in_table(u8 is_legacy, +static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy, struct iwl4965_lq_sta *lq_sta) { IWL_DEBUG_RATE("we are staying in the same table\n"); @@ -1079,7 +1081,8 @@ static s32 rs_get_best_rate(struct iwl_priv *priv, new_rate = high = low = start_hi = IWL_RATE_INVALID; for (; ;) { - high_low = rs_get_adjacent_rate(rate, rate_mask, tbl->lq_type); + high_low = rs_get_adjacent_rate(priv, rate, rate_mask, + tbl->lq_type); low = high_low & 0xff; high = (high_low >> 8) & 0xff; @@ -1565,7 +1568,9 @@ static void rs_stay_in_table(struct iwl4965_lq_sta *lq_sta) int i; int active_tbl; int flush_interval_passed = 0; + struct iwl_priv *priv; + priv = lq_sta->drv; active_tbl = lq_sta->active_tbl; tbl = &(lq_sta->lq_info[active_tbl]); @@ -1838,7 +1843,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, /* (Else) not in search of better modulation mode, try for better * starting rate, while staying in this mode. */ - high_low = rs_get_adjacent_rate(index, rate_scale_index_msk, + high_low = rs_get_adjacent_rate(priv, index, rate_scale_index_msk, tbl->lq_type); low = high_low & 0xff; high = (high_low >> 8) & 0xff; @@ -1998,7 +2003,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, (lq_sta->action_counter >= 1)) { lq_sta->action_counter = 0; IWL_DEBUG_RATE("LQ: STAY in legacy table\n"); - rs_set_stay_in_table(1, lq_sta); + rs_set_stay_in_table(priv, 1, lq_sta); } /* If we're in an HT mode, and all 3 mode switch actions @@ -2015,7 +2020,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, } #endif /*CONFIG_IWL4965_HT */ lq_sta->action_counter = 0; - rs_set_stay_in_table(0, lq_sta); + rs_set_stay_in_table(priv, 0, lq_sta); } /* @@ -2169,11 +2174,13 @@ out: rcu_read_unlock(); } -static void *rs_alloc_sta(void *priv, gfp_t gfp) +static void *rs_alloc_sta(void *priv_rate, gfp_t gfp) { struct iwl4965_lq_sta *lq_sta; + struct iwl_priv *priv; int i, j; + priv = (struct iwl_priv *)priv_rate; IWL_DEBUG_RATE("create station rate scale window\n"); lq_sta = kzalloc(sizeof(struct iwl4965_lq_sta), gfp); @@ -2443,10 +2450,12 @@ static void rs_clear(void *priv_rate) IWL_DEBUG_RATE("leave\n"); } -static void rs_free_sta(void *priv, void *priv_sta) +static void rs_free_sta(void *priv_rate, void *priv_sta) { struct iwl4965_lq_sta *lq_sta = priv_sta; + struct iwl_priv *priv; + priv = (struct iwl_priv *)priv_rate; IWL_DEBUG_RATE("enter\n"); kfree(lq_sta); IWL_DEBUG_RATE("leave\n"); @@ -2462,6 +2471,9 @@ static int open_file_generic(struct inode *inode, struct file *file) static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta, u32 *rate_n_flags, int index) { + struct iwl_priv *priv; + + priv = lq_sta->drv; if (lq_sta->dbg_fixed_rate) { if (index < 12) { *rate_n_flags = lq_sta->dbg_fixed_rate; @@ -2481,10 +2493,12 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { struct iwl4965_lq_sta *lq_sta = file->private_data; + struct iwl_priv *priv; char buf[64]; int buf_size; u32 parsed_rate; + priv = lq_sta->drv; memset(buf, 0, sizeof(buf)); buf_size = min(count, sizeof(buf) - 1); if (copy_from_user(buf, user_buf, buf_size)) diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 0644e22fe78..b4f2c3c8954 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2743,7 +2743,7 @@ static int iwl4965_set_decrypted_flag(struct iwl_priv *priv, return 0; } -static u32 iwl4965_translate_rx_status(u32 decrypt_in) +static u32 iwl4965_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in) { u32 decrypt_out = 0; @@ -2855,7 +2855,7 @@ static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data, if (!include_phy) { /* New status scheme, need to translate */ ampdu_status_legacy = ampdu_status; - ampdu_status = iwl4965_translate_rx_status(ampdu_status); + ampdu_status = iwl4965_translate_rx_status(priv, ampdu_status); } /* start from MAC */ @@ -2887,7 +2887,8 @@ static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data, } /* Calc max signal level (dBm) among 3 possible receivers */ -static int iwl4965_calc_rssi(struct iwl4965_rx_phy_res *rx_resp) +static int iwl4965_calc_rssi(struct iwl_priv *priv, + struct iwl4965_rx_phy_res *rx_resp) { /* data from PHY/DSP regarding signal strength, etc., * contents are always there, not configurable by host. */ @@ -2991,7 +2992,7 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv, struct iwl4965_rx_frame_end *rx_end = IWL_RX_END(pkt); u8 *data = IWL_RX_DATA(pkt); - if (likely(!(iwl_debug_level & IWL_DL_RX))) + if (likely(!(priv->debug_level & IWL_DL_RX))) return; /* MAC header */ @@ -3094,7 +3095,7 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv, } } if (print_dump) - iwl_print_hex_dump(IWL_DL_RX, data, length); + iwl_print_hex_dump(priv, IWL_DL_RX, data, length); } #else static inline void iwl4965_dbg_report_frame(struct iwl_priv *priv, @@ -3187,7 +3188,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp); /* Find max signal strength (dBm) among 3 antenna/receiver chains */ - rx_status.ssi = iwl4965_calc_rssi(rx_start); + rx_status.ssi = iwl4965_calc_rssi(priv, rx_start); /* Meaningful noise values are available only from beacon statistics, * which are gathered only when associated, and indicate noise diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 7e68d24114f..14d95dd0e14 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -32,24 +32,15 @@ #ifdef CONFIG_IWLWIFI_DEBUG extern u32 iwl_debug_level; #define IWL_DEBUG(level, fmt, args...) \ -do { if (iwl_debug_level & (level)) \ - printk(KERN_ERR DRV_NAME": %c %s " fmt, \ +do { if (priv->debug_level & (level)) \ + dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \ in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0) #define IWL_DEBUG_LIMIT(level, fmt, args...) \ -do { if ((iwl_debug_level & (level)) && net_ratelimit()) \ - printk(KERN_ERR DRV_NAME": %c %s " fmt, \ +do { if ((priv->debug_level & (level)) && net_ratelimit()) \ + dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \ in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0) -static inline void iwl_print_hex_dump(int level, void *p, u32 len) -{ - if (!(iwl_debug_level & level)) - return; - - print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1, - p, len, 1); -} - #ifdef CONFIG_IWLWIFI_DEBUGFS struct iwl_debugfs { const char *name; @@ -77,9 +68,6 @@ static inline void IWL_DEBUG(int level, const char *fmt, ...) static inline void IWL_DEBUG_LIMIT(int level, const char *fmt, ...) { } -static inline void iwl_print_hex_dump(int level, void *p, u32 len) -{ -} #endif /* CONFIG_IWLWIFI_DEBUG */ diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 4786194c045..0a37ff4d98b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1194,6 +1194,7 @@ struct iwl_priv { #ifdef CONFIG_IWLWIFI_DEBUG /* debugging info */ + u32 debug_level; u32 framecnt_to_us; atomic_t restrict_refcnt; #ifdef CONFIG_IWLWIFI_DEBUGFS @@ -1246,6 +1247,23 @@ static inline int is_channel_ibss(const struct iwl_channel_info *ch) return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0; } +#ifdef CONFIG_IWLWIFI_DEBUG +static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level, + void *p, u32 len) +{ + if (!(priv->debug_level & level)) + return; + + print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1, + p, len, 1); +} +#else +static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level, + void *p, u32 len) +{ +} +#endif + extern const struct iwl_channel_info *iwl_get_channel_info( const struct iwl_priv *priv, enum ieee80211_band band, u16 channel); diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 8427bc9a9bb..9f51d3a61f3 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -145,6 +145,7 @@ static const char *iwl4965_escape_essid(const char *essid, u8 essid_len) return escaped; } + /*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** * DMA services * @@ -1914,7 +1915,7 @@ static int iwl4965_get_sta_id(struct iwl_priv *priv, IWL_DEBUG_DROP("Station %s not in station map. " "Defaulting to broadcast...\n", print_mac(mac, hdr->addr1)); - iwl_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); + iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); return priv->hw_params.bcast_sta_id; default: @@ -2130,10 +2131,10 @@ static int iwl4965_tx_skb(struct iwl_priv *priv, txq->need_update = 0; } - iwl_print_hex_dump(IWL_DL_TX, out_cmd->cmd.payload, + iwl_print_hex_dump(priv, IWL_DL_TX, out_cmd->cmd.payload, sizeof(out_cmd->cmd.tx)); - iwl_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr, + iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr, ieee80211_get_hdrlen(fc)); /* Set up entry for this TFD in Tx byte-count array */ @@ -2911,7 +2912,7 @@ static void iwl4965_rx_pm_debug_statistics_notif(struct iwl_priv *priv, IWL_DEBUG_RADIO("Dumping %d bytes of unhandled " "notification for %s:\n", le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd)); - iwl_print_hex_dump(IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len)); + iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len)); } static void iwl4965_bg_beacon_update(struct work_struct *work) @@ -3484,12 +3485,13 @@ static int iwl4965_tx_queue_update_write_ptr(struct iwl_priv *priv, } #ifdef CONFIG_IWLWIFI_DEBUG -static void iwl4965_print_rx_config_cmd(struct iwl4965_rxon_cmd *rxon) +static void iwl4965_print_rx_config_cmd(struct iwl_priv *priv) { + struct iwl4965_rxon_cmd *rxon = &priv->staging_rxon; DECLARE_MAC_BUF(mac); IWL_DEBUG_RADIO("RX CONFIG:\n"); - iwl_print_hex_dump(IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon)); + iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon)); IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel)); IWL_DEBUG_RADIO("u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags)); IWL_DEBUG_RADIO("u32 filter_flags: 0x%08x\n", @@ -3715,10 +3717,10 @@ static void iwl4965_irq_handle_error(struct iwl_priv *priv) clear_bit(STATUS_HCMD_ACTIVE, &priv->status); #ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_debug_level & IWL_DL_FW_ERRORS) { + if (priv->debug_level & IWL_DL_FW_ERRORS) { iwl4965_dump_nic_error_log(priv); iwl4965_dump_nic_event_log(priv); - iwl4965_print_rx_config_cmd(&priv->staging_rxon); + iwl4965_print_rx_config_cmd(priv); } #endif @@ -3782,7 +3784,7 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv) iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh); #ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_debug_level & IWL_DL_ISR) { + if (priv->debug_level & IWL_DL_ISR) { /* just for debug */ inta_mask = iwl_read32(priv, CSR_INT_MASK); IWL_DEBUG_ISR("inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", @@ -3816,7 +3818,7 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv) } #ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_debug_level & (IWL_DL_ISR)) { + if (priv->debug_level & (IWL_DL_ISR)) { /* NIC fires this, but we don't use it, redundant with WAKEUP */ if (inta & CSR_INT_BIT_SCD) IWL_DEBUG_ISR("Scheduler finished to transmit " @@ -3909,7 +3911,7 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv) iwl4965_enable_interrupts(priv); #ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_debug_level & (IWL_DL_ISR)) { + if (priv->debug_level & (IWL_DL_ISR)) { inta = iwl_read32(priv, CSR_INT); inta_mask = iwl_read32(priv, CSR_INT_MASK); inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); @@ -6049,6 +6051,9 @@ static int iwl4965_mac_get_tx_stats(struct ieee80211_hw *hw, static int iwl4965_mac_get_stats(struct ieee80211_hw *hw, struct ieee80211_low_level_stats *stats) { + struct iwl_priv *priv = hw->priv; + + priv = hw->priv; IWL_DEBUG_MAC80211("enter\n"); IWL_DEBUG_MAC80211("leave\n"); @@ -6057,6 +6062,9 @@ static int iwl4965_mac_get_stats(struct ieee80211_hw *hw, static u64 iwl4965_mac_get_tsf(struct ieee80211_hw *hw) { + struct iwl_priv *priv; + + priv = hw->priv; IWL_DEBUG_MAC80211("enter\n"); IWL_DEBUG_MAC80211("leave\n"); @@ -6706,7 +6714,9 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e /* Disabling hardware scan means that mac80211 will perform scans * "the hard way", rather than using device's scan. */ if (cfg->mod_params->disable_hw_scan) { - IWL_DEBUG_INFO("Disabling hw_scan\n"); + if (cfg->mod_params->debug & IWL_DL_INFO) + dev_printk(KERN_DEBUG, &(pdev->dev), + "Disabling hw_scan\n"); iwl4965_hw_ops.hw_scan = NULL; } @@ -6725,7 +6735,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e priv->pci_dev = pdev; #ifdef CONFIG_IWLWIFI_DEBUG - iwl_debug_level = priv->cfg->mod_params->debug; + priv->debug_level = priv->cfg->mod_params->debug; atomic_set(&priv->restrict_refcnt, 0); #endif -- cgit v1.2.3 From 47c5196e4a340667d8d92053380ecca24ed45a9b Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 5 May 2008 10:22:41 +0800 Subject: iwlwifi: move iwl4965_set_rxon_ht into iwlcore This patch moves iwl4965_set_rxon_ht to iwlcore under name iwl_set_rxon_ht. It also moves collateral changes iwl_is_channel_extension and iwl_is_fat_tx_allowed. Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-4965.c | 99 +---------------------------- drivers/net/wireless/iwlwifi/iwl-core.c | 99 +++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 3 + drivers/net/wireless/iwlwifi/iwl-dev.h | 2 - drivers/net/wireless/iwlwifi/iwl4965-base.c | 6 +- 5 files changed, 105 insertions(+), 104 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index b4f2c3c8954..bc988c3b678 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -3719,103 +3719,6 @@ void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) #ifdef CONFIG_IWL4965_HT -static u8 iwl4965_is_channel_extension(struct iwl_priv *priv, - enum ieee80211_band band, - u16 channel, u8 extension_chan_offset) -{ - const struct iwl_channel_info *ch_info; - - ch_info = iwl_get_channel_info(priv, band, channel); - if (!is_channel_valid(ch_info)) - return 0; - - if (extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_NONE) - return 0; - - if ((ch_info->fat_extension_channel == extension_chan_offset) || - (ch_info->fat_extension_channel == HT_IE_EXT_CHANNEL_MAX)) - return 1; - - return 0; -} - -static u8 iwl4965_is_fat_tx_allowed(struct iwl_priv *priv, - struct ieee80211_ht_info *sta_ht_inf) -{ - struct iwl_ht_info *iwl_ht_conf = &priv->current_ht_config; - - if ((!iwl_ht_conf->is_ht) || - (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ) || - (iwl_ht_conf->extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_NONE)) - return 0; - - if (sta_ht_inf) { - if ((!sta_ht_inf->ht_supported) || - (!(sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH))) - return 0; - } - - return (iwl4965_is_channel_extension(priv, priv->band, - iwl_ht_conf->control_channel, - iwl_ht_conf->extension_chan_offset)); -} - -void iwl4965_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info) -{ - struct iwl4965_rxon_cmd *rxon = &priv->staging_rxon; - u32 val; - - if (!ht_info->is_ht) - return; - - /* Set up channel bandwidth: 20 MHz only, or 20/40 mixed if fat ok */ - if (iwl4965_is_fat_tx_allowed(priv, NULL)) - rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED_MSK; - else - rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK | - RXON_FLG_CHANNEL_MODE_PURE_40_MSK); - - if (le16_to_cpu(rxon->channel) != ht_info->control_channel) { - IWL_ERROR("control diff than current %d %d\n", - le16_to_cpu(rxon->channel), - ht_info->control_channel); - WARN_ON(1); - return; - } - - /* Note: control channel is opposite of extension channel */ - switch (ht_info->extension_chan_offset) { - case IWL_EXT_CHANNEL_OFFSET_ABOVE: - rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); - break; - case IWL_EXT_CHANNEL_OFFSET_BELOW: - rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; - break; - case IWL_EXT_CHANNEL_OFFSET_NONE: - default: - rxon->flags &= ~RXON_FLG_CHANNEL_MODE_MIXED_MSK; - break; - } - - val = ht_info->ht_protection; - - rxon->flags |= cpu_to_le32(val << RXON_FLG_HT_OPERATING_MODE_POS); - - iwl_set_rxon_chain(priv); - - IWL_DEBUG_ASSOC("supported HT rate 0x%X 0x%X 0x%X " - "rxon flags 0x%X operation mode :0x%X " - "extension channel offset 0x%x " - "control chan %d\n", - ht_info->supp_mcs_set[0], - ht_info->supp_mcs_set[1], - ht_info->supp_mcs_set[2], - le32_to_cpu(rxon->flags), ht_info->ht_protection, - ht_info->extension_chan_offset, - ht_info->control_channel); - return; -} - void iwl4965_set_ht_add_station(struct iwl_priv *priv, u8 index, struct ieee80211_ht_info *sta_ht_inf) { @@ -3851,7 +3754,7 @@ void iwl4965_set_ht_add_station(struct iwl_priv *priv, u8 index, sta_flags |= cpu_to_le32( (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); - if (iwl4965_is_fat_tx_allowed(priv, sta_ht_inf)) + if (iwl_is_fat_tx_allowed(priv, sta_ht_inf)) sta_flags |= STA_FLG_FAT_EN_MSK; else sta_flags &= ~STA_FLG_FAT_EN_MSK; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 55e3d139f42..2ff27a01cf6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -434,6 +434,105 @@ static u8 is_single_rx_stream(struct iwl_priv *priv) (priv->current_ht_config.supp_mcs_set[2] == 0)) || priv->ps_mode == IWL_MIMO_PS_STATIC; } +static u8 iwl_is_channel_extension(struct iwl_priv *priv, + enum ieee80211_band band, + u16 channel, u8 extension_chan_offset) +{ + const struct iwl_channel_info *ch_info; + + ch_info = iwl_get_channel_info(priv, band, channel); + if (!is_channel_valid(ch_info)) + return 0; + + if (extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_NONE) + return 0; + + if ((ch_info->fat_extension_channel == extension_chan_offset) || + (ch_info->fat_extension_channel == HT_IE_EXT_CHANNEL_MAX)) + return 1; + + return 0; +} + +u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv, + struct ieee80211_ht_info *sta_ht_inf) +{ + struct iwl_ht_info *iwl_ht_conf = &priv->current_ht_config; + + if ((!iwl_ht_conf->is_ht) || + (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ) || + (iwl_ht_conf->extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_NONE)) + return 0; + + if (sta_ht_inf) { + if ((!sta_ht_inf->ht_supported) || + (!(sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH))) + return 0; + } + + return iwl_is_channel_extension(priv, priv->band, + iwl_ht_conf->control_channel, + iwl_ht_conf->extension_chan_offset); +} +EXPORT_SYMBOL(iwl_is_fat_tx_allowed); + +void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info) +{ + struct iwl4965_rxon_cmd *rxon = &priv->staging_rxon; + u32 val; + + if (!ht_info->is_ht) + return; + + /* Set up channel bandwidth: 20 MHz only, or 20/40 mixed if fat ok */ + if (iwl_is_fat_tx_allowed(priv, NULL)) + rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED_MSK; + else + rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK | + RXON_FLG_CHANNEL_MODE_PURE_40_MSK); + + if (le16_to_cpu(rxon->channel) != ht_info->control_channel) { + IWL_DEBUG_ASSOC("control diff than current %d %d\n", + le16_to_cpu(rxon->channel), + ht_info->control_channel); + rxon->channel = cpu_to_le16(ht_info->control_channel); + return; + } + + /* Note: control channel is opposite of extension channel */ + switch (ht_info->extension_chan_offset) { + case IWL_EXT_CHANNEL_OFFSET_ABOVE: + rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); + break; + case IWL_EXT_CHANNEL_OFFSET_BELOW: + rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; + break; + case IWL_EXT_CHANNEL_OFFSET_NONE: + default: + rxon->flags &= ~RXON_FLG_CHANNEL_MODE_MIXED_MSK; + break; + } + + val = ht_info->ht_protection; + + rxon->flags |= cpu_to_le32(val << RXON_FLG_HT_OPERATING_MODE_POS); + + iwl_set_rxon_chain(priv); + + IWL_DEBUG_ASSOC("supported HT rate 0x%X 0x%X 0x%X " + "rxon flags 0x%X operation mode :0x%X " + "extension channel offset 0x%x " + "control chan %d\n", + ht_info->supp_mcs_set[0], + ht_info->supp_mcs_set[1], + ht_info->supp_mcs_set[2], + le32_to_cpu(rxon->flags), ht_info->ht_protection, + ht_info->extension_chan_offset, + ht_info->control_channel); + return; +} +EXPORT_SYMBOL(iwl_set_rxon_ht); + #else static inline u8 is_single_rx_stream(struct iwl_priv *priv) { diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index df27ee65015..12418061ab7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -173,6 +173,9 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, u16 channel); void iwlcore_free_geos(struct iwl_priv *priv); int iwl_setup(struct iwl_priv *priv); +void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info); +u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv, + struct ieee80211_ht_info *sta_ht_inf); /***************************************************** * RX diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 0a37ff4d98b..23cae4c1345 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -454,7 +454,6 @@ union iwl4965_ht_rate_supp { }; }; -#ifdef CONFIG_IWL4965_HT #define CFG_HT_RX_AMPDU_FACTOR_DEF (0x3) #define CFG_HT_MPDU_DENSITY_2USEC (0x5) #define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_2USEC @@ -477,7 +476,6 @@ struct iwl_ht_info { u8 ht_protection; u8 non_GF_STA_present; }; -#endif /*CONFIG_IWL4965_HT */ union iwl4965_qos_capabity { struct { diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 9f51d3a61f3..ad45249454f 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -2783,9 +2783,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, tx_resp->failure_frame); IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); +#ifdef CONFIG_IWL4965_HT if (index != -1) { int freed = iwl4965_tx_queue_reclaim(priv, txq_id, index); -#ifdef CONFIG_IWL4965_HT if (tid != MAX_TID_COUNT) priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && @@ -2793,9 +2793,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, ieee80211_wake_queue(priv->hw, txq_id); if (tid != MAX_TID_COUNT) iwl4965_check_empty_hw_queue(priv, sta_id, tid, txq_id); -#endif } -#ifdef CONFIG_IWL4965_HT } #endif /* CONFIG_IWL4965_HT */ @@ -5124,7 +5122,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv) #ifdef CONFIG_IWL4965_HT if (priv->current_ht_config.is_ht) - iwl4965_set_rxon_ht(priv, &priv->current_ht_config); + iwl_set_rxon_ht(priv, &priv->current_ht_config); #endif /* CONFIG_IWL4965_HT*/ iwl_set_rxon_chain(priv); priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); -- cgit v1.2.3 From 5a676bbeaf9e534b75286f2294ec57a4c544f1d2 Mon Sep 17 00:00:00 2001 From: Ron Rindjunsky Date: Mon, 5 May 2008 10:22:42 +0800 Subject: iwlwifi: create disable SCD Tx FIFOs handler This patch moves disabeling Tx FIFOs in NIC SCD to seperate handlers in 4965 and 5000 cards. Signed-off-by: Ron Rindjunsky Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-4965.c | 40 +++++++++++++++++++++------------ drivers/net/wireless/iwlwifi/iwl-5000.c | 22 ++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 2 ++ 3 files changed, 50 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index bc988c3b678..9e6f3e33ab6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -470,6 +470,27 @@ static void iwl4965_kw_free(struct iwl_priv *priv) } } +static int iwl4965_disable_tx_fifo(struct iwl_priv *priv) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&priv->lock, flags); + + ret = iwl_grab_nic_access(priv); + if (unlikely(ret)) { + IWL_ERROR("Tx fifo reset failed"); + spin_unlock_irqrestore(&priv->lock, flags); + return ret; + } + + iwl_write_prph(priv, IWL49_SCD_TXFACT, 0); + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + /** * iwl4965_txq_ctx_reset - Reset TX queue context * Destroys all DMA structures and initialise them again @@ -481,7 +502,6 @@ static int iwl4965_txq_ctx_reset(struct iwl_priv *priv) { int rc = 0; int txq_id, slots_num; - unsigned long flags; iwl4965_kw_free(priv); @@ -495,19 +515,10 @@ static int iwl4965_txq_ctx_reset(struct iwl_priv *priv) goto error_kw; } - spin_lock_irqsave(&priv->lock, flags); - - rc = iwl_grab_nic_access(priv); - if (unlikely(rc)) { - IWL_ERROR("TX reset failed"); - spin_unlock_irqrestore(&priv->lock, flags); + /* Turn off all Tx DMA fifos */ + rc = priv->cfg->ops->lib->disable_tx_fifo(priv); + if (unlikely(rc)) goto error_reset; - } - - /* Turn off all Tx DMA channels */ - iwl_write_prph(priv, IWL49_SCD_TXFACT, 0); - iwl_release_nic_access(priv); - spin_unlock_irqrestore(&priv->lock, flags); /* Tell 4965 where to find the keep-warm buffer */ rc = iwl4965_kw_init(priv); @@ -538,6 +549,7 @@ static int iwl4965_txq_ctx_reset(struct iwl_priv *priv) error_kw: return rc; } + static int iwl4965_apm_init(struct iwl_priv *priv) { unsigned long flags; @@ -621,7 +633,6 @@ static void iwl4965_nic_config(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); } - int iwl4965_hw_nic_init(struct iwl_priv *priv) { unsigned long flags; @@ -4044,6 +4055,7 @@ static struct iwl_lib_ops iwl4965_lib = { .free_shared_mem = iwl4965_free_shared_mem, .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl, .hw_nic_init = iwl4965_hw_nic_init, + .disable_tx_fifo = iwl4965_disable_tx_fifo, .rx_handler_setup = iwl4965_rx_handler_setup, .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr, .alive_notify = iwl4965_alive_notify, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index f9c22741308..feffcafe149 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -430,6 +430,27 @@ static u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) } +static int iwl5000_disable_tx_fifo(struct iwl_priv *priv) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&priv->lock, flags); + + ret = iwl_grab_nic_access(priv); + if (unlikely(ret)) { + IWL_ERROR("Tx fifo reset failed"); + spin_unlock_irqrestore(&priv->lock, flags); + return ret; + } + + iwl_write_prph(priv, IWL50_SCD_TXFACT, 0); + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + static struct iwl_hcmd_ops iwl5000_hcmd = { }; @@ -446,6 +467,7 @@ static struct iwl_lib_ops iwl5000_lib = { .alloc_shared_mem = iwl5000_alloc_shared_mem, .free_shared_mem = iwl5000_free_shared_mem, .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, + .disable_tx_fifo = iwl5000_disable_tx_fifo, .apm_ops = { .init = iwl5000_apm_init, .config = iwl5000_nic_config, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 12418061ab7..c29f8b34712 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -110,6 +110,8 @@ struct iwl_lib_ops { void (*rx_handler_setup)(struct iwl_priv *priv); /* nic init */ int (*hw_nic_init)(struct iwl_priv *priv); + /* nic Tx fifo handling */ + int (*disable_tx_fifo)(struct iwl_priv *priv); /* alive notification */ int (*alive_notify)(struct iwl_priv *priv); /* check validity of rtc data address */ -- cgit v1.2.3 From 1053d35f4ed6876ad9d3a14cdae363db0a7e9b0a Mon Sep 17 00:00:00 2001 From: Ron Rindjunsky Date: Mon, 5 May 2008 10:22:43 +0800 Subject: iwlwifi: move NIC init and Tx queues init to iwlcore This patch does the following: 1 - change hw_nic_init from a handler to a function 2 - move hw_nic_init function to iwlcore 3 - open a new file - iwl-tx.c 4 - move all Tx queues initialization (part of NIC init) to iwl-tx.c 5 - move iwl_rx_init, previously as part of the NIC init, to iwl-rx.c 6 - iwl4965_tfd_frame rename to iwl_tfd_frame Signed-off-by: Ron Rindjunsky Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Makefile | 2 +- drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 10 +- drivers/net/wireless/iwlwifi/iwl-4965.c | 339 +------------------------ drivers/net/wireless/iwlwifi/iwl-core.c | 95 +++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 17 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 10 +- drivers/net/wireless/iwlwifi/iwl-rx.c | 52 ++++ drivers/net/wireless/iwlwifi/iwl-tx.c | 374 ++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl4965-base.c | 177 +------------ 9 files changed, 550 insertions(+), 526 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/iwl-tx.c (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 0211a7f7147..85c8bf62d59 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -1,6 +1,6 @@ obj-$(CONFIG_IWLCORE) += iwlcore.o iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o -iwlcore-objs += iwl-rx.o +iwlcore-objs += iwl-rx.o iwl-tx.o iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h index 29749e2a8ff..ee55b283226 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h @@ -829,7 +829,7 @@ static inline __le32 iwl4965_hw_set_rate_n_flags(u8 rate, u16 flags) #define IWL49_NUM_QUEUES 16 /** - * struct iwl4965_tfd_frame_data + * struct iwl_tfd_frame_data * * Describes up to 2 buffers containing (contiguous) portions of a Tx frame. * Each buffer must be on dword boundary. @@ -848,7 +848,7 @@ static inline __le32 iwl4965_hw_set_rate_n_flags(u8 rate, u16 flags) * 31-20: Tx buffer 2 length (bytes) * 19- 0: Tx buffer 2 address bits [35:16] */ -struct iwl4965_tfd_frame_data { +struct iwl_tfd_frame_data { __le32 tb1_addr; __le32 val1; @@ -878,7 +878,7 @@ struct iwl4965_tfd_frame_data { /** - * struct iwl4965_tfd_frame + * struct iwl_tfd_frame * * Transmit Frame Descriptor (TFD) * @@ -905,7 +905,7 @@ struct iwl4965_tfd_frame_data { * * A maximum of 255 (not 256!) TFDs may be on a queue waiting for Tx. */ -struct iwl4965_tfd_frame { +struct iwl_tfd_frame { __le32 val0; /* __le32 rsvd1:24; */ /* __le32 num_tbs:5; */ @@ -914,7 +914,7 @@ struct iwl4965_tfd_frame { #define IWL_num_tbs_SYM val0 /* __le32 rsvd2:1; */ /* __le32 padding:2; */ - struct iwl4965_tfd_frame_data pa[10]; + struct iwl_tfd_frame_data pa[10]; __le32 reserved; } __attribute__ ((packed)); diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 9e6f3e33ab6..319ffe747a7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -53,8 +53,6 @@ static struct iwl_mod_params iwl4965_mod_params = { /* the rest are 0 by default */ }; -static void iwl4965_hw_card_show_info(struct iwl_priv *priv); - #ifdef CONFIG_IWL4965_HT static const u16 default_tid_to_tx_fifo[] = { @@ -372,104 +370,6 @@ int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src) return ret; } -static int iwl4965_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) -{ - int ret; - unsigned long flags; - unsigned int rb_size; - - spin_lock_irqsave(&priv->lock, flags); - ret = iwl_grab_nic_access(priv); - if (ret) { - spin_unlock_irqrestore(&priv->lock, flags); - return ret; - } - - if (priv->cfg->mod_params->amsdu_size_8K) - rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; - else - rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; - - /* Stop Rx DMA */ - iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); - - /* Reset driver's Rx queue write index */ - iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); - - /* Tell device where to find RBD circular buffer in DRAM */ - iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG, - rxq->dma_addr >> 8); - - /* Tell device where in DRAM to update its Rx status */ - iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG, - (priv->shared_phys + - offsetof(struct iwl4965_shared, rb_closed)) >> 4); - - /* Enable Rx DMA, enable host interrupt, Rx buffer size 4k, 256 RBDs */ - iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, - FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | - FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | - rb_size | - /* 0x10 << 4 | */ - (RX_QUEUE_SIZE_LOG << - FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT)); - - /* - * iwl_write32(priv,CSR_INT_COAL_REG,0); - */ - - iwl_release_nic_access(priv); - spin_unlock_irqrestore(&priv->lock, flags); - - return 0; -} - -/* Tell 4965 where to find the "keep warm" buffer */ -static int iwl4965_kw_init(struct iwl_priv *priv) -{ - unsigned long flags; - int rc; - - spin_lock_irqsave(&priv->lock, flags); - rc = iwl_grab_nic_access(priv); - if (rc) - goto out; - - iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, - priv->kw.dma_addr >> 4); - iwl_release_nic_access(priv); -out: - spin_unlock_irqrestore(&priv->lock, flags); - return rc; -} - -static int iwl4965_kw_alloc(struct iwl_priv *priv) -{ - struct pci_dev *dev = priv->pci_dev; - struct iwl4965_kw *kw = &priv->kw; - - kw->size = IWL4965_KW_SIZE; /* TBW need set somewhere else */ - kw->v_addr = pci_alloc_consistent(dev, kw->size, &kw->dma_addr); - if (!kw->v_addr) - return -ENOMEM; - - return 0; -} - -/** - * iwl4965_kw_free - Free the "keep warm" buffer - */ -static void iwl4965_kw_free(struct iwl_priv *priv) -{ - struct pci_dev *dev = priv->pci_dev; - struct iwl4965_kw *kw = &priv->kw; - - if (kw->v_addr) { - pci_free_consistent(dev, kw->size, kw->v_addr, kw->dma_addr); - memset(kw, 0, sizeof(*kw)); - } -} - static int iwl4965_disable_tx_fifo(struct iwl_priv *priv) { unsigned long flags; @@ -491,65 +391,6 @@ static int iwl4965_disable_tx_fifo(struct iwl_priv *priv) return 0; } -/** - * iwl4965_txq_ctx_reset - Reset TX queue context - * Destroys all DMA structures and initialise them again - * - * @param priv - * @return error code - */ -static int iwl4965_txq_ctx_reset(struct iwl_priv *priv) -{ - int rc = 0; - int txq_id, slots_num; - - iwl4965_kw_free(priv); - - /* Free all tx/cmd queues and keep-warm buffer */ - iwl4965_hw_txq_ctx_free(priv); - - /* Alloc keep-warm buffer */ - rc = iwl4965_kw_alloc(priv); - if (rc) { - IWL_ERROR("Keep Warm allocation failed"); - goto error_kw; - } - - /* Turn off all Tx DMA fifos */ - rc = priv->cfg->ops->lib->disable_tx_fifo(priv); - if (unlikely(rc)) - goto error_reset; - - /* Tell 4965 where to find the keep-warm buffer */ - rc = iwl4965_kw_init(priv); - if (rc) { - IWL_ERROR("kw_init failed\n"); - goto error_reset; - } - - /* Alloc and init all (default 16) Tx queues, - * including the command queue (#4) */ - for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { - slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ? - TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; - rc = iwl4965_tx_queue_init(priv, &priv->txq[txq_id], slots_num, - txq_id); - if (rc) { - IWL_ERROR("Tx %d queue init failed\n", txq_id); - goto error; - } - } - - return rc; - - error: - iwl4965_hw_txq_ctx_free(priv); - error_reset: - iwl4965_kw_free(priv); - error_kw: - return rc; -} - static int iwl4965_apm_init(struct iwl_priv *priv) { unsigned long flags; @@ -633,58 +474,6 @@ static void iwl4965_nic_config(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); } -int iwl4965_hw_nic_init(struct iwl_priv *priv) -{ - unsigned long flags; - struct iwl_rx_queue *rxq = &priv->rxq; - int ret; - - /* nic_init */ - priv->cfg->ops->lib->apm_ops.init(priv); - - spin_lock_irqsave(&priv->lock, flags); - iwl_write32(priv, CSR_INT_COALESCING, 512 / 32); - spin_unlock_irqrestore(&priv->lock, flags); - - ret = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN); - - priv->cfg->ops->lib->apm_ops.config(priv); - - iwl4965_hw_card_show_info(priv); - - /* end nic_init */ - - /* Allocate the RX queue, or reset if it is already allocated */ - if (!rxq->bd) { - ret = iwl_rx_queue_alloc(priv); - if (ret) { - IWL_ERROR("Unable to initialize Rx queue\n"); - return -ENOMEM; - } - } else - iwl_rx_queue_reset(priv, rxq); - - iwl_rx_replenish(priv); - - iwl4965_rx_init(priv, rxq); - - spin_lock_irqsave(&priv->lock, flags); - - rxq->need_update = 1; - iwl_rx_queue_update_write_ptr(priv, rxq); - - spin_unlock_irqrestore(&priv->lock, flags); - - /* Allocate and init all Tx and Command queues */ - ret = iwl4965_txq_ctx_reset(priv); - if (ret) - return ret; - - set_bit(STATUS_INIT, &priv->status); - - return 0; -} - int iwl4965_hw_nic_stop_master(struct iwl_priv *priv) { int rc = 0; @@ -745,7 +534,7 @@ void iwl4965_hw_txq_ctx_stop(struct iwl_priv *priv) } /* Deallocate memory for all Tx queues */ - iwl4965_hw_txq_ctx_free(priv); + iwl_hw_txq_ctx_free(priv); } int iwl4965_hw_nic_reset(struct iwl_priv *priv) @@ -1199,82 +988,6 @@ int iwl4965_hw_set_hw_params(struct iwl_priv *priv) return 0; } -/** - * iwl4965_hw_txq_ctx_free - Free TXQ Context - * - * Destroy all TX DMA queues and structures - */ -void iwl4965_hw_txq_ctx_free(struct iwl_priv *priv) -{ - int txq_id; - - /* Tx queues */ - for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) - iwl4965_tx_queue_free(priv, &priv->txq[txq_id]); - - /* Keep-warm buffer */ - iwl4965_kw_free(priv); -} - -/** - * iwl4965_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] - * - * Does NOT advance any TFD circular buffer read/write indexes - * Does NOT free the TFD itself (which is within circular buffer) - */ -int iwl4965_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl4965_tx_queue *txq) -{ - struct iwl4965_tfd_frame *bd_tmp = (struct iwl4965_tfd_frame *)&txq->bd[0]; - struct iwl4965_tfd_frame *bd = &bd_tmp[txq->q.read_ptr]; - struct pci_dev *dev = priv->pci_dev; - int i; - int counter = 0; - int index, is_odd; - - /* Host command buffers stay mapped in memory, nothing to clean */ - if (txq->q.id == IWL_CMD_QUEUE_NUM) - return 0; - - /* Sanity check on number of chunks */ - counter = IWL_GET_BITS(*bd, num_tbs); - if (counter > MAX_NUM_OF_TBS) { - IWL_ERROR("Too many chunks: %i\n", counter); - /* @todo issue fatal error, it is quite serious situation */ - return 0; - } - - /* Unmap chunks, if any. - * TFD info for odd chunks is different format than for even chunks. */ - for (i = 0; i < counter; i++) { - index = i / 2; - is_odd = i & 0x1; - - if (is_odd) - pci_unmap_single( - dev, - IWL_GET_BITS(bd->pa[index], tb2_addr_lo16) | - (IWL_GET_BITS(bd->pa[index], - tb2_addr_hi20) << 16), - IWL_GET_BITS(bd->pa[index], tb2_len), - PCI_DMA_TODEVICE); - - else if (i > 0) - pci_unmap_single(dev, - le32_to_cpu(bd->pa[index].tb1_addr), - IWL_GET_BITS(bd->pa[index], tb1_len), - PCI_DMA_TODEVICE); - - /* Free SKB, if any, for this chunk */ - if (txq->txb[txq->q.read_ptr].skb[i]) { - struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[i]; - - dev_kfree_skb(skb); - txq->txb[txq->q.read_ptr].skb[i] = NULL; - } - } - return 0; -} - /* set card power command */ static int iwl4965_set_power(struct iwl_priv *priv, void *cmd) @@ -2240,46 +1953,11 @@ unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, return (sizeof(*tx_beacon_cmd) + frame_size); } -/* - * Tell 4965 where to find circular buffer of Tx Frame Descriptors for - * given Tx queue, and enable the DMA channel used for that queue. - * - * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA - * channels supported in hardware. - */ -int iwl4965_hw_tx_queue_init(struct iwl_priv *priv, struct iwl4965_tx_queue *txq) -{ - int rc; - unsigned long flags; - int txq_id = txq->q.id; - - spin_lock_irqsave(&priv->lock, flags); - rc = iwl_grab_nic_access(priv); - if (rc) { - spin_unlock_irqrestore(&priv->lock, flags); - return rc; - } - - /* Circular buffer (TFD queue in DRAM) physical base address */ - iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id), - txq->q.dma_addr >> 8); - - /* Enable DMA channel, using same id as for TFD queue */ - iwl_write_direct32( - priv, FH_TCSR_CHNL_TX_CONFIG_REG(txq_id), - FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | - FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL); - iwl_release_nic_access(priv); - spin_unlock_irqrestore(&priv->lock, flags); - - return 0; -} - int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr, dma_addr_t addr, u16 len) { int index, is_odd; - struct iwl4965_tfd_frame *tfd = ptr; + struct iwl_tfd_frame *tfd = ptr; u32 num_tbs = IWL_GET_BITS(*tfd, num_tbs); /* Each TFD can point to a maximum 20 Tx buffers */ @@ -2309,18 +1987,6 @@ int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr, return 0; } -static void iwl4965_hw_card_show_info(struct iwl_priv *priv) -{ - u16 hw_version = iwl_eeprom_query16(priv, EEPROM_4965_BOARD_REVISION); - - IWL_DEBUG_INFO("4965ABGN HW Version %u.%u.%u\n", - ((hw_version >> 8) & 0x0F), - ((hw_version >> 8) >> 4), (hw_version & 0x00FF)); - - IWL_DEBUG_INFO("4965ABGN PBA Number %.16s\n", - &priv->eeprom[EEPROM_4965_BOARD_PBA]); -} - static int iwl4965_alloc_shared_mem(struct iwl_priv *priv) { priv->shared_virt = pci_alloc_consistent(priv->pci_dev, @@ -4054,7 +3720,6 @@ static struct iwl_lib_ops iwl4965_lib = { .alloc_shared_mem = iwl4965_alloc_shared_mem, .free_shared_mem = iwl4965_free_shared_mem, .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl, - .hw_nic_init = iwl4965_hw_nic_init, .disable_tx_fifo = iwl4965_disable_tx_fifo, .rx_handler_setup = iwl4965_rx_handler_setup, .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 2ff27a01cf6..4ba860741f8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -121,6 +121,101 @@ void iwl_hw_detect(struct iwl_priv *priv) } EXPORT_SYMBOL(iwl_hw_detect); +/* Tell nic where to find the "keep warm" buffer */ +int iwl_kw_init(struct iwl_priv *priv) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&priv->lock, flags); + ret = iwl_grab_nic_access(priv); + if (ret) + goto out; + + iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, + priv->kw.dma_addr >> 4); + iwl_release_nic_access(priv); +out: + spin_unlock_irqrestore(&priv->lock, flags); + return ret; +} + +int iwl_kw_alloc(struct iwl_priv *priv) +{ + struct pci_dev *dev = priv->pci_dev; + struct iwl4965_kw *kw = &priv->kw; + + kw->size = IWL4965_KW_SIZE; /* TBW need set somewhere else */ + kw->v_addr = pci_alloc_consistent(dev, kw->size, &kw->dma_addr); + if (!kw->v_addr) + return -ENOMEM; + + return 0; +} + +/** + * iwl_kw_free - Free the "keep warm" buffer + */ +void iwl_kw_free(struct iwl_priv *priv) +{ + struct pci_dev *dev = priv->pci_dev; + struct iwl4965_kw *kw = &priv->kw; + + if (kw->v_addr) { + pci_free_consistent(dev, kw->size, kw->v_addr, kw->dma_addr); + memset(kw, 0, sizeof(*kw)); + } +} + +int iwl_hw_nic_init(struct iwl_priv *priv) +{ + unsigned long flags; + struct iwl_rx_queue *rxq = &priv->rxq; + int ret; + + /* nic_init */ + priv->cfg->ops->lib->apm_ops.init(priv); + + spin_lock_irqsave(&priv->lock, flags); + iwl_write32(priv, CSR_INT_COALESCING, 512 / 32); + spin_unlock_irqrestore(&priv->lock, flags); + + ret = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN); + + priv->cfg->ops->lib->apm_ops.config(priv); + + /* Allocate the RX queue, or reset if it is already allocated */ + if (!rxq->bd) { + ret = iwl_rx_queue_alloc(priv); + if (ret) { + IWL_ERROR("Unable to initialize Rx queue\n"); + return -ENOMEM; + } + } else + iwl_rx_queue_reset(priv, rxq); + + iwl_rx_replenish(priv); + + iwl_rx_init(priv, rxq); + + spin_lock_irqsave(&priv->lock, flags); + + rxq->need_update = 1; + iwl_rx_queue_update_write_ptr(priv, rxq); + + spin_unlock_irqrestore(&priv->lock, flags); + + /* Allocate and init all Tx and Command queues */ + ret = iwl_txq_ctx_reset(priv); + if (ret) + return ret; + + set_bit(STATUS_INIT, &priv->status); + + return 0; +} +EXPORT_SYMBOL(iwl_hw_nic_init); + /** * iwlcore_clear_stations_table - Clear the driver's station table * diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index c29f8b34712..3a75dc6e35a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -108,8 +108,6 @@ struct iwl_lib_ops { u16 byte_cnt); /* setup Rx handler */ void (*rx_handler_setup)(struct iwl_priv *priv); - /* nic init */ - int (*hw_nic_init)(struct iwl_priv *priv); /* nic Tx fifo handling */ int (*disable_tx_fifo)(struct iwl_priv *priv); /* alive notification */ @@ -178,6 +176,12 @@ int iwl_setup(struct iwl_priv *priv); void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info); u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv, struct ieee80211_ht_info *sta_ht_inf); +int iwl_hw_nic_init(struct iwl_priv *priv); + +/* "keep warm" functions */ +int iwl_kw_init(struct iwl_priv *priv); +int iwl_kw_alloc(struct iwl_priv *priv); +void iwl_kw_free(struct iwl_priv *priv); /***************************************************** * RX @@ -189,11 +193,20 @@ int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q); void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); void iwl_rx_replenish(struct iwl_priv *priv); +int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq); /* FIXME: remove when TX is moved to iwl core */ int iwl_rx_queue_restock(struct iwl_priv *priv); int iwl_rx_queue_space(const struct iwl_rx_queue *q); void iwl_rx_allocate(struct iwl_priv *priv); +/***************************************************** +* TX +******************************************************/ +int iwl_txq_ctx_reset(struct iwl_priv *priv); +/* FIXME: remove when free Tx is fully merged into iwlcore */ +int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl4965_tx_queue *txq); +void iwl_hw_txq_ctx_free(struct iwl_priv *priv); + /***************************************************** * S e n d i n g H o s t C o m m a n d s * *****************************************************/ diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 23cae4c1345..e730583d88c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -138,7 +138,7 @@ struct iwl4965_tx_info { */ struct iwl4965_tx_queue { struct iwl4965_queue q; - struct iwl4965_tfd_frame *bd; + struct iwl_tfd_frame *bd; struct iwl_cmd *cmd; dma_addr_t dma_addr_cmd; struct iwl4965_tx_info *txb; @@ -649,9 +649,6 @@ extern int iwl4965_is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header); extern int iwl4965_calc_db_from_ratio(int sig_ratio); extern int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm); -extern int iwl4965_tx_queue_init(struct iwl_priv *priv, - struct iwl4965_tx_queue *txq, int count, u32 id); -extern void iwl4965_tx_queue_free(struct iwl_priv *priv, struct iwl4965_tx_queue *txq); extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv, struct ieee80211_hdr *hdr, const u8 *dest, int left); @@ -692,17 +689,12 @@ extern void iwl4965_hw_setup_deferred_work(struct iwl_priv *priv); extern void iwl4965_hw_cancel_deferred_work(struct iwl_priv *priv); extern int iwl4965_hw_rxq_stop(struct iwl_priv *priv); extern int iwl4965_hw_set_hw_params(struct iwl_priv *priv); -extern int iwl4965_hw_nic_init(struct iwl_priv *priv); extern int iwl4965_hw_nic_stop_master(struct iwl_priv *priv); -extern void iwl4965_hw_txq_ctx_free(struct iwl_priv *priv); extern void iwl4965_hw_txq_ctx_stop(struct iwl_priv *priv); extern int iwl4965_hw_nic_reset(struct iwl_priv *priv); extern int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *tfd, dma_addr_t addr, u16 len); -extern int iwl4965_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl4965_tx_queue *txq); extern int iwl4965_hw_get_temperature(struct iwl_priv *priv); -extern int iwl4965_hw_tx_queue_init(struct iwl_priv *priv, - struct iwl4965_tx_queue *txq); extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, struct iwl4965_frame *frame, u8 rate); extern int iwl4965_hw_get_rx_read(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 667b592e6ad..171751e417d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -369,3 +369,55 @@ void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) } EXPORT_SYMBOL(iwl_rx_queue_reset); +int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) +{ + int ret; + unsigned long flags; + unsigned int rb_size; + + spin_lock_irqsave(&priv->lock, flags); + ret = iwl_grab_nic_access(priv); + if (ret) { + spin_unlock_irqrestore(&priv->lock, flags); + return ret; + } + + if (priv->cfg->mod_params->amsdu_size_8K) + rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; + else + rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; + + /* Stop Rx DMA */ + iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); + + /* Reset driver's Rx queue write index */ + iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); + + /* Tell device where to find RBD circular buffer in DRAM */ + iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG, + rxq->dma_addr >> 8); + + /* Tell device where in DRAM to update its Rx status */ + iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG, + (priv->shared_phys + + offsetof(struct iwl4965_shared, rb_closed)) >> 4); + + /* Enable Rx DMA, enable host interrupt, Rx buffer size 4k, 256 RBDs */ + iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, + FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | + FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | + rb_size | + /* 0x10 << 4 | */ + (RX_QUEUE_SIZE_LOG << + FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT)); + + /* + * iwl_write32(priv,CSR_INT_COAL_REG,0); + */ + + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c new file mode 100644 index 00000000000..ade247e6310 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -0,0 +1,374 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * James P. Ketrenos + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include "iwl-eeprom.h" +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-sta.h" +#include "iwl-io.h" +#include "iwl-helpers.h" + +/** + * iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] + * + * Does NOT advance any TFD circular buffer read/write indexes + * Does NOT free the TFD itself (which is within circular buffer) + */ +int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl4965_tx_queue *txq) +{ + struct iwl_tfd_frame *bd_tmp = (struct iwl_tfd_frame *)&txq->bd[0]; + struct iwl_tfd_frame *bd = &bd_tmp[txq->q.read_ptr]; + struct pci_dev *dev = priv->pci_dev; + int i; + int counter = 0; + int index, is_odd; + + /* Host command buffers stay mapped in memory, nothing to clean */ + if (txq->q.id == IWL_CMD_QUEUE_NUM) + return 0; + + /* Sanity check on number of chunks */ + counter = IWL_GET_BITS(*bd, num_tbs); + if (counter > MAX_NUM_OF_TBS) { + IWL_ERROR("Too many chunks: %i\n", counter); + /* @todo issue fatal error, it is quite serious situation */ + return 0; + } + + /* Unmap chunks, if any. + * TFD info for odd chunks is different format than for even chunks. */ + for (i = 0; i < counter; i++) { + index = i / 2; + is_odd = i & 0x1; + + if (is_odd) + pci_unmap_single( + dev, + IWL_GET_BITS(bd->pa[index], tb2_addr_lo16) | + (IWL_GET_BITS(bd->pa[index], + tb2_addr_hi20) << 16), + IWL_GET_BITS(bd->pa[index], tb2_len), + PCI_DMA_TODEVICE); + + else if (i > 0) + pci_unmap_single(dev, + le32_to_cpu(bd->pa[index].tb1_addr), + IWL_GET_BITS(bd->pa[index], tb1_len), + PCI_DMA_TODEVICE); + + /* Free SKB, if any, for this chunk */ + if (txq->txb[txq->q.read_ptr].skb[i]) { + struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[i]; + + dev_kfree_skb(skb); + txq->txb[txq->q.read_ptr].skb[i] = NULL; + } + } + return 0; +} +EXPORT_SYMBOL(iwl_hw_txq_free_tfd); + +/** + * iwl_tx_queue_free - Deallocate DMA queue. + * @txq: Transmit queue to deallocate. + * + * Empty queue by removing and destroying all BD's. + * Free all buffers. + * 0-fill, but do not free "txq" descriptor structure. + */ +static void iwl_tx_queue_free(struct iwl_priv *priv, + struct iwl4965_tx_queue *txq) +{ + struct iwl4965_queue *q = &txq->q; + struct pci_dev *dev = priv->pci_dev; + int len; + + if (q->n_bd == 0) + return; + + /* first, empty all BD's */ + for (; q->write_ptr != q->read_ptr; + q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) + iwl_hw_txq_free_tfd(priv, txq); + + len = sizeof(struct iwl_cmd) * q->n_window; + if (q->id == IWL_CMD_QUEUE_NUM) + len += IWL_MAX_SCAN_SIZE; + + /* De-alloc array of command/tx buffers */ + pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); + + /* De-alloc circular buffer of TFDs */ + if (txq->q.n_bd) + pci_free_consistent(dev, sizeof(struct iwl_tfd_frame) * + txq->q.n_bd, txq->bd, txq->q.dma_addr); + + /* De-alloc array of per-TFD driver data */ + kfree(txq->txb); + txq->txb = NULL; + + /* 0-fill queue descriptor structure */ + memset(txq, 0, sizeof(*txq)); +} + +/** + * iwl_hw_txq_ctx_free - Free TXQ Context + * + * Destroy all TX DMA queues and structures + */ +void iwl_hw_txq_ctx_free(struct iwl_priv *priv) +{ + int txq_id; + + /* Tx queues */ + for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) + iwl_tx_queue_free(priv, &priv->txq[txq_id]); + + /* Keep-warm buffer */ + iwl_kw_free(priv); +} +EXPORT_SYMBOL(iwl_hw_txq_ctx_free); + +/** + * iwl_queue_init - Initialize queue's high/low-water and read/write indexes + */ +static int iwl_queue_init(struct iwl_priv *priv, struct iwl4965_queue *q, + int count, int slots_num, u32 id) +{ + q->n_bd = count; + q->n_window = slots_num; + q->id = id; + + /* count must be power-of-two size, otherwise iwl_queue_inc_wrap + * and iwl_queue_dec_wrap are broken. */ + BUG_ON(!is_power_of_2(count)); + + /* slots_num must be power-of-two size, otherwise + * get_cmd_index is broken. */ + BUG_ON(!is_power_of_2(slots_num)); + + q->low_mark = q->n_window / 4; + if (q->low_mark < 4) + q->low_mark = 4; + + q->high_mark = q->n_window / 8; + if (q->high_mark < 2) + q->high_mark = 2; + + q->write_ptr = q->read_ptr = 0; + + return 0; +} + +/** + * iwl_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue + */ +static int iwl_tx_queue_alloc(struct iwl_priv *priv, + struct iwl4965_tx_queue *txq, u32 id) +{ + struct pci_dev *dev = priv->pci_dev; + + /* Driver private data, only for Tx (not command) queues, + * not shared with device. */ + if (id != IWL_CMD_QUEUE_NUM) { + txq->txb = kmalloc(sizeof(txq->txb[0]) * + TFD_QUEUE_SIZE_MAX, GFP_KERNEL); + if (!txq->txb) { + IWL_ERROR("kmalloc for auxiliary BD " + "structures failed\n"); + goto error; + } + } else + txq->txb = NULL; + + /* Circular buffer of transmit frame descriptors (TFDs), + * shared with device */ + txq->bd = pci_alloc_consistent(dev, + sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX, + &txq->q.dma_addr); + + if (!txq->bd) { + IWL_ERROR("pci_alloc_consistent(%zd) failed\n", + sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX); + goto error; + } + txq->q.id = id; + + return 0; + + error: + kfree(txq->txb); + txq->txb = NULL; + + return -ENOMEM; +} + +/* + * Tell nic where to find circular buffer of Tx Frame Descriptors for + * given Tx queue, and enable the DMA channel used for that queue. + * + * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA + * channels supported in hardware. + */ +static int iwl_hw_tx_queue_init(struct iwl_priv *priv, + struct iwl4965_tx_queue *txq) +{ + int rc; + unsigned long flags; + int txq_id = txq->q.id; + + spin_lock_irqsave(&priv->lock, flags); + rc = iwl_grab_nic_access(priv); + if (rc) { + spin_unlock_irqrestore(&priv->lock, flags); + return rc; + } + + /* Circular buffer (TFD queue in DRAM) physical base address */ + iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id), + txq->q.dma_addr >> 8); + + /* Enable DMA channel, using same id as for TFD queue */ + iwl_write_direct32( + priv, FH_TCSR_CHNL_TX_CONFIG_REG(txq_id), + FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | + FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL); + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + +/** + * iwl_tx_queue_init - Allocate and initialize one tx/cmd queue + */ +static int iwl_tx_queue_init(struct iwl_priv *priv, + struct iwl4965_tx_queue *txq, + int slots_num, u32 txq_id) +{ + struct pci_dev *dev = priv->pci_dev; + int len; + int rc = 0; + + /* + * Alloc buffer array for commands (Tx or other types of commands). + * For the command queue (#4), allocate command space + one big + * command for scan, since scan command is very huge; the system will + * not have two scans at the same time, so only one is needed. + * For normal Tx queues (all other queues), no super-size command + * space is needed. + */ + len = sizeof(struct iwl_cmd) * slots_num; + if (txq_id == IWL_CMD_QUEUE_NUM) + len += IWL_MAX_SCAN_SIZE; + txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd); + if (!txq->cmd) + return -ENOMEM; + + /* Alloc driver data array and TFD circular buffer */ + rc = iwl_tx_queue_alloc(priv, txq, txq_id); + if (rc) { + pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); + + return -ENOMEM; + } + txq->need_update = 0; + + /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise + * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */ + BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); + + /* Initialize queue's high/low-water marks, and head/tail indexes */ + iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); + + /* Tell device where to find queue */ + iwl_hw_tx_queue_init(priv, txq); + + return 0; +} + +/** + * iwl_txq_ctx_reset - Reset TX queue context + * Destroys all DMA structures and initialise them again + * + * @param priv + * @return error code + */ +int iwl_txq_ctx_reset(struct iwl_priv *priv) +{ + int ret = 0; + int txq_id, slots_num; + + iwl_kw_free(priv); + + /* Free all tx/cmd queues and keep-warm buffer */ + iwl_hw_txq_ctx_free(priv); + + /* Alloc keep-warm buffer */ + ret = iwl_kw_alloc(priv); + if (ret) { + IWL_ERROR("Keep Warm allocation failed"); + goto error_kw; + } + + /* Turn off all Tx DMA fifos */ + ret = priv->cfg->ops->lib->disable_tx_fifo(priv); + if (unlikely(ret)) + goto error_reset; + + /* Tell nic where to find the keep-warm buffer */ + ret = iwl_kw_init(priv); + if (ret) { + IWL_ERROR("kw_init failed\n"); + goto error_reset; + } + + /* Alloc and init all (default 16) Tx queues, + * including the command queue (#4) */ + for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { + slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ? + TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; + ret = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num, + txq_id); + if (ret) { + IWL_ERROR("Tx %d queue init failed\n", txq_id); + goto error; + } + } + + return ret; + + error: + iwl_hw_txq_ctx_free(priv); + error_reset: + iwl_kw_free(priv); + error_kw: + return ret; +} diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index ad45249454f..8d06cf1a319 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -207,173 +207,6 @@ static inline u8 get_cmd_index(struct iwl4965_queue *q, u32 index, int is_huge) return index & (q->n_window - 1); } -/** - * iwl4965_queue_init - Initialize queue's high/low-water and read/write indexes - */ -static int iwl4965_queue_init(struct iwl_priv *priv, struct iwl4965_queue *q, - int count, int slots_num, u32 id) -{ - q->n_bd = count; - q->n_window = slots_num; - q->id = id; - - /* count must be power-of-two size, otherwise iwl_queue_inc_wrap - * and iwl_queue_dec_wrap are broken. */ - BUG_ON(!is_power_of_2(count)); - - /* slots_num must be power-of-two size, otherwise - * get_cmd_index is broken. */ - BUG_ON(!is_power_of_2(slots_num)); - - q->low_mark = q->n_window / 4; - if (q->low_mark < 4) - q->low_mark = 4; - - q->high_mark = q->n_window / 8; - if (q->high_mark < 2) - q->high_mark = 2; - - q->write_ptr = q->read_ptr = 0; - - return 0; -} - -/** - * iwl4965_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue - */ -static int iwl4965_tx_queue_alloc(struct iwl_priv *priv, - struct iwl4965_tx_queue *txq, u32 id) -{ - struct pci_dev *dev = priv->pci_dev; - - /* Driver private data, only for Tx (not command) queues, - * not shared with device. */ - if (id != IWL_CMD_QUEUE_NUM) { - txq->txb = kmalloc(sizeof(txq->txb[0]) * - TFD_QUEUE_SIZE_MAX, GFP_KERNEL); - if (!txq->txb) { - IWL_ERROR("kmalloc for auxiliary BD " - "structures failed\n"); - goto error; - } - } else - txq->txb = NULL; - - /* Circular buffer of transmit frame descriptors (TFDs), - * shared with device */ - txq->bd = pci_alloc_consistent(dev, - sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX, - &txq->q.dma_addr); - - if (!txq->bd) { - IWL_ERROR("pci_alloc_consistent(%zd) failed\n", - sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX); - goto error; - } - txq->q.id = id; - - return 0; - - error: - if (txq->txb) { - kfree(txq->txb); - txq->txb = NULL; - } - - return -ENOMEM; -} - -/** - * iwl4965_tx_queue_init - Allocate and initialize one tx/cmd queue - */ -int iwl4965_tx_queue_init(struct iwl_priv *priv, - struct iwl4965_tx_queue *txq, int slots_num, u32 txq_id) -{ - struct pci_dev *dev = priv->pci_dev; - int len; - int rc = 0; - - /* - * Alloc buffer array for commands (Tx or other types of commands). - * For the command queue (#4), allocate command space + one big - * command for scan, since scan command is very huge; the system will - * not have two scans at the same time, so only one is needed. - * For normal Tx queues (all other queues), no super-size command - * space is needed. - */ - len = sizeof(struct iwl_cmd) * slots_num; - if (txq_id == IWL_CMD_QUEUE_NUM) - len += IWL_MAX_SCAN_SIZE; - txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd); - if (!txq->cmd) - return -ENOMEM; - - /* Alloc driver data array and TFD circular buffer */ - rc = iwl4965_tx_queue_alloc(priv, txq, txq_id); - if (rc) { - pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); - - return -ENOMEM; - } - txq->need_update = 0; - - /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise - * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */ - BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); - - /* Initialize queue's high/low-water marks, and head/tail indexes */ - iwl4965_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); - - /* Tell device where to find queue */ - iwl4965_hw_tx_queue_init(priv, txq); - - return 0; -} - -/** - * iwl4965_tx_queue_free - Deallocate DMA queue. - * @txq: Transmit queue to deallocate. - * - * Empty queue by removing and destroying all BD's. - * Free all buffers. - * 0-fill, but do not free "txq" descriptor structure. - */ -void iwl4965_tx_queue_free(struct iwl_priv *priv, struct iwl4965_tx_queue *txq) -{ - struct iwl4965_queue *q = &txq->q; - struct pci_dev *dev = priv->pci_dev; - int len; - - if (q->n_bd == 0) - return; - - /* first, empty all BD's */ - for (; q->write_ptr != q->read_ptr; - q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) - iwl4965_hw_txq_free_tfd(priv, txq); - - len = sizeof(struct iwl_cmd) * q->n_window; - if (q->id == IWL_CMD_QUEUE_NUM) - len += IWL_MAX_SCAN_SIZE; - - /* De-alloc array of command/tx buffers */ - pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); - - /* De-alloc circular buffer of TFDs */ - if (txq->q.n_bd) - pci_free_consistent(dev, sizeof(struct iwl4965_tfd_frame) * - 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; - } - - /* 0-fill queue descriptor structure */ - memset(txq, 0, sizeof(*txq)); -} - const u8 iwl4965_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; /*************** STATION TABLE MANAGEMENT **** @@ -516,7 +349,7 @@ int iwl4965_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) { struct iwl4965_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; struct iwl4965_queue *q = &txq->q; - struct iwl4965_tfd_frame *tfd; + struct iwl_tfd_frame *tfd; u32 *control_flags; struct iwl_cmd *out_cmd; u32 idx; @@ -1931,7 +1764,7 @@ static int iwl4965_tx_skb(struct iwl_priv *priv, struct sk_buff *skb, struct ieee80211_tx_control *ctl) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct iwl4965_tfd_frame *tfd; + struct iwl_tfd_frame *tfd; u32 *control_flags; int txq_id = ctl->queue; struct iwl4965_tx_queue *txq = NULL; @@ -2515,7 +2348,7 @@ int iwl4965_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) if (txq_id != IWL_CMD_QUEUE_NUM) { iwl4965_txstatus_to_ieee(priv, &(txq->txb[txq->q.read_ptr])); - iwl4965_hw_txq_free_tfd(priv, txq); + iwl_hw_txq_free_tfd(priv, txq); } else if (nfreed > 1) { IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index, q->write_ptr, q->read_ptr); @@ -4677,7 +4510,7 @@ static int __iwl4965_up(struct iwl_priv *priv) return ret; } - ret = priv->cfg->ops->lib->hw_nic_init(priv); + ret = iwl_hw_nic_init(priv); if (ret) { IWL_ERROR("Unable to init nic\n"); return ret; @@ -6940,7 +6773,7 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) if (priv->rxq.bd) iwl_rx_queue_free(priv, &priv->rxq); - iwl4965_hw_txq_ctx_free(priv); + iwl_hw_txq_ctx_free(priv); iwlcore_clear_stations_table(priv); iwl_eeprom_free(priv); -- cgit v1.2.3 From 27aaba0ca099461badb496bf7cde5ab5cdc89b98 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 5 May 2008 10:22:44 +0800 Subject: iwlwifi: compile iwl-sta into iwlcore This patch moves iwl-sta into iwl-core. Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Makefile | 4 ++-- drivers/net/wireless/iwlwifi/iwl-sta.c | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 85c8bf62d59..5c73eede719 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -1,6 +1,6 @@ obj-$(CONFIG_IWLCORE) += iwlcore.o iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o -iwlcore-objs += iwl-rx.o iwl-tx.o +iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o @@ -11,7 +11,7 @@ iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl3945-$(CONFIG_IWL3945_LEDS) += iwl-3945-led.o obj-$(CONFIG_IWL4965) += iwl4965.o -iwl4965-objs := iwl4965-base.o iwl-4965.o iwl-4965-rs.o iwl-sta.o +iwl4965-objs := iwl4965-base.o iwl-4965.o iwl-4965-rs.o ifeq ($(CONFIG_IWL5000),y) iwl4965-objs += iwl-5000.o diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 34f54244ed2..f2267047d10 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -170,6 +170,7 @@ int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty) else return 0; } +EXPORT_SYMBOL(iwl_send_static_wepkey_cmd); int iwl_remove_default_wep_key(struct iwl_priv *priv, struct ieee80211_key_conf *keyconf) @@ -190,6 +191,7 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv, return ret; } +EXPORT_SYMBOL(iwl_remove_default_wep_key); int iwl_set_default_wep_key(struct iwl_priv *priv, struct ieee80211_key_conf *keyconf) @@ -217,6 +219,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv, return ret; } +EXPORT_SYMBOL(iwl_set_default_wep_key); static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, struct ieee80211_key_conf *keyconf, @@ -391,6 +394,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, spin_unlock_irqrestore(&priv->sta_lock, flags); return ret; } +EXPORT_SYMBOL(iwl_remove_dynamic_key); int iwl_set_dynamic_key(struct iwl_priv *priv, struct ieee80211_key_conf *key, u8 sta_id) @@ -416,6 +420,7 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, return ret; } +EXPORT_SYMBOL(iwl_set_dynamic_key); #ifdef CONFIG_IWLWIFI_DEBUG static void iwl_dump_lq_cmd(struct iwl_priv *priv, -- cgit v1.2.3 From f3ccc08c8cdeb784087348e67f41a779c787fa0e Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 5 May 2008 10:22:45 +0800 Subject: iwlwifi: move iwl4965_init_alive_start to iwl-4965.c This patch moves iwl_4965_init_alive_start to iwl-4965.c. Signed-off-by: Emmanuel Grumbach Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-4965.c | 97 ++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 2 + drivers/net/wireless/iwlwifi/iwl4965-base.c | 101 +--------------------------- 3 files changed, 100 insertions(+), 100 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 319ffe747a7..f56b9a91d78 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -222,6 +222,102 @@ static int iwl4965_load_bsm(struct iwl_priv *priv) return 0; } +/** + * iwl4965_set_ucode_ptrs - Set uCode address location + * + * Tell initialization uCode where to find runtime uCode. + * + * BSM registers initially contain pointers to initialization uCode. + * We need to replace them to load runtime uCode inst and data, + * and to save runtime data when powering down. + */ +static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv) +{ + dma_addr_t pinst; + dma_addr_t pdata; + unsigned long flags; + int ret = 0; + + /* bits 35:4 for 4965 */ + pinst = priv->ucode_code.p_addr >> 4; + pdata = priv->ucode_data_backup.p_addr >> 4; + + spin_lock_irqsave(&priv->lock, flags); + ret = iwl_grab_nic_access(priv); + if (ret) { + spin_unlock_irqrestore(&priv->lock, flags); + return ret; + } + + /* Tell bootstrap uCode where to find image to load */ + iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); + iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); + iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, + priv->ucode_data.len); + + /* Inst bytecount must be last to set up, bit 31 signals uCode + * that all new ptr/size info is in place */ + iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, + priv->ucode_code.len | BSM_DRAM_INST_LOAD); + iwl_release_nic_access(priv); + + spin_unlock_irqrestore(&priv->lock, flags); + + IWL_DEBUG_INFO("Runtime uCode pointers are set.\n"); + + return ret; +} + +/** + * iwl4965_init_alive_start - Called after REPLY_ALIVE notification received + * + * Called after REPLY_ALIVE notification received from "initialize" uCode. + * + * The 4965 "initialize" ALIVE reply contains calibration data for: + * Voltage, temperature, and MIMO tx gain correction, now stored in priv + * (3945 does not contain this data). + * + * Tell "initialize" uCode to go ahead and load the runtime uCode. +*/ +static void iwl4965_init_alive_start(struct iwl_priv *priv) +{ + /* Check alive response for "valid" sign from uCode */ + if (priv->card_alive_init.is_valid != UCODE_VALID_OK) { + /* We had an error bringing up the hardware, so take it + * all the way back down so we can try again */ + IWL_DEBUG_INFO("Initialize Alive failed.\n"); + goto restart; + } + + /* Bootstrap uCode has loaded initialize uCode ... verify inst image. + * This is a paranoid check, because we would not have gotten the + * "initialize" alive if code weren't properly loaded. */ + if (iwl_verify_ucode(priv)) { + /* Runtime instruction load was bad; + * take it all the way back down so we can try again */ + IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n"); + goto restart; + } + + /* Calculate temperature */ + priv->temperature = iwl4965_get_temperature(priv); + + /* Send pointers to protocol/runtime uCode image ... init code will + * load and launch runtime uCode, which will send us another "Alive" + * notification. */ + IWL_DEBUG_INFO("Initialization Alive received.\n"); + if (iwl4965_set_ucode_ptrs(priv)) { + /* Runtime instruction load won't happen; + * take it all the way back down so we can try again */ + IWL_DEBUG_INFO("Couldn't set up uCode pointers.\n"); + goto restart; + } + return; + +restart: + queue_work(priv->workqueue, &priv->restart); +} + static int is_fat_channel(__le32 rxon_flags) { return (rxon_flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) || @@ -3724,6 +3820,7 @@ static struct iwl_lib_ops iwl4965_lib = { .rx_handler_setup = iwl4965_rx_handler_setup, .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr, .alive_notify = iwl4965_alive_notify, + .init_alive_start = iwl4965_init_alive_start, .load_ucode = iwl4965_load_bsm, .apm_ops = { .init = iwl4965_apm_init, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 3a75dc6e35a..08eccdefd72 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -110,6 +110,8 @@ struct iwl_lib_ops { void (*rx_handler_setup)(struct iwl_priv *priv); /* nic Tx fifo handling */ int (*disable_tx_fifo)(struct iwl_priv *priv); + /* alive notification after init uCode load */ + void (*init_alive_start)(struct iwl_priv *priv); /* alive notification */ int (*alive_notify)(struct iwl_priv *priv); /* check validity of rtc data address */ diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 8d06cf1a319..2e976c3881e 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -4162,105 +4162,6 @@ static int iwl4965_read_ucode(struct iwl_priv *priv) return ret; } - -/** - * iwl4965_set_ucode_ptrs - Set uCode address location - * - * Tell initialization uCode where to find runtime uCode. - * - * BSM registers initially contain pointers to initialization uCode. - * We need to replace them to load runtime uCode inst and data, - * and to save runtime data when powering down. - */ -static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv) -{ - dma_addr_t pinst; - dma_addr_t pdata; - int rc = 0; - unsigned long flags; - - /* bits 35:4 for 4965 */ - pinst = priv->ucode_code.p_addr >> 4; - pdata = priv->ucode_data_backup.p_addr >> 4; - - spin_lock_irqsave(&priv->lock, flags); - rc = iwl_grab_nic_access(priv); - if (rc) { - spin_unlock_irqrestore(&priv->lock, flags); - return rc; - } - - /* Tell bootstrap uCode where to find image to load */ - iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); - iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); - iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, - priv->ucode_data.len); - - /* Inst bytecount must be last to set up, bit 31 signals uCode - * that all new ptr/size info is in place */ - iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, - priv->ucode_code.len | BSM_DRAM_INST_LOAD); - - iwl_release_nic_access(priv); - - spin_unlock_irqrestore(&priv->lock, flags); - - IWL_DEBUG_INFO("Runtime uCode pointers are set.\n"); - - return rc; -} - -/** - * iwl4965_init_alive_start - Called after REPLY_ALIVE notification received - * - * Called after REPLY_ALIVE notification received from "initialize" uCode. - * - * The 4965 "initialize" ALIVE reply contains calibration data for: - * Voltage, temperature, and MIMO tx gain correction, now stored in priv - * (3945 does not contain this data). - * - * Tell "initialize" uCode to go ahead and load the runtime uCode. -*/ -static void iwl4965_init_alive_start(struct iwl_priv *priv) -{ - /* Check alive response for "valid" sign from uCode */ - if (priv->card_alive_init.is_valid != UCODE_VALID_OK) { - /* We had an error bringing up the hardware, so take it - * all the way back down so we can try again */ - IWL_DEBUG_INFO("Initialize Alive failed.\n"); - goto restart; - } - - /* Bootstrap uCode has loaded initialize uCode ... verify inst image. - * This is a paranoid check, because we would not have gotten the - * "initialize" alive if code weren't properly loaded. */ - if (iwl_verify_ucode(priv)) { - /* Runtime instruction load was bad; - * take it all the way back down so we can try again */ - IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n"); - goto restart; - } - - /* Calculate temperature */ - priv->temperature = iwl4965_get_temperature(priv); - - /* Send pointers to protocol/runtime uCode image ... init code will - * load and launch runtime uCode, which will send us another "Alive" - * notification. */ - IWL_DEBUG_INFO("Initialization Alive received.\n"); - if (iwl4965_set_ucode_ptrs(priv)) { - /* Runtime instruction load won't happen; - * take it all the way back down so we can try again */ - IWL_DEBUG_INFO("Couldn't set up uCode pointers.\n"); - goto restart; - } - return; - - restart: - queue_work(priv->workqueue, &priv->restart); -} - - /** * iwl4965_alive_start - called after REPLY_ALIVE notification received * from protocol/runtime uCode (initialization uCode's @@ -4586,7 +4487,7 @@ static void iwl4965_bg_init_alive_start(struct work_struct *data) return; mutex_lock(&priv->mutex); - iwl4965_init_alive_start(priv); + priv->cfg->ops->lib->init_alive_start(priv); mutex_unlock(&priv->mutex); } -- cgit v1.2.3 From 4419e39b6041b213e49bb13fd40fb267de0eb568 Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Mon, 5 May 2008 10:22:47 +0800 Subject: iwlwifi : Set monitor mode for 4965 The patch leverages mac80211 configure_filter to enable iwl4965 monitor mode. Signed-off-by: Abhijeet Kolekar Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-4965.c | 11 ++++++++- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + drivers/net/wireless/iwlwifi/iwl4965-base.c | 36 ++++++++++++++++++++++++++++- 3 files changed, 46 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index f56b9a91d78..866a93e3de9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2617,7 +2617,9 @@ static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data, rx_start->byte_count = amsdu->byte_count; rx_end = (__le32 *) (((u8 *) hdr) + len); } - if (len > priv->hw_params.max_pkt_size || len < 16) { + /* In monitor mode allow 802.11 ACk frames (10 bytes) */ + if (len > priv->hw_params.max_pkt_size || + len < ((priv->iw_mode == IEEE80211_IF_TYPE_MNTR) ? 10 : 16)) { IWL_WARNING("byte count out of range [16,4K] : %d\n", len); return; } @@ -2989,6 +2991,13 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, rx_status.ssi, rx_status.noise, rx_status.signal, (unsigned long long)rx_status.mactime); + + if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) { + iwl4965_handle_data_packet(priv, 1, include_phy, + rxb, &rx_status); + return; + } + network_packet = iwl4965_is_network_packet(priv, header); if (network_packet) { priv->last_rx_rssi = rx_status.ssi; diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index e730583d88c..25dce14c87d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1163,6 +1163,7 @@ struct iwl_priv { struct work_struct report_work; struct work_struct request_scan; struct work_struct beacon_update; + struct work_struct set_monitor; struct tasklet_struct irq_tasklet; diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 2e976c3881e..88f3554c0fb 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -4539,6 +4539,24 @@ static void iwl4965_bg_rf_kill(struct work_struct *work) mutex_unlock(&priv->mutex); } +static void iwl4965_bg_set_monitor(struct work_struct *work) +{ + struct iwl_priv *priv = container_of(work, + struct iwl_priv, set_monitor); + + IWL_DEBUG(IWL_DL_STATE, "setting monitor mode\n"); + + mutex_lock(&priv->mutex); + + if (!iwl_is_ready(priv)) + IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n"); + else + if (iwl4965_set_mode(priv, IEEE80211_IF_TYPE_MNTR) != 0) + IWL_ERROR("iwl4965_set_mode() failed\n"); + + mutex_unlock(&priv->mutex); +} + #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) static void iwl4965_bg_scan_check(struct work_struct *data) @@ -5428,7 +5446,22 @@ static void iwl4965_configure_filter(struct ieee80211_hw *hw, * XXX: dummy * see also iwl4965_connection_init_rx_config */ - *total_flags = 0; + struct iwl_priv *priv = hw->priv; + int new_flags = 0; + if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { + if (*total_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { + IWL_DEBUG_MAC80211("Enter: type %d (0x%x, 0x%x)\n", + IEEE80211_IF_TYPE_MNTR, + changed_flags, *total_flags); + /* queue work 'cuz mac80211 is holding a lock which + * prevents us from issuing (synchronous) f/w cmds */ + queue_work(priv->workqueue, &priv->set_monitor); + new_flags &= FIF_PROMISC_IN_BSS | + FIF_OTHER_BSS | + FIF_ALLMULTI; + } + } + *total_flags = new_flags; } static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw, @@ -6359,6 +6392,7 @@ static void iwl4965_setup_deferred_work(struct iwl_priv *priv) INIT_WORK(&priv->abort_scan, iwl4965_bg_abort_scan); INIT_WORK(&priv->rf_kill, iwl4965_bg_rf_kill); INIT_WORK(&priv->beacon_update, iwl4965_bg_beacon_update); + INIT_WORK(&priv->set_monitor, iwl4965_bg_set_monitor); INIT_DELAYED_WORK(&priv->post_associate, iwl4965_bg_post_associate); INIT_DELAYED_WORK(&priv->init_alive_start, iwl4965_bg_init_alive_start); INIT_DELAYED_WORK(&priv->alive_start, iwl4965_bg_alive_start); -- cgit v1.2.3 From 5ec0397679f1c1606199cfd6f3e24351891c60c3 Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Mon, 5 May 2008 10:22:48 +0800 Subject: iwlwifi : Set monitor mode for 3945 The patch leverages mac80211 configure_filter to enable iwl3945 monitor mode. Signed-off-by: Abhijeet Kolekar Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-3945.h | 1 + drivers/net/wireless/iwlwifi/iwl3945-base.c | 36 ++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index fb96c62ad0f..9fdc1405e85 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -886,6 +886,7 @@ struct iwl3945_priv { struct work_struct report_work; struct work_struct request_scan; struct work_struct beacon_update; + struct work_struct set_monitor; struct tasklet_struct irq_tasklet; diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 7040cde8bc2..f021eba41e6 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -6144,6 +6144,24 @@ static void iwl3945_bg_rf_kill(struct work_struct *work) mutex_unlock(&priv->mutex); } +static void iwl3945_bg_set_monitor(struct work_struct *work) +{ + struct iwl3945_priv *priv = container_of(work, + struct iwl3945_priv, set_monitor); + + IWL_DEBUG(IWL_DL_STATE, "setting monitor mode\n"); + + mutex_lock(&priv->mutex); + + if (!iwl3945_is_ready(priv)) + IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n"); + else + if (iwl3945_set_mode(priv, IEEE80211_IF_TYPE_MNTR) != 0) + IWL_ERROR("iwl3945_set_mode() failed\n"); + + mutex_unlock(&priv->mutex); +} + #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) static void iwl3945_bg_scan_check(struct work_struct *data) @@ -6996,7 +7014,22 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw, * XXX: dummy * see also iwl3945_connection_init_rx_config */ - *total_flags = 0; + struct iwl3945_priv *priv = hw->priv; + int new_flags = 0; + if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { + if (*total_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { + IWL_DEBUG_MAC80211("Enter: type %d (0x%x, 0x%x)\n", + IEEE80211_IF_TYPE_MNTR, + changed_flags, *total_flags); + /* queue work 'cuz mac80211 is holding a lock which + * prevents us from issuing (synchronous) f/w cmds */ + queue_work(priv->workqueue, &priv->set_monitor); + new_flags &= FIF_PROMISC_IN_BSS | + FIF_OTHER_BSS | + FIF_ALLMULTI; + } + } + *total_flags = new_flags; } static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw, @@ -7872,6 +7905,7 @@ static void iwl3945_setup_deferred_work(struct iwl3945_priv *priv) INIT_WORK(&priv->abort_scan, iwl3945_bg_abort_scan); INIT_WORK(&priv->rf_kill, iwl3945_bg_rf_kill); INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); + INIT_WORK(&priv->set_monitor, iwl3945_bg_set_monitor); INIT_DELAYED_WORK(&priv->post_associate, iwl3945_bg_post_associate); INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); -- cgit v1.2.3 From d67f5489d8d9be09bc8e1615ec6c57c3120a731d Mon Sep 17 00:00:00 2001 From: Ron Rindjunsky Date: Mon, 5 May 2008 10:22:49 +0800 Subject: iwlwifi: handle shared memory Rx index access This patch splits ucode's and driver's shared memory Rx index access to match 4965 and 5000 offsets. Signed-off-by: Ron Rindjunsky Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-4965.c | 5 ++++- drivers/net/wireless/iwlwifi/iwl-5000.c | 9 +++++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 1 + drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +- drivers/net/wireless/iwlwifi/iwl-rx.c | 3 +-- drivers/net/wireless/iwlwifi/iwl4965-base.c | 2 +- 6 files changed, 17 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 866a93e3de9..a475ecea900 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2006,7 +2006,7 @@ void iwl4965_hw_build_tx_cmd_rate(struct iwl_priv *priv, tx->rate_n_flags = iwl4965_hw_set_rate_n_flags(rate_plcp, rate_flags); } -int iwl4965_hw_get_rx_read(struct iwl_priv *priv) +static int iwl4965_shared_mem_rx_idx(struct iwl_priv *priv) { struct iwl4965_shared *s = priv->shared_virt; return le32_to_cpu(s->rb_closed) & 0xFFF; @@ -2093,6 +2093,8 @@ static int iwl4965_alloc_shared_mem(struct iwl_priv *priv) memset(priv->shared_virt, 0, sizeof(struct iwl4965_shared)); + priv->rb_closed_offset = offsetof(struct iwl4965_shared, rb_closed); + return 0; } @@ -3824,6 +3826,7 @@ static struct iwl_lib_ops iwl4965_lib = { .set_hw_params = iwl4965_hw_set_hw_params, .alloc_shared_mem = iwl4965_alloc_shared_mem, .free_shared_mem = iwl4965_free_shared_mem, + .shared_mem_rx_idx = iwl4965_shared_mem_rx_idx, .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl, .disable_tx_fifo = iwl4965_disable_tx_fifo, .rx_handler_setup = iwl4965_rx_handler_setup, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index feffcafe149..d6b91f7e0b1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -362,6 +362,8 @@ static int iwl5000_alloc_shared_mem(struct iwl_priv *priv) memset(priv->shared_virt, 0, sizeof(struct iwl5000_shared)); + priv->rb_closed_offset = offsetof(struct iwl5000_shared, rb_closed); + return 0; } @@ -374,6 +376,12 @@ static void iwl5000_free_shared_mem(struct iwl_priv *priv) priv->shared_phys); } +static int iwl5000_shared_mem_rx_idx(struct iwl_priv *priv) +{ + struct iwl5000_shared *s = priv->shared_virt; + return le32_to_cpu(s->rb_closed) & 0xFFF; +} + /** * iwl5000_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array */ @@ -466,6 +474,7 @@ static struct iwl_lib_ops iwl5000_lib = { .set_hw_params = iwl5000_hw_set_hw_params, .alloc_shared_mem = iwl5000_alloc_shared_mem, .free_shared_mem = iwl5000_free_shared_mem, + .shared_mem_rx_idx = iwl5000_shared_mem_rx_idx, .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, .disable_tx_fifo = iwl5000_disable_tx_fifo, .apm_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 08eccdefd72..77428db6a21 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -103,6 +103,7 @@ struct iwl_lib_ops { /* ucode shared memory */ int (*alloc_shared_mem)(struct iwl_priv *priv); void (*free_shared_mem)(struct iwl_priv *priv); + int (*shared_mem_rx_idx)(struct iwl_priv *priv); void (*txq_update_byte_cnt_tbl)(struct iwl_priv *priv, struct iwl4965_tx_queue *txq, u16 byte_cnt); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 25dce14c87d..1683bee800d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -697,7 +697,6 @@ extern int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *tfd, extern int iwl4965_hw_get_temperature(struct iwl_priv *priv); extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, struct iwl4965_frame *frame, u8 rate); -extern int iwl4965_hw_get_rx_read(struct iwl_priv *priv); extern void iwl4965_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd, struct ieee80211_tx_control *ctrl, @@ -1138,6 +1137,7 @@ struct iwl_priv { struct iwl_hw_params hw_params; /* driver/uCode shared Tx Byte Counts and Rx status */ void *shared_virt; + int rb_closed_offset; /* Physical Pointer to Tx Byte Counts and Rx status */ dma_addr_t shared_phys; diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 171751e417d..a2eb90d40b7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -399,8 +399,7 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) /* Tell device where in DRAM to update its Rx status */ iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG, - (priv->shared_phys + - offsetof(struct iwl4965_shared, rb_closed)) >> 4); + (priv->shared_phys + priv->rb_closed_offset) >> 4); /* Enable Rx DMA, enable host interrupt, Rx buffer size 4k, 256 RBDs */ iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 88f3554c0fb..09f2a6383d2 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -3095,7 +3095,7 @@ void iwl_rx_handle(struct iwl_priv *priv) /* uCode's read index (stored in shared DRAM) indicates the last Rx * buffer that the driver may process (last buffer filled by ucode). */ - r = iwl4965_hw_get_rx_read(priv); + r = priv->cfg->ops->lib->shared_mem_rx_idx(priv); i = rxq->read; /* Rx interrupt, but nothing sent from uCode */ -- cgit v1.2.3 From 164669032ecbf7c9a3bc78adad4e13ee486e975c Mon Sep 17 00:00:00 2001 From: Ron Rindjunsky Date: Mon, 5 May 2008 10:22:50 +0800 Subject: iwlwifi: remove 4965 prefix from iwl4965_kw and iwl4965_tx_queue This patch removes the 4965 prefix to form iwl_kw and iwl_tx_queue structs, as they are used mostly in iwlcore now. Signed-off-by: Ron Rindjunsky Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-4965.c | 6 +++--- drivers/net/wireless/iwlwifi/iwl-5000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-core.c | 6 +++--- drivers/net/wireless/iwlwifi/iwl-core.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-dev.h | 14 +++++++------- drivers/net/wireless/iwlwifi/iwl-tx.c | 11 +++++------ drivers/net/wireless/iwlwifi/iwl4965-base.c | 14 +++++++------- 7 files changed, 28 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index a475ecea900..126ecf7023e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -880,7 +880,7 @@ static void iwl4965_set_wr_ptrs(struct iwl_priv *priv, int txq_id, u32 index) * NOTE: Acquire priv->lock before calling this function ! */ static void iwl4965_tx_queue_set_status(struct iwl_priv *priv, - struct iwl4965_tx_queue *txq, + struct iwl_tx_queue *txq, int tx_fifo_id, int scd_retry) { int txq_id = txq->q.id; @@ -2111,7 +2111,7 @@ static void iwl4965_free_shared_mem(struct iwl_priv *priv) * iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array */ static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv, - struct iwl4965_tx_queue *txq, + struct iwl_tx_queue *txq, u16 byte_cnt) { int len; @@ -3286,7 +3286,7 @@ static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv, struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; struct iwl4965_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; int index; - struct iwl4965_tx_queue *txq = NULL; + struct iwl_tx_queue *txq = NULL; struct iwl_ht_agg *agg; DECLARE_MAC_BUF(mac); diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index d6b91f7e0b1..43b4d20467d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -386,7 +386,7 @@ static int iwl5000_shared_mem_rx_idx(struct iwl_priv *priv) * iwl5000_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array */ static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv, - struct iwl4965_tx_queue *txq, + struct iwl_tx_queue *txq, u16 byte_cnt) { struct iwl5000_shared *shared_data = priv->shared_virt; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 4ba860741f8..aab0ee6d8af 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -143,9 +143,9 @@ out: int iwl_kw_alloc(struct iwl_priv *priv) { struct pci_dev *dev = priv->pci_dev; - struct iwl4965_kw *kw = &priv->kw; + struct iwl_kw *kw = &priv->kw; - kw->size = IWL4965_KW_SIZE; /* TBW need set somewhere else */ + kw->size = IWL_KW_SIZE; kw->v_addr = pci_alloc_consistent(dev, kw->size, &kw->dma_addr); if (!kw->v_addr) return -ENOMEM; @@ -159,7 +159,7 @@ int iwl_kw_alloc(struct iwl_priv *priv) void iwl_kw_free(struct iwl_priv *priv) { struct pci_dev *dev = priv->pci_dev; - struct iwl4965_kw *kw = &priv->kw; + struct iwl_kw *kw = &priv->kw; if (kw->v_addr) { pci_free_consistent(dev, kw->size, kw->v_addr, kw->dma_addr); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 77428db6a21..83fe0cbf6ae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -105,7 +105,7 @@ struct iwl_lib_ops { void (*free_shared_mem)(struct iwl_priv *priv); int (*shared_mem_rx_idx)(struct iwl_priv *priv); void (*txq_update_byte_cnt_tbl)(struct iwl_priv *priv, - struct iwl4965_tx_queue *txq, + struct iwl_tx_queue *txq, u16 byte_cnt); /* setup Rx handler */ void (*rx_handler_setup)(struct iwl_priv *priv); @@ -207,7 +207,7 @@ void iwl_rx_allocate(struct iwl_priv *priv); ******************************************************/ int iwl_txq_ctx_reset(struct iwl_priv *priv); /* FIXME: remove when free Tx is fully merged into iwlcore */ -int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl4965_tx_queue *txq); +int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); void iwl_hw_txq_ctx_free(struct iwl_priv *priv); /***************************************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 1683bee800d..5dccc5a8fa9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -124,7 +124,7 @@ struct iwl4965_tx_info { }; /** - * struct iwl4965_tx_queue - Tx Queue for DMA + * struct iwl_tx_queue - Tx Queue for DMA * @q: generic Rx/Tx queue descriptor * @bd: base of circular buffer of TFDs * @cmd: array of command/Tx buffers @@ -136,7 +136,7 @@ struct iwl4965_tx_info { * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame * descriptors) and required locking structures. */ -struct iwl4965_tx_queue { +struct iwl_tx_queue { struct iwl4965_queue q; struct iwl_tfd_frame *bd; struct iwl_cmd *cmd; @@ -729,7 +729,7 @@ extern void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio); * Forward declare iwl-4965.c functions for iwl-base.c */ extern int iwl4965_tx_queue_update_wr_ptr(struct iwl_priv *priv, - struct iwl4965_tx_queue *txq, + struct iwl_tx_queue *txq, u16 byte_cnt); extern void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap); @@ -761,9 +761,9 @@ static inline void iwl4965_init_ht_hw_capab(const struct iwl_priv *priv, #endif /*CONFIG_IWL4965_HT */ /* Structures, enum, and defines specific to the 4965 */ -#define IWL4965_KW_SIZE 0x1000 /*4k */ +#define IWL_KW_SIZE 0x1000 /*4k */ -struct iwl4965_kw { +struct iwl_kw { dma_addr_t dma_addr; void *v_addr; size_t size; @@ -1061,9 +1061,9 @@ struct iwl_priv { /* Rx and Tx DMA processing queues */ struct iwl_rx_queue rxq; - struct iwl4965_tx_queue txq[IWL_MAX_NUM_QUEUES]; + struct iwl_tx_queue txq[IWL_MAX_NUM_QUEUES]; unsigned long txq_ctx_active_msk; - struct iwl4965_kw kw; /* keep warm address */ + struct iwl_kw kw; /* keep warm address */ u32 scd_base_addr; /* scheduler sram base address */ unsigned long status; diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index ade247e6310..a1e03ccd514 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -41,7 +41,7 @@ * Does NOT advance any TFD circular buffer read/write indexes * Does NOT free the TFD itself (which is within circular buffer) */ -int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl4965_tx_queue *txq) +int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) { struct iwl_tfd_frame *bd_tmp = (struct iwl_tfd_frame *)&txq->bd[0]; struct iwl_tfd_frame *bd = &bd_tmp[txq->q.read_ptr]; @@ -103,8 +103,7 @@ EXPORT_SYMBOL(iwl_hw_txq_free_tfd); * Free all buffers. * 0-fill, but do not free "txq" descriptor structure. */ -static void iwl_tx_queue_free(struct iwl_priv *priv, - struct iwl4965_tx_queue *txq) +static void iwl_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq) { struct iwl4965_queue *q = &txq->q; struct pci_dev *dev = priv->pci_dev; @@ -191,7 +190,7 @@ static int iwl_queue_init(struct iwl_priv *priv, struct iwl4965_queue *q, * iwl_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue */ static int iwl_tx_queue_alloc(struct iwl_priv *priv, - struct iwl4965_tx_queue *txq, u32 id) + struct iwl_tx_queue *txq, u32 id) { struct pci_dev *dev = priv->pci_dev; @@ -238,7 +237,7 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv, * channels supported in hardware. */ static int iwl_hw_tx_queue_init(struct iwl_priv *priv, - struct iwl4965_tx_queue *txq) + struct iwl_tx_queue *txq) { int rc; unsigned long flags; @@ -270,7 +269,7 @@ static int iwl_hw_tx_queue_init(struct iwl_priv *priv, * iwl_tx_queue_init - Allocate and initialize one tx/cmd queue */ static int iwl_tx_queue_init(struct iwl_priv *priv, - struct iwl4965_tx_queue *txq, + struct iwl_tx_queue *txq, int slots_num, u32 txq_id) { struct pci_dev *dev = priv->pci_dev; diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 09f2a6383d2..45bbce7f66a 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -54,7 +54,7 @@ #include "iwl-calib.h" static int iwl4965_tx_queue_update_write_ptr(struct iwl_priv *priv, - struct iwl4965_tx_queue *txq); + struct iwl_tx_queue *txq); /****************************************************************************** * @@ -347,7 +347,7 @@ u8 iwl4965_add_station_flags(struct iwl_priv *priv, const u8 *addr, */ int iwl4965_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) { - struct iwl4965_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; + struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; struct iwl4965_queue *q = &txq->q; struct iwl_tfd_frame *tfd; u32 *control_flags; @@ -1767,7 +1767,7 @@ static int iwl4965_tx_skb(struct iwl_priv *priv, struct iwl_tfd_frame *tfd; u32 *control_flags; int txq_id = ctl->queue; - struct iwl4965_tx_queue *txq = NULL; + struct iwl_tx_queue *txq = NULL; struct iwl4965_queue *q = NULL; dma_addr_t phys_addr; dma_addr_t txcmd_phys; @@ -2331,7 +2331,7 @@ static void iwl4965_txstatus_to_ieee(struct iwl_priv *priv, */ int iwl4965_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) { - struct iwl4965_tx_queue *txq = &priv->txq[txq_id]; + struct iwl_tx_queue *txq = &priv->txq[txq_id]; struct iwl4965_queue *q = &txq->q; int nfreed = 0; @@ -2531,7 +2531,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, u16 sequence = le16_to_cpu(pkt->hdr.sequence); int txq_id = SEQ_TO_QUEUE(sequence); int index = SEQ_TO_INDEX(sequence); - struct iwl4965_tx_queue *txq = &priv->txq[txq_id]; + struct iwl_tx_queue *txq = &priv->txq[txq_id]; struct ieee80211_tx_status *tx_status; struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; u32 status = le32_to_cpu(tx_resp->status); @@ -3273,7 +3273,7 @@ int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm) * iwl4965_tx_queue_update_write_ptr - Send new write index to hardware */ static int iwl4965_tx_queue_update_write_ptr(struct iwl_priv *priv, - struct iwl4965_tx_queue *txq) + struct iwl_tx_queue *txq) { u32 reg = 0; int rc = 0; @@ -5783,7 +5783,7 @@ static int iwl4965_mac_get_tx_stats(struct ieee80211_hw *hw, { struct iwl_priv *priv = hw->priv; int i, avail; - struct iwl4965_tx_queue *txq; + struct iwl_tx_queue *txq; struct iwl4965_queue *q; unsigned long flags; -- cgit v1.2.3 From 1b73af8284c3fcbb65eefb9141237b7e45cedd21 Mon Sep 17 00:00:00 2001 From: Ron Rindjunsky Date: Mon, 5 May 2008 10:22:51 +0800 Subject: iwlwifi: fix spinlock used before initialized The patch fixes spinlock priv->lock (apm_ops.init) is used before it has been initialized. Signed-off-by: Ron Rindjunsky Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-4965.c | 3 --- drivers/net/wireless/iwlwifi/iwl-core.c | 3 +-- 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 126ecf7023e..0b441383050 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -489,10 +489,8 @@ static int iwl4965_disable_tx_fifo(struct iwl_priv *priv) static int iwl4965_apm_init(struct iwl_priv *priv) { - unsigned long flags; int ret = 0; - spin_lock_irqsave(&priv->lock, flags); iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); @@ -524,7 +522,6 @@ static int iwl4965_apm_init(struct iwl_priv *priv) iwl_release_nic_access(priv); out: - spin_unlock_irqrestore(&priv->lock, flags); return ret; } diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index aab0ee6d8af..7759e63b2bc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -174,9 +174,8 @@ int iwl_hw_nic_init(struct iwl_priv *priv) int ret; /* nic_init */ - priv->cfg->ops->lib->apm_ops.init(priv); - spin_lock_irqsave(&priv->lock, flags); + priv->cfg->ops->lib->apm_ops.init(priv); iwl_write32(priv, CSR_INT_COALESCING, 512 / 32); spin_unlock_irqrestore(&priv->lock, flags); -- cgit v1.2.3 From 5d9276daa4c489e9c37c0f0cda915ece632f3cf1 Mon Sep 17 00:00:00 2001 From: Paulius Zaleckas Date: Mon, 5 May 2008 22:38:34 +0300 Subject: airo: use netstats in net_device structure Use net_device_stats from net_device structure instead of local. Changed airo_read_stats function parameter to net_device. Signed-off-by: Paulius Zaleckas Signed-off-by: John W. Linville --- drivers/net/wireless/airo.c | 57 +++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 45f47c1c0a3..8a78283e860 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -1148,7 +1148,6 @@ static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm); static void airo_networks_free(struct airo_info *ai); struct airo_info { - struct net_device_stats stats; struct net_device *dev; struct list_head dev_list; /* Note, we can have MAX_FIDS outstanding. FIDs are 16-bits, so we @@ -1924,7 +1923,7 @@ static int mpi_start_xmit(struct sk_buff *skb, struct net_device *dev) { if (npacks >= MAXTXQ - 1) { netif_stop_queue (dev); if (npacks > MAXTXQ) { - ai->stats.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; return 1; } skb_queue_tail (&ai->txq, skb); @@ -2044,13 +2043,13 @@ static void get_tx_error(struct airo_info *ai, s32 fid) bap_read(ai, &status, 2, BAP0); } if (le16_to_cpu(status) & 2) /* Too many retries */ - ai->stats.tx_aborted_errors++; + ai->dev->stats.tx_aborted_errors++; if (le16_to_cpu(status) & 4) /* Transmit lifetime exceeded */ - ai->stats.tx_heartbeat_errors++; + ai->dev->stats.tx_heartbeat_errors++; if (le16_to_cpu(status) & 8) /* Aid fail */ { } if (le16_to_cpu(status) & 0x10) /* MAC disabled */ - ai->stats.tx_carrier_errors++; + ai->dev->stats.tx_carrier_errors++; if (le16_to_cpu(status) & 0x20) /* Association lost */ { } /* We produce a TXDROP event only for retry or lifetime @@ -2102,7 +2101,7 @@ static void airo_end_xmit(struct net_device *dev) { for (; i < MAX_FIDS / 2 && (priv->fids[i] & 0xffff0000); i++); } else { priv->fids[fid] &= 0xffff; - priv->stats.tx_window_errors++; + dev->stats.tx_window_errors++; } if (i < MAX_FIDS / 2) netif_wake_queue(dev); @@ -2128,7 +2127,7 @@ static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) { netif_stop_queue(dev); if (i == MAX_FIDS / 2) { - priv->stats.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; return 1; } } @@ -2167,7 +2166,7 @@ static void airo_end_xmit11(struct net_device *dev) { for (; i < MAX_FIDS && (priv->fids[i] & 0xffff0000); i++); } else { priv->fids[fid] &= 0xffff; - priv->stats.tx_window_errors++; + dev->stats.tx_window_errors++; } if (i < MAX_FIDS) netif_wake_queue(dev); @@ -2199,7 +2198,7 @@ static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) { netif_stop_queue(dev); if (i == MAX_FIDS) { - priv->stats.tx_fifo_errors++; + dev->stats.tx_fifo_errors++; return 1; } } @@ -2219,8 +2218,9 @@ static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) { return 0; } -static void airo_read_stats(struct airo_info *ai) +static void airo_read_stats(struct net_device *dev) { + struct airo_info *ai = dev->priv; StatsRid stats_rid; __le32 *vals = stats_rid.vals; @@ -2232,23 +2232,24 @@ static void airo_read_stats(struct airo_info *ai) readStatsRid(ai, &stats_rid, RID_STATS, 0); up(&ai->sem); - ai->stats.rx_packets = le32_to_cpu(vals[43]) + le32_to_cpu(vals[44]) + + dev->stats.rx_packets = le32_to_cpu(vals[43]) + le32_to_cpu(vals[44]) + le32_to_cpu(vals[45]); - ai->stats.tx_packets = le32_to_cpu(vals[39]) + le32_to_cpu(vals[40]) + + dev->stats.tx_packets = le32_to_cpu(vals[39]) + le32_to_cpu(vals[40]) + le32_to_cpu(vals[41]); - ai->stats.rx_bytes = le32_to_cpu(vals[92]); - ai->stats.tx_bytes = le32_to_cpu(vals[91]); - ai->stats.rx_errors = le32_to_cpu(vals[0]) + le32_to_cpu(vals[2]) + + dev->stats.rx_bytes = le32_to_cpu(vals[92]); + dev->stats.tx_bytes = le32_to_cpu(vals[91]); + dev->stats.rx_errors = le32_to_cpu(vals[0]) + le32_to_cpu(vals[2]) + le32_to_cpu(vals[3]) + le32_to_cpu(vals[4]); - ai->stats.tx_errors = le32_to_cpu(vals[42]) + ai->stats.tx_fifo_errors; - ai->stats.multicast = le32_to_cpu(vals[43]); - ai->stats.collisions = le32_to_cpu(vals[89]); + dev->stats.tx_errors = le32_to_cpu(vals[42]) + + dev->stats.tx_fifo_errors; + dev->stats.multicast = le32_to_cpu(vals[43]); + dev->stats.collisions = le32_to_cpu(vals[89]); /* detailed rx_errors: */ - ai->stats.rx_length_errors = le32_to_cpu(vals[3]); - ai->stats.rx_crc_errors = le32_to_cpu(vals[4]); - ai->stats.rx_frame_errors = le32_to_cpu(vals[2]); - ai->stats.rx_fifo_errors = le32_to_cpu(vals[0]); + dev->stats.rx_length_errors = le32_to_cpu(vals[3]); + dev->stats.rx_crc_errors = le32_to_cpu(vals[4]); + dev->stats.rx_frame_errors = le32_to_cpu(vals[2]); + dev->stats.rx_fifo_errors = le32_to_cpu(vals[0]); } static struct net_device_stats *airo_get_stats(struct net_device *dev) @@ -2261,10 +2262,10 @@ static struct net_device_stats *airo_get_stats(struct net_device *dev) set_bit(JOB_STATS, &local->jobs); wake_up_interruptible(&local->thr_wait); } else - airo_read_stats(local); + airo_read_stats(dev); } - return &local->stats; + return &dev->stats; } static void airo_set_promisc(struct airo_info *ai) { @@ -3092,7 +3093,7 @@ static int airo_thread(void *data) { else if (test_bit(JOB_XMIT11, &ai->jobs)) airo_end_xmit11(dev); else if (test_bit(JOB_STATS, &ai->jobs)) - airo_read_stats(ai); + airo_read_stats(dev); else if (test_bit(JOB_WSTATS, &ai->jobs)) airo_read_wireless_stats(ai); else if (test_bit(JOB_PROMISC, &ai->jobs)) @@ -3288,7 +3289,7 @@ static irqreturn_t airo_interrupt(int irq, void *dev_id) skb = dev_alloc_skb( len + hdrlen + 2 + 2 ); if ( !skb ) { - apriv->stats.rx_dropped++; + dev->stats.rx_dropped++; goto badrx; } skb_reserve(skb, 2); /* This way the IP header is aligned */ @@ -3556,7 +3557,7 @@ static void mpi_receive_802_3(struct airo_info *ai) skb = dev_alloc_skb(len); if (!skb) { - ai->stats.rx_dropped++; + ai->dev->stats.rx_dropped++; goto badrx; } buffer = skb_put(skb,len); @@ -3649,7 +3650,7 @@ void mpi_receive_802_11 (struct airo_info *ai) skb = dev_alloc_skb( len + hdrlen + 2 ); if ( !skb ) { - ai->stats.rx_dropped++; + ai->dev->stats.rx_dropped++; goto badrx; } buffer = (u16*)skb_put (skb, len + hdrlen); -- cgit v1.2.3 From 8cf769c6dcb7b83d380f20d2873ac20ec7a734b1 Mon Sep 17 00:00:00 2001 From: Ester Kummer Date: Tue, 6 May 2008 11:05:11 +0800 Subject: iwlwifi: move debug_level to sysfs/bus/pci/devices This patch ports the debug_level from sysfs/bus/pci/drivers/iwl4965 to /sys/class/net/wlanX/device/debug_level Signed-off-by: Ester Kummer Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Kconfig | 4 ++-- drivers/net/wireless/iwlwifi/iwl-core.c | 5 ----- drivers/net/wireless/iwlwifi/iwl-debug.h | 1 - drivers/net/wireless/iwlwifi/iwl4965-base.c | 31 ++++++++++++++--------------- 4 files changed, 17 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index cc0006900b3..193e48f3ed5 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -97,13 +97,13 @@ config IWLWIFI_DEBUG control which debug output is sent to the kernel log by setting the value in - /sys/bus/pci/drivers/${DRIVER}/debug_level + /sys/class/net/wlan0/device/debug_level This entry will only exist if this option is enabled. To set a value, simply echo an 8-byte hex value to the same file: - % echo 0x43fff > /sys/bus/pci/drivers/${DRIVER}/debug_level + % echo 0x43fff > /sys/class/net/wlan0/device/debug_level You can find the list of debug mask values in: drivers/net/wireless/iwlwifi/iwl-4965-debug.h diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 7759e63b2bc..27e56b89d94 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -46,11 +46,6 @@ MODULE_VERSION(IWLWIFI_VERSION); MODULE_AUTHOR(DRV_COPYRIGHT); MODULE_LICENSE("GPL"); -#ifdef CONFIG_IWLWIFI_DEBUG -u32 iwl_debug_level; -EXPORT_SYMBOL(iwl_debug_level); -#endif - #define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \ [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ IWL_RATE_SISO_##s##M_PLCP, \ diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 14d95dd0e14..2f24594c5fe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -30,7 +30,6 @@ #define __iwl_debug_h__ #ifdef CONFIG_IWLWIFI_DEBUG -extern u32 iwl_debug_level; #define IWL_DEBUG(level, fmt, args...) \ do { if (priv->debug_level & (level)) \ dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \ diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 45bbce7f66a..7902d90d58c 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -5963,13 +5963,18 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk * See the level definitions in iwl for details. */ -static ssize_t show_debug_level(struct device_driver *d, char *buf) +static ssize_t show_debug_level(struct device *d, + struct device_attribute *attr, char *buf) { - return sprintf(buf, "0x%08X\n", iwl_debug_level); + struct iwl_priv *priv = d->driver_data; + + return sprintf(buf, "0x%08X\n", priv->debug_level); } -static ssize_t store_debug_level(struct device_driver *d, +static ssize_t store_debug_level(struct device *d, + struct device_attribute *attr, const char *buf, size_t count) { + struct iwl_priv *priv = d->driver_data; char *p = (char *)buf; u32 val; @@ -5978,13 +5983,14 @@ static ssize_t store_debug_level(struct device_driver *d, printk(KERN_INFO DRV_NAME ": %s is not in hex or decimal form.\n", buf); else - iwl_debug_level = val; + priv->debug_level = val; return strnlen(buf, count); } -static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, - show_debug_level, store_debug_level); +static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, + show_debug_level, store_debug_level); + #endif /* CONFIG_IWLWIFI_DEBUG */ @@ -6431,6 +6437,9 @@ static struct attribute *iwl4965_sysfs_entries[] = { &dev_attr_status.attr, &dev_attr_temperature.attr, &dev_attr_tx_power.attr, +#ifdef CONFIG_IWLWIFI_DEBUG + &dev_attr_debug_level.attr, +#endif NULL }; @@ -6817,13 +6826,6 @@ static int __init iwl4965_init(void) IWL_ERROR("Unable to initialize PCI module\n"); goto error_register; } -#ifdef CONFIG_IWLWIFI_DEBUG - ret = driver_create_file(&iwl_driver.driver, &driver_attr_debug_level); - if (ret) { - IWL_ERROR("Unable to create driver sysfs file\n"); - goto error_debug; - } -#endif return ret; @@ -6838,9 +6840,6 @@ error_register: static void __exit iwl4965_exit(void) { -#ifdef CONFIG_IWLWIFI_DEBUG - driver_remove_file(&iwl_driver.driver, &driver_attr_debug_level); -#endif pci_unregister_driver(&iwl_driver); iwl4965_rate_control_unregister(); } -- cgit v1.2.3 From f3d67999348776638644fd0035ee465261cc8c68 Mon Sep 17 00:00:00 2001 From: Ester Kummer Date: Tue, 6 May 2008 11:05:12 +0800 Subject: iwlwifi: update levels of debug prints This patch updates the levels of debug prints, leaving only one level in each debug print. It was anoying and caused unnecessary prints on hot path. Signed-off-by: Ester Kummer Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl4965-base.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 7902d90d58c..901d9cf9ad7 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -2715,8 +2715,8 @@ static void iwl4965_rx_spectrum_measure_notif(struct iwl_priv *priv, struct iwl4965_spectrum_notification *report = &(pkt->u.spectrum_notif); if (!report->state) { - IWL_DEBUG(IWL_DL_11H | IWL_DL_INFO, - "Spectrum Measure Notification: Start\n"); + IWL_DEBUG(IWL_DL_11H, + "Spectrum Measure Notification: Start\n"); return; } @@ -3100,7 +3100,7 @@ void iwl_rx_handle(struct iwl_priv *priv) /* Rx interrupt, but nothing sent from uCode */ if (i == r) - IWL_DEBUG(IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d\n", r, i); + IWL_DEBUG(IWL_DL_RX, "r = %d, i = %d\n", r, i); if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2)) fill_rx = 1; @@ -3137,13 +3137,12 @@ void iwl_rx_handle(struct iwl_priv *priv) * handle those that need handling via function in * rx_handlers table. See iwl4965_setup_rx_handlers() */ if (priv->rx_handlers[pkt->hdr.cmd]) { - IWL_DEBUG(IWL_DL_HOST_COMMAND | IWL_DL_RX | IWL_DL_ISR, - "r = %d, i = %d, %s, 0x%02x\n", r, i, - get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); + IWL_DEBUG(IWL_DL_RX, "r = %d, i = %d, %s, 0x%02x\n", r, + i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); priv->rx_handlers[pkt->hdr.cmd] (priv, rxb); } else { /* No handling needed */ - IWL_DEBUG(IWL_DL_HOST_COMMAND | IWL_DL_RX | IWL_DL_ISR, + IWL_DEBUG(IWL_DL_RX, "r %d i %d No handler needed for %s, 0x%02x\n", r, i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); @@ -3562,7 +3561,7 @@ static void iwl4965_irq_handle_error(struct iwl_priv *priv) clear_bit(STATUS_READY, &priv->status); if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) { - IWL_DEBUG(IWL_DL_INFO | IWL_DL_FW_ERRORS, + IWL_DEBUG(IWL_DL_FW_ERRORS, "Restarting adapter due to uCode error.\n"); if (iwl_is_associated(priv)) { @@ -3670,8 +3669,7 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv) CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) hw_rf_kill = 1; - IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL | IWL_DL_ISR, - "RF_KILL bit toggled to %s.\n", + IWL_DEBUG(IWL_DL_RF_KILL, "RF_KILL bit toggled to %s.\n", hw_rf_kill ? "disable radio":"enable radio"); /* Queue restart only if RF_KILL switch was set to "kill" @@ -4516,7 +4514,7 @@ static void iwl4965_bg_rf_kill(struct work_struct *work) mutex_lock(&priv->mutex); if (!iwl_is_rfkill(priv)) { - IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL, + IWL_DEBUG(IWL_DL_RF_KILL, "HW and/or SW RF Kill no longer active, restarting " "device\n"); if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) @@ -4570,9 +4568,9 @@ static void iwl4965_bg_scan_check(struct work_struct *data) mutex_lock(&priv->mutex); if (test_bit(STATUS_SCANNING, &priv->status) || test_bit(STATUS_SCAN_ABORTING, &priv->status)) { - IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN, - "Scan completion watchdog resetting adapter (%dms)\n", - jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG)); + IWL_DEBUG(IWL_DL_SCAN, "Scan completion watchdog resetting " + "adapter (%dms)\n", + jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG)); if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) iwl4965_send_scan_abort(priv); @@ -4973,7 +4971,7 @@ static void iwl4965_bg_scan_completed(struct work_struct *work) struct iwl_priv *priv = container_of(work, struct iwl_priv, scan_completed); - IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN, "SCAN complete scan\n"); + IWL_DEBUG(IWL_DL_SCAN, "SCAN complete scan\n"); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; @@ -6830,7 +6828,6 @@ static int __init iwl4965_init(void) return ret; #ifdef CONFIG_IWLWIFI_DEBUG -error_debug: pci_unregister_driver(&iwl_driver); #endif error_register: -- cgit v1.2.3 From bc6f59bc9b2f494ca1b018622f1fbd25933bc920 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 6 May 2008 11:05:13 +0800 Subject: iwlwifi: add device sysfs version entry This patch adds sysfs version file that displays ucode version and type. Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl4965-base.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 901d9cf9ad7..7708b19ca0c 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -5993,6 +5993,25 @@ static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, #endif /* CONFIG_IWLWIFI_DEBUG */ +static ssize_t show_version(struct device *d, + struct device_attribute *attr, char *buf) +{ + struct iwl_priv *priv = d->driver_data; + struct iwl4965_alive_resp *palive = &priv->card_alive; + + if (palive->is_valid) + return sprintf(buf, "fw version: 0x%01X.0x%01X.0x%01X.0x%01X\n" + "fw type: 0x%01X 0x%01X\n", + palive->ucode_major, palive->ucode_minor, + palive->sw_rev[0], palive->sw_rev[1], + palive->ver_type, palive->ver_subtype); + + else + return sprintf(buf, "fw not loaded\n"); +} + +static DEVICE_ATTR(version, S_IWUSR | S_IRUGO, show_version, NULL); + static ssize_t show_temperature(struct device *d, struct device_attribute *attr, char *buf) { @@ -6438,6 +6457,7 @@ static struct attribute *iwl4965_sysfs_entries[] = { #ifdef CONFIG_IWLWIFI_DEBUG &dev_attr_debug_level.attr, #endif + &dev_attr_version.attr, NULL }; -- cgit v1.2.3 From 3a1081e84b0008de8171a95f2c0fff8489af4300 Mon Sep 17 00:00:00 2001 From: Ester Kummer Date: Tue, 6 May 2008 11:05:14 +0800 Subject: iwlwifi: adding parameter of fw_restart This patch adds a module parameter of fw_restart which determine if the uCode will be restarted or not in case of error. Signed-off-by: Ester Kummer Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-4965.c | 4 +++- drivers/net/wireless/iwlwifi/iwl-5000.c | 5 +++-- drivers/net/wireless/iwlwifi/iwl-core.h | 1 + drivers/net/wireless/iwlwifi/iwl4965-base.c | 4 +++- 4 files changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 0b441383050..b7036e01145 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -50,6 +50,7 @@ static struct iwl_mod_params iwl4965_mod_params = { .num_of_queues = IWL49_NUM_QUEUES, .enable_qos = 1, .amsdu_size_8K = 1, + .restart_fw = 1, /* the rest are 0 by default */ }; @@ -3892,4 +3893,5 @@ module_param_named(qos_enable, iwl4965_mod_params.enable_qos, int, 0444); MODULE_PARM_DESC(qos_enable, "enable all QoS functionality"); module_param_named(amsdu_size_8K, iwl4965_mod_params.amsdu_size_8K, int, 0444); MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size"); - +module_param_named(fw_restart4965, iwl4965_mod_params.restart_fw, int, 0444); +MODULE_PARM_DESC(fw_restart4965, "restart firmware in case of error"); diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 43b4d20467d..b5e28b81179 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -510,6 +510,7 @@ static struct iwl_mod_params iwl50_mod_params = { .num_of_queues = IWL50_NUM_QUEUES, .enable_qos = 1, .amsdu_size_8K = 1, + .restart_fw = 1, /* the rest are 0 by default */ }; @@ -555,5 +556,5 @@ module_param_named(qos_enable50, iwl50_mod_params.enable_qos, int, 0444); MODULE_PARM_DESC(qos_enable50, "enable all 50XX QoS functionality"); module_param_named(amsdu_size_8K50, iwl50_mod_params.amsdu_size_8K, int, 0444); MODULE_PARM_DESC(amsdu_size_8K50, "enable 8K amsdu size in 50XX series"); - - +module_param_named(fw_restart50, iwl50_mod_params.restart_fw, int, 0444); +MODULE_PARM_DESC(fw_restart50, "restart firmware in case of error"); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 83fe0cbf6ae..e139c8ffa9a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -149,6 +149,7 @@ struct iwl_mod_params { int enable_qos; /* def: 1 = use quality of service */ int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */ int antenna; /* def: 0 = both antennas (use diversity) */ + int restart_fw; /* def: 1 = restart firmware */ }; struct iwl_cfg { diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 7708b19ca0c..55ca752ae9e 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -3569,7 +3569,8 @@ static void iwl4965_irq_handle_error(struct iwl_priv *priv) sizeof(priv->recovery_rxon)); priv->error_recovering = 1; } - queue_work(priv->workqueue, &priv->restart); + if (priv->cfg->mod_params->restart_fw) + queue_work(priv->workqueue, &priv->restart); } } @@ -6847,6 +6848,7 @@ static int __init iwl4965_init(void) return ret; + #ifdef CONFIG_IWLWIFI_DEBUG pci_unregister_driver(&iwl_driver); #endif -- cgit v1.2.3 From 15dbf1b7b7b6ba6e5159dde60e111f617b2c54ea Mon Sep 17 00:00:00 2001 From: Bill Moss Date: Tue, 6 May 2008 11:05:15 +0800 Subject: iwl3945: do not delay hardware scan if it is a direct scan iwl3945 <---> mac80211 <----> wpa_supplicant <---> NetworkManager When a hardware scan is completed and another scan is requested in less than two seconds, iwlwifi will not do the second scan and will pass the error code -EAGAIN back to mac80211 where it quickly dies. The error code is not passed along to the calling program wpa_supplicant. After a timeout, wpa_supplicant will just give up but it will not know why the scan failed. This is a weakness in the design. I ran into this issue when I was trying to figure out why it takes more an a minute for NetworkManager to connect after Networking has been disabled and then re-enabled. I found a good deal of unnecessary work being done because mac80211 requests authentication when the interface is not configured, the ANY mode. I created an experimental passive (NOTANY) mode for mac80211 to eliminate this case. Then NetworkManager became so fast that I ran into the iwlwifi 2 second delay next scan issue which we are discussing. The patch resolves the problem by bypassing the delay if the scan request is a direct scan. It should do less harm to the hardware. Signed-off-by: Bill Moss Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl3945-base.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index f021eba41e6..4baa185ba50 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -7087,9 +7087,10 @@ static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) rc = -EAGAIN; goto out_unlock; } - /* if we just finished scan ask for delay */ - if (priv->last_scan_jiffies && time_after(priv->last_scan_jiffies + - IWL_DELAY_NEXT_SCAN, jiffies)) { + /* if we just finished scan ask for delay for a broadcast scan */ + if ((len == 0) && priv->last_scan_jiffies && + time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, + jiffies)) { rc = -EAGAIN; goto out_unlock; } -- cgit v1.2.3 From 06a5223d68a7c48bf72a05aad533ea0e8a3453be Mon Sep 17 00:00:00 2001 From: Paulius Zaleckas Date: Tue, 6 May 2008 14:44:08 +0300 Subject: arlan: use netstats in net_device structure Use net_device_stats from net_device structure instead of local. Signed-off-by: Paulius Zaleckas Signed-off-by: John W. Linville --- drivers/net/wireless/arlan-main.c | 40 +++++++++++++++++++-------------------- drivers/net/wireless/arlan.h | 1 - 2 files changed, 20 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/arlan-main.c b/drivers/net/wireless/arlan-main.c index dbdfc9e39d2..dec5e874a54 100644 --- a/drivers/net/wireless/arlan-main.c +++ b/drivers/net/wireless/arlan-main.c @@ -125,7 +125,7 @@ static inline int arlan_drop_tx(struct net_device *dev) { struct arlan_private *priv = netdev_priv(dev); - priv->stats.tx_errors++; + dev->stats.tx_errors++; if (priv->Conf->tx_delay_ms) { priv->tx_done_delayed = jiffies + priv->Conf->tx_delay_ms * HZ / 1000 + 1; @@ -1269,7 +1269,7 @@ static void arlan_tx_done_interrupt(struct net_device *dev, int status) { IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk("arlan intr: transmit OK\n"); - priv->stats.tx_packets++; + dev->stats.tx_packets++; priv->bad = 0; priv->reset = 0; priv->retransmissions = 0; @@ -1496,7 +1496,7 @@ static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short if (skb == NULL) { printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", dev->name); - priv->stats.rx_dropped++; + dev->stats.rx_dropped++; break; } skb_reserve(skb, 2); @@ -1536,14 +1536,14 @@ static void arlan_rx_interrupt(struct net_device *dev, u_char rxStatus, u_short } netif_rx(skb); dev->last_rx = jiffies; - priv->stats.rx_packets++; - priv->stats.rx_bytes += pkt_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; } break; default: printk(KERN_ERR "arlan intr: received unknown status\n"); - priv->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; break; } ARLAN_DEBUG_EXIT("arlan_rx_interrupt"); @@ -1719,23 +1719,23 @@ static struct net_device_stats *arlan_statistics(struct net_device *dev) /* Update the statistics from the device registers. */ - READSHM(priv->stats.collisions, arlan->numReTransmissions, u_int); - READSHM(priv->stats.rx_crc_errors, arlan->numCRCErrors, u_int); - READSHM(priv->stats.rx_dropped, arlan->numFramesDiscarded, u_int); - READSHM(priv->stats.rx_fifo_errors, arlan->numRXBufferOverflows, u_int); - READSHM(priv->stats.rx_frame_errors, arlan->numReceiveFramesLost, u_int); - READSHM(priv->stats.rx_over_errors, arlan->numRXOverruns, u_int); - READSHM(priv->stats.rx_packets, arlan->numDatagramsReceived, u_int); - READSHM(priv->stats.tx_aborted_errors, arlan->numAbortErrors, u_int); - READSHM(priv->stats.tx_carrier_errors, arlan->numStatusTimeouts, u_int); - READSHM(priv->stats.tx_dropped, arlan->numDatagramsDiscarded, u_int); - READSHM(priv->stats.tx_fifo_errors, arlan->numTXUnderruns, u_int); - READSHM(priv->stats.tx_packets, arlan->numDatagramsTransmitted, u_int); - READSHM(priv->stats.tx_window_errors, arlan->numHoldOffs, u_int); + READSHM(dev->stats.collisions, arlan->numReTransmissions, u_int); + READSHM(dev->stats.rx_crc_errors, arlan->numCRCErrors, u_int); + READSHM(dev->stats.rx_dropped, arlan->numFramesDiscarded, u_int); + READSHM(dev->stats.rx_fifo_errors, arlan->numRXBufferOverflows, u_int); + READSHM(dev->stats.rx_frame_errors, arlan->numReceiveFramesLost, u_int); + READSHM(dev->stats.rx_over_errors, arlan->numRXOverruns, u_int); + READSHM(dev->stats.rx_packets, arlan->numDatagramsReceived, u_int); + READSHM(dev->stats.tx_aborted_errors, arlan->numAbortErrors, u_int); + READSHM(dev->stats.tx_carrier_errors, arlan->numStatusTimeouts, u_int); + READSHM(dev->stats.tx_dropped, arlan->numDatagramsDiscarded, u_int); + READSHM(dev->stats.tx_fifo_errors, arlan->numTXUnderruns, u_int); + READSHM(dev->stats.tx_packets, arlan->numDatagramsTransmitted, u_int); + READSHM(dev->stats.tx_window_errors, arlan->numHoldOffs, u_int); ARLAN_DEBUG_EXIT("arlan_statistics"); - return &priv->stats; + return &dev->stats; } diff --git a/drivers/net/wireless/arlan.h b/drivers/net/wireless/arlan.h index 3ed1df75900..fb3ad51a1ca 100644 --- a/drivers/net/wireless/arlan.h +++ b/drivers/net/wireless/arlan.h @@ -330,7 +330,6 @@ struct TxParam #define TX_RING_SIZE 2 /* Information that need to be kept for each board. */ struct arlan_private { - struct net_device_stats stats; struct arlan_shmem __iomem * card; struct arlan_shmem * conf; -- cgit v1.2.3 From 736bc924fe7183dd27182a9148e78f250c1637ee Mon Sep 17 00:00:00 2001 From: Paulius Zaleckas Date: Tue, 6 May 2008 23:50:30 +0300 Subject: atmel: use netstats in net_device structure Use net_device_stats from net_device structure instead of local. Kill atmel_get_stats function, because by default it is used identical internal_stats function from net/core/dev.c No need to memset stats to 0, because they are allocated by kzalloc. P.S. Someone should cleanup init_atmel_card function from unneeded initializations to 0/NULL. Out of scope for this patch. Signed-off-by: Paulius Zaleckas Signed-off-by: John W. Linville --- drivers/net/wireless/atmel.c | 46 +++++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index ef2da4023d6..f978a9d5190 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -433,7 +433,6 @@ struct atmel_private { struct net_device *dev; struct device *sys_dev; struct iw_statistics wstats; - struct net_device_stats stats; // device stats spinlock_t irqlock, timerlock; // spinlocks enum { BUS_TYPE_PCCARD, BUS_TYPE_PCI } bus_type; enum { @@ -694,9 +693,9 @@ static void tx_done_irq(struct atmel_private *priv) if (type == TX_PACKET_TYPE_DATA) { if (status == TX_STATUS_SUCCESS) - priv->stats.tx_packets++; + priv->dev->stats.tx_packets++; else - priv->stats.tx_errors++; + priv->dev->stats.tx_errors++; netif_wake_queue(priv->dev); } } @@ -792,13 +791,13 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev) if (priv->card && priv->present_callback && !(*priv->present_callback)(priv->card)) { - priv->stats.tx_errors++; + dev->stats.tx_errors++; dev_kfree_skb(skb); return 0; } if (priv->station_state != STATION_STATE_READY) { - priv->stats.tx_errors++; + dev->stats.tx_errors++; dev_kfree_skb(skb); return 0; } @@ -815,7 +814,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev) initial + 18 (+30-12) */ if (!(buff = find_tx_buff(priv, len + 18))) { - priv->stats.tx_dropped++; + dev->stats.tx_dropped++; spin_unlock_irqrestore(&priv->irqlock, flags); spin_unlock_bh(&priv->timerlock); netif_stop_queue(dev); @@ -851,7 +850,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev) /* low bit of first byte of destination tells us if broadcast */ tx_update_descriptor(priv, *(skb->data) & 0x01, len + 18, buff, TX_PACKET_TYPE_DATA); dev->trans_start = jiffies; - priv->stats.tx_bytes += len; + dev->stats.tx_bytes += len; spin_unlock_irqrestore(&priv->irqlock, flags); spin_unlock_bh(&priv->timerlock); @@ -895,7 +894,7 @@ static void fast_rx_path(struct atmel_private *priv, } if (!(skb = dev_alloc_skb(msdu_size + 14))) { - priv->stats.rx_dropped++; + priv->dev->stats.rx_dropped++; return; } @@ -908,7 +907,7 @@ static void fast_rx_path(struct atmel_private *priv, crc = crc32_le(crc, skbp + 12, msdu_size); atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + 30 + msdu_size, 4); if ((crc ^ 0xffffffff) != netcrc) { - priv->stats.rx_crc_errors++; + priv->dev->stats.rx_crc_errors++; dev_kfree_skb(skb); return; } @@ -924,8 +923,8 @@ static void fast_rx_path(struct atmel_private *priv, skb->protocol = eth_type_trans(skb, priv->dev); skb->ip_summed = CHECKSUM_NONE; netif_rx(skb); - priv->stats.rx_bytes += 12 + msdu_size; - priv->stats.rx_packets++; + priv->dev->stats.rx_bytes += 12 + msdu_size; + priv->dev->stats.rx_packets++; } /* Test to see if the packet in card memory at packet_loc has a valid CRC @@ -991,7 +990,7 @@ static void frag_rx_path(struct atmel_private *priv, crc = crc32_le(crc, &priv->rx_buf[12], msdu_size); atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4); if ((crc ^ 0xffffffff) != netcrc) { - priv->stats.rx_crc_errors++; + priv->dev->stats.rx_crc_errors++; memset(priv->frag_source, 0xff, 6); } } @@ -1009,7 +1008,7 @@ static void frag_rx_path(struct atmel_private *priv, msdu_size); atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4); if ((crc ^ 0xffffffff) != netcrc) { - priv->stats.rx_crc_errors++; + priv->dev->stats.rx_crc_errors++; memset(priv->frag_source, 0xff, 6); more_frags = 1; /* don't send broken assembly */ } @@ -1021,7 +1020,7 @@ static void frag_rx_path(struct atmel_private *priv, if (!more_frags) { /* last one */ memset(priv->frag_source, 0xff, 6); if (!(skb = dev_alloc_skb(priv->frag_len + 14))) { - priv->stats.rx_dropped++; + priv->dev->stats.rx_dropped++; } else { skb_reserve(skb, 2); memcpy(skb_put(skb, priv->frag_len + 12), @@ -1031,8 +1030,8 @@ static void frag_rx_path(struct atmel_private *priv, skb->protocol = eth_type_trans(skb, priv->dev); skb->ip_summed = CHECKSUM_NONE; netif_rx(skb); - priv->stats.rx_bytes += priv->frag_len + 12; - priv->stats.rx_packets++; + priv->dev->stats.rx_bytes += priv->frag_len + 12; + priv->dev->stats.rx_packets++; } } } else @@ -1057,7 +1056,7 @@ static void rx_done_irq(struct atmel_private *priv) if (status == 0xc1) /* determined by experiment */ priv->wstats.discard.nwid++; else - priv->stats.rx_errors++; + priv->dev->stats.rx_errors++; goto next; } @@ -1065,7 +1064,7 @@ static void rx_done_irq(struct atmel_private *priv) rx_packet_loc = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_POS_OFFSET, priv->rx_desc_head)); if (msdu_size < 30) { - priv->stats.rx_errors++; + priv->dev->stats.rx_errors++; goto next; } @@ -1123,7 +1122,7 @@ static void rx_done_irq(struct atmel_private *priv) msdu_size -= 4; crc = crc32_le(crc, (unsigned char *)&priv->rx_buf, msdu_size); if ((crc ^ 0xffffffff) != (*((u32 *)&priv->rx_buf[msdu_size]))) { - priv->stats.rx_crc_errors++; + priv->dev->stats.rx_crc_errors++; goto next; } } @@ -1250,12 +1249,6 @@ static irqreturn_t service_interrupt(int irq, void *dev_id) } } -static struct net_device_stats *atmel_get_stats(struct net_device *dev) -{ - struct atmel_private *priv = netdev_priv(dev); - return &priv->stats; -} - static struct iw_statistics *atmel_get_wireless_stats(struct net_device *dev) { struct atmel_private *priv = netdev_priv(dev); @@ -1518,8 +1511,6 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port, priv->crc_ok_cnt = priv->crc_ko_cnt = 0; } else priv->probe_crc = 0; - memset(&priv->stats, 0, sizeof(priv->stats)); - memset(&priv->wstats, 0, sizeof(priv->wstats)); priv->last_qual = jiffies; priv->last_beacon_timestamp = 0; memset(priv->frag_source, 0xff, sizeof(priv->frag_source)); @@ -1568,7 +1559,6 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port, dev->change_mtu = atmel_change_mtu; dev->set_mac_address = atmel_set_mac_address; dev->hard_start_xmit = start_tx; - dev->get_stats = atmel_get_stats; dev->wireless_handlers = (struct iw_handler_def *)&atmel_handler_def; dev->do_ioctl = atmel_ioctl; dev->irq = irq; -- cgit v1.2.3 From 84e6dc9acf6825f508feae9db6b7d695e64894e0 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Wed, 7 May 2008 11:46:02 +0200 Subject: zd1211rw: initial IBSS support this adds initial IBSS support for the zydas zd1211rw: convince driver that it can do IBSS mode. add mac80211 beacon_update callback. IBSS merge and TSF updates don't work yet, but it makes the driver usable in ad-hoc networks. Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_mac.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 69c45ca9905..ee4331229f1 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -751,6 +751,7 @@ static int zd_op_add_interface(struct ieee80211_hw *hw, case IEEE80211_IF_TYPE_MNTR: case IEEE80211_IF_TYPE_MESH_POINT: case IEEE80211_IF_TYPE_STA: + case IEEE80211_IF_TYPE_IBSS: mac->type = conf->type; break; default: @@ -781,7 +782,8 @@ static int zd_op_config_interface(struct ieee80211_hw *hw, struct zd_mac *mac = zd_hw_mac(hw); int associated; - if (mac->type == IEEE80211_IF_TYPE_MESH_POINT) { + if (mac->type == IEEE80211_IF_TYPE_MESH_POINT || + mac->type == IEEE80211_IF_TYPE_IBSS) { associated = true; if (conf->beacon) { zd_mac_config_beacon(hw, conf->beacon); @@ -941,6 +943,18 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw, } } +static int zd_op_beacon_update(struct ieee80211_hw *hw, + struct sk_buff *skb, + struct ieee80211_tx_control *ctl) +{ + struct zd_mac *mac = zd_hw_mac(hw); + zd_mac_config_beacon(hw, skb); + kfree_skb(skb); + zd_set_beacon_interval(&mac->chip, BCN_MODE_IBSS | + hw->conf.beacon_int); + return 0; +} + static const struct ieee80211_ops zd_ops = { .tx = zd_op_tx, .start = zd_op_start, @@ -951,6 +965,7 @@ static const struct ieee80211_ops zd_ops = { .config_interface = zd_op_config_interface, .configure_filter = zd_op_configure_filter, .bss_info_changed = zd_op_bss_info_changed, + .beacon_update = zd_op_beacon_update, }; struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) -- cgit v1.2.3 From 566bfe5a8bcde13188a356f77666f8115813cf31 Mon Sep 17 00:00:00 2001 From: Bruno Randolf Date: Thu, 8 May 2008 19:15:40 +0200 Subject: mac80211: use hardware flags for signal/noise units trying to clean up the signal/noise code. the previous code in mac80211 had confusing names for the related variables, did not have much definition of what units of signal and noise were provided and used implicit mechanisms from the wireless extensions. this patch introduces hardware capability flags to let the hardware specify clearly if it can provide signal and noise level values and which units it can provide. this also anticipates possible new units like RCPI in the future. for signal: IEEE80211_HW_SIGNAL_UNSPEC - unspecified, unknown, hw specific IEEE80211_HW_SIGNAL_DB - dB difference to unspecified reference point IEEE80211_HW_SIGNAL_DBM - dBm, difference to 1mW for noise we currently only have dBm: IEEE80211_HW_NOISE_DBM - dBm, difference to 1mW if IEEE80211_HW_SIGNAL_UNSPEC or IEEE80211_HW_SIGNAL_DB is used the driver has to provide the maximum value (max_signal) it reports in order for applications to make sense of the signal values. i tried my best to find out for each driver what it can provide and update it but i'm not sure (?) for some of them and used the more conservative guess in doubt. this can be fixed easily after this patch has been merged by changing the hardware flags of the driver. DRIVER SIGNAL MAX NOISE QUAL ----------------------------------------------------------------- adm8211 unspec(?) 100 n/a missing at76_usb unspec(?) (?) unused missing ath5k dBm dBm percent rssi b43legacy dBm dBm percent jssi(?) b43 dBm dBm percent jssi(?) iwl-3945 dBm dBm percent snr+more iwl-4965 dBm dBm percent snr+more p54 unspec 127 n/a missing rt2x00 dBm n/a percent rssi+tx/rx frame success rt2400 dBm n/a rt2500pci dBm n/a rt2500usb dBm n/a rt61pci dBm n/a rt73usb dBm n/a rtl8180 unspec(?) 65 n/a (?) rtl8187 unspec(?) 65 (?) noise(?) zd1211 dB(?) 100 n/a percent drivers/net/wireless/ath5k/base.c: Changes-licensed-under: 3-Clause-BSD Signed-off-by: Bruno Randolf Signed-off-by: John W. Linville --- drivers/net/wireless/adm8211.c | 7 ++++--- drivers/net/wireless/ath5k/base.c | 23 +++++------------------ drivers/net/wireless/b43/main.c | 8 ++++---- drivers/net/wireless/b43/xmit.c | 5 ++--- drivers/net/wireless/b43legacy/main.c | 7 +++---- drivers/net/wireless/b43legacy/xmit.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-3945.c | 18 +++++++++--------- drivers/net/wireless/iwlwifi/iwl-4965.c | 12 ++++++------ drivers/net/wireless/iwlwifi/iwl-core.c | 16 ++++------------ drivers/net/wireless/iwlwifi/iwl3945-base.c | 15 ++++----------- drivers/net/wireless/p54/p54common.c | 7 ++++--- drivers/net/wireless/rt2x00/rt2400pci.c | 5 ++--- drivers/net/wireless/rt2x00/rt2500pci.c | 6 +++--- drivers/net/wireless/rt2x00/rt2500usb.c | 6 +++--- drivers/net/wireless/rt2x00/rt2x00dev.c | 4 ++-- drivers/net/wireless/rt2x00/rt61pci.c | 5 ++--- drivers/net/wireless/rt2x00/rt73usb.c | 5 ++--- drivers/net/wireless/rtl8180_dev.c | 9 +++++---- drivers/net/wireless/rtl8187_dev.c | 10 +++++----- drivers/net/wireless/zd1211rw/zd_mac.c | 12 ++++++------ 20 files changed, 77 insertions(+), 107 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c index d93a1de77eb..7af5d8851f6 100644 --- a/drivers/net/wireless/adm8211.c +++ b/drivers/net/wireless/adm8211.c @@ -445,9 +445,9 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev) struct ieee80211_rx_status rx_status = {0}; if (priv->pdev->revision < ADM8211_REV_CA) - rx_status.ssi = rssi; + rx_status.signal = rssi; else - rx_status.ssi = 100 - rssi; + rx_status.signal = 100 - rssi; rx_status.rate_idx = rate; @@ -1893,9 +1893,10 @@ static int __devinit adm8211_probe(struct pci_dev *pdev, dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr); /* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */ + dev->flags = IEEE80211_HW_SIGNAL_UNSPEC; dev->channel_change_time = 1000; - dev->max_rssi = 100; /* FIXME: find better value */ + dev->max_signal = 100; /* FIXME: find better value */ dev->queues = 1; /* ADM8211C supports more, maybe ADM8211B too */ diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 3201c160434..dd8adaddd7a 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c @@ -458,13 +458,11 @@ ath5k_pci_probe(struct pci_dev *pdev, /* Initialize driver private data */ SET_IEEE80211_DEV(hw, &pdev->dev); - hw->flags = IEEE80211_HW_RX_INCLUDES_FCS; + hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | + IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_NOISE_DBM; hw->extra_tx_headroom = 2; hw->channel_change_time = 5000; - /* these names are misleading */ - hw->max_rssi = -110; /* signal in dBm */ - hw->max_noise = -110; /* noise in dBm */ - hw->max_signal = 100; /* we will provide a percentage based on rssi */ sc = hw->priv; sc->hw = hw; sc->pdev = pdev; @@ -1893,20 +1891,9 @@ accept: rxs.freq = sc->curchan->center_freq; rxs.band = sc->curband->band; - /* - * signal quality: - * the names here are misleading and the usage of these - * values by iwconfig makes it even worse - */ - /* noise floor in dBm, from the last noise calibration */ rxs.noise = sc->ah->ah_noise_floor; - /* signal level in dBm */ - rxs.ssi = rxs.noise + rs.rs_rssi; - /* - * "signal" is actually displayed as Link Quality by iwconfig - * we provide a percentage based on rssi (assuming max rssi 64) - */ - rxs.signal = rs.rs_rssi * 100 / 64; + rxs.signal = rxs.noise + rs.rs_rssi; + rxs.qual = rs.rs_rssi * 100 / 64; rxs.antenna = rs.rs_antenna; rxs.rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 7c23aa8705c..fc23ba5309b 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -4466,10 +4466,10 @@ static int b43_wireless_init(struct ssb_device *dev) /* fill hw info */ hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | - IEEE80211_HW_RX_INCLUDES_FCS; - hw->max_signal = 100; - hw->max_rssi = -110; - hw->max_noise = -110; + IEEE80211_HW_RX_INCLUDES_FCS | + IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_NOISE_DBM; + hw->queues = b43_modparam_qos ? 4 : 1; SET_IEEE80211_DEV(hw, dev->dev); if (is_valid_ether_addr(sprom->et1mac)) diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index 88491947a20..afce9338d83 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c @@ -581,12 +581,11 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) // and also find out what the maximum possible value is. // Fill status.ssi and status.signal fields. } else { - status.ssi = b43_rssi_postprocess(dev, rxhdr->jssi, + status.signal = b43_rssi_postprocess(dev, rxhdr->jssi, (phystat0 & B43_RX_PHYST0_OFDM), (phystat0 & B43_RX_PHYST0_GAINCTL), (phystat3 & B43_RX_PHYST3_TRSTATE)); - /* the next line looks wrong, but is what mac80211 wants */ - status.signal = (rxhdr->jssi * 100) / B43_RX_MAX_SSI; + status.qual = (rxhdr->jssi * 100) / B43_RX_MAX_SSI; } if (phystat0 & B43_RX_PHYST0_OFDM) diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index d3820dce3c4..7755c59e080 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -3718,10 +3718,9 @@ static int b43legacy_wireless_init(struct ssb_device *dev) /* fill hw info */ hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | - IEEE80211_HW_RX_INCLUDES_FCS; - hw->max_signal = 100; - hw->max_rssi = -110; - hw->max_noise = -110; + IEEE80211_HW_RX_INCLUDES_FCS | + IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_NOISE_DBM; hw->queues = 1; /* FIXME: hardware has more queues */ SET_IEEE80211_DEV(hw, dev->dev); if (is_valid_ether_addr(sprom->et1mac)) diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index fc83dab6e2c..bed9e041d6c 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c @@ -532,12 +532,12 @@ void b43legacy_rx(struct b43legacy_wldev *dev, } } - status.ssi = b43legacy_rssi_postprocess(dev, jssi, + status.signal = b43legacy_rssi_postprocess(dev, jssi, (phystat0 & B43legacy_RX_PHYST0_OFDM), (phystat0 & B43legacy_RX_PHYST0_GAINCTL), (phystat3 & B43legacy_RX_PHYST3_TRSTATE)); status.noise = dev->stats.link_noise; - status.signal = (jssi * 100) / B43legacy_RX_MAX_SSI; + status.qual = (jssi * 100) / B43legacy_RX_MAX_SSI; /* change to support A PHY */ if (phystat0 & B43legacy_RX_PHYST0_OFDM) status.rate_idx = b43legacy_plcp_get_bitrate_idx_ofdm(plcp, false); diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 8464397f781..d7beeff2642 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -520,7 +520,7 @@ static void iwl3945_add_radiotap(struct iwl3945_priv *priv, { /* First cache any information we need before we overwrite * the information provided in the skb from the hardware */ - s8 signal = stats->ssi; + s8 signal = stats->signal; s8 noise = 0; int rate = stats->rate_idx; u64 tsf = stats->mactime; @@ -693,7 +693,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, } /* Convert 3945's rssi indicator to dBm */ - rx_status.ssi = rx_stats->rssi - IWL_RSSI_OFFSET; + rx_status.signal = rx_stats->rssi - IWL_RSSI_OFFSET; /* Set default noise value to -127 */ if (priv->last_rx_noise == 0) @@ -712,21 +712,21 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, * Calculate rx_status.signal (quality indicator in %) based on SNR. */ if (rx_stats_noise_diff) { snr = rx_stats_sig_avg / rx_stats_noise_diff; - rx_status.noise = rx_status.ssi - + rx_status.noise = rx_status.signal - iwl3945_calc_db_from_ratio(snr); - rx_status.signal = iwl3945_calc_sig_qual(rx_status.ssi, + rx_status.qual = iwl3945_calc_sig_qual(rx_status.signal, rx_status.noise); /* If noise info not available, calculate signal quality indicator (%) * using just the dBm signal level. */ } else { rx_status.noise = priv->last_rx_noise; - rx_status.signal = iwl3945_calc_sig_qual(rx_status.ssi, 0); + rx_status.qual = iwl3945_calc_sig_qual(rx_status.signal, 0); } IWL_DEBUG_STATS("Rssi %d noise %d qual %d sig_avg %d noise_diff %d\n", - rx_status.ssi, rx_status.noise, rx_status.signal, + rx_status.signal, rx_status.noise, rx_status.qual, rx_stats_sig_avg, rx_stats_noise_diff); header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); @@ -736,8 +736,8 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, IWL_DEBUG_STATS_LIMIT("[%c] %d RSSI:%d Signal:%u, Noise:%u, Rate:%u\n", network_packet ? '*' : ' ', le16_to_cpu(rx_hdr->channel), - rx_status.ssi, rx_status.ssi, - rx_status.ssi, rx_status.rate_idx); + rx_status.signal, rx_status.signal, + rx_status.noise, rx_status.rate_idx); #ifdef CONFIG_IWL3945_DEBUG if (iwl3945_debug_level & (IWL_DL_RX)) @@ -748,7 +748,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, if (network_packet) { priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp); priv->last_tsf = le64_to_cpu(rx_end->timestamp); - priv->last_rx_rssi = rx_status.ssi; + priv->last_rx_rssi = rx_status.signal; priv->last_rx_noise = rx_status.noise; } diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index b7036e01145..45cbd7789bd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2362,7 +2362,7 @@ static void iwl4965_add_radiotap(struct iwl_priv *priv, struct ieee80211_rx_status *stats, u32 ampdu_status) { - s8 signal = stats->ssi; + s8 signal = stats->signal; s8 noise = 0; int rate = stats->rate_idx; u64 tsf = stats->mactime; @@ -2963,7 +2963,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp); /* Find max signal strength (dBm) among 3 antenna/receiver chains */ - rx_status.ssi = iwl4965_calc_rssi(priv, rx_start); + rx_status.signal = iwl4965_calc_rssi(priv, rx_start); /* Meaningful noise values are available only from beacon statistics, * which are gathered only when associated, and indicate noise @@ -2972,11 +2972,11 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, if (iwl_is_associated(priv) && !test_bit(STATUS_SCANNING, &priv->status)) { rx_status.noise = priv->last_rx_noise; - rx_status.signal = iwl4965_calc_sig_qual(rx_status.ssi, + rx_status.qual = iwl4965_calc_sig_qual(rx_status.signal, rx_status.noise); } else { rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE; - rx_status.signal = iwl4965_calc_sig_qual(rx_status.ssi, 0); + rx_status.qual = iwl4965_calc_sig_qual(rx_status.signal, 0); } /* Reset beacon noise level if not associated. */ @@ -2988,7 +2988,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, iwl4965_dbg_report_frame(priv, pkt, header, 1); IWL_DEBUG_STATS_LIMIT("Rssi %d, noise %d, qual %d, TSF %llu\n", - rx_status.ssi, rx_status.noise, rx_status.signal, + rx_status.signal, rx_status.noise, rx_status.signal, (unsigned long long)rx_status.mactime); @@ -3000,7 +3000,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, network_packet = iwl4965_is_network_packet(priv, header); if (network_packet) { - priv->last_rx_rssi = rx_status.ssi; + priv->last_rx_rssi = rx_status.signal; priv->last_beacon_time = priv->ucode_beacon_time; priv->last_tsf = le64_to_cpu(rx_start->timestamp); } diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 27e56b89d94..d3cbad2bf87 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -746,18 +746,10 @@ static void iwlcore_init_hw(struct iwl_priv *priv) struct ieee80211_hw *hw = priv->hw; hw->rate_control_algorithm = "iwl-4965-rs"; - /* Tell mac80211 and its clients (e.g. Wireless Extensions) - * the range of signal quality values that we'll provide. - * Negative values for level/noise indicate that we'll provide dBm. - * For WE, at least, non-0 values here *enable* display of values - * in app (iwconfig). */ - hw->max_rssi = -20; /* signal level, negative indicates dBm */ - hw->max_noise = -20; /* noise level, negative indicates dBm */ - hw->max_signal = 100; /* link quality indication (%) */ - - /* Tell mac80211 our Tx characteristics */ - hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE; - + /* Tell mac80211 our characteristics */ + hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | + IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_NOISE_DBM; /* Default value; 4 EDCA QOS priorities */ hw->queues = 4; #ifdef CONFIG_IWL4965_HT diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 4baa185ba50..c1234ff4fc9 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -8029,17 +8029,10 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e priv->ibss_beacon = NULL; - /* Tell mac80211 and its clients (e.g. Wireless Extensions) - * the range of signal quality values that we'll provide. - * Negative values for level/noise indicate that we'll provide dBm. - * For WE, at least, non-0 values here *enable* display of values - * in app (iwconfig). */ - hw->max_rssi = -20; /* signal level, negative indicates dBm */ - hw->max_noise = -20; /* noise level, negative indicates dBm */ - hw->max_signal = 100; /* link quality indication (%) */ - - /* Tell mac80211 our Tx characteristics */ - hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE; + /* Tell mac80211 our characteristics */ + hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | + IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_NOISE_DBM; /* 4 EDCA QOS priorities */ hw->queues = 4; diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 33d608a60d7..9cbef5bce0f 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -355,7 +355,7 @@ static void p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb) struct ieee80211_rx_status rx_status = {0}; u16 freq = le16_to_cpu(hdr->freq); - rx_status.ssi = hdr->rssi; + rx_status.signal = hdr->rssi; /* XX correct? */ rx_status.rate_idx = hdr->rate & 0xf; rx_status.freq = freq; @@ -1000,9 +1000,10 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) skb_queue_head_init(&priv->tx_queue); dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz; dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */ - IEEE80211_HW_RX_INCLUDES_FCS; + IEEE80211_HW_RX_INCLUDES_FCS | + IEEE80211_HW_SIGNAL_UNSPEC; dev->channel_change_time = 1000; /* TODO: find actual value */ - dev->max_rssi = 127; + dev->max_signal = 127; priv->tx_stats[0].limit = 5; dev->queues = 1; diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 247fbbfb0f2..afa565c6362 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1361,10 +1361,9 @@ static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Initialize all hw fields. */ - rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; + rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | + IEEE80211_HW_SIGNAL_DBM; rt2x00dev->hw->extra_tx_headroom = 0; - rt2x00dev->hw->max_signal = MAX_SIGNAL; - rt2x00dev->hw->max_rssi = MAX_RX_SSI; rt2x00dev->hw->queues = 2; SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 0d53c75d55d..c06f1b5e588 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -1680,10 +1680,10 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Initialize all hw fields. */ - rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; + rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | + IEEE80211_HW_SIGNAL_DBM; + rt2x00dev->hw->extra_tx_headroom = 0; - rt2x00dev->hw->max_signal = MAX_SIGNAL; - rt2x00dev->hw->max_rssi = MAX_RX_SSI; rt2x00dev->hw->queues = 2; SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 80b34d47114..88bafdf8f0f 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -1587,10 +1587,10 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) rt2x00dev->hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | IEEE80211_HW_RX_INCLUDES_FCS | - IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; + IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | + IEEE80211_HW_SIGNAL_DBM; + rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; - rt2x00dev->hw->max_signal = MAX_SIGNAL; - rt2x00dev->hw->max_rssi = MAX_RX_SSI; rt2x00dev->hw->queues = 2; SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 9929b15e28b..f51a50b31e1 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -600,9 +600,9 @@ void rt2x00lib_rxdone(struct queue_entry *entry, rt2x00dev->link.qual.rx_success++; rx_status->rate_idx = idx; - rx_status->signal = + rx_status->qual = rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc->rssi); - rx_status->ssi = rxdesc->rssi; + rx_status->signal = rxdesc->rssi; rx_status->flag = rxdesc->flags; rx_status->antenna = rt2x00dev->link.ant.active.rx; diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 98af4d26583..eaf23b90877 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2245,10 +2245,9 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) */ rt2x00dev->hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | - IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; + IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | + IEEE80211_HW_SIGNAL_DBM; rt2x00dev->hw->extra_tx_headroom = 0; - rt2x00dev->hw->max_signal = MAX_SIGNAL; - rt2x00dev->hw->max_rssi = MAX_RX_SSI; rt2x00dev->hw->queues = 4; SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 351d95c4f50..51c5575ed02 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -1830,10 +1830,9 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) */ rt2x00dev->hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | - IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; + IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | + IEEE80211_HW_SIGNAL_DBM; rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; - rt2x00dev->hw->max_signal = MAX_SIGNAL; - rt2x00dev->hw->max_rssi = MAX_RX_SSI; rt2x00dev->hw->queues = 4; SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c index c181f23e930..c220998cee6 100644 --- a/drivers/net/wireless/rtl8180_dev.c +++ b/drivers/net/wireless/rtl8180_dev.c @@ -132,8 +132,8 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) rx_status.antenna = (flags2 >> 15) & 1; /* TODO: improve signal/rssi reporting */ - rx_status.signal = flags2 & 0xFF; - rx_status.ssi = (flags2 >> 8) & 0x7F; + rx_status.qual = flags2 & 0xFF; + rx_status.signal = (flags2 >> 8) & 0x7F; /* XXX: is this correct? */ rx_status.rate_idx = (flags >> 20) & 0xF; rx_status.freq = dev->conf.channel->center_freq; @@ -894,9 +894,10 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | - IEEE80211_HW_RX_INCLUDES_FCS; + IEEE80211_HW_RX_INCLUDES_FCS | + IEEE80211_HW_SIGNAL_UNSPEC; dev->queues = 1; - dev->max_rssi = 65; + dev->max_signal = 65; reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); reg &= RTL818X_TX_CONF_HWVER_MASK; diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index d5787b37e1f..e14c8424868 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c @@ -261,8 +261,8 @@ static void rtl8187_rx_cb(struct urb *urb) } rx_status.antenna = (hdr->signal >> 7) & 1; - rx_status.signal = 64 - min(hdr->noise, (u8)64); - rx_status.ssi = signal; + rx_status.qual = 64 - min(hdr->noise, (u8)64); + rx_status.signal = signal; rx_status.rate_idx = rate; rx_status.freq = dev->conf.channel->center_freq; rx_status.band = dev->conf.channel->band; @@ -740,11 +740,11 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, priv->mode = IEEE80211_IF_TYPE_MNTR; dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | - IEEE80211_HW_RX_INCLUDES_FCS; + IEEE80211_HW_RX_INCLUDES_FCS | + IEEE80211_HW_SIGNAL_UNSPEC; dev->extra_tx_headroom = sizeof(struct rtl8187_tx_hdr); dev->queues = 1; - dev->max_rssi = 65; - dev->max_signal = 64; + dev->max_signal = 65; eeprom.data = dev; eeprom.register_read = rtl8187_eeprom_register_read; diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index ee4331229f1..0c736735e21 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -638,7 +638,7 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr, memset(&status, 0, sizeof(status)); status.flags = IEEE80211_TX_STATUS_ACK; - status.ack_signal = stats->ssi; + status.ack_signal = stats->signal; __skb_unlink(skb, q); tx_status(hw, skb, &status, 1); goto out; @@ -691,8 +691,8 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length) stats.freq = zd_channels[_zd_chip_get_channel(&mac->chip) - 1].center_freq; stats.band = IEEE80211_BAND_2GHZ; - stats.ssi = status->signal_strength; - stats.signal = zd_rx_qual_percent(buffer, + stats.signal = status->signal_strength; + stats.qual = zd_rx_qual_percent(buffer, length - sizeof(struct rx_status), status); @@ -997,10 +997,10 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band; hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | - IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE; - hw->max_rssi = 100; - hw->max_signal = 100; + IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | + IEEE80211_HW_SIGNAL_DB; + hw->max_signal = 100; hw->queues = 1; hw->extra_tx_headroom = sizeof(struct zd_ctrlset); -- cgit v1.2.3 From 7a1d65235da829e6dc8938b82c991e40e278fc50 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Sat, 10 May 2008 11:12:31 +0200 Subject: b43: nphy.c remove duplicated include Remove duplicated include in drivers/net/wireless/b43/nphy.c Signed-off-by: Huang Weiyi Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/net/wireless/b43/nphy.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/nphy.c b/drivers/net/wireless/b43/nphy.c index 8695eb22347..644eed993be 100644 --- a/drivers/net/wireless/b43/nphy.c +++ b/drivers/net/wireless/b43/nphy.c @@ -29,8 +29,6 @@ #include "nphy.h" #include "tables_nphy.h" -#include - void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) {//TODO -- cgit v1.2.3 From d6894b5be1d674a31a94ed8f057c9f7d98c53999 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Mon, 12 May 2008 21:16:44 -0400 Subject: ath5k: Fix loop variable initializations In ath5k_tasklet_rx, both status structures 'rxs' and 'rs' are initialized at the top of the tasklet, but not within the loop. If the loop is executed multiple times in the tasklet then the variables may see changes from previous packets. For TKIP, this results in 'Invalid Michael MIC' errors if two packets are processed in the tasklet: rxs.flag gets set to RX_DECRYPTED by mac80211 when it decrypts the first encrypted packet. The subsequent packet will have RX_DECRYPTED set upon entry to mac80211, so mac80211 will not try to decrypt it. We currently initialize all but two fields in the structures, so fix the other two. Signed-off-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath5k/base.c | 2 ++ drivers/net/wireless/ath5k/hw.c | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index dd8adaddd7a..c76ada17878 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c @@ -1785,6 +1785,8 @@ ath5k_tasklet_rx(unsigned long data) spin_lock(&sc->rxbuflock); do { + rxs.flag = 0; + if (unlikely(list_empty(&sc->rxbuf))) { ATH5K_WARN(sc, "empty rx buf pool\n"); break; diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c index 5fb1ae6ad3e..77990b56860 100644 --- a/drivers/net/wireless/ath5k/hw.c +++ b/drivers/net/wireless/ath5k/hw.c @@ -4119,6 +4119,7 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); rs->rs_status = 0; + rs->rs_phyerr = 0; /* * Key table status @@ -4145,7 +4146,7 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) { rs->rs_status |= AR5K_RXERR_PHY; - rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1, + rs->rs_phyerr |= AR5K_REG_MS(rx_status->rx_status_1, AR5K_5210_RX_DESC_STATUS1_PHY_ERROR); } @@ -4193,6 +4194,7 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); rs->rs_status = 0; + rs->rs_phyerr = 0; /* * Key table status @@ -4215,7 +4217,7 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { rs->rs_status |= AR5K_RXERR_PHY; - rs->rs_phyerr = AR5K_REG_MS(rx_err->rx_error_1, + rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1, AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE); } -- cgit v1.2.3 From 6dcdc19e4ba4e6a9ccd733fdb745ad062cf3ea0a Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Tue, 13 May 2008 18:13:35 -0700 Subject: b43: use the bitrev helpers rather than rolling a private one The 4-bit reversal flip_4bit is replaced with the bitrev helper bitrev8 and a 4-bit shift. The B43_WARN is moved to the location where a register is read from for checking there. The other caller explicitly passes an array index which is guaranteed to be within range and so a B43_WARN is not added there. Signed-off-by: Harvey Harrison Reviewed-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy.c | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy.c b/drivers/net/wireless/b43/phy.c index 6378c266549..305d4cd6fd0 100644 --- a/drivers/net/wireless/b43/phy.c +++ b/drivers/net/wireless/b43/phy.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "b43.h" #include "phy.h" @@ -83,25 +84,9 @@ const u8 b43_radio_channel_codes_bg[] = { 72, 84, }; +#define bitrev4(tmp) (bitrev8(tmp) >> 4) static void b43_phy_initg(struct b43_wldev *dev); -/* Reverse the bits of a 4bit value. - * Example: 1101 is flipped 1011 - */ -static u16 flip_4bit(u16 value) -{ - u16 flipped = 0x0000; - - B43_WARN_ON(value & ~0x000F); - - flipped |= (value & 0x0001) << 3; - flipped |= (value & 0x0002) << 1; - flipped |= (value & 0x0004) >> 1; - flipped |= (value & 0x0008) >> 3; - - return flipped; -} - static void generate_rfatt_list(struct b43_wldev *dev, struct b43_rfatt_list *list) { @@ -2891,13 +2876,13 @@ b43_radio_interference_mitigation_enable(struct b43_wldev *dev, int mode) } radio_stacksave(0x0078); tmp = (b43_radio_read16(dev, 0x0078) & 0x001E); - flipped = flip_4bit(tmp); + B43_WARN_ON(tmp > 15); + flipped = bitrev4(tmp); if (flipped < 10 && flipped >= 8) flipped = 7; else if (flipped >= 10) flipped -= 3; - flipped = flip_4bit(flipped); - flipped = (flipped << 1) | 0x0020; + flipped = (bitrev4(flipped) << 1) | 0x0020; b43_radio_write16(dev, 0x0078, flipped); b43_calc_nrssi_threshold(dev); @@ -3530,7 +3515,7 @@ u16 b43_radio_init2050(struct b43_wldev *dev) tmp1 >>= 9; for (i = 0; i < 16; i++) { - radio78 = ((flip_4bit(i) << 1) | 0x20); + radio78 = (bitrev4(i) << 1) | 0x0020; b43_radio_write16(dev, 0x78, radio78); udelay(10); for (j = 0; j < 16; j++) { -- cgit v1.2.3 From ef85ad541f9a6ccd3f89ec73f92b2d6f45a9d3e8 Mon Sep 17 00:00:00 2001 From: Holger Schurig Date: Wed, 14 May 2008 16:27:18 +0200 Subject: libertas: remove lbs_get_data_rate() lbs_get_data_rate() gets called, but no-one uses it's result. Signed-off-by: Holger Schurig Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/cmd.c | 32 -------------------------------- drivers/net/wireless/libertas/cmd.h | 1 - drivers/net/wireless/libertas/main.c | 12 +----------- 3 files changed, 1 insertion(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 6328b959387..c2dd43ece06 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -696,38 +696,6 @@ static int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv, return 0; } -/** - * @brief Get the current data rate - * - * @param priv A pointer to struct lbs_private structure - * - * @return The data rate on success, error on failure - */ -int lbs_get_data_rate(struct lbs_private *priv) -{ - struct cmd_ds_802_11_data_rate cmd; - int ret = -1; - - lbs_deb_enter(LBS_DEB_CMD); - - memset(&cmd, 0, sizeof(cmd)); - cmd.hdr.size = cpu_to_le16(sizeof(cmd)); - cmd.action = cpu_to_le16(CMD_ACT_GET_TX_RATE); - - ret = lbs_cmd_with_response(priv, CMD_802_11_DATA_RATE, &cmd); - if (ret) - goto out; - - lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) &cmd, sizeof (cmd)); - - ret = (int) lbs_fw_index_to_data_rate(cmd.rates[0]); - lbs_deb_cmd("DATA_RATE: current rate 0x%02x\n", ret); - -out: - lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); - return ret; -} - /** * @brief Set the data rate * diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h index 4295bc61366..f4019c22adf 100644 --- a/drivers/net/wireless/libertas/cmd.h +++ b/drivers/net/wireless/libertas/cmd.h @@ -34,7 +34,6 @@ int lbs_update_hw_spec(struct lbs_private *priv); int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action, struct cmd_ds_mesh_access *cmd); -int lbs_get_data_rate(struct lbs_private *priv); int lbs_set_data_rate(struct lbs_private *priv, u8 rate); int lbs_get_channel(struct lbs_private *priv); diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 0be89573716..e333f14dce2 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -927,20 +927,10 @@ static int lbs_setup_firmware(struct lbs_private *priv) */ memset(priv->current_addr, 0xff, ETH_ALEN); ret = lbs_update_hw_spec(priv); - if (ret) { - ret = -1; + if (ret) goto done; - } lbs_set_mac_control(priv); - - ret = lbs_get_data_rate(priv); - if (ret < 0) { - ret = -1; - goto done; - } - - ret = 0; done: lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret); return ret; -- cgit v1.2.3