Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless

Conflicts:
	net/mac80211/sta_info.c
	net/wireless/core.h
This commit is contained in:
John W. Linville
2013-03-29 16:41:36 -04:00
34 changed files with 473 additions and 421 deletions

View File

@@ -1023,6 +1023,7 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
AR_PHY_AGC_CONTROL_FLTR_CAL |
AR_PHY_AGC_CONTROL_PKDET_CAL;
/* Use chip chainmask only for calibration */
ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
if (rtt) {
@@ -1151,6 +1152,9 @@ skip_tx_iqcal:
ar9003_hw_rtt_disable(ah);
}
/* Revert chainmask to runtime parameters */
ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
/* Initialize list pointers */
ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;

View File

@@ -28,21 +28,21 @@ void ath_tx_complete_poll_work(struct work_struct *work)
int i;
bool needreset = false;
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
if (ATH_TXQ_SETUP(sc, i)) {
txq = &sc->tx.txq[i];
ath_txq_lock(sc, txq);
if (txq->axq_depth) {
if (txq->axq_tx_inprogress) {
needreset = true;
ath_txq_unlock(sc, txq);
break;
} else {
txq->axq_tx_inprogress = true;
}
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
txq = sc->tx.txq_map[i];
ath_txq_lock(sc, txq);
if (txq->axq_depth) {
if (txq->axq_tx_inprogress) {
needreset = true;
ath_txq_unlock(sc, txq);
break;
} else {
txq->axq_tx_inprogress = true;
}
ath_txq_unlock_complete(sc, txq);
}
ath_txq_unlock_complete(sc, txq);
}
if (needreset) {
ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
@@ -170,7 +170,8 @@ void ath_rx_poll(unsigned long data)
{
struct ath_softc *sc = (struct ath_softc *)data;
ieee80211_queue_work(sc->hw, &sc->hw_check_work);
if (!test_bit(SC_OP_INVALID, &sc->sc_flags))
ieee80211_queue_work(sc->hw, &sc->hw_check_work);
}
/*

View File

@@ -1487,8 +1487,12 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
const struct b43_dma_ops *ops;
struct b43_dmaring *ring;
struct b43_dmadesc_meta *meta;
static const struct b43_txstatus fake; /* filled with 0 */
const struct b43_txstatus *txstat;
int slot, firstused;
bool frame_succeed;
int skip;
static u8 err_out1, err_out2;
ring = parse_cookie(dev, status->cookie, &slot);
if (unlikely(!ring))
@@ -1501,13 +1505,36 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
firstused = ring->current_slot - ring->used_slots + 1;
if (firstused < 0)
firstused = ring->nr_slots + firstused;
skip = 0;
if (unlikely(slot != firstused)) {
/* This possibly is a firmware bug and will result in
* malfunction, memory leaks and/or stall of DMA functionality. */
b43dbg(dev->wl, "Out of order TX status report on DMA ring %d. "
"Expected %d, but got %d\n",
ring->index, firstused, slot);
return;
* malfunction, memory leaks and/or stall of DMA functionality.
*/
if (slot == next_slot(ring, next_slot(ring, firstused))) {
/* If a single header/data pair was missed, skip over
* the first two slots in an attempt to recover.
*/
slot = firstused;
skip = 2;
if (!err_out1) {
/* Report the error once. */
b43dbg(dev->wl,
"Skip on DMA ring %d slot %d.\n",
ring->index, slot);
err_out1 = 1;
}
} else {
/* More than a single header/data pair were missed.
* Report this error once.
*/
if (!err_out2)
b43dbg(dev->wl,
"Out of order TX status report on DMA ring %d. Expected %d, but got %d\n",
ring->index, firstused, slot);
err_out2 = 1;
return;
}
}
ops = ring->ops;
@@ -1522,11 +1549,13 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
slot, firstused, ring->index);
break;
}
if (meta->skb) {
struct b43_private_tx_info *priv_info =
b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb));
b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb));
unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1);
unmap_descbuffer(ring, meta->dmaaddr,
meta->skb->len, 1);
kfree(priv_info->bouncebuffer);
priv_info->bouncebuffer = NULL;
} else {
@@ -1538,8 +1567,9 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
struct ieee80211_tx_info *info;
if (unlikely(!meta->skb)) {
/* This is a scatter-gather fragment of a frame, so
* the skb pointer must not be NULL. */
/* This is a scatter-gather fragment of a frame,
* so the skb pointer must not be NULL.
*/
b43dbg(dev->wl, "TX status unexpected NULL skb "
"at slot %d (first=%d) on ring %d\n",
slot, firstused, ring->index);
@@ -1550,9 +1580,18 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
/*
* Call back to inform the ieee80211 subsystem about
* the status of the transmission.
* the status of the transmission. When skipping over
* a missed TX status report, use a status structure
* filled with zeros to indicate that the frame was not
* sent (frame_count 0) and not acknowledged
*/
frame_succeed = b43_fill_txstatus_report(dev, info, status);
if (unlikely(skip))
txstat = &fake;
else
txstat = status;
frame_succeed = b43_fill_txstatus_report(dev, info,
txstat);
#ifdef CONFIG_B43_DEBUG
if (frame_succeed)
ring->nr_succeed_tx_packets++;
@@ -1580,12 +1619,14 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
/* Everything unmapped and free'd. So it's not used anymore. */
ring->used_slots--;
if (meta->is_last_fragment) {
if (meta->is_last_fragment && !skip) {
/* This is the last scatter-gather
* fragment of the frame. We are done. */
break;
}
slot = next_slot(ring, slot);
if (skip > 0)
--skip;
}
if (ring->stopped) {
B43_WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME);

View File

@@ -1564,7 +1564,7 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
u16 clip_off[2] = { 0xFFFF, 0xFFFF };
u8 vcm_final = 0;
s8 offset[4];
s32 offset[4];
s32 results[8][4] = { };
s32 results_min[4] = { };
s32 poll_results[4] = { };
@@ -1615,7 +1615,7 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
}
for (i = 0; i < 4; i += 2) {
s32 curr;
s32 mind = 40;
s32 mind = 0x100000;
s32 minpoll = 249;
u8 minvcm = 0;
if (2 * core != i)
@@ -1732,7 +1732,7 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
u8 regs_save_radio[2];
u16 regs_save_phy[2];
s8 offset[4];
s32 offset[4];
u8 core;
u8 rail;
@@ -1799,7 +1799,7 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
}
for (i = 0; i < 4; i++) {
s32 mind = 40;
s32 mind = 0x100000;
u8 minvcm = 0;
s32 minpoll = 249;
s32 curr;

View File

@@ -1137,9 +1137,8 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
gain0_15 = ((biq1 & 0xf) << 12) |
((tia & 0xf) << 8) |
((lna2 & 0x3) << 6) |
((lna2 & 0x3) << 4) |
((lna1 & 0x3) << 2) |
((lna1 & 0x3) << 0);
((lna2 &
0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0);
mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
@@ -1157,8 +1156,6 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
}
mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0);
mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
mod_phy_reg(pi, 0x4e6, (0x3 << 3), lna1 << 3);
}
@@ -1331,43 +1328,6 @@ static u32 wlc_lcnphy_measure_digital_power(struct brcms_phy *pi, u16 nsamples)
return (iq_est.i_pwr + iq_est.q_pwr) / nsamples;
}
static bool wlc_lcnphy_rx_iq_cal_gain(struct brcms_phy *pi, u16 biq1_gain,
u16 tia_gain, u16 lna2_gain)
{
u32 i_thresh_l, q_thresh_l;
u32 i_thresh_h, q_thresh_h;
struct lcnphy_iq_est iq_est_h, iq_est_l;
wlc_lcnphy_set_rx_gain_by_distribution(pi, 0, 0, 0, biq1_gain, tia_gain,
lna2_gain, 0);
wlc_lcnphy_rx_gain_override_enable(pi, true);
wlc_lcnphy_start_tx_tone(pi, 2000, (40 >> 1), 0);
udelay(500);
write_radio_reg(pi, RADIO_2064_REG112, 0);
if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_l))
return false;
wlc_lcnphy_start_tx_tone(pi, 2000, 40, 0);
udelay(500);
write_radio_reg(pi, RADIO_2064_REG112, 0);
if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_h))
return false;
i_thresh_l = (iq_est_l.i_pwr << 1);
i_thresh_h = (iq_est_l.i_pwr << 2) + iq_est_l.i_pwr;
q_thresh_l = (iq_est_l.q_pwr << 1);
q_thresh_h = (iq_est_l.q_pwr << 2) + iq_est_l.q_pwr;
if ((iq_est_h.i_pwr > i_thresh_l) &&
(iq_est_h.i_pwr < i_thresh_h) &&
(iq_est_h.q_pwr > q_thresh_l) &&
(iq_est_h.q_pwr < q_thresh_h))
return true;
return false;
}
static bool
wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
const struct lcnphy_rx_iqcomp *iqcomp,
@@ -1382,8 +1342,8 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old,
rfoverride3_old, rfoverride3val_old, rfoverride4_old,
rfoverride4val_old, afectrlovr_old, afectrlovrval_old;
int tia_gain, lna2_gain, biq1_gain;
bool set_gain;
int tia_gain;
u32 received_power, rx_pwr_threshold;
u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl;
u16 values_to_save[11];
s16 *ptr;
@@ -1408,135 +1368,127 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
goto cal_done;
}
WARN_ON(module != 1);
tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
if (module == 1) {
for (i = 0; i < 11; i++)
values_to_save[i] =
read_radio_reg(pi, rxiq_cal_rf_reg[i]);
Core1TxControl_old = read_phy_reg(pi, 0x631);
tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
or_phy_reg(pi, 0x631, 0x0015);
for (i = 0; i < 11; i++)
values_to_save[i] =
read_radio_reg(pi, rxiq_cal_rf_reg[i]);
Core1TxControl_old = read_phy_reg(pi, 0x631);
RFOverride0_old = read_phy_reg(pi, 0x44c);
RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
rfoverride2_old = read_phy_reg(pi, 0x4b0);
rfoverride2val_old = read_phy_reg(pi, 0x4b1);
rfoverride3_old = read_phy_reg(pi, 0x4f9);
rfoverride3val_old = read_phy_reg(pi, 0x4fa);
rfoverride4_old = read_phy_reg(pi, 0x938);
rfoverride4val_old = read_phy_reg(pi, 0x939);
afectrlovr_old = read_phy_reg(pi, 0x43b);
afectrlovrval_old = read_phy_reg(pi, 0x43c);
old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
or_phy_reg(pi, 0x631, 0x0015);
tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
if (tx_gain_override_old) {
wlc_lcnphy_get_tx_gain(pi, &old_gains);
tx_gain_index_old = pi_lcn->lcnphy_current_index;
}
RFOverride0_old = read_phy_reg(pi, 0x44c);
RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
rfoverride2_old = read_phy_reg(pi, 0x4b0);
rfoverride2val_old = read_phy_reg(pi, 0x4b1);
rfoverride3_old = read_phy_reg(pi, 0x4f9);
rfoverride3val_old = read_phy_reg(pi, 0x4fa);
rfoverride4_old = read_phy_reg(pi, 0x938);
rfoverride4val_old = read_phy_reg(pi, 0x939);
afectrlovr_old = read_phy_reg(pi, 0x43b);
afectrlovrval_old = read_phy_reg(pi, 0x43c);
old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
write_radio_reg(pi, RADIO_2064_REG116, 0x06);
write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
write_radio_reg(pi, RADIO_2064_REG098, 0x03);
write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
write_radio_reg(pi, RADIO_2064_REG114, 0x01);
write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
write_phy_reg(pi, 0x6da, 0xffff);
or_phy_reg(pi, 0x6db, 0x3);
wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
set_gain = false;
lna2_gain = 3;
while ((lna2_gain >= 0) && !set_gain) {
tia_gain = 4;
while ((tia_gain >= 0) && !set_gain) {
biq1_gain = 6;
while ((biq1_gain >= 0) && !set_gain) {
set_gain = wlc_lcnphy_rx_iq_cal_gain(pi,
(u16)
biq1_gain,
(u16)
tia_gain,
(u16)
lna2_gain);
biq1_gain -= 1;
}
tia_gain -= 1;
tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
if (tx_gain_override_old) {
wlc_lcnphy_get_tx_gain(pi, &old_gains);
tx_gain_index_old = pi_lcn->lcnphy_current_index;
}
lna2_gain -= 1;
wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
write_radio_reg(pi, RADIO_2064_REG116, 0x06);
write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
write_radio_reg(pi, RADIO_2064_REG098, 0x03);
write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
write_radio_reg(pi, RADIO_2064_REG114, 0x01);
write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0);
write_phy_reg(pi, 0x6da, 0xffff);
or_phy_reg(pi, 0x6db, 0x3);
wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
wlc_lcnphy_rx_gain_override_enable(pi, true);
tia_gain = 8;
rx_pwr_threshold = 950;
while (tia_gain > 0) {
tia_gain -= 1;
wlc_lcnphy_set_rx_gain_by_distribution(pi,
0, 0, 2, 2,
(u16)
tia_gain, 1, 0);
udelay(500);
received_power =
wlc_lcnphy_measure_digital_power(pi, 2000);
if (received_power < rx_pwr_threshold)
break;
}
result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff);
wlc_lcnphy_stop_tx_tone(pi);
write_phy_reg(pi, 0x631, Core1TxControl_old);
write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
write_phy_reg(pi, 0x4b0, rfoverride2_old);
write_phy_reg(pi, 0x4b1, rfoverride2val_old);
write_phy_reg(pi, 0x4f9, rfoverride3_old);
write_phy_reg(pi, 0x4fa, rfoverride3val_old);
write_phy_reg(pi, 0x938, rfoverride4_old);
write_phy_reg(pi, 0x939, rfoverride4val_old);
write_phy_reg(pi, 0x43b, afectrlovr_old);
write_phy_reg(pi, 0x43c, afectrlovrval_old);
write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
wlc_lcnphy_clear_trsw_override(pi);
mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
for (i = 0; i < 11; i++)
write_radio_reg(pi, rxiq_cal_rf_reg[i],
values_to_save[i]);
if (tx_gain_override_old)
wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
else
wlc_lcnphy_disable_tx_gain_override(pi);
wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
wlc_lcnphy_rx_gain_override_enable(pi, false);
}
if (set_gain)
result = wlc_lcnphy_calc_rx_iq_comp(pi, 1024);
else
result = false;
wlc_lcnphy_stop_tx_tone(pi);
write_phy_reg(pi, 0x631, Core1TxControl_old);
write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
write_phy_reg(pi, 0x4b0, rfoverride2_old);
write_phy_reg(pi, 0x4b1, rfoverride2val_old);
write_phy_reg(pi, 0x4f9, rfoverride3_old);
write_phy_reg(pi, 0x4fa, rfoverride3val_old);
write_phy_reg(pi, 0x938, rfoverride4_old);
write_phy_reg(pi, 0x939, rfoverride4val_old);
write_phy_reg(pi, 0x43b, afectrlovr_old);
write_phy_reg(pi, 0x43c, afectrlovrval_old);
write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
wlc_lcnphy_clear_trsw_override(pi);
mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
for (i = 0; i < 11; i++)
write_radio_reg(pi, rxiq_cal_rf_reg[i],
values_to_save[i]);
if (tx_gain_override_old)
wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
else
wlc_lcnphy_disable_tx_gain_override(pi);
wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
wlc_lcnphy_rx_gain_override_enable(pi, false);
cal_done:
kfree(ptr);
return result;
@@ -1837,17 +1789,6 @@ wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel)
write_radio_reg(pi, RADIO_2064_REG038, 3);
write_radio_reg(pi, RADIO_2064_REG091, 7);
}
if (!(pi->sh->boardflags & BFL_FEM)) {
u8 reg038[14] = {0xd, 0xe, 0xd, 0xd, 0xd, 0xc,
0xa, 0xb, 0xb, 0x3, 0x3, 0x2, 0x0, 0x0};
write_radio_reg(pi, RADIO_2064_REG02A, 0xf);
write_radio_reg(pi, RADIO_2064_REG091, 0x3);
write_radio_reg(pi, RADIO_2064_REG038, 0x3);
write_radio_reg(pi, RADIO_2064_REG038, reg038[channel - 1]);
}
}
static int
@@ -2042,16 +1983,6 @@ wlc_lcnphy_set_tssi_mux(struct brcms_phy *pi, enum lcnphy_tssi_mode pos)
} else {
mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1);
mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
mod_radio_reg(pi, RADIO_2064_REG028, 0x1, 0x0);
mod_radio_reg(pi, RADIO_2064_REG11A, 0x4, 1<<2);
mod_radio_reg(pi, RADIO_2064_REG036, 0x10, 0x0);
mod_radio_reg(pi, RADIO_2064_REG11A, 0x10, 1<<4);
mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0);
mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x77);
mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0xe<<1);
mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 1<<7);
mod_radio_reg(pi, RADIO_2064_REG005, 0x7, 1<<1);
mod_radio_reg(pi, RADIO_2064_REG029, 0xf0, 0<<4);
}
} else {
mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2);
@@ -2138,14 +2069,12 @@ static void wlc_lcnphy_pwrctrl_rssiparams(struct brcms_phy *pi)
(auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5));
mod_radio_reg(pi, RADIO_2064_REG07C, (1 << 0), (1 << 0));
}
static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
{
struct phytbl_info tab;
u32 rfseq, ind;
u8 tssi_sel;
tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
tab.tbl_width = 32;
@@ -2167,13 +2096,7 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4);
if (pi->sh->boardflags & BFL_FEM) {
tssi_sel = 0x1;
wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT);
} else {
tssi_sel = 0xe;
wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_POST_PA);
}
wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT);
mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15);
@@ -2209,10 +2132,9 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0);
if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
mod_radio_reg(pi, RADIO_2064_REG028, 0xf, tssi_sel);
mod_radio_reg(pi, RADIO_2064_REG028, 0xf, 0xe);
mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
} else {
mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, tssi_sel << 1);
mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3);
}
@@ -2259,10 +2181,6 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8);
mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x0);
mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0);
mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
wlc_lcnphy_pwrctrl_rssiparams(pi);
}
@@ -2881,8 +2799,6 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
read_radio_reg(pi, RADIO_2064_REG007) & 1;
u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10;
u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4;
u8 SAVE_bbmult = wlc_lcnphy_get_bbmult(pi);
idleTssi = read_phy_reg(pi, 0x4ab);
suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
MCTL_EN_MAC));
@@ -2900,12 +2816,6 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4);
mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2);
wlc_lcnphy_tssi_setup(pi);
mod_phy_reg(pi, 0x4d7, (0x1 << 0), (1 << 0));
mod_phy_reg(pi, 0x4d7, (0x1 << 6), (1 << 6));
wlc_lcnphy_set_bbmult(pi, 0x0);
wlc_phy_do_dummy_tx(pi, true, OFF);
idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
>> 0);
@@ -2927,7 +2837,6 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12);
wlc_lcnphy_set_bbmult(pi, SAVE_bbmult);
wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old);
wlc_lcnphy_set_tx_gain(pi, &old_gains);
wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
@@ -3141,11 +3050,6 @@ static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi)
wlc_lcnphy_write_table(pi, &tab);
tab.tbl_offset++;
}
mod_phy_reg(pi, 0x4d0, (0x1 << 0), (0) << 0);
mod_phy_reg(pi, 0x4d3, (0xff << 0), (0) << 0);
mod_phy_reg(pi, 0x4d3, (0xff << 8), (0) << 8);
mod_phy_reg(pi, 0x4d0, (0x1 << 4), (0) << 4);
mod_phy_reg(pi, 0x4d0, (0x1 << 2), (0) << 2);
mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7);
@@ -3947,6 +3851,7 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
target_gains.pad_gain = 21;
target_gains.dac_gain = 0;
wlc_lcnphy_set_tx_gain(pi, &target_gains);
wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) {
@@ -3957,7 +3862,6 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
lcnphy_recal ? LCNPHY_CAL_RECAL :
LCNPHY_CAL_FULL), false);
} else {
wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
}
@@ -4382,22 +4286,17 @@ wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi,
if (CHSPEC_IS5G(pi->radio_chanspec))
pa_gain = 0x70;
else
pa_gain = 0x60;
pa_gain = 0x70;
if (pi->sh->boardflags & BFL_FEM)
pa_gain = 0x10;
tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
tab.tbl_width = 32;
tab.tbl_len = 1;
tab.tbl_ptr = &val;
for (j = 0; j < 128; j++) {
if (pi->sh->boardflags & BFL_FEM)
gm_gain = gain_table[j].gm;
else
gm_gain = 15;
gm_gain = gain_table[j].gm;
val = (((u32) pa_gain << 24) |
(gain_table[j].pad << 16) |
(gain_table[j].pga << 8) | gm_gain);
@@ -4608,10 +4507,7 @@ static void wlc_radio_2064_init(struct brcms_phy *pi)
write_phy_reg(pi, 0x4ea, 0x4688);
if (pi->sh->boardflags & BFL_FEM)
mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
else
mod_phy_reg(pi, 0x4eb, (0x7 << 0), 3 << 0);
mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6);
@@ -4622,13 +4518,6 @@ static void wlc_radio_2064_init(struct brcms_phy *pi)
wlc_lcnphy_rcal(pi);
wlc_lcnphy_rc_cal(pi);
if (!(pi->sh->boardflags & BFL_FEM)) {
write_radio_reg(pi, RADIO_2064_REG032, 0x6f);
write_radio_reg(pi, RADIO_2064_REG033, 0x19);
write_radio_reg(pi, RADIO_2064_REG039, 0xe);
}
}
static void wlc_lcnphy_radio_init(struct brcms_phy *pi)
@@ -4658,20 +4547,22 @@ static void wlc_lcnphy_tbl_init(struct brcms_phy *pi)
wlc_lcnphy_write_table(pi, &tab);
}
if (!(pi->sh->boardflags & BFL_FEM)) {
tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
tab.tbl_width = 16;
tab.tbl_ptr = &val;
tab.tbl_len = 1;
tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
tab.tbl_width = 16;
tab.tbl_ptr = &val;
tab.tbl_len = 1;
val = 150;
tab.tbl_offset = 0;
wlc_lcnphy_write_table(pi, &tab);
val = 114;
tab.tbl_offset = 0;
wlc_lcnphy_write_table(pi, &tab);
val = 220;
tab.tbl_offset = 1;
wlc_lcnphy_write_table(pi, &tab);
}
val = 130;
tab.tbl_offset = 1;
wlc_lcnphy_write_table(pi, &tab);
val = 6;
tab.tbl_offset = 8;
wlc_lcnphy_write_table(pi, &tab);
if (CHSPEC_IS2G(pi->radio_chanspec)) {
if (pi->sh->boardflags & BFL_FEM)
@@ -5064,7 +4955,6 @@ void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec)
wlc_lcnphy_load_tx_iir_filter(pi, true, 3);
mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3);
wlc_lcnphy_tssi_setup(pi);
}
void wlc_phy_detach_lcnphy(struct brcms_phy *pi)
@@ -5103,7 +4993,8 @@ bool wlc_phy_attach_lcnphy(struct brcms_phy *pi)
if (!wlc_phy_txpwr_srom_read_lcnphy(pi))
return false;
if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
if ((pi->sh->boardflags & BFL_FEM) &&
(LCNREV_IS(pi->pubpi.phy_rev, 1))) {
if (pi_lcn->lcnphy_tempsense_option == 3) {
pi->hwpwrctrl = true;
pi->hwpwrctrl_capable = true;

View File

@@ -1992,70 +1992,70 @@ static const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0[] = {
};
static const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = {
0x0009,
0x000a,
0x0005,
0x0006,
0x0009,
0x000a,
0x0005,
0x0006,
0x0005,
0x000a,
0x0009,
0x000a,
0x0005,
0x0006,
0x0005,
0x000a,
0x0009,
0x000a,
0x0005,
0x0006,
0x0005,
0x000a,
0x0009,
0x000a,
0x0005,
0x0006,
0x0005,
0x000a,
0x0009,
0x000a,
0x0005,
0x0006,
0x0005,
0x000a,
0x0009,
0x000a,
0x0005,
0x0006,
0x0005,
0x000a,
0x0009,
0x000a,
0x0005,
0x0006,
0x0005,
0x000a,
0x0009,
0x000a,
0x0005,
0x0006,
0x0005,
0x000a,
0x0009,
0x000a,
0x0005,
0x0006,
0x0005,
0x000a,
0x0009,
0x000a,
0x0005,
0x0006,
0x0005,
0x000a,
0x0009,
0x000a,
0x0005,
0x0006,
0x0005,
0x000a,
0x0009,
0x000a,
0x0005,
0x0006,
0x0005,
0x000a,
0x0009,
0x000a,
0x0005,
0x0006,
0x0005,
0x000a,
0x0009,
0x000a,
0x0005,
0x0006,
0x0005,
0x000a,
0x0009,
0x000a,
0x0005,
0x0006,
0x0005,
0x000a,
0x0009,
0x0006,
0x0005,
};
static const u16 dot11lcn_sw_ctrl_tbl_rev0[] = {

View File

@@ -475,6 +475,7 @@ il3945_tx_skb(struct il_priv *il,
dma_addr_t txcmd_phys;
int txq_id = skb_get_queue_mapping(skb);
u16 len, idx, hdr_len;
u16 firstlen, secondlen;
u8 id;
u8 unicast;
u8 sta_id;
@@ -589,21 +590,22 @@ il3945_tx_skb(struct il_priv *il,
len =
sizeof(struct il3945_tx_cmd) + sizeof(struct il_cmd_header) +
hdr_len;
len = (len + 3) & ~3;
firstlen = (len + 3) & ~3;
/* Physical address of this Tx command's header (not MAC header!),
* within command buffer array. */
txcmd_phys =
pci_map_single(il->pci_dev, &out_cmd->hdr, len, PCI_DMA_TODEVICE);
pci_map_single(il->pci_dev, &out_cmd->hdr, firstlen,
PCI_DMA_TODEVICE);
if (unlikely(pci_dma_mapping_error(il->pci_dev, txcmd_phys)))
goto drop_unlock;
/* Set up TFD's 2nd entry to point directly to remainder of skb,
* if any (802.11 null frames have no payload). */
len = skb->len - hdr_len;
if (len) {
secondlen = skb->len - hdr_len;
if (secondlen > 0) {
phys_addr =
pci_map_single(il->pci_dev, skb->data + hdr_len, len,
pci_map_single(il->pci_dev, skb->data + hdr_len, secondlen,
PCI_DMA_TODEVICE);
if (unlikely(pci_dma_mapping_error(il->pci_dev, phys_addr)))
goto drop_unlock;
@@ -611,12 +613,12 @@ il3945_tx_skb(struct il_priv *il,
/* Add buffer containing Tx command and MAC(!) header to TFD's
* first entry */
il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, len, 1, 0);
il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, firstlen, 1, 0);
dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
dma_unmap_len_set(out_meta, len, len);
if (len)
il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, len, 0,
U32_PAD(len));
dma_unmap_len_set(out_meta, len, firstlen);
if (secondlen > 0)
il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, secondlen, 0,
U32_PAD(secondlen));
if (!ieee80211_has_morefrags(hdr->frame_control)) {
txq->need_update = 1;

View File

@@ -2152,7 +2152,7 @@ il4965_rs_initialize_lq(struct il_priv *il, struct ieee80211_conf *conf,
int rate_idx;
int i;
u32 rate;
u8 use_green = il4965_rs_use_green(il, sta);
u8 use_green;
u8 active_tbl = 0;
u8 valid_tx_ant;
struct il_station_priv *sta_priv;
@@ -2160,6 +2160,7 @@ il4965_rs_initialize_lq(struct il_priv *il, struct ieee80211_conf *conf,
if (!sta || !lq_sta)
return;
use_green = il4965_rs_use_green(il, sta);
sta_priv = (void *)sta->drv_priv;
i = lq_sta->last_txrate_idx;

View File

@@ -1261,6 +1261,15 @@ int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
return -EIO;
}
/*
* This can happen upon FW ASSERT: we clear the STATUS_FW_ERROR flag
* in iwl_down but cancel the workers only later.
*/
if (!priv->ucode_loaded) {
IWL_ERR(priv, "Fw not loaded - dropping CMD: %x\n", cmd->id);
return -EIO;
}
/*
* Synchronous commands from this op-mode must hold
* the mutex, this ensures we don't try to send two

View File

@@ -367,6 +367,8 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
return -EIO;
}
priv->ucode_loaded = true;
if (ucode_type != IWL_UCODE_WOWLAN) {
/* delay a bit to give rfkill time to run */
msleep(5);
@@ -380,8 +382,6 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv,
return ret;
}
priv->ucode_loaded = true;
return 0;
}

View File

@@ -475,6 +475,10 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
/* If platform's RF_KILL switch is NOT set to KILL */
hw_rfkill = iwl_is_rfkill_set(trans);
if (hw_rfkill)
set_bit(STATUS_RFKILL, &trans_pcie->status);
else
clear_bit(STATUS_RFKILL, &trans_pcie->status);
iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
if (hw_rfkill && !run_in_rfkill)
return -ERFKILL;
@@ -641,6 +645,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
bool hw_rfkill;
int err;
@@ -656,6 +661,10 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans)
iwl_enable_rfkill_int(trans);
hw_rfkill = iwl_is_rfkill_set(trans);
if (hw_rfkill)
set_bit(STATUS_RFKILL, &trans_pcie->status);
else
clear_bit(STATUS_RFKILL, &trans_pcie->status);
iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
return 0;
@@ -694,6 +703,10 @@ static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans,
* op_mode.
*/
hw_rfkill = iwl_is_rfkill_set(trans);
if (hw_rfkill)
set_bit(STATUS_RFKILL, &trans_pcie->status);
else
clear_bit(STATUS_RFKILL, &trans_pcie->status);
iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill);
}
}

View File

@@ -1264,7 +1264,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
int copy = 0;
if (!cmd->len)
if (!cmd->len[i])
continue;
/* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */

View File

@@ -157,6 +157,20 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
return -1;
}
cmd_code = le16_to_cpu(host_cmd->command);
cmd_size = le16_to_cpu(host_cmd->size);
if (adapter->hw_status == MWIFIEX_HW_STATUS_RESET &&
cmd_code != HostCmd_CMD_FUNC_SHUTDOWN &&
cmd_code != HostCmd_CMD_FUNC_INIT) {
dev_err(adapter->dev,
"DNLD_CMD: FW in reset state, ignore cmd %#x\n",
cmd_code);
mwifiex_complete_cmd(adapter, cmd_node);
mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
return -1;
}
/* Set command sequence number */
adapter->seq_num++;
host_cmd->seq_num = cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO
@@ -168,9 +182,6 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
adapter->curr_cmd = cmd_node;
spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
cmd_code = le16_to_cpu(host_cmd->command);
cmd_size = le16_to_cpu(host_cmd->size);
/* Adjust skb length */
if (cmd_node->cmd_skb->len > cmd_size)
/*
@@ -484,8 +495,6 @@ int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no,
ret = mwifiex_send_cmd_async(priv, cmd_no, cmd_action, cmd_oid,
data_buf);
if (!ret)
ret = mwifiex_wait_queue_complete(adapter);
return ret;
}
@@ -588,9 +597,10 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
if (cmd_no == HostCmd_CMD_802_11_SCAN) {
mwifiex_queue_scan_cmd(priv, cmd_node);
} else {
adapter->cmd_queued = cmd_node;
mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
queue_work(adapter->workqueue, &adapter->main_work);
if (cmd_node->wait_q_enabled)
ret = mwifiex_wait_queue_complete(adapter, cmd_node);
}
return ret;

View File

@@ -709,6 +709,14 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
return ret;
}
/* cancel current command */
if (adapter->curr_cmd) {
dev_warn(adapter->dev, "curr_cmd is still in processing\n");
del_timer(&adapter->cmd_timer);
mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
adapter->curr_cmd = NULL;
}
/* shut down mwifiex */
dev_dbg(adapter->dev, "info: shutdown mwifiex...\n");

View File

@@ -728,7 +728,6 @@ struct mwifiex_adapter {
u16 cmd_wait_q_required;
struct mwifiex_wait_queue cmd_wait_q;
u8 scan_wait_q_woken;
struct cmd_ctrl_node *cmd_queued;
spinlock_t queue_lock; /* lock for tx queues */
struct completion fw_load;
u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
@@ -1029,7 +1028,8 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
struct mwifiex_multicast_list *mcast_list);
int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
struct net_device *dev);
int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter);
int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter,
struct cmd_ctrl_node *cmd_queued);
int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
struct cfg80211_ssid *req_ssid);
int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type);

View File

@@ -1519,6 +1519,7 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
}
memcpy(adapter->upld_buf, skb->data,
min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
skb_push(skb, INTF_HEADER_LEN);
if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE,
PCI_DMA_FROMDEVICE))
return -1;

View File

@@ -1388,10 +1388,13 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
list_del(&cmd_node->list);
spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
flags);
adapter->cmd_queued = cmd_node;
mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
true);
queue_work(adapter->workqueue, &adapter->main_work);
/* Perform internal scan synchronously */
if (!priv->scan_request)
mwifiex_wait_queue_complete(adapter, cmd_node);
} else {
spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
flags);
@@ -1946,9 +1949,6 @@ int mwifiex_request_scan(struct mwifiex_private *priv,
/* Normal scan */
ret = mwifiex_scan_networks(priv, NULL);
if (!ret)
ret = mwifiex_wait_queue_complete(priv->adapter);
up(&priv->async_sem);
return ret;

View File

@@ -54,16 +54,10 @@ int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
* This function waits on a cmd wait queue. It also cancels the pending
* request after waking up, in case of errors.
*/
int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter)
int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter,
struct cmd_ctrl_node *cmd_queued)
{
int status;
struct cmd_ctrl_node *cmd_queued;
if (!adapter->cmd_queued)
return 0;
cmd_queued = adapter->cmd_queued;
adapter->cmd_queued = NULL;
dev_dbg(adapter->dev, "cmd pending\n");
atomic_inc(&adapter->cmd_pending);

View File

@@ -932,6 +932,7 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb,
if (unlikely(!_urb)) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Can't allocate urb. Drop skb!\n");
kfree_skb(skb);
return;
}
_rtl_submit_tx_urb(hw, _urb);