提交 d72751ed 编写于 作者: D David S. Miller

Merge branch 'for-davem' of...

Merge branch 'for-davem' of ssh://master.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
...@@ -274,6 +274,7 @@ source "drivers/net/wireless/b43legacy/Kconfig" ...@@ -274,6 +274,7 @@ source "drivers/net/wireless/b43legacy/Kconfig"
source "drivers/net/wireless/hostap/Kconfig" source "drivers/net/wireless/hostap/Kconfig"
source "drivers/net/wireless/ipw2x00/Kconfig" source "drivers/net/wireless/ipw2x00/Kconfig"
source "drivers/net/wireless/iwlwifi/Kconfig" source "drivers/net/wireless/iwlwifi/Kconfig"
source "drivers/net/wireless/iwlegacy/Kconfig"
source "drivers/net/wireless/iwmc3200wifi/Kconfig" source "drivers/net/wireless/iwmc3200wifi/Kconfig"
source "drivers/net/wireless/libertas/Kconfig" source "drivers/net/wireless/libertas/Kconfig"
source "drivers/net/wireless/orinoco/Kconfig" source "drivers/net/wireless/orinoco/Kconfig"
......
...@@ -24,7 +24,7 @@ obj-$(CONFIG_B43LEGACY) += b43legacy/ ...@@ -24,7 +24,7 @@ obj-$(CONFIG_B43LEGACY) += b43legacy/
obj-$(CONFIG_ZD1211RW) += zd1211rw/ obj-$(CONFIG_ZD1211RW) += zd1211rw/
obj-$(CONFIG_RTL8180) += rtl818x/ obj-$(CONFIG_RTL8180) += rtl818x/
obj-$(CONFIG_RTL8187) += rtl818x/ obj-$(CONFIG_RTL8187) += rtl818x/
obj-$(CONFIG_RTL8192CE) += rtlwifi/ obj-$(CONFIG_RTLWIFI) += rtlwifi/
# 16-bit wireless PCMCIA client drivers # 16-bit wireless PCMCIA client drivers
obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
...@@ -41,7 +41,8 @@ obj-$(CONFIG_ADM8211) += adm8211.o ...@@ -41,7 +41,8 @@ obj-$(CONFIG_ADM8211) += adm8211.o
obj-$(CONFIG_MWL8K) += mwl8k.o obj-$(CONFIG_MWL8K) += mwl8k.o
obj-$(CONFIG_IWLWIFI) += iwlwifi/ obj-$(CONFIG_IWLAGN) += iwlwifi/
obj-$(CONFIG_IWLWIFI_LEGACY) += iwlegacy/
obj-$(CONFIG_RT2X00) += rt2x00/ obj-$(CONFIG_RT2X00) += rt2x00/
obj-$(CONFIG_P54_COMMON) += p54/ obj-$(CONFIG_P54_COMMON) += p54/
......
...@@ -1658,7 +1658,7 @@ static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb, ...@@ -1658,7 +1658,7 @@ static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb,
} }
/* Put adm8211_tx_hdr on skb and transmit */ /* Put adm8211_tx_hdr on skb and transmit */
static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb) static void adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
{ {
struct adm8211_tx_hdr *txhdr; struct adm8211_tx_hdr *txhdr;
size_t payload_len, hdrlen; size_t payload_len, hdrlen;
...@@ -1707,8 +1707,6 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb) ...@@ -1707,8 +1707,6 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
txhdr->retry_limit = info->control.rates[0].count; txhdr->retry_limit = info->control.rates[0].count;
adm8211_tx_raw(dev, skb, plcp_signal, hdrlen); adm8211_tx_raw(dev, skb, plcp_signal, hdrlen);
return NETDEV_TX_OK;
} }
static int adm8211_alloc_rings(struct ieee80211_hw *dev) static int adm8211_alloc_rings(struct ieee80211_hw *dev)
......
...@@ -1728,7 +1728,7 @@ static void at76_mac80211_tx_callback(struct urb *urb) ...@@ -1728,7 +1728,7 @@ static void at76_mac80211_tx_callback(struct urb *urb)
ieee80211_wake_queues(priv->hw); ieee80211_wake_queues(priv->hw);
} }
static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb) static void at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{ {
struct at76_priv *priv = hw->priv; struct at76_priv *priv = hw->priv;
struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer; struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer;
...@@ -1741,7 +1741,8 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -1741,7 +1741,8 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
if (priv->tx_urb->status == -EINPROGRESS) { if (priv->tx_urb->status == -EINPROGRESS) {
wiphy_err(priv->hw->wiphy, wiphy_err(priv->hw->wiphy,
"%s called while tx urb is pending\n", __func__); "%s called while tx urb is pending\n", __func__);
return NETDEV_TX_BUSY; dev_kfree_skb_any(skb);
return;
} }
/* The following code lines are important when the device is going to /* The following code lines are important when the device is going to
...@@ -1755,7 +1756,8 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -1755,7 +1756,8 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
if (compare_ether_addr(priv->bssid, mgmt->bssid)) { if (compare_ether_addr(priv->bssid, mgmt->bssid)) {
memcpy(priv->bssid, mgmt->bssid, ETH_ALEN); memcpy(priv->bssid, mgmt->bssid, ETH_ALEN);
ieee80211_queue_work(hw, &priv->work_join_bssid); ieee80211_queue_work(hw, &priv->work_join_bssid);
return NETDEV_TX_BUSY; dev_kfree_skb_any(skb);
return;
} }
} }
...@@ -1795,8 +1797,6 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -1795,8 +1797,6 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
priv->tx_urb, priv->tx_urb,
priv->tx_urb->hcpriv, priv->tx_urb->complete); priv->tx_urb->hcpriv, priv->tx_urb->complete);
} }
return 0;
} }
static int at76_mac80211_start(struct ieee80211_hw *hw) static int at76_mac80211_start(struct ieee80211_hw *hw)
......
...@@ -224,7 +224,7 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len); ...@@ -224,7 +224,7 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len);
int ar9170_nag_limiter(struct ar9170 *ar); int ar9170_nag_limiter(struct ar9170 *ar);
/* MAC */ /* MAC */
int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); void ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
int ar9170_init_mac(struct ar9170 *ar); int ar9170_init_mac(struct ar9170 *ar);
int ar9170_set_qos(struct ar9170 *ar); int ar9170_set_qos(struct ar9170 *ar);
int ar9170_update_multicast(struct ar9170 *ar, const u64 mc_hast); int ar9170_update_multicast(struct ar9170 *ar, const u64 mc_hast);
......
...@@ -1475,7 +1475,7 @@ static void ar9170_tx(struct ar9170 *ar) ...@@ -1475,7 +1475,7 @@ static void ar9170_tx(struct ar9170 *ar)
msecs_to_jiffies(AR9170_JANITOR_DELAY)); msecs_to_jiffies(AR9170_JANITOR_DELAY));
} }
int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) void ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{ {
struct ar9170 *ar = hw->priv; struct ar9170 *ar = hw->priv;
struct ieee80211_tx_info *info; struct ieee80211_tx_info *info;
...@@ -1493,11 +1493,10 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -1493,11 +1493,10 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
skb_queue_tail(&ar->tx_pending[queue], skb); skb_queue_tail(&ar->tx_pending[queue], skb);
ar9170_tx(ar); ar9170_tx(ar);
return NETDEV_TX_OK; return;
err_free: err_free:
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
} }
static int ar9170_op_add_interface(struct ieee80211_hw *hw, static int ar9170_op_add_interface(struct ieee80211_hw *hw,
......
...@@ -1164,7 +1164,7 @@ struct ath5k_txq; ...@@ -1164,7 +1164,7 @@ struct ath5k_txq;
void set_beacon_filter(struct ieee80211_hw *hw, bool enable); void set_beacon_filter(struct ieee80211_hw *hw, bool enable);
bool ath_any_vif_assoc(struct ath5k_softc *sc); bool ath_any_vif_assoc(struct ath5k_softc *sc);
int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, void ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ath5k_txq *txq); struct ath5k_txq *txq);
int ath5k_init_hw(struct ath5k_softc *sc); int ath5k_init_hw(struct ath5k_softc *sc);
int ath5k_stop_hw(struct ath5k_softc *sc); int ath5k_stop_hw(struct ath5k_softc *sc);
......
...@@ -1361,7 +1361,7 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb, ...@@ -1361,7 +1361,7 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb,
* right now, so it's not too bad... * right now, so it's not too bad...
*/ */
rxs->mactime = ath5k_extend_tsf(sc->ah, rs->rs_tstamp); rxs->mactime = ath5k_extend_tsf(sc->ah, rs->rs_tstamp);
rxs->flag |= RX_FLAG_TSFT; rxs->flag |= RX_FLAG_MACTIME_MPDU;
rxs->freq = sc->curchan->center_freq; rxs->freq = sc->curchan->center_freq;
rxs->band = sc->curchan->band; rxs->band = sc->curchan->band;
...@@ -1518,7 +1518,7 @@ ath5k_tasklet_rx(unsigned long data) ...@@ -1518,7 +1518,7 @@ ath5k_tasklet_rx(unsigned long data)
* TX Handling * * TX Handling *
\*************/ \*************/
int void
ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ath5k_txq *txq) struct ath5k_txq *txq)
{ {
...@@ -1567,11 +1567,10 @@ ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, ...@@ -1567,11 +1567,10 @@ ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
spin_unlock_irqrestore(&sc->txbuflock, flags); spin_unlock_irqrestore(&sc->txbuflock, flags);
goto drop_packet; goto drop_packet;
} }
return NETDEV_TX_OK; return;
drop_packet: drop_packet:
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
} }
static void static void
......
...@@ -52,7 +52,7 @@ extern int ath5k_modparam_nohwcrypt; ...@@ -52,7 +52,7 @@ extern int ath5k_modparam_nohwcrypt;
* Mac80211 functions * * Mac80211 functions *
\********************/ \********************/
static int static void
ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{ {
struct ath5k_softc *sc = hw->priv; struct ath5k_softc *sc = hw->priv;
...@@ -60,10 +60,10 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -60,10 +60,10 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
if (WARN_ON(qnum >= sc->ah->ah_capabilities.cap_queues.q_tx_num)) { if (WARN_ON(qnum >= sc->ah->ah_capabilities.cap_queues.q_tx_num)) {
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return 0; return;
} }
return ath5k_tx_queue(hw, skb, &sc->txqs[qnum]); ath5k_tx_queue(hw, skb, &sc->txqs[qnum]);
} }
......
...@@ -78,15 +78,15 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) ...@@ -78,15 +78,15 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
/* Awake Setting */ /* Awake Setting */
INIT_INI_ARRAY(&ah->iniPcieSerdes, INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1, ar9485_1_1_pcie_phy_clkreq_disable_L1,
ARRAY_SIZE(ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1), ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
2); 2);
/* Sleep Setting */ /* Sleep Setting */
INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1, ar9485_1_1_pcie_phy_clkreq_disable_L1,
ARRAY_SIZE(ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1), ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
2); 2);
} else if (AR_SREV_9485(ah)) { } else if (AR_SREV_9485(ah)) {
/* mac */ /* mac */
......
...@@ -449,26 +449,21 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc); ...@@ -449,26 +449,21 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc);
#define ATH_LED_PIN_DEF 1 #define ATH_LED_PIN_DEF 1
#define ATH_LED_PIN_9287 8 #define ATH_LED_PIN_9287 8
#define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */ #define ATH_LED_PIN_9485 6
#define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */
enum ath_led_type {
ATH_LED_RADIO,
ATH_LED_ASSOC,
ATH_LED_TX,
ATH_LED_RX
};
struct ath_led {
struct ath_softc *sc;
struct led_classdev led_cdev;
enum ath_led_type led_type;
char name[32];
bool registered;
};
#ifdef CONFIG_MAC80211_LEDS
void ath_init_leds(struct ath_softc *sc); void ath_init_leds(struct ath_softc *sc);
void ath_deinit_leds(struct ath_softc *sc); void ath_deinit_leds(struct ath_softc *sc);
#else
static inline void ath_init_leds(struct ath_softc *sc)
{
}
static inline void ath_deinit_leds(struct ath_softc *sc)
{
}
#endif
/* Antenna diversity/combining */ /* Antenna diversity/combining */
#define ATH_ANT_RX_CURRENT_SHIFT 4 #define ATH_ANT_RX_CURRENT_SHIFT 4
...@@ -620,15 +615,11 @@ struct ath_softc { ...@@ -620,15 +615,11 @@ struct ath_softc {
struct ath_beacon beacon; struct ath_beacon beacon;
struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
struct ath_led radio_led; #ifdef CONFIG_MAC80211_LEDS
struct ath_led assoc_led; bool led_registered;
struct ath_led tx_led; char led_name[32];
struct ath_led rx_led; struct led_classdev led_cdev;
struct delayed_work ath_led_blink_work; #endif
int led_on_duration;
int led_off_duration;
int led_on_cnt;
int led_off_cnt;
struct ath9k_hw_cal_data caldata; struct ath9k_hw_cal_data caldata;
int last_rssi; int last_rssi;
......
...@@ -20,121 +20,31 @@ ...@@ -20,121 +20,31 @@
/* LED functions */ /* LED functions */
/********************************/ /********************************/
static void ath_led_blink_work(struct work_struct *work) #ifdef CONFIG_MAC80211_LEDS
{
struct ath_softc *sc = container_of(work, struct ath_softc,
ath_led_blink_work.work);
if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED))
return;
if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
(sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
else
ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
(sc->sc_flags & SC_OP_LED_ON) ? 1 : 0);
ieee80211_queue_delayed_work(sc->hw,
&sc->ath_led_blink_work,
(sc->sc_flags & SC_OP_LED_ON) ?
msecs_to_jiffies(sc->led_off_duration) :
msecs_to_jiffies(sc->led_on_duration));
sc->led_on_duration = sc->led_on_cnt ?
max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) :
ATH_LED_ON_DURATION_IDLE;
sc->led_off_duration = sc->led_off_cnt ?
max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10) :
ATH_LED_OFF_DURATION_IDLE;
sc->led_on_cnt = sc->led_off_cnt = 0;
if (sc->sc_flags & SC_OP_LED_ON)
sc->sc_flags &= ~SC_OP_LED_ON;
else
sc->sc_flags |= SC_OP_LED_ON;
}
static void ath_led_brightness(struct led_classdev *led_cdev, static void ath_led_brightness(struct led_classdev *led_cdev,
enum led_brightness brightness) enum led_brightness brightness)
{ {
struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev); struct ath_softc *sc = container_of(led_cdev, struct ath_softc, led_cdev);
struct ath_softc *sc = led->sc; ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, (brightness == LED_OFF));
switch (brightness) {
case LED_OFF:
if (led->led_type == ATH_LED_ASSOC ||
led->led_type == ATH_LED_RADIO) {
ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
(led->led_type == ATH_LED_RADIO));
sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
if (led->led_type == ATH_LED_RADIO)
sc->sc_flags &= ~SC_OP_LED_ON;
} else {
sc->led_off_cnt++;
}
break;
case LED_FULL:
if (led->led_type == ATH_LED_ASSOC) {
sc->sc_flags |= SC_OP_LED_ASSOCIATED;
if (led_blink)
ieee80211_queue_delayed_work(sc->hw,
&sc->ath_led_blink_work, 0);
} else if (led->led_type == ATH_LED_RADIO) {
ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
sc->sc_flags |= SC_OP_LED_ON;
} else {
sc->led_on_cnt++;
}
break;
default:
break;
}
}
static int ath_register_led(struct ath_softc *sc, struct ath_led *led,
char *trigger)
{
int ret;
led->sc = sc;
led->led_cdev.name = led->name;
led->led_cdev.default_trigger = trigger;
led->led_cdev.brightness_set = ath_led_brightness;
ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev);
if (ret)
ath_err(ath9k_hw_common(sc->sc_ah),
"Failed to register led:%s", led->name);
else
led->registered = 1;
return ret;
}
static void ath_unregister_led(struct ath_led *led)
{
if (led->registered) {
led_classdev_unregister(&led->led_cdev);
led->registered = 0;
}
} }
void ath_deinit_leds(struct ath_softc *sc) void ath_deinit_leds(struct ath_softc *sc)
{ {
ath_unregister_led(&sc->assoc_led); if (!sc->led_registered)
sc->sc_flags &= ~SC_OP_LED_ASSOCIATED; return;
ath_unregister_led(&sc->tx_led);
ath_unregister_led(&sc->rx_led); ath_led_brightness(&sc->led_cdev, LED_OFF);
ath_unregister_led(&sc->radio_led); led_classdev_unregister(&sc->led_cdev);
ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
} }
void ath_init_leds(struct ath_softc *sc) void ath_init_leds(struct ath_softc *sc)
{ {
char *trigger;
int ret; int ret;
if (AR_SREV_9287(sc->sc_ah)) if (AR_SREV_9287(sc->sc_ah))
sc->sc_ah->led_pin = ATH_LED_PIN_9287; sc->sc_ah->led_pin = ATH_LED_PIN_9287;
else if (AR_SREV_9485(sc->sc_ah))
sc->sc_ah->led_pin = ATH_LED_PIN_9485;
else else
sc->sc_ah->led_pin = ATH_LED_PIN_DEF; sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
...@@ -144,48 +54,22 @@ void ath_init_leds(struct ath_softc *sc) ...@@ -144,48 +54,22 @@ void ath_init_leds(struct ath_softc *sc)
/* LED off, active low */ /* LED off, active low */
ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
if (led_blink) if (!led_blink)
INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work); sc->led_cdev.default_trigger =
ieee80211_get_radio_led_name(sc->hw);
trigger = ieee80211_get_radio_led_name(sc->hw);
snprintf(sc->radio_led.name, sizeof(sc->radio_led.name), snprintf(sc->led_name, sizeof(sc->led_name),
"ath9k-%s::radio", wiphy_name(sc->hw->wiphy)); "ath9k-%s", wiphy_name(sc->hw->wiphy));
ret = ath_register_led(sc, &sc->radio_led, trigger); sc->led_cdev.name = sc->led_name;
sc->radio_led.led_type = ATH_LED_RADIO; sc->led_cdev.brightness_set = ath_led_brightness;
if (ret)
goto fail;
trigger = ieee80211_get_assoc_led_name(sc->hw);
snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name),
"ath9k-%s::assoc", wiphy_name(sc->hw->wiphy));
ret = ath_register_led(sc, &sc->assoc_led, trigger);
sc->assoc_led.led_type = ATH_LED_ASSOC;
if (ret)
goto fail;
trigger = ieee80211_get_tx_led_name(sc->hw);
snprintf(sc->tx_led.name, sizeof(sc->tx_led.name),
"ath9k-%s::tx", wiphy_name(sc->hw->wiphy));
ret = ath_register_led(sc, &sc->tx_led, trigger);
sc->tx_led.led_type = ATH_LED_TX;
if (ret)
goto fail;
trigger = ieee80211_get_rx_led_name(sc->hw);
snprintf(sc->rx_led.name, sizeof(sc->rx_led.name),
"ath9k-%s::rx", wiphy_name(sc->hw->wiphy));
ret = ath_register_led(sc, &sc->rx_led, trigger);
sc->rx_led.led_type = ATH_LED_RX;
if (ret)
goto fail;
ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &sc->led_cdev);
if (ret < 0)
return; return;
fail: sc->led_registered = true;
if (led_blink)
cancel_delayed_work_sync(&sc->ath_led_blink_work);
ath_deinit_leds(sc);
} }
#endif
/*******************/ /*******************/
/* Rfkill */ /* Rfkill */
......
...@@ -52,6 +52,9 @@ static struct usb_device_id ath9k_hif_usb_ids[] = { ...@@ -52,6 +52,9 @@ static struct usb_device_id ath9k_hif_usb_ids[] = {
{ USB_DEVICE(0x083A, 0xA704), { USB_DEVICE(0x083A, 0xA704),
.driver_info = AR9280_USB }, /* SMC Networks */ .driver_info = AR9280_USB }, /* SMC Networks */
{ USB_DEVICE(0x0cf3, 0x20ff),
.driver_info = STORAGE_DEVICE },
{ }, { },
}; };
...@@ -914,13 +917,11 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, u32 drv_info) ...@@ -914,13 +917,11 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, u32 drv_info)
if (ret) { if (ret) {
dev_err(&hif_dev->udev->dev, dev_err(&hif_dev->udev->dev,
"ath9k_htc: Unable to allocate URBs\n"); "ath9k_htc: Unable to allocate URBs\n");
goto err_urb; goto err_fw_download;
} }
return 0; return 0;
err_urb:
ath9k_hif_usb_dealloc_urbs(hif_dev);
err_fw_download: err_fw_download:
release_firmware(hif_dev->firmware); release_firmware(hif_dev->firmware);
err_fw_req: err_fw_req:
...@@ -935,6 +936,61 @@ static void ath9k_hif_usb_dev_deinit(struct hif_device_usb *hif_dev) ...@@ -935,6 +936,61 @@ static void ath9k_hif_usb_dev_deinit(struct hif_device_usb *hif_dev)
release_firmware(hif_dev->firmware); release_firmware(hif_dev->firmware);
} }
/*
* An exact copy of the function from zd1211rw.
*/
static int send_eject_command(struct usb_interface *interface)
{
struct usb_device *udev = interface_to_usbdev(interface);
struct usb_host_interface *iface_desc = &interface->altsetting[0];
struct usb_endpoint_descriptor *endpoint;
unsigned char *cmd;
u8 bulk_out_ep;
int r;
/* Find bulk out endpoint */
for (r = 1; r >= 0; r--) {
endpoint = &iface_desc->endpoint[r].desc;
if (usb_endpoint_dir_out(endpoint) &&
usb_endpoint_xfer_bulk(endpoint)) {
bulk_out_ep = endpoint->bEndpointAddress;
break;
}
}
if (r == -1) {
dev_err(&udev->dev,
"ath9k_htc: Could not find bulk out endpoint\n");
return -ENODEV;
}
cmd = kzalloc(31, GFP_KERNEL);
if (cmd == NULL)
return -ENODEV;
/* USB bulk command block */
cmd[0] = 0x55; /* bulk command signature */
cmd[1] = 0x53; /* bulk command signature */
cmd[2] = 0x42; /* bulk command signature */
cmd[3] = 0x43; /* bulk command signature */
cmd[14] = 6; /* command length */
cmd[15] = 0x1b; /* SCSI command: START STOP UNIT */
cmd[19] = 0x2; /* eject disc */
dev_info(&udev->dev, "Ejecting storage device...\n");
r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, bulk_out_ep),
cmd, 31, NULL, 2000);
kfree(cmd);
if (r)
return r;
/* At this point, the device disconnects and reconnects with the real
* ID numbers. */
usb_set_intfdata(interface, NULL);
return 0;
}
static int ath9k_hif_usb_probe(struct usb_interface *interface, static int ath9k_hif_usb_probe(struct usb_interface *interface,
const struct usb_device_id *id) const struct usb_device_id *id)
{ {
...@@ -942,6 +998,9 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, ...@@ -942,6 +998,9 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
struct hif_device_usb *hif_dev; struct hif_device_usb *hif_dev;
int ret = 0; int ret = 0;
if (id->driver_info == STORAGE_DEVICE)
return send_eject_command(interface);
hif_dev = kzalloc(sizeof(struct hif_device_usb), GFP_KERNEL); hif_dev = kzalloc(sizeof(struct hif_device_usb), GFP_KERNEL);
if (!hif_dev) { if (!hif_dev) {
ret = -ENOMEM; ret = -ENOMEM;
...@@ -1028,12 +1087,13 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface) ...@@ -1028,12 +1087,13 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
struct hif_device_usb *hif_dev = usb_get_intfdata(interface); struct hif_device_usb *hif_dev = usb_get_intfdata(interface);
bool unplugged = (udev->state == USB_STATE_NOTATTACHED) ? true : false; bool unplugged = (udev->state == USB_STATE_NOTATTACHED) ? true : false;
if (hif_dev) { if (!hif_dev)
return;
ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged); ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged);
ath9k_htc_hw_free(hif_dev->htc_handle); ath9k_htc_hw_free(hif_dev->htc_handle);
ath9k_hif_usb_dev_deinit(hif_dev); ath9k_hif_usb_dev_deinit(hif_dev);
usb_set_intfdata(interface, NULL); usb_set_intfdata(interface, NULL);
}
if (!unplugged && (hif_dev->flags & HIF_USB_START)) if (!unplugged && (hif_dev->flags & HIF_USB_START))
ath9k_hif_usb_reboot(udev); ath9k_hif_usb_reboot(udev);
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include "wmi.h" #include "wmi.h"
#define ATH_STA_SHORT_CALINTERVAL 1000 /* 1 second */ #define ATH_STA_SHORT_CALINTERVAL 1000 /* 1 second */
#define ATH_AP_SHORT_CALINTERVAL 100 /* 100 ms */
#define ATH_ANI_POLLINTERVAL 100 /* 100 ms */ #define ATH_ANI_POLLINTERVAL 100 /* 100 ms */
#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ #define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */
#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */
...@@ -204,8 +205,50 @@ struct ath9k_htc_target_stats { ...@@ -204,8 +205,50 @@ struct ath9k_htc_target_stats {
__be32 ht_tx_xretries; __be32 ht_tx_xretries;
} __packed; } __packed;
#define ATH9K_HTC_MAX_VIF 2
#define ATH9K_HTC_MAX_BCN_VIF 2
#define INC_VIF(_priv, _type) do { \
switch (_type) { \
case NL80211_IFTYPE_STATION: \
_priv->num_sta_vif++; \
break; \
case NL80211_IFTYPE_ADHOC: \
_priv->num_ibss_vif++; \
break; \
case NL80211_IFTYPE_AP: \
_priv->num_ap_vif++; \
break; \
default: \
break; \
} \
} while (0)
#define DEC_VIF(_priv, _type) do { \
switch (_type) { \
case NL80211_IFTYPE_STATION: \
_priv->num_sta_vif--; \
break; \
case NL80211_IFTYPE_ADHOC: \
_priv->num_ibss_vif--; \
break; \
case NL80211_IFTYPE_AP: \
_priv->num_ap_vif--; \
break; \
default: \
break; \
} \
} while (0)
struct ath9k_htc_vif { struct ath9k_htc_vif {
u8 index; u8 index;
u16 seq_no;
bool beacon_configured;
};
struct ath9k_vif_iter_data {
const u8 *hw_macaddr;
u8 mask[ETH_ALEN];
}; };
#define ATH9K_HTC_MAX_STA 8 #define ATH9K_HTC_MAX_STA 8
...@@ -310,10 +353,8 @@ struct ath_led { ...@@ -310,10 +353,8 @@ struct ath_led {
struct htc_beacon_config { struct htc_beacon_config {
u16 beacon_interval; u16 beacon_interval;
u16 listen_interval;
u16 dtim_period; u16 dtim_period;
u16 bmiss_timeout; u16 bmiss_timeout;
u8 dtim_count;
}; };
struct ath_btcoex { struct ath_btcoex {
...@@ -333,13 +374,12 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv); ...@@ -333,13 +374,12 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv);
#define OP_SCANNING BIT(1) #define OP_SCANNING BIT(1)
#define OP_LED_ASSOCIATED BIT(2) #define OP_LED_ASSOCIATED BIT(2)
#define OP_LED_ON BIT(3) #define OP_LED_ON BIT(3)
#define OP_PREAMBLE_SHORT BIT(4) #define OP_ENABLE_BEACON BIT(4)
#define OP_PROTECT_ENABLE BIT(5) #define OP_LED_DEINIT BIT(5)
#define OP_ASSOCIATED BIT(6) #define OP_BT_PRIORITY_DETECTED BIT(6)
#define OP_ENABLE_BEACON BIT(7) #define OP_BT_SCAN BIT(7)
#define OP_LED_DEINIT BIT(8) #define OP_ANI_RUNNING BIT(8)
#define OP_BT_PRIORITY_DETECTED BIT(9) #define OP_TSF_RESET BIT(9)
#define OP_BT_SCAN BIT(10)
struct ath9k_htc_priv { struct ath9k_htc_priv {
struct device *dev; struct device *dev;
...@@ -358,13 +398,22 @@ struct ath9k_htc_priv { ...@@ -358,13 +398,22 @@ struct ath9k_htc_priv {
enum htc_endpoint_id data_vi_ep; enum htc_endpoint_id data_vi_ep;
enum htc_endpoint_id data_vo_ep; enum htc_endpoint_id data_vo_ep;
u8 vif_slot;
u8 mon_vif_idx;
u8 sta_slot;
u8 vif_sta_pos[ATH9K_HTC_MAX_VIF];
u8 num_ibss_vif;
u8 num_sta_vif;
u8 num_ap_vif;
u16 op_flags; u16 op_flags;
u16 curtxpow; u16 curtxpow;
u16 txpowlimit; u16 txpowlimit;
u16 nvifs; u16 nvifs;
u16 nstations; u16 nstations;
u16 seq_no;
u32 bmiss_cnt; u32 bmiss_cnt;
bool rearm_ani;
bool reconfig_beacon;
struct ath9k_hw_cal_data caldata; struct ath9k_hw_cal_data caldata;
...@@ -382,7 +431,7 @@ struct ath9k_htc_priv { ...@@ -382,7 +431,7 @@ struct ath9k_htc_priv {
struct ath9k_htc_rx rx; struct ath9k_htc_rx rx;
struct tasklet_struct tx_tasklet; struct tasklet_struct tx_tasklet;
struct sk_buff_head tx_queue; struct sk_buff_head tx_queue;
struct delayed_work ath9k_ani_work; struct delayed_work ani_work;
struct work_struct ps_work; struct work_struct ps_work;
struct work_struct fatal_work; struct work_struct fatal_work;
...@@ -424,6 +473,7 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv); ...@@ -424,6 +473,7 @@ void ath9k_htc_reset(struct ath9k_htc_priv *priv);
void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv); void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv);
void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
struct ieee80211_vif *vif); struct ieee80211_vif *vif);
void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv);
void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending); void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending);
void ath9k_htc_rxep(void *priv, struct sk_buff *skb, void ath9k_htc_rxep(void *priv, struct sk_buff *skb,
...@@ -436,8 +486,9 @@ void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, ...@@ -436,8 +486,9 @@ void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb,
int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv); int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv);
void ath9k_htc_station_work(struct work_struct *work); void ath9k_htc_station_work(struct work_struct *work);
void ath9k_htc_aggr_work(struct work_struct *work); void ath9k_htc_aggr_work(struct work_struct *work);
void ath9k_ani_work(struct work_struct *work);; void ath9k_htc_ani_work(struct work_struct *work);
void ath_start_ani(struct ath9k_htc_priv *priv); void ath9k_htc_start_ani(struct ath9k_htc_priv *priv);
void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv);
int ath9k_tx_init(struct ath9k_htc_priv *priv); int ath9k_tx_init(struct ath9k_htc_priv *priv);
void ath9k_tx_tasklet(unsigned long data); void ath9k_tx_tasklet(unsigned long data);
......
...@@ -123,8 +123,9 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv, ...@@ -123,8 +123,9 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
/* TSF out of range threshold fixed at 1 second */ /* TSF out of range threshold fixed at 1 second */
bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD; bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
ath_dbg(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu); ath_dbg(common, ATH_DBG_CONFIG, "intval: %u tsf: %llu tsftu: %u\n",
ath_dbg(common, ATH_DBG_BEACON, intval, tsf, tsftu);
ath_dbg(common, ATH_DBG_CONFIG,
"bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n", "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
bs.bs_bmissthreshold, bs.bs_sleepduration, bs.bs_bmissthreshold, bs.bs_sleepduration,
bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext); bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
...@@ -138,25 +139,81 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv, ...@@ -138,25 +139,81 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
} }
static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv,
struct htc_beacon_config *bss_conf)
{
struct ath_common *common = ath9k_hw_common(priv->ah);
enum ath9k_int imask = 0;
u32 nexttbtt, intval, tsftu;
__be32 htc_imask = 0;
int ret;
u8 cmd_rsp;
u64 tsf;
intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD;
intval /= ATH9K_HTC_MAX_BCN_VIF;
nexttbtt = intval;
if (priv->op_flags & OP_TSF_RESET) {
intval |= ATH9K_BEACON_RESET_TSF;
priv->op_flags &= ~OP_TSF_RESET;
} else {
/*
* Pull nexttbtt forward to reflect the current TSF.
*/
tsf = ath9k_hw_gettsf64(priv->ah);
tsftu = TSF_TO_TU(tsf >> 32, tsf) + FUDGE;
do {
nexttbtt += intval;
} while (nexttbtt < tsftu);
}
intval |= ATH9K_BEACON_ENA;
if (priv->op_flags & OP_ENABLE_BEACON)
imask |= ATH9K_INT_SWBA;
ath_dbg(common, ATH_DBG_CONFIG,
"AP Beacon config, intval: %d, nexttbtt: %u imask: 0x%x\n",
bss_conf->beacon_interval, nexttbtt, imask);
WMI_CMD(WMI_DISABLE_INTR_CMDID);
ath9k_hw_beaconinit(priv->ah, nexttbtt, intval);
priv->bmiss_cnt = 0;
htc_imask = cpu_to_be32(imask);
WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
}
static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
struct htc_beacon_config *bss_conf) struct htc_beacon_config *bss_conf)
{ {
struct ath_common *common = ath9k_hw_common(priv->ah); struct ath_common *common = ath9k_hw_common(priv->ah);
enum ath9k_int imask = 0; enum ath9k_int imask = 0;
u32 nexttbtt, intval; u32 nexttbtt, intval, tsftu;
__be32 htc_imask = 0; __be32 htc_imask = 0;
int ret; int ret;
u8 cmd_rsp; u8 cmd_rsp;
u64 tsf;
intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD; intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD;
nexttbtt = intval; nexttbtt = intval;
/*
* Pull nexttbtt forward to reflect the current TSF.
*/
tsf = ath9k_hw_gettsf64(priv->ah);
tsftu = TSF_TO_TU(tsf >> 32, tsf) + FUDGE;
do {
nexttbtt += intval;
} while (nexttbtt < tsftu);
intval |= ATH9K_BEACON_ENA; intval |= ATH9K_BEACON_ENA;
if (priv->op_flags & OP_ENABLE_BEACON) if (priv->op_flags & OP_ENABLE_BEACON)
imask |= ATH9K_INT_SWBA; imask |= ATH9K_INT_SWBA;
ath_dbg(common, ATH_DBG_BEACON, ath_dbg(common, ATH_DBG_CONFIG,
"IBSS Beacon config, intval: %d, imask: 0x%x\n", "IBSS Beacon config, intval: %d, nexttbtt: %u, imask: 0x%x\n",
bss_conf->beacon_interval, imask); bss_conf->beacon_interval, nexttbtt, imask);
WMI_CMD(WMI_DISABLE_INTR_CMDID); WMI_CMD(WMI_DISABLE_INTR_CMDID);
ath9k_hw_beaconinit(priv->ah, nexttbtt, intval); ath9k_hw_beaconinit(priv->ah, nexttbtt, intval);
...@@ -207,9 +264,9 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending) ...@@ -207,9 +264,9 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending)
if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
struct ieee80211_hdr *hdr = struct ieee80211_hdr *hdr =
(struct ieee80211_hdr *) beacon->data; (struct ieee80211_hdr *) beacon->data;
priv->seq_no += 0x10; avp->seq_no += 0x10;
hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
hdr->seq_ctrl |= cpu_to_le16(priv->seq_no); hdr->seq_ctrl |= cpu_to_le16(avp->seq_no);
} }
tx_ctl.type = ATH9K_HTC_NORMAL; tx_ctl.type = ATH9K_HTC_NORMAL;
...@@ -253,30 +310,123 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) ...@@ -253,30 +310,123 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv)
} }
} }
static void ath9k_htc_beacon_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
{
bool *beacon_configured = (bool *)data;
struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
if (vif->type == NL80211_IFTYPE_STATION &&
avp->beacon_configured)
*beacon_configured = true;
}
static bool ath9k_htc_check_beacon_config(struct ath9k_htc_priv *priv,
struct ieee80211_vif *vif)
{
struct ath_common *common = ath9k_hw_common(priv->ah);
struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf;
struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
bool beacon_configured;
/*
* Changing the beacon interval when multiple AP interfaces
* are configured will affect beacon transmission of all
* of them.
*/
if ((priv->ah->opmode == NL80211_IFTYPE_AP) &&
(priv->num_ap_vif > 1) &&
(vif->type == NL80211_IFTYPE_AP) &&
(cur_conf->beacon_interval != bss_conf->beacon_int)) {
ath_dbg(common, ATH_DBG_CONFIG,
"Changing beacon interval of multiple AP interfaces !\n");
return false;
}
/*
* If the HW is operating in AP mode, any new station interfaces that
* are added cannot change the beacon parameters.
*/
if (priv->num_ap_vif &&
(vif->type != NL80211_IFTYPE_AP)) {
ath_dbg(common, ATH_DBG_CONFIG,
"HW in AP mode, cannot set STA beacon parameters\n");
return false;
}
/*
* The beacon parameters are configured only for the first
* station interface.
*/
if ((priv->ah->opmode == NL80211_IFTYPE_STATION) &&
(priv->num_sta_vif > 1) &&
(vif->type == NL80211_IFTYPE_STATION)) {
beacon_configured = false;
ieee80211_iterate_active_interfaces_atomic(priv->hw,
ath9k_htc_beacon_iter,
&beacon_configured);
if (beacon_configured) {
ath_dbg(common, ATH_DBG_CONFIG,
"Beacon already configured for a station interface\n");
return false;
}
}
return true;
}
void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
struct ieee80211_vif *vif) struct ieee80211_vif *vif)
{ {
struct ath_common *common = ath9k_hw_common(priv->ah); struct ath_common *common = ath9k_hw_common(priv->ah);
struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf; struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf;
struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
if (!ath9k_htc_check_beacon_config(priv, vif))
return;
cur_conf->beacon_interval = bss_conf->beacon_int; cur_conf->beacon_interval = bss_conf->beacon_int;
if (cur_conf->beacon_interval == 0) if (cur_conf->beacon_interval == 0)
cur_conf->beacon_interval = 100; cur_conf->beacon_interval = 100;
cur_conf->dtim_period = bss_conf->dtim_period; cur_conf->dtim_period = bss_conf->dtim_period;
cur_conf->listen_interval = 1;
cur_conf->dtim_count = 1;
cur_conf->bmiss_timeout = cur_conf->bmiss_timeout =
ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval; ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;
switch (vif->type) { switch (vif->type) {
case NL80211_IFTYPE_STATION:
ath9k_htc_beacon_config_sta(priv, cur_conf);
avp->beacon_configured = true;
break;
case NL80211_IFTYPE_ADHOC:
ath9k_htc_beacon_config_adhoc(priv, cur_conf);
break;
case NL80211_IFTYPE_AP:
ath9k_htc_beacon_config_ap(priv, cur_conf);
break;
default:
ath_dbg(common, ATH_DBG_CONFIG,
"Unsupported beaconing mode\n");
return;
}
}
void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv)
{
struct ath_common *common = ath9k_hw_common(priv->ah);
struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf;
switch (priv->ah->opmode) {
case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_STATION:
ath9k_htc_beacon_config_sta(priv, cur_conf); ath9k_htc_beacon_config_sta(priv, cur_conf);
break; break;
case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_ADHOC:
ath9k_htc_beacon_config_adhoc(priv, cur_conf); ath9k_htc_beacon_config_adhoc(priv, cur_conf);
break; break;
case NL80211_IFTYPE_AP:
ath9k_htc_beacon_config_ap(priv, cur_conf);
break;
default: default:
ath_dbg(common, ATH_DBG_CONFIG, ath_dbg(common, ATH_DBG_CONFIG,
"Unsupported beaconing mode\n"); "Unsupported beaconing mode\n");
......
...@@ -679,7 +679,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, ...@@ -679,7 +679,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
(unsigned long)priv); (unsigned long)priv);
tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet,
(unsigned long)priv); (unsigned long)priv);
INIT_DELAYED_WORK(&priv->ath9k_ani_work, ath9k_ani_work); INIT_DELAYED_WORK(&priv->ani_work, ath9k_htc_ani_work);
INIT_WORK(&priv->ps_work, ath9k_ps_work); INIT_WORK(&priv->ps_work, ath9k_ps_work);
INIT_WORK(&priv->fatal_work, ath9k_fatal_work); INIT_WORK(&priv->fatal_work, ath9k_fatal_work);
...@@ -787,6 +787,7 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, ...@@ -787,6 +787,7 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv,
struct ath_hw *ah; struct ath_hw *ah;
int error = 0; int error = 0;
struct ath_regulatory *reg; struct ath_regulatory *reg;
char hw_name[64];
/* Bring up device */ /* Bring up device */
error = ath9k_init_priv(priv, devid, product, drv_info); error = ath9k_init_priv(priv, devid, product, drv_info);
...@@ -827,6 +828,22 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, ...@@ -827,6 +828,22 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv,
goto err_world; goto err_world;
} }
ath_dbg(common, ATH_DBG_CONFIG,
"WMI:%d, BCN:%d, CAB:%d, UAPSD:%d, MGMT:%d, "
"BE:%d, BK:%d, VI:%d, VO:%d\n",
priv->wmi_cmd_ep,
priv->beacon_ep,
priv->cab_ep,
priv->uapsd_ep,
priv->mgmt_ep,
priv->data_be_ep,
priv->data_bk_ep,
priv->data_vi_ep,
priv->data_vo_ep);
ath9k_hw_name(priv->ah, hw_name, sizeof(hw_name));
wiphy_info(hw->wiphy, "%s\n", hw_name);
ath9k_init_leds(priv); ath9k_init_leds(priv);
ath9k_start_rfkill_poll(priv); ath9k_start_rfkill_poll(priv);
......
...@@ -84,7 +84,9 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) ...@@ -84,7 +84,9 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
struct ieee80211_hdr *hdr; struct ieee80211_hdr *hdr;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_sta *sta = tx_info->control.sta; struct ieee80211_sta *sta = tx_info->control.sta;
struct ieee80211_vif *vif = tx_info->control.vif;
struct ath9k_htc_sta *ista; struct ath9k_htc_sta *ista;
struct ath9k_htc_vif *avp;
struct ath9k_htc_tx_ctl tx_ctl; struct ath9k_htc_tx_ctl tx_ctl;
enum htc_endpoint_id epid; enum htc_endpoint_id epid;
u16 qnum; u16 qnum;
...@@ -95,18 +97,31 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) ...@@ -95,18 +97,31 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
hdr = (struct ieee80211_hdr *) skb->data; hdr = (struct ieee80211_hdr *) skb->data;
fc = hdr->frame_control; fc = hdr->frame_control;
if (tx_info->control.vif && /*
(struct ath9k_htc_vif *) tx_info->control.vif->drv_priv) * Find out on which interface this packet has to be
vif_idx = ((struct ath9k_htc_vif *) * sent out.
tx_info->control.vif->drv_priv)->index; */
else if (vif) {
vif_idx = priv->nvifs; avp = (struct ath9k_htc_vif *) vif->drv_priv;
vif_idx = avp->index;
} else {
if (!priv->ah->is_monitoring) {
ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
"VIF is null, but no monitor interface !\n");
return -EINVAL;
}
vif_idx = priv->mon_vif_idx;
}
/*
* Find out which station this packet is destined for.
*/
if (sta) { if (sta) {
ista = (struct ath9k_htc_sta *) sta->drv_priv; ista = (struct ath9k_htc_sta *) sta->drv_priv;
sta_idx = ista->index; sta_idx = ista->index;
} else { } else {
sta_idx = 0; sta_idx = priv->vif_sta_pos[vif_idx];
} }
memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl)); memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl));
...@@ -141,7 +156,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) ...@@ -141,7 +156,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
/* CTS-to-self */ /* CTS-to-self */
if (!(flags & ATH9K_HTC_TX_RTSCTS) && if (!(flags & ATH9K_HTC_TX_RTSCTS) &&
(priv->op_flags & OP_PROTECT_ENABLE)) (vif && vif->bss_conf.use_cts_prot))
flags |= ATH9K_HTC_TX_CTSONLY; flags |= ATH9K_HTC_TX_CTSONLY;
tx_hdr.flags = cpu_to_be32(flags); tx_hdr.flags = cpu_to_be32(flags);
...@@ -217,6 +232,7 @@ static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, ...@@ -217,6 +232,7 @@ static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv,
void ath9k_tx_tasklet(unsigned long data) void ath9k_tx_tasklet(unsigned long data)
{ {
struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
struct ieee80211_vif *vif;
struct ieee80211_sta *sta; struct ieee80211_sta *sta;
struct ieee80211_hdr *hdr; struct ieee80211_hdr *hdr;
struct ieee80211_tx_info *tx_info; struct ieee80211_tx_info *tx_info;
...@@ -228,12 +244,16 @@ void ath9k_tx_tasklet(unsigned long data) ...@@ -228,12 +244,16 @@ void ath9k_tx_tasklet(unsigned long data)
hdr = (struct ieee80211_hdr *) skb->data; hdr = (struct ieee80211_hdr *) skb->data;
fc = hdr->frame_control; fc = hdr->frame_control;
tx_info = IEEE80211_SKB_CB(skb); tx_info = IEEE80211_SKB_CB(skb);
vif = tx_info->control.vif;
memset(&tx_info->status, 0, sizeof(tx_info->status)); memset(&tx_info->status, 0, sizeof(tx_info->status));
if (!vif)
goto send_mac80211;
rcu_read_lock(); rcu_read_lock();
sta = ieee80211_find_sta(priv->vif, hdr->addr1); sta = ieee80211_find_sta(vif, hdr->addr1);
if (!sta) { if (!sta) {
rcu_read_unlock(); rcu_read_unlock();
ieee80211_tx_status(priv->hw, skb); ieee80211_tx_status(priv->hw, skb);
...@@ -263,6 +283,7 @@ void ath9k_tx_tasklet(unsigned long data) ...@@ -263,6 +283,7 @@ void ath9k_tx_tasklet(unsigned long data)
rcu_read_unlock(); rcu_read_unlock();
send_mac80211:
/* Send status to mac80211 */ /* Send status to mac80211 */
ieee80211_tx_status(priv->hw, skb); ieee80211_tx_status(priv->hw, skb);
} }
...@@ -386,7 +407,7 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv) ...@@ -386,7 +407,7 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv)
*/ */
if (((ah->opmode != NL80211_IFTYPE_AP) && if (((ah->opmode != NL80211_IFTYPE_AP) &&
(priv->rxfilter & FIF_PROMISC_IN_BSS)) || (priv->rxfilter & FIF_PROMISC_IN_BSS)) ||
(ah->opmode == NL80211_IFTYPE_MONITOR)) ah->is_monitoring)
rfilt |= ATH9K_RX_FILTER_PROM; rfilt |= ATH9K_RX_FILTER_PROM;
if (priv->rxfilter & FIF_CONTROL) if (priv->rxfilter & FIF_CONTROL)
...@@ -398,8 +419,13 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv) ...@@ -398,8 +419,13 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv)
else else
rfilt |= ATH9K_RX_FILTER_BEACON; rfilt |= ATH9K_RX_FILTER_BEACON;
if (conf_is_ht(&priv->hw->conf)) if (conf_is_ht(&priv->hw->conf)) {
rfilt |= ATH9K_RX_FILTER_COMP_BAR; rfilt |= ATH9K_RX_FILTER_COMP_BAR;
rfilt |= ATH9K_RX_FILTER_UNCOMP_BA_BAR;
}
if (priv->rxfilter & FIF_PSPOLL)
rfilt |= ATH9K_RX_FILTER_PSPOLL;
return rfilt; return rfilt;
...@@ -412,20 +438,12 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv) ...@@ -412,20 +438,12 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv)
static void ath9k_htc_opmode_init(struct ath9k_htc_priv *priv) static void ath9k_htc_opmode_init(struct ath9k_htc_priv *priv)
{ {
struct ath_hw *ah = priv->ah; struct ath_hw *ah = priv->ah;
struct ath_common *common = ath9k_hw_common(ah);
u32 rfilt, mfilt[2]; u32 rfilt, mfilt[2];
/* configure rx filter */ /* configure rx filter */
rfilt = ath9k_htc_calcrxfilter(priv); rfilt = ath9k_htc_calcrxfilter(priv);
ath9k_hw_setrxfilter(ah, rfilt); ath9k_hw_setrxfilter(ah, rfilt);
/* configure bssid mask */
ath_hw_setbssidmask(common);
/* configure operational mode */
ath9k_hw_setopmode(ah);
/* calculate and install multicast filter */ /* calculate and install multicast filter */
mfilt[0] = mfilt[1] = ~0; mfilt[0] = mfilt[1] = ~0;
ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]); ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
...@@ -576,7 +594,6 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, ...@@ -576,7 +594,6 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
ath9k_process_rate(hw, rx_status, rxbuf->rxstatus.rs_rate, ath9k_process_rate(hw, rx_status, rxbuf->rxstatus.rs_rate,
rxbuf->rxstatus.rs_flags); rxbuf->rxstatus.rs_flags);
if (priv->op_flags & OP_ASSOCIATED) {
if (rxbuf->rxstatus.rs_rssi != ATH9K_RSSI_BAD && if (rxbuf->rxstatus.rs_rssi != ATH9K_RSSI_BAD &&
!rxbuf->rxstatus.rs_moreaggr) !rxbuf->rxstatus.rs_moreaggr)
ATH_RSSI_LPF(priv->rx.last_rssi, ATH_RSSI_LPF(priv->rx.last_rssi,
...@@ -593,14 +610,13 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, ...@@ -593,14 +610,13 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
if (ieee80211_is_beacon(fc)) if (ieee80211_is_beacon(fc))
priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi; priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi;
}
rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp); rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp);
rx_status->band = hw->conf.channel->band; rx_status->band = hw->conf.channel->band;
rx_status->freq = hw->conf.channel->center_freq; rx_status->freq = hw->conf.channel->center_freq;
rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR; rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR;
rx_status->antenna = rxbuf->rxstatus.rs_antenna; rx_status->antenna = rxbuf->rxstatus.rs_antenna;
rx_status->flag |= RX_FLAG_TSFT; rx_status->flag |= RX_FLAG_MACTIME_MPDU;
return true; return true;
......
...@@ -140,6 +140,21 @@ static struct ieee80211_rate ath9k_legacy_rates[] = { ...@@ -140,6 +140,21 @@ static struct ieee80211_rate ath9k_legacy_rates[] = {
RATE(540, 0x0c, 0), RATE(540, 0x0c, 0),
}; };
#ifdef CONFIG_MAC80211_LEDS
static const struct ieee80211_tpt_blink ath9k_tpt_blink[] = {
{ .throughput = 0 * 1024, .blink_time = 334 },
{ .throughput = 1 * 1024, .blink_time = 260 },
{ .throughput = 5 * 1024, .blink_time = 220 },
{ .throughput = 10 * 1024, .blink_time = 190 },
{ .throughput = 20 * 1024, .blink_time = 170 },
{ .throughput = 50 * 1024, .blink_time = 150 },
{ .throughput = 70 * 1024, .blink_time = 130 },
{ .throughput = 100 * 1024, .blink_time = 110 },
{ .throughput = 200 * 1024, .blink_time = 80 },
{ .throughput = 300 * 1024, .blink_time = 50 },
};
#endif
static void ath9k_deinit_softc(struct ath_softc *sc); static void ath9k_deinit_softc(struct ath_softc *sc);
/* /*
...@@ -731,6 +746,13 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, ...@@ -731,6 +746,13 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
ath9k_init_txpower_limits(sc); ath9k_init_txpower_limits(sc);
#ifdef CONFIG_MAC80211_LEDS
/* must be initialized before ieee80211_register_hw */
sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw,
IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink,
ARRAY_SIZE(ath9k_tpt_blink));
#endif
/* Register with mac80211 */ /* Register with mac80211 */
error = ieee80211_register_hw(hw); error = ieee80211_register_hw(hw);
if (error) if (error)
......
...@@ -910,6 +910,8 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) ...@@ -910,6 +910,8 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
ath9k_hw_set_gpio(ah, ah->led_pin, 0); ath9k_hw_set_gpio(ah, ah->led_pin, 0);
ieee80211_wake_queues(hw); ieee80211_wake_queues(hw);
ieee80211_queue_delayed_work(hw, &sc->hw_pll_work, HZ/2);
out: out:
spin_unlock_bh(&sc->sc_pcu_lock); spin_unlock_bh(&sc->sc_pcu_lock);
...@@ -923,6 +925,8 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) ...@@ -923,6 +925,8 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
int r; int r;
ath9k_ps_wakeup(sc); ath9k_ps_wakeup(sc);
cancel_delayed_work_sync(&sc->hw_pll_work);
spin_lock_bh(&sc->sc_pcu_lock); spin_lock_bh(&sc->sc_pcu_lock);
ieee80211_stop_queues(hw); ieee80211_stop_queues(hw);
...@@ -1142,8 +1146,7 @@ static int ath9k_start(struct ieee80211_hw *hw) ...@@ -1142,8 +1146,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
return r; return r;
} }
static int ath9k_tx(struct ieee80211_hw *hw, static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
struct sk_buff *skb)
{ {
struct ath_softc *sc = hw->priv; struct ath_softc *sc = hw->priv;
struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_common *common = ath9k_hw_common(sc->sc_ah);
...@@ -1200,10 +1203,9 @@ static int ath9k_tx(struct ieee80211_hw *hw, ...@@ -1200,10 +1203,9 @@ static int ath9k_tx(struct ieee80211_hw *hw,
goto exit; goto exit;
} }
return 0; return;
exit: exit:
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return 0;
} }
static void ath9k_stop(struct ieee80211_hw *hw) static void ath9k_stop(struct ieee80211_hw *hw)
...@@ -1214,9 +1216,6 @@ static void ath9k_stop(struct ieee80211_hw *hw) ...@@ -1214,9 +1216,6 @@ static void ath9k_stop(struct ieee80211_hw *hw)
mutex_lock(&sc->mutex); mutex_lock(&sc->mutex);
if (led_blink)
cancel_delayed_work_sync(&sc->ath_led_blink_work);
cancel_delayed_work_sync(&sc->tx_complete_work); cancel_delayed_work_sync(&sc->tx_complete_work);
cancel_delayed_work_sync(&sc->hw_pll_work); cancel_delayed_work_sync(&sc->hw_pll_work);
cancel_work_sync(&sc->paprd_work); cancel_work_sync(&sc->paprd_work);
...@@ -2131,7 +2130,7 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) ...@@ -2131,7 +2130,7 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
{ {
#define ATH_FLUSH_TIMEOUT 60 /* ms */ #define ATH_FLUSH_TIMEOUT 60 /* ms */
struct ath_softc *sc = hw->priv; struct ath_softc *sc = hw->priv;
struct ath_txq *txq; struct ath_txq *txq = NULL;
struct ath_hw *ah = sc->sc_ah; struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
int i, j, npend = 0; int i, j, npend = 0;
......
...@@ -983,7 +983,7 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common, ...@@ -983,7 +983,7 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common,
rx_status->freq = hw->conf.channel->center_freq; rx_status->freq = hw->conf.channel->center_freq;
rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi; rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi;
rx_status->antenna = rx_stats->rs_antenna; rx_status->antenna = rx_stats->rs_antenna;
rx_status->flag |= RX_FLAG_TSFT; rx_status->flag |= RX_FLAG_MACTIME_MPDU;
return 0; return 0;
} }
......
...@@ -878,6 +878,7 @@ ...@@ -878,6 +878,7 @@
enum ath_usb_dev { enum ath_usb_dev {
AR9280_USB = 1, /* AR7010 + AR9280, UB94 */ AR9280_USB = 1, /* AR7010 + AR9280, UB94 */
AR9287_USB = 2, /* AR7010 + AR9287, UB95 */ AR9287_USB = 2, /* AR7010 + AR9287, UB95 */
STORAGE_DEVICE = 3,
}; };
#define AR_DEVID_7010(_ah) \ #define AR_DEVID_7010(_ah) \
......
...@@ -123,12 +123,8 @@ void ath9k_deinit_wmi(struct ath9k_htc_priv *priv) ...@@ -123,12 +123,8 @@ void ath9k_deinit_wmi(struct ath9k_htc_priv *priv)
void ath9k_swba_tasklet(unsigned long data) void ath9k_swba_tasklet(unsigned long data)
{ {
struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
struct ath_common *common = ath9k_hw_common(priv->ah);
ath_dbg(common, ATH_DBG_WMI, "SWBA Event received\n");
ath9k_htc_swba(priv, priv->wmi->beacon_pending); ath9k_htc_swba(priv, priv->wmi->beacon_pending);
} }
void ath9k_fatal_work(struct work_struct *work) void ath9k_fatal_work(struct work_struct *work)
......
...@@ -534,7 +534,7 @@ void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len); ...@@ -534,7 +534,7 @@ void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len);
void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len); void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len);
/* TX */ /* TX */
int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); void carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
void carl9170_tx_janitor(struct work_struct *work); void carl9170_tx_janitor(struct work_struct *work);
void carl9170_tx_process_status(struct ar9170 *ar, void carl9170_tx_process_status(struct ar9170 *ar,
const struct carl9170_rsp *cmd); const struct carl9170_rsp *cmd);
......
...@@ -1339,7 +1339,7 @@ static bool carl9170_tx_ampdu_queue(struct ar9170 *ar, ...@@ -1339,7 +1339,7 @@ static bool carl9170_tx_ampdu_queue(struct ar9170 *ar,
return false; return false;
} }
int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) void carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{ {
struct ar9170 *ar = hw->priv; struct ar9170 *ar = hw->priv;
struct ieee80211_tx_info *info; struct ieee80211_tx_info *info;
...@@ -1373,12 +1373,11 @@ int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -1373,12 +1373,11 @@ int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
} }
carl9170_tx(ar); carl9170_tx(ar);
return NETDEV_TX_OK; return;
err_free: err_free:
ar->tx_dropped++; ar->tx_dropped++;
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
} }
void carl9170_tx_scheduler(struct ar9170 *ar) void carl9170_tx_scheduler(struct ar9170 *ar)
......
...@@ -3203,7 +3203,7 @@ static void b43_tx_work(struct work_struct *work) ...@@ -3203,7 +3203,7 @@ static void b43_tx_work(struct work_struct *work)
mutex_unlock(&wl->mutex); mutex_unlock(&wl->mutex);
} }
static int b43_op_tx(struct ieee80211_hw *hw, static void b43_op_tx(struct ieee80211_hw *hw,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct b43_wl *wl = hw_to_b43_wl(hw); struct b43_wl *wl = hw_to_b43_wl(hw);
...@@ -3211,14 +3211,12 @@ static int b43_op_tx(struct ieee80211_hw *hw, ...@@ -3211,14 +3211,12 @@ static int b43_op_tx(struct ieee80211_hw *hw,
if (unlikely(skb->len < 2 + 2 + 6)) { if (unlikely(skb->len < 2 + 2 + 6)) {
/* Too short, this can't be a valid frame. */ /* Too short, this can't be a valid frame. */
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return NETDEV_TX_OK; return;
} }
B43_WARN_ON(skb_shinfo(skb)->nr_frags); B43_WARN_ON(skb_shinfo(skb)->nr_frags);
skb_queue_tail(&wl->tx_queue, skb); skb_queue_tail(&wl->tx_queue, skb);
ieee80211_queue_work(wl->hw, &wl->tx_work); ieee80211_queue_work(wl->hw, &wl->tx_work);
return NETDEV_TX_OK;
} }
static void b43_qos_params_upload(struct b43_wldev *dev, static void b43_qos_params_upload(struct b43_wldev *dev,
......
...@@ -430,9 +430,9 @@ static void b43_radio_init2055_post(struct b43_wldev *dev) ...@@ -430,9 +430,9 @@ static void b43_radio_init2055_post(struct b43_wldev *dev)
bool workaround = false; bool workaround = false;
if (sprom->revision < 4) if (sprom->revision < 4)
workaround = (binfo->vendor != PCI_VENDOR_ID_BROADCOM || workaround = (binfo->vendor != PCI_VENDOR_ID_BROADCOM &&
binfo->type != 0x46D || binfo->type == 0x46D &&
binfo->rev < 0x41); binfo->rev >= 0x41);
else else
workaround = workaround =
!(sprom->boardflags2_lo & B43_BFL2_RXBB_INT_REG_DIS); !(sprom->boardflags2_lo & B43_BFL2_RXBB_INT_REG_DIS);
...@@ -1281,6 +1281,7 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) ...@@ -1281,6 +1281,7 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
B43_NPHY_TABLE_DATALO, tmp); B43_NPHY_TABLE_DATALO, tmp);
} }
} }
}
b43_nphy_set_rf_sequence(dev, 5, b43_nphy_set_rf_sequence(dev, 5,
rfseq_events, rfseq_delays, 3); rfseq_events, rfseq_delays, 3);
...@@ -1292,7 +1293,6 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) ...@@ -1292,7 +1293,6 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
b43_phy_maskset(dev, B43_PHY_N(0xC5D), b43_phy_maskset(dev, B43_PHY_N(0xC5D),
0xFF80, 4); 0xFF80, 4);
} }
}
} }
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */ /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */
...@@ -2128,7 +2128,7 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, ...@@ -2128,7 +2128,7 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0); save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0);
save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1); save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1);
} else if (dev->phy.rev == 2) { } else {
save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1); save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2); save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
...@@ -2179,7 +2179,7 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, ...@@ -2179,7 +2179,7 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]); b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]);
b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]); b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]);
b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, save_regs_phy[7]); b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, save_regs_phy[7]);
} else if (dev->phy.rev == 2) { } else {
b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[0]); b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[0]);
b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[1]); b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[1]);
b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[2]); b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[2]);
......
...@@ -109,6 +109,33 @@ b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq); ...@@ -109,6 +109,33 @@ b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq);
#define B43_NTAB_C1_LOFEEDTH B43_NTAB16(0x1B, 0x1C0) /* Local Oscillator Feed Through Lookup Table Core 1 */ #define B43_NTAB_C1_LOFEEDTH B43_NTAB16(0x1B, 0x1C0) /* Local Oscillator Feed Through Lookup Table Core 1 */
#define B43_NTAB_C1_LOFEEDTH_SIZE 128 #define B43_NTAB_C1_LOFEEDTH_SIZE 128
/* Static N-PHY tables, PHY revision >= 3 */
#define B43_NTAB_FRAMESTRUCT_R3 B43_NTAB32(10, 000) /* frame struct */
#define B43_NTAB_PILOT_R3 B43_NTAB16(11, 000) /* pilot */
#define B43_NTAB_TMAP_R3 B43_NTAB32(12, 000) /* TM AP */
#define B43_NTAB_INTLEVEL_R3 B43_NTAB32(13, 000) /* INT LV */
#define B43_NTAB_TDTRN_R3 B43_NTAB32(14, 000) /* TD TRN */
#define B43_NTAB_NOISEVAR0_R3 B43_NTAB32(16, 000) /* noise variance 0 */
#define B43_NTAB_NOISEVAR1_R3 B43_NTAB32(16, 128) /* noise variance 1 */
#define B43_NTAB_MCS_R3 B43_NTAB16(18, 000) /* MCS */
#define B43_NTAB_TDI20A0_R3 B43_NTAB32(19, 128) /* TDI 20/0 */
#define B43_NTAB_TDI20A1_R3 B43_NTAB32(19, 256) /* TDI 20/1 */
#define B43_NTAB_TDI40A0_R3 B43_NTAB32(19, 640) /* TDI 40/0 */
#define B43_NTAB_TDI40A1_R3 B43_NTAB32(19, 768) /* TDI 40/1 */
#define B43_NTAB_PILOTLT_R3 B43_NTAB32(20, 000) /* PLT lookup */
#define B43_NTAB_CHANEST_R3 B43_NTAB32(22, 000) /* channel estimate */
#define B43_NTAB_FRAMELT_R3 B43_NTAB8 (24, 000) /* frame lookup */
#define B43_NTAB_C0_ESTPLT_R3 B43_NTAB8 (26, 000) /* estimated power lookup 0 */
#define B43_NTAB_C1_ESTPLT_R3 B43_NTAB8 (27, 000) /* estimated power lookup 1 */
#define B43_NTAB_C0_ADJPLT_R3 B43_NTAB8 (26, 064) /* adjusted power lookup 0 */
#define B43_NTAB_C1_ADJPLT_R3 B43_NTAB8 (27, 064) /* adjusted power lookup 1 */
#define B43_NTAB_C0_GAINCTL_R3 B43_NTAB32(26, 192) /* gain control lookup 0 */
#define B43_NTAB_C1_GAINCTL_R3 B43_NTAB32(27, 192) /* gain control lookup 1 */
#define B43_NTAB_C0_IQLT_R3 B43_NTAB32(26, 320) /* I/Q lookup 0 */
#define B43_NTAB_C1_IQLT_R3 B43_NTAB32(27, 320) /* I/Q lookup 1 */
#define B43_NTAB_C0_LOFEEDTH_R3 B43_NTAB16(26, 448) /* Local Oscillator Feed Through lookup 0 */
#define B43_NTAB_C1_LOFEEDTH_R3 B43_NTAB16(27, 448) /* Local Oscillator Feed Through lookup 1 */
#define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_40_SIZE 18 #define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_40_SIZE 18
#define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_20_SIZE 18 #define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_20_SIZE 18
#define B43_NTAB_TX_IQLO_CAL_IQIMB_LADDER_40_SIZE 18 #define B43_NTAB_TX_IQLO_CAL_IQIMB_LADDER_40_SIZE 18
......
...@@ -32,6 +32,36 @@ ...@@ -32,6 +32,36 @@
#include "dma.h" #include "dma.h"
#include "pio.h" #include "pio.h"
static const struct b43_tx_legacy_rate_phy_ctl_entry b43_tx_legacy_rate_phy_ctl[] = {
{ B43_CCK_RATE_1MB, 0x0, 0x0 },
{ B43_CCK_RATE_2MB, 0x0, 0x1 },
{ B43_CCK_RATE_5MB, 0x0, 0x2 },
{ B43_CCK_RATE_11MB, 0x0, 0x3 },
{ B43_OFDM_RATE_6MB, B43_TXH_PHY1_CRATE_1_2, B43_TXH_PHY1_MODUL_BPSK },
{ B43_OFDM_RATE_9MB, B43_TXH_PHY1_CRATE_3_4, B43_TXH_PHY1_MODUL_BPSK },
{ B43_OFDM_RATE_12MB, B43_TXH_PHY1_CRATE_1_2, B43_TXH_PHY1_MODUL_QPSK },
{ B43_OFDM_RATE_18MB, B43_TXH_PHY1_CRATE_3_4, B43_TXH_PHY1_MODUL_QPSK },
{ B43_OFDM_RATE_24MB, B43_TXH_PHY1_CRATE_1_2, B43_TXH_PHY1_MODUL_QAM16 },
{ B43_OFDM_RATE_36MB, B43_TXH_PHY1_CRATE_3_4, B43_TXH_PHY1_MODUL_QAM16 },
{ B43_OFDM_RATE_48MB, B43_TXH_PHY1_CRATE_2_3, B43_TXH_PHY1_MODUL_QAM64 },
{ B43_OFDM_RATE_54MB, B43_TXH_PHY1_CRATE_3_4, B43_TXH_PHY1_MODUL_QAM64 },
};
static const struct b43_tx_legacy_rate_phy_ctl_entry *
b43_tx_legacy_rate_phy_ctl_ent(u8 bitrate)
{
const struct b43_tx_legacy_rate_phy_ctl_entry *e;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(b43_tx_legacy_rate_phy_ctl); i++) {
e = &(b43_tx_legacy_rate_phy_ctl[i]);
if (e->bitrate == bitrate)
return e;
}
B43_WARN_ON(1);
return NULL;
}
/* Extract the bitrate index out of a CCK PLCP header. */ /* Extract the bitrate index out of a CCK PLCP header. */
static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp) static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp)
...@@ -145,6 +175,34 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp, ...@@ -145,6 +175,34 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp,
} }
} }
static u16 b43_generate_tx_phy_ctl1(struct b43_wldev *dev, u8 bitrate)
{
const struct b43_phy *phy = &dev->phy;
const struct b43_tx_legacy_rate_phy_ctl_entry *e;
u16 control = 0;
u16 bw;
if (phy->type == B43_PHYTYPE_LP)
bw = B43_TXH_PHY1_BW_20;
else /* FIXME */
bw = B43_TXH_PHY1_BW_20;
if (0) { /* FIXME: MIMO */
} else if (b43_is_cck_rate(bitrate) && phy->type != B43_PHYTYPE_LP) {
control = bw;
} else {
control = bw;
e = b43_tx_legacy_rate_phy_ctl_ent(bitrate);
if (e) {
control |= e->coding_rate;
control |= e->modulation;
}
control |= B43_TXH_PHY1_MODE_SISO;
}
return control;
}
static u8 b43_calc_fallback_rate(u8 bitrate) static u8 b43_calc_fallback_rate(u8 bitrate)
{ {
switch (bitrate) { switch (bitrate) {
...@@ -437,6 +495,14 @@ int b43_generate_txhdr(struct b43_wldev *dev, ...@@ -437,6 +495,14 @@ int b43_generate_txhdr(struct b43_wldev *dev,
extra_ft |= B43_TXH_EFT_RTSFB_OFDM; extra_ft |= B43_TXH_EFT_RTSFB_OFDM;
else else
extra_ft |= B43_TXH_EFT_RTSFB_CCK; extra_ft |= B43_TXH_EFT_RTSFB_CCK;
if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS &&
phy->type == B43_PHYTYPE_N) {
txhdr->phy_ctl1_rts = cpu_to_le16(
b43_generate_tx_phy_ctl1(dev, rts_rate));
txhdr->phy_ctl1_rts_fb = cpu_to_le16(
b43_generate_tx_phy_ctl1(dev, rts_rate_fb));
}
} }
/* Magic cookie */ /* Magic cookie */
...@@ -445,6 +511,13 @@ int b43_generate_txhdr(struct b43_wldev *dev, ...@@ -445,6 +511,13 @@ int b43_generate_txhdr(struct b43_wldev *dev,
else else
txhdr->new_format.cookie = cpu_to_le16(cookie); txhdr->new_format.cookie = cpu_to_le16(cookie);
if (phy->type == B43_PHYTYPE_N) {
txhdr->phy_ctl1 =
cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate));
txhdr->phy_ctl1_fb =
cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate_fb));
}
/* Apply the bitfields */ /* Apply the bitfields */
txhdr->mac_ctl = cpu_to_le32(mac_ctl); txhdr->mac_ctl = cpu_to_le32(mac_ctl);
txhdr->phy_ctl = cpu_to_le16(phy_ctl); txhdr->phy_ctl = cpu_to_le16(phy_ctl);
...@@ -652,7 +725,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) ...@@ -652,7 +725,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
status.mactime += mactime; status.mactime += mactime;
if (low_mactime_now <= mactime) if (low_mactime_now <= mactime)
status.mactime -= 0x10000; status.mactime -= 0x10000;
status.flag |= RX_FLAG_TSFT; status.flag |= RX_FLAG_MACTIME_MPDU;
} }
chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT; chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT;
......
...@@ -73,6 +73,12 @@ struct b43_txhdr { ...@@ -73,6 +73,12 @@ struct b43_txhdr {
} __packed; } __packed;
} __packed; } __packed;
struct b43_tx_legacy_rate_phy_ctl_entry {
u8 bitrate;
u16 coding_rate;
u16 modulation;
};
/* MAC TX control */ /* MAC TX control */
#define B43_TXH_MAC_USEFBR 0x10000000 /* Use fallback rate for this AMPDU */ #define B43_TXH_MAC_USEFBR 0x10000000 /* Use fallback rate for this AMPDU */
#define B43_TXH_MAC_KEYIDX 0x0FF00000 /* Security key index */ #define B43_TXH_MAC_KEYIDX 0x0FF00000 /* Security key index */
......
...@@ -2442,7 +2442,7 @@ static int b43legacy_rng_init(struct b43legacy_wl *wl) ...@@ -2442,7 +2442,7 @@ static int b43legacy_rng_init(struct b43legacy_wl *wl)
return err; return err;
} }
static int b43legacy_op_tx(struct ieee80211_hw *hw, static void b43legacy_op_tx(struct ieee80211_hw *hw,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
...@@ -2466,7 +2466,6 @@ static int b43legacy_op_tx(struct ieee80211_hw *hw, ...@@ -2466,7 +2466,6 @@ static int b43legacy_op_tx(struct ieee80211_hw *hw,
/* Drop the packet. */ /* Drop the packet. */
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
} }
return NETDEV_TX_OK;
} }
static int b43legacy_op_conf_tx(struct ieee80211_hw *hw, u16 queue, static int b43legacy_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
......
...@@ -572,7 +572,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev, ...@@ -572,7 +572,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
status.mactime += mactime; status.mactime += mactime;
if (low_mactime_now <= mactime) if (low_mactime_now <= mactime)
status.mactime -= 0x10000; status.mactime -= 0x10000;
status.flag |= RX_FLAG_TSFT; status.flag |= RX_FLAG_MACTIME_MPDU;
} }
chanid = (chanstat & B43legacy_RX_CHAN_ID) >> chanid = (chanstat & B43legacy_RX_CHAN_ID) >>
......
config IWLWIFI_LEGACY
tristate "Intel Wireless Wifi legacy devices"
depends on PCI && MAC80211
select FW_LOADER
select NEW_LEDS
select LEDS_CLASS
select LEDS_TRIGGERS
select MAC80211_LEDS
menu "Debugging Options"
depends on IWLWIFI_LEGACY
config IWLWIFI_LEGACY_DEBUG
bool "Enable full debugging output in 4965 and 3945 drivers"
depends on IWLWIFI_LEGACY
---help---
This option will enable debug tracing output for the iwlwifilegacy
drivers.
This will result in the kernel module being ~100k larger. You can
control which debug output is sent to the kernel log by setting the
value in
/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/class/net/wlan0/device/debug_level
You can find the list of debug mask values in:
drivers/net/wireless/iwlwifilegacy/iwl-debug.h
If this is your first time using this driver, you should say Y here
as the debug information can assist others in helping you resolve
any problems you may encounter.
config IWLWIFI_LEGACY_DEBUGFS
bool "4965 and 3945 debugfs support"
depends on IWLWIFI_LEGACY && MAC80211_DEBUGFS
---help---
Enable creation of debugfs files for the iwlwifilegacy drivers. This
is a low-impact option that allows getting insight into the
driver's state at runtime.
config IWLWIFI_LEGACY_DEVICE_TRACING
bool "iwlwifilegacy legacy device access tracing"
depends on IWLWIFI_LEGACY
depends on EVENT_TRACING
help
Say Y here to trace all commands, including TX frames and IO
accesses, sent to the device. If you say yes, iwlwifilegacy will
register with the ftrace framework for event tracing and dump
all this information to the ringbuffer, you may need to
increase the ringbuffer size. See the ftrace documentation
for more information.
When tracing is not enabled, this option still has some
(though rather small) overhead.
If unsure, say Y so we can help you better when problems
occur.
endmenu
config IWL4965
tristate "Intel Wireless WiFi 4965AGN (iwl4965)"
depends on IWLWIFI_LEGACY
---help---
This option enables support for
Select to build the driver supporting the:
Intel Wireless WiFi Link 4965AGN
This driver uses the kernel's mac80211 subsystem.
In order to use this driver, you will need a microcode (uCode)
image for it. You can obtain the microcode from:
<http://intellinuxwireless.org/>.
The microcode is typically installed in /lib/firmware. You can
look in the hotplug script /etc/hotplug/firmware.agent to
determine which directory FIRMWARE_DIR is set to when the script
runs.
If you want to compile the driver as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
say M here and read <file:Documentation/kbuild/modules.txt>. The
module will be called iwl4965.
config IWL3945
tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)"
depends on IWLWIFI_LEGACY
---help---
Select to build the driver supporting the:
Intel PRO/Wireless 3945ABG/BG Network Connection
This driver uses the kernel's mac80211 subsystem.
In order to use this driver, you will need a microcode (uCode)
image for it. You can obtain the microcode from:
<http://intellinuxwireless.org/>.
The microcode is typically installed in /lib/firmware. You can
look in the hotplug script /etc/hotplug/firmware.agent to
determine which directory FIRMWARE_DIR is set to when the script
runs.
If you want to compile the driver as a module ( = code which can be
inserted in and removed from the running kernel whenever you want),
say M here and read <file:Documentation/kbuild/modules.txt>. The
module will be called iwl3945.
obj-$(CONFIG_IWLWIFI_LEGACY) += iwl-legacy.o
iwl-legacy-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o
iwl-legacy-objs += iwl-rx.o iwl-tx.o iwl-sta.o
iwl-legacy-objs += iwl-scan.o iwl-led.o
iwl-legacy-$(CONFIG_IWLWIFI_LEGACY_DEBUGFS) += iwl-debugfs.o
iwl-legacy-$(CONFIG_IWLWIFI_LEGACY_DEVICE_TRACING) += iwl-devtrace.o
iwl-legacy-objs += $(iwl-legacy-m)
CFLAGS_iwl-devtrace.o := -I$(src)
# 4965
obj-$(CONFIG_IWL4965) += iwl4965.o
iwl4965-objs := iwl-4965.o iwl4965-base.o iwl-4965-rs.o iwl-4965-led.o
iwl4965-objs += iwl-4965-ucode.o iwl-4965-tx.o
iwl4965-objs += iwl-4965-lib.o iwl-4965-rx.o iwl-4965-calib.o
iwl4965-objs += iwl-4965-sta.o iwl-4965-eeprom.o
iwl4965-$(CONFIG_IWLWIFI_LEGACY_DEBUGFS) += iwl-4965-debugfs.o
# 3945
obj-$(CONFIG_IWL3945) += iwl3945.o
iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o
iwl3945-$(CONFIG_IWLWIFI_LEGACY_DEBUGFS) += iwl-3945-debugfs.o
ccflags-y += -D__CHECK_ENDIAN__
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* *
* GPL LICENSE SUMMARY * GPL LICENSE SUMMARY
* *
* Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of version 2 of the GNU General Public License as
...@@ -60,12 +60,13 @@ ssize_t iwl3945_ucode_rx_stats_read(struct file *file, ...@@ -60,12 +60,13 @@ ssize_t iwl3945_ucode_rx_stats_read(struct file *file,
int bufsz = sizeof(struct iwl39_statistics_rx_phy) * 40 + int bufsz = sizeof(struct iwl39_statistics_rx_phy) * 40 +
sizeof(struct iwl39_statistics_rx_non_phy) * 40 + 400; sizeof(struct iwl39_statistics_rx_non_phy) * 40 + 400;
ssize_t ret; ssize_t ret;
struct iwl39_statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm; struct iwl39_statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm,
*max_ofdm;
struct iwl39_statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck; struct iwl39_statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck;
struct iwl39_statistics_rx_non_phy *general, *accum_general; struct iwl39_statistics_rx_non_phy *general, *accum_general;
struct iwl39_statistics_rx_non_phy *delta_general, *max_general; struct iwl39_statistics_rx_non_phy *delta_general, *max_general;
if (!iwl_is_alive(priv)) if (!iwl_legacy_is_alive(priv))
return -EAGAIN; return -EAGAIN;
buf = kzalloc(bufsz, GFP_KERNEL); buf = kzalloc(bufsz, GFP_KERNEL);
...@@ -335,7 +336,7 @@ ssize_t iwl3945_ucode_tx_stats_read(struct file *file, ...@@ -335,7 +336,7 @@ ssize_t iwl3945_ucode_tx_stats_read(struct file *file,
ssize_t ret; ssize_t ret;
struct iwl39_statistics_tx *tx, *accum_tx, *delta_tx, *max_tx; struct iwl39_statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
if (!iwl_is_alive(priv)) if (!iwl_legacy_is_alive(priv))
return -EAGAIN; return -EAGAIN;
buf = kzalloc(bufsz, GFP_KERNEL); buf = kzalloc(bufsz, GFP_KERNEL);
...@@ -434,7 +435,7 @@ ssize_t iwl3945_ucode_general_stats_read(struct file *file, ...@@ -434,7 +435,7 @@ ssize_t iwl3945_ucode_general_stats_read(struct file *file,
struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg; struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
struct iwl39_statistics_div *div, *accum_div, *delta_div, *max_div; struct iwl39_statistics_div *div, *accum_div, *delta_div, *max_div;
if (!iwl_is_alive(priv)) if (!iwl_legacy_is_alive(priv))
return -EAGAIN; return -EAGAIN;
buf = kzalloc(bufsz, GFP_KERNEL); buf = kzalloc(bufsz, GFP_KERNEL);
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* *
* GPL LICENSE SUMMARY * GPL LICENSE SUMMARY
* *
* Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of version 2 of the GNU General Public License as
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include "iwl-core.h" #include "iwl-core.h"
#include "iwl-debug.h" #include "iwl-debug.h"
#ifdef CONFIG_IWLWIFI_DEBUGFS #ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS
ssize_t iwl3945_ucode_rx_stats_read(struct file *file, char __user *user_buf, ssize_t iwl3945_ucode_rx_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos); size_t count, loff_t *ppos);
ssize_t iwl3945_ucode_tx_stats_read(struct file *file, char __user *user_buf, ssize_t iwl3945_ucode_tx_stats_read(struct file *file, char __user *user_buf,
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* GPL LICENSE SUMMARY * GPL LICENSE SUMMARY
* *
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of version 2 of the GNU General Public License as
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
* *
* BSD LICENSE * BSD LICENSE
* *
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -185,4 +185,3 @@ struct iwl3945_tfd { ...@@ -185,4 +185,3 @@ struct iwl3945_tfd {
#endif /* __iwl_3945_fh_h__ */ #endif /* __iwl_3945_fh_h__ */
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* GPL LICENSE SUMMARY * GPL LICENSE SUMMARY
* *
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of version 2 of the GNU General Public License as
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
* *
* BSD LICENSE * BSD LICENSE
* *
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -164,12 +164,11 @@ struct iwl3945_eeprom { ...@@ -164,12 +164,11 @@ struct iwl3945_eeprom {
/* /*
* Per-channel regulatory data. * Per-channel regulatory data.
* *
* Each channel that *might* be supported by 3945 or 4965 has a fixed location * Each channel that *might* be supported by 3945 has a fixed location
* in EEPROM containing EEPROM_CHANNEL_* usage flags (LSB) and max regulatory * in EEPROM containing EEPROM_CHANNEL_* usage flags (LSB) and max regulatory
* txpower (MSB). * txpower (MSB).
* *
* Entries immediately below are for 20 MHz channel width. HT40 (40 MHz) * Entries immediately below are for 20 MHz channel width.
* channels (only for 4965, not supported by 3945) appear later in the EEPROM.
* *
* 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 * 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
*/ */
......
/****************************************************************************** /******************************************************************************
* *
* Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify it * 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 * under the terms of version 2 of the GNU General Public License as
...@@ -56,7 +56,7 @@ static int iwl3945_send_led_cmd(struct iwl_priv *priv, ...@@ -56,7 +56,7 @@ static int iwl3945_send_led_cmd(struct iwl_priv *priv,
.callback = NULL, .callback = NULL,
}; };
return iwl_send_cmd(priv, &cmd); return iwl_legacy_send_cmd(priv, &cmd);
} }
const struct iwl_led_ops iwl3945_led_ops = { const struct iwl_led_ops iwl3945_led_ops = {
......
/****************************************************************************** /******************************************************************************
* *
* Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify it * 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 * under the terms of version 2 of the GNU General Public License as
......
/****************************************************************************** /******************************************************************************
* *
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify it * 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 * under the terms of version 2 of the GNU General Public License as
...@@ -394,18 +394,18 @@ void iwl3945_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 s ...@@ -394,18 +394,18 @@ void iwl3945_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 s
IWL_DEBUG_INFO(priv, "leave\n"); IWL_DEBUG_INFO(priv, "leave\n");
} }
static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) static void *iwl3945_rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
{ {
return hw->priv; return hw->priv;
} }
/* rate scale requires free function to be implemented */ /* rate scale requires free function to be implemented */
static void rs_free(void *priv) static void iwl3945_rs_free(void *priv)
{ {
return; return;
} }
static void *rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp) static void *iwl3945_rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp)
{ {
struct iwl3945_rs_sta *rs_sta; struct iwl3945_rs_sta *rs_sta;
struct iwl3945_sta_priv *psta = (void *) sta->drv_priv; struct iwl3945_sta_priv *psta = (void *) sta->drv_priv;
...@@ -423,7 +423,7 @@ static void *rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp) ...@@ -423,7 +423,7 @@ static void *rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp)
return rs_sta; return rs_sta;
} }
static void rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta, static void iwl3945_rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta,
void *priv_sta) void *priv_sta)
{ {
struct iwl3945_rs_sta *rs_sta = priv_sta; struct iwl3945_rs_sta *rs_sta = priv_sta;
...@@ -438,12 +438,12 @@ static void rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta, ...@@ -438,12 +438,12 @@ static void rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta,
/** /**
* rs_tx_status - Update rate control values based on Tx results * iwl3945_rs_tx_status - Update rate control values based on Tx results
* *
* NOTE: Uses iwl_priv->retry_rate for the # of retries attempted by * NOTE: Uses iwl_priv->retry_rate for the # of retries attempted by
* the hardware for each rate. * the hardware for each rate.
*/ */
static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband, static void iwl3945_rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, void *priv_sta, struct ieee80211_sta *sta, void *priv_sta,
struct sk_buff *skb) struct sk_buff *skb)
{ {
...@@ -612,7 +612,7 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta, ...@@ -612,7 +612,7 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta,
} }
/** /**
* rs_get_rate - find the rate for the requested packet * iwl3945_rs_get_rate - find the rate for the requested packet
* *
* Returns the ieee80211_rate structure allocated by the driver. * Returns the ieee80211_rate structure allocated by the driver.
* *
...@@ -627,7 +627,7 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta, ...@@ -627,7 +627,7 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta,
* rate table and must reference the driver allocated rate table * rate table and must reference the driver allocated rate table
* *
*/ */
static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, static void iwl3945_rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
void *priv_sta, struct ieee80211_tx_rate_control *txrc) void *priv_sta, struct ieee80211_tx_rate_control *txrc)
{ {
struct ieee80211_supported_band *sband = txrc->sband; struct ieee80211_supported_band *sband = txrc->sband;
...@@ -644,7 +644,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, ...@@ -644,7 +644,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
u32 fail_count; u32 fail_count;
s8 scale_action = 0; s8 scale_action = 0;
unsigned long flags; unsigned long flags;
u16 rate_mask = sta ? sta->supp_rates[sband->band] : 0; u16 rate_mask;
s8 max_rate_idx = -1; s8 max_rate_idx = -1;
struct iwl_priv *priv __maybe_unused = (struct iwl_priv *)priv_r; struct iwl_priv *priv __maybe_unused = (struct iwl_priv *)priv_r;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
...@@ -899,7 +899,8 @@ static void iwl3945_remove_debugfs(void *priv, void *priv_sta) ...@@ -899,7 +899,8 @@ static void iwl3945_remove_debugfs(void *priv, void *priv_sta)
* the station is added. Since mac80211 calls this function before a * the station is added. Since mac80211 calls this function before a
* station is added we ignore it. * station is added we ignore it.
*/ */
static void rs_rate_init_stub(void *priv_r, struct ieee80211_supported_band *sband, static void iwl3945_rs_rate_init_stub(void *priv_r,
struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, void *priv_sta) struct ieee80211_sta *sta, void *priv_sta)
{ {
} }
...@@ -907,13 +908,13 @@ static void rs_rate_init_stub(void *priv_r, struct ieee80211_supported_band *sba ...@@ -907,13 +908,13 @@ static void rs_rate_init_stub(void *priv_r, struct ieee80211_supported_band *sba
static struct rate_control_ops rs_ops = { static struct rate_control_ops rs_ops = {
.module = NULL, .module = NULL,
.name = RS_NAME, .name = RS_NAME,
.tx_status = rs_tx_status, .tx_status = iwl3945_rs_tx_status,
.get_rate = rs_get_rate, .get_rate = iwl3945_rs_get_rate,
.rate_init = rs_rate_init_stub, .rate_init = iwl3945_rs_rate_init_stub,
.alloc = rs_alloc, .alloc = iwl3945_rs_alloc,
.free = rs_free, .free = iwl3945_rs_free,
.alloc_sta = rs_alloc_sta, .alloc_sta = iwl3945_rs_alloc_sta,
.free_sta = rs_free_sta, .free_sta = iwl3945_rs_free_sta,
#ifdef CONFIG_MAC80211_DEBUGFS #ifdef CONFIG_MAC80211_DEBUGFS
.add_sta_debugfs = iwl3945_add_debugfs, .add_sta_debugfs = iwl3945_add_debugfs,
.remove_sta_debugfs = iwl3945_remove_debugfs, .remove_sta_debugfs = iwl3945_remove_debugfs,
...@@ -991,5 +992,3 @@ void iwl3945_rate_control_unregister(void) ...@@ -991,5 +992,3 @@ void iwl3945_rate_control_unregister(void)
{ {
ieee80211_rate_control_unregister(&rs_ops); ieee80211_rate_control_unregister(&rs_ops);
} }
/****************************************************************************** /******************************************************************************
* *
* Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify it * 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 * under the terms of version 2 of the GNU General Public License as
...@@ -108,7 +108,7 @@ struct iwl3945_rs_sta { ...@@ -108,7 +108,7 @@ struct iwl3945_rs_sta {
/* /*
* The common struct MUST be first because it is shared between * The common struct MUST be first because it is shared between
* 3945 and agn! * 3945 and 4965!
*/ */
struct iwl3945_sta_priv { struct iwl3945_sta_priv {
struct iwl_station_priv_common common; struct iwl_station_priv_common common;
...@@ -201,7 +201,7 @@ struct iwl3945_ibss_seq { ...@@ -201,7 +201,7 @@ struct iwl3945_ibss_seq {
/****************************************************************************** /******************************************************************************
* *
* Functions implemented in iwl-base.c which are forward declared here * Functions implemented in iwl3945-base.c which are forward declared here
* for use by iwl-*.c * for use by iwl-*.c
* *
*****************************************************************************/ *****************************************************************************/
...@@ -209,7 +209,7 @@ extern int iwl3945_calc_db_from_ratio(int sig_ratio); ...@@ -209,7 +209,7 @@ extern int iwl3945_calc_db_from_ratio(int sig_ratio);
extern void iwl3945_rx_replenish(void *data); extern void iwl3945_rx_replenish(void *data);
extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
struct ieee80211_hdr *hdr,int left); struct ieee80211_hdr *hdr, int left);
extern int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log, extern int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
char **buf, bool display); char **buf, bool display);
extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv); extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv);
...@@ -217,7 +217,7 @@ extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv); ...@@ -217,7 +217,7 @@ extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv);
/****************************************************************************** /******************************************************************************
* *
* Functions implemented in iwl-[34]*.c which are forward declared here * Functions implemented in iwl-[34]*.c which are forward declared here
* for use by iwl-base.c * for use by iwl3945-base.c
* *
* NOTE: The implementation of these functions are hardware specific * NOTE: The implementation of these functions are hardware specific
* which is why they are in the hardware specific files (vs. iwl-base.c) * which is why they are in the hardware specific files (vs. iwl-base.c)
...@@ -283,7 +283,7 @@ extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid); ...@@ -283,7 +283,7 @@ extern u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *bssid);
extern struct ieee80211_ops iwl3945_hw_ops; extern struct ieee80211_ops iwl3945_hw_ops;
/* /*
* Forward declare iwl-3945.c functions for iwl-base.c * Forward declare iwl-3945.c functions for iwl3945-base.c
*/ */
extern __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv); extern __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv);
extern int iwl3945_init_hw_rate_table(struct iwl_priv *priv); extern int iwl3945_init_hw_rate_table(struct iwl_priv *priv);
......
此差异已折叠。
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* GPL LICENSE SUMMARY * GPL LICENSE SUMMARY
* *
* Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of version 2 of the GNU General Public License as
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
* *
* BSD LICENSE * BSD LICENSE
* *
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -59,21 +59,17 @@ ...@@ -59,21 +59,17 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/ *****************************************************************************/
#ifndef __iwl_4965_calib_h__
#define __iwl_4965_calib_h__
#ifndef __iwl_legacy_h__ #include "iwl-dev.h"
#define __iwl_legacy_h__ #include "iwl-core.h"
#include "iwl-commands.h"
/* mac80211 handlers */ void iwl4965_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp);
int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed); void iwl4965_sensitivity_calibration(struct iwl_priv *priv, void *resp);
void iwl_legacy_mac_reset_tsf(struct ieee80211_hw *hw); void iwl4965_init_sensitivity(struct iwl_priv *priv);
void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw, void iwl4965_reset_run_time_calib(struct iwl_priv *priv);
struct ieee80211_vif *vif, void iwl4965_calib_free_results(struct iwl_priv *priv);
struct ieee80211_bss_conf *bss_conf,
u32 changes);
void iwl_legacy_tx_cmd_protection(struct iwl_priv *priv,
struct ieee80211_tx_info *info,
__le16 fc, __le32 *tx_flags);
irqreturn_t iwl_isr_legacy(int irq, void *data); #endif /* __iwl_4965_calib_h__ */
#endif /* __iwl_legacy_h__ */
此差异已折叠。
/******************************************************************************
*
* GPL LICENSE SUMMARY
*
* Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
*
* 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.GPL.
*
* Contact Information:
* Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*****************************************************************************/
#include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-debug.h"
#ifdef CONFIG_IWLWIFI_LEGACY_DEBUGFS
ssize_t iwl4965_ucode_rx_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos);
ssize_t iwl4965_ucode_tx_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos);
ssize_t iwl4965_ucode_general_stats_read(struct file *file,
char __user *user_buf, size_t count, loff_t *ppos);
#else
static ssize_t
iwl4965_ucode_rx_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
return 0;
}
static ssize_t
iwl4965_ucode_tx_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
return 0;
}
static ssize_t
iwl4965_ucode_general_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
return 0;
}
#endif
/******************************************************************************
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* GPL LICENSE SUMMARY
*
* Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
*
* 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.GPL.
*
* Contact Information:
* Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
*
* Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <net/mac80211.h>
#include "iwl-commands.h"
#include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-debug.h"
#include "iwl-4965.h"
#include "iwl-io.h"
/******************************************************************************
*
* EEPROM related functions
*
******************************************************************************/
/*
* The device's EEPROM semaphore prevents conflicts between driver and uCode
* when accessing the EEPROM; each access is a series of pulses to/from the
* EEPROM chip, not a single event, so even reads could conflict if they
* weren't arbitrated by the semaphore.
*/
int iwl4965_eeprom_acquire_semaphore(struct iwl_priv *priv)
{
u16 count;
int ret;
for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
/* Request semaphore */
iwl_legacy_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
/* See if we got it */
ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
EEPROM_SEM_TIMEOUT);
if (ret >= 0) {
IWL_DEBUG_IO(priv,
"Acquired semaphore after %d tries.\n",
count+1);
return ret;
}
}
return ret;
}
void iwl4965_eeprom_release_semaphore(struct iwl_priv *priv)
{
iwl_legacy_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
}
int iwl4965_eeprom_check_version(struct iwl_priv *priv)
{
u16 eeprom_ver;
u16 calib_ver;
eeprom_ver = iwl_legacy_eeprom_query16(priv, EEPROM_VERSION);
calib_ver = iwl_legacy_eeprom_query16(priv,
EEPROM_4965_CALIB_VERSION_OFFSET);
if (eeprom_ver < priv->cfg->eeprom_ver ||
calib_ver < priv->cfg->eeprom_calib_ver)
goto err;
IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n",
eeprom_ver, calib_ver);
return 0;
err:
IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x "
"CALIB=0x%x < 0x%x\n",
eeprom_ver, priv->cfg->eeprom_ver,
calib_ver, priv->cfg->eeprom_calib_ver);
return -EINVAL;
}
void iwl4965_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac)
{
const u8 *addr = iwl_legacy_eeprom_query_addr(priv,
EEPROM_MAC_ADDRESS);
memcpy(mac, addr, ETH_ALEN);
}
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* GPL LICENSE SUMMARY * GPL LICENSE SUMMARY
* *
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of version 2 of the GNU General Public License as
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
* *
* BSD LICENSE * BSD LICENSE
* *
* Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -789,4 +789,26 @@ struct iwl4965_scd_bc_tbl { ...@@ -789,4 +789,26 @@ struct iwl4965_scd_bc_tbl {
u8 pad[1024 - (TFD_QUEUE_BC_SIZE) * sizeof(__le16)]; u8 pad[1024 - (TFD_QUEUE_BC_SIZE) * sizeof(__le16)];
} __packed; } __packed;
#define IWL4965_RTC_INST_LOWER_BOUND (0x000000)
/* RSSI to dBm */
#define IWL4965_RSSI_OFFSET 44
/* PCI registers */
#define PCI_CFG_RETRY_TIMEOUT 0x041
/* PCI register values */
#define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01
#define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02
#define IWL4965_DEFAULT_TX_RETRY 15
/* Limit range of txpower output target to be between these values */
#define IWL4965_TX_POWER_TARGET_POWER_MIN (0) /* 0 dBm: 1 milliwatt */
/* EEPROM */
#define IWL4965_FIRST_AMPDU_QUEUE 10
#endif /* !__iwl_4965_hw_h__ */ #endif /* !__iwl_4965_hw_h__ */
/******************************************************************************
*
* Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
*
* 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:
* Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/wireless.h>
#include <net/mac80211.h>
#include <linux/etherdevice.h>
#include <asm/unaligned.h>
#include "iwl-commands.h"
#include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-io.h"
#include "iwl-4965-led.h"
/* Send led command */
static int
iwl4965_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
{
struct iwl_host_cmd cmd = {
.id = REPLY_LEDS_CMD,
.len = sizeof(struct iwl_led_cmd),
.data = led_cmd,
.flags = CMD_ASYNC,
.callback = NULL,
};
u32 reg;
reg = iwl_read32(priv, CSR_LED_REG);
if (reg != (reg & CSR_LED_BSM_CTRL_MSK))
iwl_write32(priv, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK);
return iwl_legacy_send_cmd(priv, &cmd);
}
/* Set led register off */
void iwl4965_led_enable(struct iwl_priv *priv)
{
iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON);
}
const struct iwl_led_ops iwl4965_led_ops = {
.cmd = iwl4965_send_led_cmd,
};
/****************************************************************************** /******************************************************************************
* *
* Copyright(c) 2009-2010 Realtek Corporation. * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify it * 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 * under the terms of version 2 of the GNU General Public License as
...@@ -19,12 +19,15 @@ ...@@ -19,12 +19,15 @@
* file called LICENSE. * file called LICENSE.
* *
* Contact Information: * Contact Information:
* wlanfae <wlanfae@realtek.com> * Intel Linux Wireless <ilw@linux.intel.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
* *
*****************************************************************************/ *****************************************************************************/
#include "../rtl8192ce/fw.h" #ifndef __iwl_4965_led_h__
#define __iwl_4965_led_h__
extern const struct iwl_led_ops iwl4965_led_ops;
void iwl4965_led_enable(struct iwl_priv *priv);
#endif /* __iwl_4965_led_h__ */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
/******************************************************************************
*
* Copyright(c) 2009 - 2011 Intel Corporation. All rights reserved.
*
* 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:
* Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
*****************************************************************************/
#include <linux/module.h>
/* sparse doesn't like tracepoint macros */
#ifndef __CHECKER__
#include "iwl-dev.h"
#define CREATE_TRACE_POINTS
#include "iwl-devtrace.h"
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_iowrite8);
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ioread32);
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_iowrite32);
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_rx);
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_tx);
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ucode_event);
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ucode_error);
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ucode_cont_event);
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_legacy_dev_ucode_wrap_event);
#endif
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册