Loading drivers/net/wireless/Kconfig +1 −1 Original line number Diff line number Diff line Loading @@ -153,7 +153,7 @@ config LIBERTAS_SDIO config LIBERTAS_SPI tristate "Marvell Libertas 8686 SPI 802.11b/g cards" depends on LIBERTAS && SPI && GENERIC_GPIO depends on LIBERTAS && SPI ---help--- A driver for Marvell Libertas 8686 SPI devices. Loading drivers/net/wireless/ath/ar9170/ar9170.h +24 −10 Original line number Diff line number Diff line Loading @@ -109,6 +109,11 @@ struct ar9170_rxstream_mpdu_merge { bool has_plcp; }; #define AR9170_QUEUE_TIMEOUT 64 #define AR9170_TX_TIMEOUT 8 #define AR9170_JANITOR_DELAY 128 #define AR9170_TX_INVALID_RATE 0xffffffff struct ar9170 { struct ieee80211_hw *hw; struct mutex mutex; Loading @@ -117,10 +122,11 @@ struct ar9170 { int (*open)(struct ar9170 *); void (*stop)(struct ar9170 *); int (*tx)(struct ar9170 *, struct sk_buff *, bool, unsigned int); int (*tx)(struct ar9170 *, struct sk_buff *); int (*exec_cmd)(struct ar9170 *, enum ar9170_cmd, u32 , void *, u32 , void *); void (*callback_cmd)(struct ar9170 *, u32 , void *); int (*flush)(struct ar9170 *); /* interface mode settings */ struct ieee80211_vif *vif; Loading Loading @@ -177,10 +183,10 @@ struct ar9170 { struct ar9170_eeprom eeprom; struct ath_regulatory regulatory; /* global tx status for unregistered Stations. */ struct sk_buff_head global_tx_status; struct sk_buff_head global_tx_status_waste; struct delayed_work tx_status_janitor; /* tx queues - as seen by hw - */ struct sk_buff_head tx_pending[__AR9170_NUM_TXQ]; struct sk_buff_head tx_status[__AR9170_NUM_TXQ]; struct delayed_work tx_janitor; /* rxstream mpdu merge */ struct ar9170_rxstream_mpdu_merge rx_mpdu; Loading @@ -189,11 +195,19 @@ struct ar9170 { }; struct ar9170_sta_info { struct sk_buff_head tx_status[__AR9170_NUM_TXQ]; }; #define IS_STARTED(a) (a->state >= AR9170_STARTED) #define IS_ACCEPTING_CMD(a) (a->state >= AR9170_IDLE) #define AR9170_TX_FLAG_WAIT_FOR_ACK BIT(0) #define AR9170_TX_FLAG_NO_ACK BIT(1) #define AR9170_TX_FLAG_BLOCK_ACK BIT(2) struct ar9170_tx_info { unsigned long timeout; unsigned int flags; }; #define IS_STARTED(a) (((struct ar9170 *)a)->state >= AR9170_STARTED) #define IS_ACCEPTING_CMD(a) (((struct ar9170 *)a)->state >= AR9170_IDLE) #define AR9170_FILTER_CHANGED_MODE BIT(0) #define AR9170_FILTER_CHANGED_MULTICAST BIT(1) Loading @@ -204,9 +218,9 @@ void *ar9170_alloc(size_t priv_size); int ar9170_register(struct ar9170 *ar, struct device *pdev); void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb); void ar9170_unregister(struct ar9170 *ar); void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb, bool update_statistics, u16 tx_status); void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb); void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len); int ar9170_nag_limiter(struct ar9170 *ar); /* MAC */ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); Loading drivers/net/wireless/ath/ar9170/hw.h +3 −0 Original line number Diff line number Diff line Loading @@ -420,4 +420,7 @@ enum ar9170_txq { __AR9170_NUM_TXQ, }; #define AR9170_TXQ_DEPTH 32 #define AR9170_TX_MAX_PENDING 128 #endif /* __AR9170_HW_H */ drivers/net/wireless/ath/ar9170/main.c +452 −224 File changed.Preview size limit exceeded, changes collapsed. Show changes drivers/net/wireless/ath/ar9170/usb.c +97 −25 Original line number Diff line number Diff line Loading @@ -96,7 +96,49 @@ static struct usb_device_id ar9170_usb_ids[] = { }; MODULE_DEVICE_TABLE(usb, ar9170_usb_ids); static void ar9170_usb_tx_urb_complete_free(struct urb *urb) static void ar9170_usb_submit_urb(struct ar9170_usb *aru) { struct urb *urb; unsigned long flags; int err; if (unlikely(!IS_STARTED(&aru->common))) return ; spin_lock_irqsave(&aru->tx_urb_lock, flags); if (aru->tx_submitted_urbs >= AR9170_NUM_TX_URBS) { spin_unlock_irqrestore(&aru->tx_urb_lock, flags); return ; } aru->tx_submitted_urbs++; urb = usb_get_from_anchor(&aru->tx_pending); if (!urb) { aru->tx_submitted_urbs--; spin_unlock_irqrestore(&aru->tx_urb_lock, flags); return ; } spin_unlock_irqrestore(&aru->tx_urb_lock, flags); aru->tx_pending_urbs--; usb_anchor_urb(urb, &aru->tx_submitted); err = usb_submit_urb(urb, GFP_ATOMIC); if (unlikely(err)) { if (ar9170_nag_limiter(&aru->common)) dev_err(&aru->udev->dev, "submit_urb failed (%d).\n", err); usb_unanchor_urb(urb); aru->tx_submitted_urbs--; ar9170_tx_callback(&aru->common, urb->context); } usb_free_urb(urb); } static void ar9170_usb_tx_urb_complete_frame(struct urb *urb) { struct sk_buff *skb = urb->context; struct ar9170_usb *aru = (struct ar9170_usb *) Loading @@ -107,8 +149,11 @@ static void ar9170_usb_tx_urb_complete_free(struct urb *urb) return ; } ar9170_handle_tx_status(&aru->common, skb, false, AR9170_TX_STATUS_COMPLETE); aru->tx_submitted_urbs--; ar9170_tx_callback(&aru->common, skb); ar9170_usb_submit_urb(aru); } static void ar9170_usb_tx_urb_complete(struct urb *urb) Loading Loading @@ -290,21 +335,47 @@ static int ar9170_usb_alloc_rx_bulk_urbs(struct ar9170_usb *aru) return err; } static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru) static int ar9170_usb_flush(struct ar9170 *ar) { int ret; struct ar9170_usb *aru = (void *) ar; struct urb *urb; int ret, err = 0; aru->common.state = AR9170_UNKNOWN_STATE; if (IS_STARTED(ar)) aru->common.state = AR9170_IDLE; usb_unlink_anchored_urbs(&aru->tx_submitted); usb_wait_anchor_empty_timeout(&aru->tx_pending, msecs_to_jiffies(800)); while ((urb = usb_get_from_anchor(&aru->tx_pending))) { ar9170_tx_callback(&aru->common, (void *) urb->context); usb_free_urb(urb); } /* give the LED OFF command and the deauth frame a chance to air. */ /* lets wait a while until the tx - queues are dried out */ ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted, msecs_to_jiffies(100)); if (ret == 0) dev_err(&aru->udev->dev, "kill pending tx urbs.\n"); usb_poison_anchored_urbs(&aru->tx_submitted); err = -ETIMEDOUT; usb_kill_anchored_urbs(&aru->tx_submitted); if (IS_ACCEPTING_CMD(ar)) aru->common.state = AR9170_STARTED; return err; } static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru) { int err; aru->common.state = AR9170_UNKNOWN_STATE; err = ar9170_usb_flush(&aru->common); if (err) dev_err(&aru->udev->dev, "stuck tx urbs!\n"); usb_poison_anchored_urbs(&aru->tx_submitted); usb_poison_anchored_urbs(&aru->rx_submitted); } Loading Loading @@ -388,12 +459,10 @@ static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd, return err; } static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb, bool txstatus_needed, unsigned int extra_len) static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb) { struct ar9170_usb *aru = (struct ar9170_usb *) ar; struct urb *urb; int err; if (unlikely(!IS_STARTED(ar))) { /* Seriously, what were you drink... err... thinking!? */ Loading @@ -406,18 +475,17 @@ static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb, usb_fill_bulk_urb(urb, aru->udev, usb_sndbulkpipe(aru->udev, AR9170_EP_TX), skb->data, skb->len + extra_len, (txstatus_needed ? ar9170_usb_tx_urb_complete : ar9170_usb_tx_urb_complete_free), skb); skb->data, skb->len, ar9170_usb_tx_urb_complete_frame, skb); urb->transfer_flags |= URB_ZERO_PACKET; usb_anchor_urb(urb, &aru->tx_submitted); err = usb_submit_urb(urb, GFP_ATOMIC); if (unlikely(err)) usb_unanchor_urb(urb); usb_anchor_urb(urb, &aru->tx_pending); aru->tx_pending_urbs++; usb_free_urb(urb); return err; ar9170_usb_submit_urb(aru); return 0; } static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer) Loading Loading @@ -617,10 +685,8 @@ static void ar9170_usb_stop(struct ar9170 *ar) if (IS_ACCEPTING_CMD(ar)) aru->common.state = AR9170_STOPPED; /* lets wait a while until the tx - queues are dried out */ ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted, msecs_to_jiffies(1000)); if (ret == 0) ret = ar9170_usb_flush(ar); if (ret) dev_err(&aru->udev->dev, "kill pending tx urbs.\n"); usb_poison_anchored_urbs(&aru->tx_submitted); Loading Loading @@ -716,10 +782,16 @@ static int ar9170_usb_probe(struct usb_interface *intf, SET_IEEE80211_DEV(ar->hw, &udev->dev); init_usb_anchor(&aru->rx_submitted); init_usb_anchor(&aru->tx_pending); init_usb_anchor(&aru->tx_submitted); init_completion(&aru->cmd_wait); spin_lock_init(&aru->tx_urb_lock); aru->tx_pending_urbs = 0; aru->tx_submitted_urbs = 0; aru->common.stop = ar9170_usb_stop; aru->common.flush = ar9170_usb_flush; aru->common.open = ar9170_usb_open; aru->common.tx = ar9170_usb_tx; aru->common.exec_cmd = ar9170_usb_exec_cmd; Loading Loading
drivers/net/wireless/Kconfig +1 −1 Original line number Diff line number Diff line Loading @@ -153,7 +153,7 @@ config LIBERTAS_SDIO config LIBERTAS_SPI tristate "Marvell Libertas 8686 SPI 802.11b/g cards" depends on LIBERTAS && SPI && GENERIC_GPIO depends on LIBERTAS && SPI ---help--- A driver for Marvell Libertas 8686 SPI devices. Loading
drivers/net/wireless/ath/ar9170/ar9170.h +24 −10 Original line number Diff line number Diff line Loading @@ -109,6 +109,11 @@ struct ar9170_rxstream_mpdu_merge { bool has_plcp; }; #define AR9170_QUEUE_TIMEOUT 64 #define AR9170_TX_TIMEOUT 8 #define AR9170_JANITOR_DELAY 128 #define AR9170_TX_INVALID_RATE 0xffffffff struct ar9170 { struct ieee80211_hw *hw; struct mutex mutex; Loading @@ -117,10 +122,11 @@ struct ar9170 { int (*open)(struct ar9170 *); void (*stop)(struct ar9170 *); int (*tx)(struct ar9170 *, struct sk_buff *, bool, unsigned int); int (*tx)(struct ar9170 *, struct sk_buff *); int (*exec_cmd)(struct ar9170 *, enum ar9170_cmd, u32 , void *, u32 , void *); void (*callback_cmd)(struct ar9170 *, u32 , void *); int (*flush)(struct ar9170 *); /* interface mode settings */ struct ieee80211_vif *vif; Loading Loading @@ -177,10 +183,10 @@ struct ar9170 { struct ar9170_eeprom eeprom; struct ath_regulatory regulatory; /* global tx status for unregistered Stations. */ struct sk_buff_head global_tx_status; struct sk_buff_head global_tx_status_waste; struct delayed_work tx_status_janitor; /* tx queues - as seen by hw - */ struct sk_buff_head tx_pending[__AR9170_NUM_TXQ]; struct sk_buff_head tx_status[__AR9170_NUM_TXQ]; struct delayed_work tx_janitor; /* rxstream mpdu merge */ struct ar9170_rxstream_mpdu_merge rx_mpdu; Loading @@ -189,11 +195,19 @@ struct ar9170 { }; struct ar9170_sta_info { struct sk_buff_head tx_status[__AR9170_NUM_TXQ]; }; #define IS_STARTED(a) (a->state >= AR9170_STARTED) #define IS_ACCEPTING_CMD(a) (a->state >= AR9170_IDLE) #define AR9170_TX_FLAG_WAIT_FOR_ACK BIT(0) #define AR9170_TX_FLAG_NO_ACK BIT(1) #define AR9170_TX_FLAG_BLOCK_ACK BIT(2) struct ar9170_tx_info { unsigned long timeout; unsigned int flags; }; #define IS_STARTED(a) (((struct ar9170 *)a)->state >= AR9170_STARTED) #define IS_ACCEPTING_CMD(a) (((struct ar9170 *)a)->state >= AR9170_IDLE) #define AR9170_FILTER_CHANGED_MODE BIT(0) #define AR9170_FILTER_CHANGED_MULTICAST BIT(1) Loading @@ -204,9 +218,9 @@ void *ar9170_alloc(size_t priv_size); int ar9170_register(struct ar9170 *ar, struct device *pdev); void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb); void ar9170_unregister(struct ar9170 *ar); void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb, bool update_statistics, u16 tx_status); void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb); void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len); int ar9170_nag_limiter(struct ar9170 *ar); /* MAC */ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); Loading
drivers/net/wireless/ath/ar9170/hw.h +3 −0 Original line number Diff line number Diff line Loading @@ -420,4 +420,7 @@ enum ar9170_txq { __AR9170_NUM_TXQ, }; #define AR9170_TXQ_DEPTH 32 #define AR9170_TX_MAX_PENDING 128 #endif /* __AR9170_HW_H */
drivers/net/wireless/ath/ar9170/main.c +452 −224 File changed.Preview size limit exceeded, changes collapsed. Show changes
drivers/net/wireless/ath/ar9170/usb.c +97 −25 Original line number Diff line number Diff line Loading @@ -96,7 +96,49 @@ static struct usb_device_id ar9170_usb_ids[] = { }; MODULE_DEVICE_TABLE(usb, ar9170_usb_ids); static void ar9170_usb_tx_urb_complete_free(struct urb *urb) static void ar9170_usb_submit_urb(struct ar9170_usb *aru) { struct urb *urb; unsigned long flags; int err; if (unlikely(!IS_STARTED(&aru->common))) return ; spin_lock_irqsave(&aru->tx_urb_lock, flags); if (aru->tx_submitted_urbs >= AR9170_NUM_TX_URBS) { spin_unlock_irqrestore(&aru->tx_urb_lock, flags); return ; } aru->tx_submitted_urbs++; urb = usb_get_from_anchor(&aru->tx_pending); if (!urb) { aru->tx_submitted_urbs--; spin_unlock_irqrestore(&aru->tx_urb_lock, flags); return ; } spin_unlock_irqrestore(&aru->tx_urb_lock, flags); aru->tx_pending_urbs--; usb_anchor_urb(urb, &aru->tx_submitted); err = usb_submit_urb(urb, GFP_ATOMIC); if (unlikely(err)) { if (ar9170_nag_limiter(&aru->common)) dev_err(&aru->udev->dev, "submit_urb failed (%d).\n", err); usb_unanchor_urb(urb); aru->tx_submitted_urbs--; ar9170_tx_callback(&aru->common, urb->context); } usb_free_urb(urb); } static void ar9170_usb_tx_urb_complete_frame(struct urb *urb) { struct sk_buff *skb = urb->context; struct ar9170_usb *aru = (struct ar9170_usb *) Loading @@ -107,8 +149,11 @@ static void ar9170_usb_tx_urb_complete_free(struct urb *urb) return ; } ar9170_handle_tx_status(&aru->common, skb, false, AR9170_TX_STATUS_COMPLETE); aru->tx_submitted_urbs--; ar9170_tx_callback(&aru->common, skb); ar9170_usb_submit_urb(aru); } static void ar9170_usb_tx_urb_complete(struct urb *urb) Loading Loading @@ -290,21 +335,47 @@ static int ar9170_usb_alloc_rx_bulk_urbs(struct ar9170_usb *aru) return err; } static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru) static int ar9170_usb_flush(struct ar9170 *ar) { int ret; struct ar9170_usb *aru = (void *) ar; struct urb *urb; int ret, err = 0; aru->common.state = AR9170_UNKNOWN_STATE; if (IS_STARTED(ar)) aru->common.state = AR9170_IDLE; usb_unlink_anchored_urbs(&aru->tx_submitted); usb_wait_anchor_empty_timeout(&aru->tx_pending, msecs_to_jiffies(800)); while ((urb = usb_get_from_anchor(&aru->tx_pending))) { ar9170_tx_callback(&aru->common, (void *) urb->context); usb_free_urb(urb); } /* give the LED OFF command and the deauth frame a chance to air. */ /* lets wait a while until the tx - queues are dried out */ ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted, msecs_to_jiffies(100)); if (ret == 0) dev_err(&aru->udev->dev, "kill pending tx urbs.\n"); usb_poison_anchored_urbs(&aru->tx_submitted); err = -ETIMEDOUT; usb_kill_anchored_urbs(&aru->tx_submitted); if (IS_ACCEPTING_CMD(ar)) aru->common.state = AR9170_STARTED; return err; } static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru) { int err; aru->common.state = AR9170_UNKNOWN_STATE; err = ar9170_usb_flush(&aru->common); if (err) dev_err(&aru->udev->dev, "stuck tx urbs!\n"); usb_poison_anchored_urbs(&aru->tx_submitted); usb_poison_anchored_urbs(&aru->rx_submitted); } Loading Loading @@ -388,12 +459,10 @@ static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd, return err; } static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb, bool txstatus_needed, unsigned int extra_len) static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb) { struct ar9170_usb *aru = (struct ar9170_usb *) ar; struct urb *urb; int err; if (unlikely(!IS_STARTED(ar))) { /* Seriously, what were you drink... err... thinking!? */ Loading @@ -406,18 +475,17 @@ static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb, usb_fill_bulk_urb(urb, aru->udev, usb_sndbulkpipe(aru->udev, AR9170_EP_TX), skb->data, skb->len + extra_len, (txstatus_needed ? ar9170_usb_tx_urb_complete : ar9170_usb_tx_urb_complete_free), skb); skb->data, skb->len, ar9170_usb_tx_urb_complete_frame, skb); urb->transfer_flags |= URB_ZERO_PACKET; usb_anchor_urb(urb, &aru->tx_submitted); err = usb_submit_urb(urb, GFP_ATOMIC); if (unlikely(err)) usb_unanchor_urb(urb); usb_anchor_urb(urb, &aru->tx_pending); aru->tx_pending_urbs++; usb_free_urb(urb); return err; ar9170_usb_submit_urb(aru); return 0; } static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer) Loading Loading @@ -617,10 +685,8 @@ static void ar9170_usb_stop(struct ar9170 *ar) if (IS_ACCEPTING_CMD(ar)) aru->common.state = AR9170_STOPPED; /* lets wait a while until the tx - queues are dried out */ ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted, msecs_to_jiffies(1000)); if (ret == 0) ret = ar9170_usb_flush(ar); if (ret) dev_err(&aru->udev->dev, "kill pending tx urbs.\n"); usb_poison_anchored_urbs(&aru->tx_submitted); Loading Loading @@ -716,10 +782,16 @@ static int ar9170_usb_probe(struct usb_interface *intf, SET_IEEE80211_DEV(ar->hw, &udev->dev); init_usb_anchor(&aru->rx_submitted); init_usb_anchor(&aru->tx_pending); init_usb_anchor(&aru->tx_submitted); init_completion(&aru->cmd_wait); spin_lock_init(&aru->tx_urb_lock); aru->tx_pending_urbs = 0; aru->tx_submitted_urbs = 0; aru->common.stop = ar9170_usb_stop; aru->common.flush = ar9170_usb_flush; aru->common.open = ar9170_usb_open; aru->common.tx = ar9170_usb_tx; aru->common.exec_cmd = ar9170_usb_exec_cmd; Loading