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

Merge tag 'master-2014-11-11' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless

John W. Linville says:

====================
pull request: wireless 2014-11-13

Please pull this set of a few more wireless fixes intended for the
3.18 stream...

For the mac80211 bits, Johannes says:

"This has just one fix, for an issue with the CCMP decryption
that can cause a kernel crash. I'm not sure it's remotely
exploitable, but it's an important fix nonetheless."

For the iwlwifi bits, Emmanuel says:

"Two fixes here - we weren't updating mac80211 if a scan
was cut short by RFKILL which confused cfg80211. As a
result, the latter wouldn't allow to run another scan.
Liad fixes a small bug in the firmware dump."

On top of that...

Arend van Spriel corrects a channel width conversion that caused a
WARNING in brcmfmac.

Hauke Mehrtens avoids a NULL pointer dereference in b43.

Larry Finger hits a trio of rtlwifi bugs left over from recent
backporting from the Realtek vendor driver.

Miaoqing Pan fixes a clocking problem in ath9k that could affect
packet timestamps and such.

Stanislaw Gruszka addresses an payload alignment issue that has been
plaguing rt2x00.

Please let me know if there are problems!
====================
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
...@@ -664,6 +664,19 @@ static void ar9003_hw_override_ini(struct ath_hw *ah) ...@@ -664,6 +664,19 @@ static void ar9003_hw_override_ini(struct ath_hw *ah)
ah->enabled_cals |= TX_CL_CAL; ah->enabled_cals |= TX_CL_CAL;
else else
ah->enabled_cals &= ~TX_CL_CAL; ah->enabled_cals &= ~TX_CL_CAL;
if (AR_SREV_9340(ah) || AR_SREV_9531(ah) || AR_SREV_9550(ah)) {
if (ah->is_clk_25mhz) {
REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1);
REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae);
} else {
REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1);
REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400);
REG_WRITE(ah, AR_SLP32_INC, 0x0001e800);
}
udelay(100);
}
} }
static void ar9003_hw_prog_ini(struct ath_hw *ah, static void ar9003_hw_prog_ini(struct ath_hw *ah,
......
...@@ -861,19 +861,6 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, ...@@ -861,19 +861,6 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
udelay(RTC_PLL_SETTLE_DELAY); udelay(RTC_PLL_SETTLE_DELAY);
REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK); REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
if (AR_SREV_9340(ah) || AR_SREV_9550(ah)) {
if (ah->is_clk_25mhz) {
REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1);
REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae);
} else {
REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1);
REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400);
REG_WRITE(ah, AR_SLP32_INC, 0x0001e800);
}
udelay(100);
}
} }
static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
......
...@@ -300,9 +300,7 @@ void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value) ...@@ -300,9 +300,7 @@ void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value)
void b43_phy_copy(struct b43_wldev *dev, u16 destreg, u16 srcreg) void b43_phy_copy(struct b43_wldev *dev, u16 destreg, u16 srcreg)
{ {
assert_mac_suspended(dev); b43_phy_write(dev, destreg, b43_phy_read(dev, srcreg));
dev->phy.ops->phy_write(dev, destreg,
dev->phy.ops->phy_read(dev, srcreg));
} }
void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask) void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask)
......
...@@ -299,6 +299,7 @@ static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf, ...@@ -299,6 +299,7 @@ static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
primary_offset = ch->center_freq1 - ch->chan->center_freq; primary_offset = ch->center_freq1 - ch->chan->center_freq;
switch (ch->width) { switch (ch->width) {
case NL80211_CHAN_WIDTH_20: case NL80211_CHAN_WIDTH_20:
case NL80211_CHAN_WIDTH_20_NOHT:
ch_inf.bw = BRCMU_CHAN_BW_20; ch_inf.bw = BRCMU_CHAN_BW_20;
WARN_ON(primary_offset != 0); WARN_ON(primary_offset != 0);
break; break;
...@@ -323,6 +324,10 @@ static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf, ...@@ -323,6 +324,10 @@ static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
ch_inf.sb = BRCMU_CHAN_SB_LU; ch_inf.sb = BRCMU_CHAN_SB_LU;
} }
break; break;
case NL80211_CHAN_WIDTH_80P80:
case NL80211_CHAN_WIDTH_160:
case NL80211_CHAN_WIDTH_5:
case NL80211_CHAN_WIDTH_10:
default: default:
WARN_ON_ONCE(1); WARN_ON_ONCE(1);
} }
...@@ -333,6 +338,7 @@ static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf, ...@@ -333,6 +338,7 @@ static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
case IEEE80211_BAND_5GHZ: case IEEE80211_BAND_5GHZ:
ch_inf.band = BRCMU_CHAN_BAND_5G; ch_inf.band = BRCMU_CHAN_BAND_5G;
break; break;
case IEEE80211_BAND_60GHZ:
default: default:
WARN_ON_ONCE(1); WARN_ON_ONCE(1);
} }
......
...@@ -602,16 +602,6 @@ static int iwl_mvm_cancel_regular_scan(struct iwl_mvm *mvm) ...@@ -602,16 +602,6 @@ static int iwl_mvm_cancel_regular_scan(struct iwl_mvm *mvm)
SCAN_COMPLETE_NOTIFICATION }; SCAN_COMPLETE_NOTIFICATION };
int ret; int ret;
if (mvm->scan_status == IWL_MVM_SCAN_NONE)
return 0;
if (iwl_mvm_is_radio_killed(mvm)) {
ieee80211_scan_completed(mvm->hw, true);
iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
mvm->scan_status = IWL_MVM_SCAN_NONE;
return 0;
}
iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_abort, iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_abort,
scan_abort_notif, scan_abort_notif,
ARRAY_SIZE(scan_abort_notif), ARRAY_SIZE(scan_abort_notif),
...@@ -1400,6 +1390,16 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm, ...@@ -1400,6 +1390,16 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm,
int iwl_mvm_cancel_scan(struct iwl_mvm *mvm) int iwl_mvm_cancel_scan(struct iwl_mvm *mvm)
{ {
if (mvm->scan_status == IWL_MVM_SCAN_NONE)
return 0;
if (iwl_mvm_is_radio_killed(mvm)) {
ieee80211_scan_completed(mvm->hw, true);
iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
mvm->scan_status = IWL_MVM_SCAN_NONE;
return 0;
}
if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)
return iwl_mvm_scan_offload_stop(mvm, true); return iwl_mvm_scan_offload_stop(mvm, true);
return iwl_mvm_cancel_regular_scan(mvm); return iwl_mvm_cancel_regular_scan(mvm);
......
...@@ -1894,8 +1894,7 @@ static u32 iwl_trans_pcie_dump_prph(struct iwl_trans *trans, ...@@ -1894,8 +1894,7 @@ static u32 iwl_trans_pcie_dump_prph(struct iwl_trans *trans,
int reg; int reg;
__le32 *val; __le32 *val;
prph_len += sizeof(*data) + sizeof(*prph) + prph_len += sizeof(**data) + sizeof(*prph) + num_bytes_in_chunk;
num_bytes_in_chunk;
(*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_PRPH); (*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_PRPH);
(*data)->len = cpu_to_le32(sizeof(*prph) + (*data)->len = cpu_to_le32(sizeof(*prph) +
......
...@@ -158,55 +158,29 @@ void rt2x00queue_align_frame(struct sk_buff *skb) ...@@ -158,55 +158,29 @@ void rt2x00queue_align_frame(struct sk_buff *skb)
skb_trim(skb, frame_length); skb_trim(skb, frame_length);
} }
void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length) /*
* H/W needs L2 padding between the header and the paylod if header size
* is not 4 bytes aligned.
*/
void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int hdr_len)
{ {
unsigned int payload_length = skb->len - header_length; unsigned int l2pad = (skb->len > hdr_len) ? L2PAD_SIZE(hdr_len) : 0;
unsigned int header_align = ALIGN_SIZE(skb, 0);
unsigned int payload_align = ALIGN_SIZE(skb, header_length);
unsigned int l2pad = payload_length ? L2PAD_SIZE(header_length) : 0;
/* if (!l2pad)
* Adjust the header alignment if the payload needs to be moved more
* than the header.
*/
if (payload_align > header_align)
header_align += 4;
/* There is nothing to do if no alignment is needed */
if (!header_align)
return; return;
/* Reserve the amount of space needed in front of the frame */ skb_push(skb, l2pad);
skb_push(skb, header_align); memmove(skb->data, skb->data + l2pad, hdr_len);
/*
* Move the header.
*/
memmove(skb->data, skb->data + header_align, header_length);
/* Move the payload, if present and if required */
if (payload_length && payload_align)
memmove(skb->data + header_length + l2pad,
skb->data + header_length + l2pad + payload_align,
payload_length);
/* Trim the skb to the correct size */
skb_trim(skb, header_length + l2pad + payload_length);
} }
void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length) void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int hdr_len)
{ {
/* unsigned int l2pad = (skb->len > hdr_len) ? L2PAD_SIZE(hdr_len) : 0;
* L2 padding is only present if the skb contains more than just the
* IEEE 802.11 header.
*/
unsigned int l2pad = (skb->len > header_length) ?
L2PAD_SIZE(header_length) : 0;
if (!l2pad) if (!l2pad)
return; return;
memmove(skb->data + l2pad, skb->data, header_length); memmove(skb->data + l2pad, skb->data, hdr_len);
skb_pull(skb, l2pad); skb_pull(skb, l2pad);
} }
......
...@@ -842,7 +842,8 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) ...@@ -842,7 +842,8 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
break; break;
} }
/* handle command packet here */ /* handle command packet here */
if (rtlpriv->cfg->ops->rx_command_packet(hw, stats, skb)) { if (rtlpriv->cfg->ops->rx_command_packet &&
rtlpriv->cfg->ops->rx_command_packet(hw, stats, skb)) {
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
goto end; goto end;
} }
...@@ -1127,9 +1128,14 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) ...@@ -1127,9 +1128,14 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
__skb_queue_tail(&ring->queue, pskb); __skb_queue_tail(&ring->queue, pskb);
rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true, HW_DESC_OWN, if (rtlpriv->use_new_trx_flow) {
&temp_one); temp_one = 4;
rtlpriv->cfg->ops->set_desc(hw, (u8 *)pbuffer_desc, true,
HW_DESC_OWN, (u8 *)&temp_one);
} else {
rtlpriv->cfg->ops->set_desc(hw, (u8 *)pdesc, true, HW_DESC_OWN,
&temp_one);
}
return; return;
} }
...@@ -1370,9 +1376,9 @@ static void _rtl_pci_free_tx_ring(struct ieee80211_hw *hw, ...@@ -1370,9 +1376,9 @@ static void _rtl_pci_free_tx_ring(struct ieee80211_hw *hw,
ring->desc = NULL; ring->desc = NULL;
if (rtlpriv->use_new_trx_flow) { if (rtlpriv->use_new_trx_flow) {
pci_free_consistent(rtlpci->pdev, pci_free_consistent(rtlpci->pdev,
sizeof(*ring->desc) * ring->entries, sizeof(*ring->buffer_desc) * ring->entries,
ring->buffer_desc, ring->buffer_desc_dma); ring->buffer_desc, ring->buffer_desc_dma);
ring->desc = NULL; ring->buffer_desc = NULL;
} }
} }
...@@ -1543,7 +1549,6 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw) ...@@ -1543,7 +1549,6 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw)
true, true,
HW_DESC_TXBUFF_ADDR), HW_DESC_TXBUFF_ADDR),
skb->len, PCI_DMA_TODEVICE); skb->len, PCI_DMA_TODEVICE);
ring->idx = (ring->idx + 1) % ring->entries;
kfree_skb(skb); kfree_skb(skb);
ring->idx = (ring->idx + 1) % ring->entries; ring->idx = (ring->idx + 1) % ring->entries;
} }
......
...@@ -1201,6 +1201,9 @@ static int _rtl92se_set_media_status(struct ieee80211_hw *hw, ...@@ -1201,6 +1201,9 @@ static int _rtl92se_set_media_status(struct ieee80211_hw *hw,
} }
if (type != NL80211_IFTYPE_AP &&
rtlpriv->mac80211.link_state < MAC80211_LINKED)
bt_msr = rtl_read_byte(rtlpriv, MSR) & ~MSR_LINK_MASK;
rtl_write_byte(rtlpriv, (MSR), bt_msr); rtl_write_byte(rtlpriv, (MSR), bt_msr);
temp = rtl_read_dword(rtlpriv, TCR); temp = rtl_read_dword(rtlpriv, TCR);
...@@ -1262,6 +1265,7 @@ void rtl92se_enable_interrupt(struct ieee80211_hw *hw) ...@@ -1262,6 +1265,7 @@ void rtl92se_enable_interrupt(struct ieee80211_hw *hw)
rtl_write_dword(rtlpriv, INTA_MASK, rtlpci->irq_mask[0]); rtl_write_dword(rtlpriv, INTA_MASK, rtlpci->irq_mask[0]);
/* Support Bit 32-37(Assign as Bit 0-5) interrupt setting now */ /* Support Bit 32-37(Assign as Bit 0-5) interrupt setting now */
rtl_write_dword(rtlpriv, INTA_MASK + 4, rtlpci->irq_mask[1] & 0x3F); rtl_write_dword(rtlpriv, INTA_MASK + 4, rtlpci->irq_mask[1] & 0x3F);
rtlpci->irq_enabled = true;
} }
void rtl92se_disable_interrupt(struct ieee80211_hw *hw) void rtl92se_disable_interrupt(struct ieee80211_hw *hw)
...@@ -1276,8 +1280,7 @@ void rtl92se_disable_interrupt(struct ieee80211_hw *hw) ...@@ -1276,8 +1280,7 @@ void rtl92se_disable_interrupt(struct ieee80211_hw *hw)
rtlpci = rtl_pcidev(rtl_pcipriv(hw)); rtlpci = rtl_pcidev(rtl_pcipriv(hw));
rtl_write_dword(rtlpriv, INTA_MASK, 0); rtl_write_dword(rtlpriv, INTA_MASK, 0);
rtl_write_dword(rtlpriv, INTA_MASK + 4, 0); rtl_write_dword(rtlpriv, INTA_MASK + 4, 0);
rtlpci->irq_enabled = false;
synchronize_irq(rtlpci->pdev->irq);
} }
static u8 _rtl92s_set_sysclk(struct ieee80211_hw *hw, u8 data) static u8 _rtl92s_set_sysclk(struct ieee80211_hw *hw, u8 data)
......
...@@ -399,6 +399,8 @@ static bool _rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, ...@@ -399,6 +399,8 @@ static bool _rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
case 2: case 2:
currentcmd = &postcommoncmd[*step]; currentcmd = &postcommoncmd[*step];
break; break;
default:
return true;
} }
if (currentcmd->cmdid == CMDID_END) { if (currentcmd->cmdid == CMDID_END) {
......
...@@ -236,6 +236,19 @@ static void rtl92s_deinit_sw_vars(struct ieee80211_hw *hw) ...@@ -236,6 +236,19 @@ static void rtl92s_deinit_sw_vars(struct ieee80211_hw *hw)
} }
} }
static bool rtl92se_is_tx_desc_closed(struct ieee80211_hw *hw, u8 hw_queue,
u16 index)
{
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue];
u8 *entry = (u8 *)(&ring->desc[ring->idx]);
u8 own = (u8)rtl92se_get_desc(entry, true, HW_DESC_OWN);
if (own)
return false;
return true;
}
static struct rtl_hal_ops rtl8192se_hal_ops = { static struct rtl_hal_ops rtl8192se_hal_ops = {
.init_sw_vars = rtl92s_init_sw_vars, .init_sw_vars = rtl92s_init_sw_vars,
.deinit_sw_vars = rtl92s_deinit_sw_vars, .deinit_sw_vars = rtl92s_deinit_sw_vars,
...@@ -269,6 +282,7 @@ static struct rtl_hal_ops rtl8192se_hal_ops = { ...@@ -269,6 +282,7 @@ static struct rtl_hal_ops rtl8192se_hal_ops = {
.led_control = rtl92se_led_control, .led_control = rtl92se_led_control,
.set_desc = rtl92se_set_desc, .set_desc = rtl92se_set_desc,
.get_desc = rtl92se_get_desc, .get_desc = rtl92se_get_desc,
.is_tx_desc_closed = rtl92se_is_tx_desc_closed,
.tx_polling = rtl92se_tx_polling, .tx_polling = rtl92se_tx_polling,
.enable_hw_sec = rtl92se_enable_hw_security_config, .enable_hw_sec = rtl92se_enable_hw_security_config,
.set_key = rtl92se_set_key, .set_key = rtl92se_set_key,
...@@ -306,6 +320,8 @@ static struct rtl_hal_cfg rtl92se_hal_cfg = { ...@@ -306,6 +320,8 @@ static struct rtl_hal_cfg rtl92se_hal_cfg = {
.maps[MAC_RCR_ACRC32] = RCR_ACRC32, .maps[MAC_RCR_ACRC32] = RCR_ACRC32,
.maps[MAC_RCR_ACF] = RCR_ACF, .maps[MAC_RCR_ACF] = RCR_ACF,
.maps[MAC_RCR_AAP] = RCR_AAP, .maps[MAC_RCR_AAP] = RCR_AAP,
.maps[MAC_HIMR] = INTA_MASK,
.maps[MAC_HIMRE] = INTA_MASK + 4,
.maps[EFUSE_TEST] = REG_EFUSE_TEST, .maps[EFUSE_TEST] = REG_EFUSE_TEST,
.maps[EFUSE_CTRL] = REG_EFUSE_CTRL, .maps[EFUSE_CTRL] = REG_EFUSE_CTRL,
......
...@@ -53,6 +53,9 @@ int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, ...@@ -53,6 +53,9 @@ int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
__aligned(__alignof__(struct aead_request)); __aligned(__alignof__(struct aead_request));
struct aead_request *aead_req = (void *) aead_req_data; struct aead_request *aead_req = (void *) aead_req_data;
if (data_len == 0)
return -EINVAL;
memset(aead_req, 0, sizeof(aead_req_data)); memset(aead_req, 0, sizeof(aead_req_data));
sg_init_one(&pt, data, data_len); sg_init_one(&pt, data, data_len);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册