Skip to content

Commit

Permalink
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/linville/wireless

John W. Linville says:

====================
I present to you another batch of fixes intended for the 3.9 stream...

On the bluetooth bits, Gustavo says:

"I put together 3 fixes intended for 3.9, there are support for two
new devices and a NULL dereference fix in the SCO code."

Amitkumar Karwar fixes a command queueing race in mwifiex.

Bing Zhao provides a pair of mwifiex related to cleaning-up before
a shutdown.

Felix Fietkau provides an ath9k fix for a regression caused by an
earlier calibration fix, and another ath9k fix to avoid race conditions
that unnecessarily lead to chip resets.

Jussi Kivilinna prevents and skbuff leak in rtlwifi.

Stanislaw Gruszka corrects a length paramater for a DMA buffer mapping
operation in iwlegacy.

Please let me know if there are problems!
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Mar 20, 2013
2 parents 9d73adf + b9d5319 commit f379fb9
Show file tree
Hide file tree
Showing 12 changed files with 69 additions and 43 deletions.
4 changes: 4 additions & 0 deletions drivers/bluetooth/ath3k.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,11 @@ static struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x03F0, 0x311D) },

/* Atheros AR3012 with sflash firmware*/
{ USB_DEVICE(0x0CF3, 0x0036) },
{ USB_DEVICE(0x0CF3, 0x3004) },
{ USB_DEVICE(0x0CF3, 0x3008) },
{ USB_DEVICE(0x0CF3, 0x311D) },
{ USB_DEVICE(0x0CF3, 0x817a) },
{ USB_DEVICE(0x13d3, 0x3375) },
{ USB_DEVICE(0x04CA, 0x3004) },
{ USB_DEVICE(0x04CA, 0x3005) },
Expand Down Expand Up @@ -107,9 +109,11 @@ MODULE_DEVICE_TABLE(usb, ath3k_table);
static struct usb_device_id ath3k_blist_tbl[] = {

/* Atheros AR3012 with sflash firmware*/
{ USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0CF3, 0x817a), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
Expand Down
2 changes: 2 additions & 0 deletions drivers/bluetooth/btusb.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,11 @@ static struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },

/* Atheros 3012 with sflash firmware */
{ USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x817a), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/wireless/ath/ath9k/ar9003_calib.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -1150,6 +1151,9 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
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;

Expand Down
26 changes: 13 additions & 13 deletions drivers/net/wireless/ath/ath9k/link.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
22 changes: 12 additions & 10 deletions drivers/net/wireless/iwlegacy/3945-mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -589,34 +590,35 @@ 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;
}

/* 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;
Expand Down
22 changes: 16 additions & 6 deletions drivers/net/wireless/mwifiex/cmdevt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
/*
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down
8 changes: 8 additions & 0 deletions drivers/net/wireless/mwifiex/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down
4 changes: 2 additions & 2 deletions drivers/net/wireless/mwifiex/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,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];
Expand Down Expand Up @@ -1018,7 +1017,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);
Expand Down
8 changes: 4 additions & 4 deletions drivers/net/wireless/mwifiex/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
10 changes: 2 additions & 8 deletions drivers/net/wireless/mwifiex/sta_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/rtlwifi/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,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);
Expand Down
1 change: 1 addition & 0 deletions net/bluetooth/sco.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ static void __sco_sock_close(struct sock *sk)
sco_chan_del(sk, ECONNRESET);
break;

case BT_CONNECT2:
case BT_CONNECT:
case BT_DISCONN:
sco_chan_del(sk, ECONNRESET);
Expand Down

0 comments on commit f379fb9

Please sign in to comment.