mirror of
https://github.com/torvalds/linux.git
synced 2024-12-11 13:41:55 +00:00
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6
This commit is contained in:
commit
e91db5cd6f
@ -1917,7 +1917,8 @@ ath5k_beacon_send(struct ath5k_softc *sc)
|
|||||||
sc->bmisscount = 0;
|
sc->bmisscount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) {
|
if ((sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) ||
|
||||||
|
sc->opmode == NL80211_IFTYPE_MESH_POINT) {
|
||||||
u64 tsf = ath5k_hw_get_tsf64(ah);
|
u64 tsf = ath5k_hw_get_tsf64(ah);
|
||||||
u32 tsftu = TSF_TO_TU(tsf);
|
u32 tsftu = TSF_TO_TU(tsf);
|
||||||
int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval;
|
int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval;
|
||||||
@ -1949,8 +1950,9 @@ ath5k_beacon_send(struct ath5k_softc *sc)
|
|||||||
/* NB: hw still stops DMA, so proceed */
|
/* NB: hw still stops DMA, so proceed */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* refresh the beacon for AP mode */
|
/* refresh the beacon for AP or MESH mode */
|
||||||
if (sc->opmode == NL80211_IFTYPE_AP)
|
if (sc->opmode == NL80211_IFTYPE_AP ||
|
||||||
|
sc->opmode == NL80211_IFTYPE_MESH_POINT)
|
||||||
ath5k_beacon_update(sc->hw, vif);
|
ath5k_beacon_update(sc->hw, vif);
|
||||||
|
|
||||||
ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
|
ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
|
||||||
@ -2851,7 +2853,8 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
|
|||||||
|
|
||||||
/* Assign the vap/adhoc to a beacon xmit slot. */
|
/* Assign the vap/adhoc to a beacon xmit slot. */
|
||||||
if ((avf->opmode == NL80211_IFTYPE_AP) ||
|
if ((avf->opmode == NL80211_IFTYPE_AP) ||
|
||||||
(avf->opmode == NL80211_IFTYPE_ADHOC)) {
|
(avf->opmode == NL80211_IFTYPE_ADHOC) ||
|
||||||
|
(avf->opmode == NL80211_IFTYPE_MESH_POINT)) {
|
||||||
int slot;
|
int slot;
|
||||||
|
|
||||||
WARN_ON(list_empty(&sc->bcbuf));
|
WARN_ON(list_empty(&sc->bcbuf));
|
||||||
@ -2870,7 +2873,7 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
|
|||||||
sc->bslot[avf->bslot] = vif;
|
sc->bslot[avf->bslot] = vif;
|
||||||
if (avf->opmode == NL80211_IFTYPE_AP)
|
if (avf->opmode == NL80211_IFTYPE_AP)
|
||||||
sc->num_ap_vifs++;
|
sc->num_ap_vifs++;
|
||||||
else
|
else if (avf->opmode == NL80211_IFTYPE_ADHOC)
|
||||||
sc->num_adhoc_vifs++;
|
sc->num_adhoc_vifs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,7 +329,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp);
|
|||||||
struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
|
struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
|
||||||
void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
|
void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
|
||||||
int ath_tx_setup(struct ath_softc *sc, int haltype);
|
int ath_tx_setup(struct ath_softc *sc, int haltype);
|
||||||
void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
|
bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
|
||||||
void ath_draintxq(struct ath_softc *sc,
|
void ath_draintxq(struct ath_softc *sc,
|
||||||
struct ath_txq *txq, bool retry_tx);
|
struct ath_txq *txq, bool retry_tx);
|
||||||
void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
|
void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
|
||||||
|
@ -1063,15 +1063,19 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
|
|||||||
case 1:
|
case 1:
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
|
if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN)
|
||||||
scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
|
scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
|
||||||
|
else
|
||||||
|
scaledPower = 0;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
|
if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN)
|
||||||
scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
|
scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
|
||||||
|
else
|
||||||
|
scaledPower = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
scaledPower = max((u16)0, scaledPower);
|
|
||||||
|
|
||||||
if (IS_CHAN_2GHZ(chan)) {
|
if (IS_CHAN_2GHZ(chan)) {
|
||||||
numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
|
numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
|
||||||
SUB_NUM_CTL_MODES_AT_2G_40;
|
SUB_NUM_CTL_MODES_AT_2G_40;
|
||||||
|
@ -1024,6 +1024,13 @@ static int ath9k_hif_usb_suspend(struct usb_interface *interface,
|
|||||||
struct hif_device_usb *hif_dev =
|
struct hif_device_usb *hif_dev =
|
||||||
(struct hif_device_usb *) usb_get_intfdata(interface);
|
(struct hif_device_usb *) usb_get_intfdata(interface);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The device has to be set to FULLSLEEP mode in case no
|
||||||
|
* interface is up.
|
||||||
|
*/
|
||||||
|
if (!(hif_dev->flags & HIF_USB_START))
|
||||||
|
ath9k_htc_suspend(hif_dev->htc_handle);
|
||||||
|
|
||||||
ath9k_hif_usb_dealloc_urbs(hif_dev);
|
ath9k_hif_usb_dealloc_urbs(hif_dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -455,6 +455,8 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv);
|
|||||||
void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv);
|
void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv);
|
||||||
void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv);
|
void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv);
|
||||||
void ath9k_ps_work(struct work_struct *work);
|
void ath9k_ps_work(struct work_struct *work);
|
||||||
|
bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
|
||||||
|
enum ath9k_power_mode mode);
|
||||||
|
|
||||||
void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv);
|
void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv);
|
||||||
void ath9k_init_leds(struct ath9k_htc_priv *priv);
|
void ath9k_init_leds(struct ath9k_htc_priv *priv);
|
||||||
@ -464,6 +466,7 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
|
|||||||
u16 devid, char *product);
|
u16 devid, char *product);
|
||||||
void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug);
|
void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug);
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
void ath9k_htc_suspend(struct htc_target *htc_handle);
|
||||||
int ath9k_htc_resume(struct htc_target *htc_handle);
|
int ath9k_htc_resume(struct htc_target *htc_handle);
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_ATH9K_HTC_DEBUGFS
|
#ifdef CONFIG_ATH9K_HTC_DEBUGFS
|
||||||
|
@ -891,6 +891,12 @@ void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
|
||||||
|
void ath9k_htc_suspend(struct htc_target *htc_handle)
|
||||||
|
{
|
||||||
|
ath9k_htc_setpower(htc_handle->drv_priv, ATH9K_PM_FULL_SLEEP);
|
||||||
|
}
|
||||||
|
|
||||||
int ath9k_htc_resume(struct htc_target *htc_handle)
|
int ath9k_htc_resume(struct htc_target *htc_handle)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -63,7 +63,7 @@ static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv,
|
|||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
|
bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
|
||||||
enum ath9k_power_mode mode)
|
enum ath9k_power_mode mode)
|
||||||
{
|
{
|
||||||
bool ret;
|
bool ret;
|
||||||
|
@ -703,8 +703,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
|
|||||||
rs->rs_phyerr = phyerr;
|
rs->rs_phyerr = phyerr;
|
||||||
} else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
|
} else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
|
||||||
rs->rs_status |= ATH9K_RXERR_DECRYPT;
|
rs->rs_status |= ATH9K_RXERR_DECRYPT;
|
||||||
else if ((ads.ds_rxstatus8 & AR_MichaelErr) &&
|
else if (ads.ds_rxstatus8 & AR_MichaelErr)
|
||||||
rs->rs_keyix != ATH9K_RXKEYIX_INVALID)
|
|
||||||
rs->rs_status |= ATH9K_RXERR_MIC;
|
rs->rs_status |= ATH9K_RXERR_MIC;
|
||||||
else if (ads.ds_rxstatus8 & AR_KeyMiss)
|
else if (ads.ds_rxstatus8 & AR_KeyMiss)
|
||||||
rs->rs_status |= ATH9K_RXERR_DECRYPT;
|
rs->rs_status |= ATH9K_RXERR_DECRYPT;
|
||||||
|
@ -244,11 +244,12 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
|
|||||||
* the relevant bits of the h/w.
|
* the relevant bits of the h/w.
|
||||||
*/
|
*/
|
||||||
ath9k_hw_set_interrupts(ah, 0);
|
ath9k_hw_set_interrupts(ah, 0);
|
||||||
ath_drain_all_txq(sc, false);
|
stopped = ath_drain_all_txq(sc, false);
|
||||||
|
|
||||||
spin_lock_bh(&sc->rx.pcu_lock);
|
spin_lock_bh(&sc->rx.pcu_lock);
|
||||||
|
|
||||||
stopped = ath_stoprecv(sc);
|
if (!ath_stoprecv(sc))
|
||||||
|
stopped = false;
|
||||||
|
|
||||||
/* XXX: do not flush receive queue here. We don't want
|
/* XXX: do not flush receive queue here. We don't want
|
||||||
* to flush data frames already in queue because of
|
* to flush data frames already in queue because of
|
||||||
@ -1519,8 +1520,6 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
|
|||||||
struct ath_softc *sc = aphy->sc;
|
struct ath_softc *sc = aphy->sc;
|
||||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||||
struct ath_vif *avp = (void *)vif->drv_priv;
|
struct ath_vif *avp = (void *)vif->drv_priv;
|
||||||
bool bs_valid = false;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
|
ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
|
||||||
|
|
||||||
@ -1534,26 +1533,21 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
|
|||||||
if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
|
if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
|
||||||
(sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
|
(sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
|
||||||
(sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
|
(sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
|
||||||
|
/* Disable SWBA interrupt */
|
||||||
|
sc->sc_ah->imask &= ~ATH9K_INT_SWBA;
|
||||||
ath9k_ps_wakeup(sc);
|
ath9k_ps_wakeup(sc);
|
||||||
|
ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
|
||||||
ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
|
ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
|
||||||
ath9k_ps_restore(sc);
|
ath9k_ps_restore(sc);
|
||||||
|
tasklet_kill(&sc->bcon_tasklet);
|
||||||
}
|
}
|
||||||
|
|
||||||
ath_beacon_return(sc, avp);
|
ath_beacon_return(sc, avp);
|
||||||
sc->sc_flags &= ~SC_OP_BEACONS;
|
sc->sc_flags &= ~SC_OP_BEACONS;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
|
if (sc->nbcnvifs) {
|
||||||
if (sc->beacon.bslot[i] == vif) {
|
/* Re-enable SWBA interrupt */
|
||||||
printk(KERN_DEBUG "%s: vif had allocated beacon "
|
sc->sc_ah->imask |= ATH9K_INT_SWBA;
|
||||||
"slot\n", __func__);
|
|
||||||
sc->beacon.bslot[i] = NULL;
|
|
||||||
sc->beacon.bslot_aphy[i] = NULL;
|
|
||||||
} else if (sc->beacon.bslot[i])
|
|
||||||
bs_valid = true;
|
|
||||||
}
|
|
||||||
if (!bs_valid && (sc->sc_ah->imask & ATH9K_INT_SWBA)) {
|
|
||||||
/* Disable SWBA interrupt */
|
|
||||||
sc->sc_ah->imask &= ~ATH9K_INT_SWBA;
|
|
||||||
ath9k_ps_wakeup(sc);
|
ath9k_ps_wakeup(sc);
|
||||||
ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
|
ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask);
|
||||||
ath9k_ps_restore(sc);
|
ath9k_ps_restore(sc);
|
||||||
|
@ -838,6 +838,10 @@ static bool ath9k_rx_accept(struct ath_common *common,
|
|||||||
struct ath_rx_status *rx_stats,
|
struct ath_rx_status *rx_stats,
|
||||||
bool *decrypt_error)
|
bool *decrypt_error)
|
||||||
{
|
{
|
||||||
|
#define is_mc_or_valid_tkip_keyix ((is_mc || \
|
||||||
|
(rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID && \
|
||||||
|
test_bit(rx_stats->rs_keyix, common->tkip_keymap))))
|
||||||
|
|
||||||
struct ath_hw *ah = common->ah;
|
struct ath_hw *ah = common->ah;
|
||||||
__le16 fc;
|
__le16 fc;
|
||||||
u8 rx_status_len = ah->caps.rx_status_len;
|
u8 rx_status_len = ah->caps.rx_status_len;
|
||||||
@ -879,15 +883,18 @@ static bool ath9k_rx_accept(struct ath_common *common,
|
|||||||
if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) {
|
if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) {
|
||||||
*decrypt_error = true;
|
*decrypt_error = true;
|
||||||
} else if (rx_stats->rs_status & ATH9K_RXERR_MIC) {
|
} else if (rx_stats->rs_status & ATH9K_RXERR_MIC) {
|
||||||
|
bool is_mc;
|
||||||
/*
|
/*
|
||||||
* The MIC error bit is only valid if the frame
|
* The MIC error bit is only valid if the frame
|
||||||
* is not a control frame or fragment, and it was
|
* is not a control frame or fragment, and it was
|
||||||
* decrypted using a valid TKIP key.
|
* decrypted using a valid TKIP key.
|
||||||
*/
|
*/
|
||||||
|
is_mc = !!is_multicast_ether_addr(hdr->addr1);
|
||||||
|
|
||||||
if (!ieee80211_is_ctl(fc) &&
|
if (!ieee80211_is_ctl(fc) &&
|
||||||
!ieee80211_has_morefrags(fc) &&
|
!ieee80211_has_morefrags(fc) &&
|
||||||
!(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) &&
|
!(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) &&
|
||||||
test_bit(rx_stats->rs_keyix, common->tkip_keymap))
|
is_mc_or_valid_tkip_keyix)
|
||||||
rxs->flag |= RX_FLAG_MMIC_ERROR;
|
rxs->flag |= RX_FLAG_MMIC_ERROR;
|
||||||
else
|
else
|
||||||
rx_stats->rs_status &= ~ATH9K_RXERR_MIC;
|
rx_stats->rs_status &= ~ATH9K_RXERR_MIC;
|
||||||
|
@ -1120,7 +1120,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
|
bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
|
||||||
{
|
{
|
||||||
struct ath_hw *ah = sc->sc_ah;
|
struct ath_hw *ah = sc->sc_ah;
|
||||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||||
@ -1128,7 +1128,7 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
|
|||||||
int i, npend = 0;
|
int i, npend = 0;
|
||||||
|
|
||||||
if (sc->sc_flags & SC_OP_INVALID)
|
if (sc->sc_flags & SC_OP_INVALID)
|
||||||
return;
|
return true;
|
||||||
|
|
||||||
/* Stop beacon queue */
|
/* Stop beacon queue */
|
||||||
ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
|
ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
|
||||||
@ -1142,25 +1142,15 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (npend) {
|
if (npend)
|
||||||
int r;
|
ath_print(common, ATH_DBG_FATAL, "Failed to stop TX DMA!\n");
|
||||||
|
|
||||||
ath_print(common, ATH_DBG_FATAL,
|
|
||||||
"Failed to stop TX DMA. Resetting hardware!\n");
|
|
||||||
|
|
||||||
spin_lock_bh(&sc->sc_resetlock);
|
|
||||||
r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false);
|
|
||||||
if (r)
|
|
||||||
ath_print(common, ATH_DBG_FATAL,
|
|
||||||
"Unable to reset hardware; reset status %d\n",
|
|
||||||
r);
|
|
||||||
spin_unlock_bh(&sc->sc_resetlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
|
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
|
||||||
if (ATH_TXQ_SETUP(sc, i))
|
if (ATH_TXQ_SETUP(sc, i))
|
||||||
ath_draintxq(sc, &sc->tx.txq[i], retry_tx);
|
ath_draintxq(sc, &sc->tx.txq[i], retry_tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return !npend;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
|
void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
|
||||||
|
@ -1811,6 +1811,12 @@ static int __orinoco_commit(struct orinoco_private *priv)
|
|||||||
struct net_device *dev = priv->ndev;
|
struct net_device *dev = priv->ndev;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
|
/* If we've called commit, we are reconfiguring or bringing the
|
||||||
|
* interface up. Maintaining countermeasures across this would
|
||||||
|
* be confusing, so note that we've disabled them. The port will
|
||||||
|
* be enabled later in orinoco_commit or __orinoco_up. */
|
||||||
|
priv->tkip_cm_active = 0;
|
||||||
|
|
||||||
err = orinoco_hw_program_rids(priv);
|
err = orinoco_hw_program_rids(priv);
|
||||||
|
|
||||||
/* FIXME: what about netif_tx_lock */
|
/* FIXME: what about netif_tx_lock */
|
||||||
|
@ -151,20 +151,20 @@ orinoco_cs_config(struct pcmcia_device *link)
|
|||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = pcmcia_request_irq(link, orinoco_interrupt);
|
|
||||||
if (ret)
|
|
||||||
goto failed;
|
|
||||||
|
|
||||||
/* We initialize the hermes structure before completing PCMCIA
|
|
||||||
* configuration just in case the interrupt handler gets
|
|
||||||
* called. */
|
|
||||||
mem = ioport_map(link->resource[0]->start,
|
mem = ioport_map(link->resource[0]->start,
|
||||||
resource_size(link->resource[0]));
|
resource_size(link->resource[0]));
|
||||||
if (!mem)
|
if (!mem)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
|
/* We initialize the hermes structure before completing PCMCIA
|
||||||
|
* configuration just in case the interrupt handler gets
|
||||||
|
* called. */
|
||||||
hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
|
hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
|
||||||
|
|
||||||
|
ret = pcmcia_request_irq(link, orinoco_interrupt);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
ret = pcmcia_enable_device(link);
|
ret = pcmcia_enable_device(link);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
@ -214,21 +214,21 @@ spectrum_cs_config(struct pcmcia_device *link)
|
|||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = pcmcia_request_irq(link, orinoco_interrupt);
|
|
||||||
if (ret)
|
|
||||||
goto failed;
|
|
||||||
|
|
||||||
/* We initialize the hermes structure before completing PCMCIA
|
|
||||||
* configuration just in case the interrupt handler gets
|
|
||||||
* called. */
|
|
||||||
mem = ioport_map(link->resource[0]->start,
|
mem = ioport_map(link->resource[0]->start,
|
||||||
resource_size(link->resource[0]));
|
resource_size(link->resource[0]));
|
||||||
if (!mem)
|
if (!mem)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
|
/* We initialize the hermes structure before completing PCMCIA
|
||||||
|
* configuration just in case the interrupt handler gets
|
||||||
|
* called. */
|
||||||
hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
|
hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
|
||||||
hw->eeprom_pda = true;
|
hw->eeprom_pda = true;
|
||||||
|
|
||||||
|
ret = pcmcia_request_irq(link, orinoco_interrupt);
|
||||||
|
if (ret)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
ret = pcmcia_enable_device(link);
|
ret = pcmcia_enable_device(link);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto failed;
|
goto failed;
|
||||||
|
@ -911,10 +911,10 @@ static int orinoco_ioctl_set_auth(struct net_device *dev,
|
|||||||
*/
|
*/
|
||||||
if (param->value) {
|
if (param->value) {
|
||||||
priv->tkip_cm_active = 1;
|
priv->tkip_cm_active = 1;
|
||||||
ret = hermes_enable_port(hw, 0);
|
ret = hermes_disable_port(hw, 0);
|
||||||
} else {
|
} else {
|
||||||
priv->tkip_cm_active = 0;
|
priv->tkip_cm_active = 0;
|
||||||
ret = hermes_disable_port(hw, 0);
|
ret = hermes_enable_port(hw, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1737,15 +1737,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
|
|||||||
int nh_pos, h_pos;
|
int nh_pos, h_pos;
|
||||||
struct sta_info *sta = NULL;
|
struct sta_info *sta = NULL;
|
||||||
u32 sta_flags = 0;
|
u32 sta_flags = 0;
|
||||||
|
struct sk_buff *tmp_skb;
|
||||||
|
|
||||||
if (unlikely(skb->len < ETH_HLEN)) {
|
if (unlikely(skb->len < ETH_HLEN)) {
|
||||||
ret = NETDEV_TX_OK;
|
ret = NETDEV_TX_OK;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
nh_pos = skb_network_header(skb) - skb->data;
|
|
||||||
h_pos = skb_transport_header(skb) - skb->data;
|
|
||||||
|
|
||||||
/* convert Ethernet header to proper 802.11 header (based on
|
/* convert Ethernet header to proper 802.11 header (based on
|
||||||
* operation mode) */
|
* operation mode) */
|
||||||
ethertype = (skb->data[12] << 8) | skb->data[13];
|
ethertype = (skb->data[12] << 8) | skb->data[13];
|
||||||
@ -1918,6 +1916,20 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the skb is shared we need to obtain our own copy.
|
||||||
|
*/
|
||||||
|
if (skb_shared(skb)) {
|
||||||
|
tmp_skb = skb;
|
||||||
|
skb = skb_copy(skb, GFP_ATOMIC);
|
||||||
|
kfree_skb(tmp_skb);
|
||||||
|
|
||||||
|
if (!skb) {
|
||||||
|
ret = NETDEV_TX_OK;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hdr.frame_control = fc;
|
hdr.frame_control = fc;
|
||||||
hdr.duration_id = 0;
|
hdr.duration_id = 0;
|
||||||
hdr.seq_ctrl = 0;
|
hdr.seq_ctrl = 0;
|
||||||
@ -1936,6 +1948,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
|
|||||||
encaps_len = 0;
|
encaps_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nh_pos = skb_network_header(skb) - skb->data;
|
||||||
|
h_pos = skb_transport_header(skb) - skb->data;
|
||||||
|
|
||||||
skb_pull(skb, skip_header_bytes);
|
skb_pull(skb, skip_header_bytes);
|
||||||
nh_pos -= skip_header_bytes;
|
nh_pos -= skip_header_bytes;
|
||||||
h_pos -= skip_header_bytes;
|
h_pos -= skip_header_bytes;
|
||||||
|
Loading…
Reference in New Issue
Block a user