diff options
Diffstat (limited to 'drivers')
33 files changed, 602 insertions, 166 deletions
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index 11b32d2642df..a6e5672c67e7 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c | |||
@@ -272,6 +272,7 @@ static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = { | |||
272 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) }, | 272 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) }, |
273 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) }, | 273 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) }, |
274 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) }, | 274 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) }, |
275 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) }, | ||
275 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, | 276 | { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, |
276 | { 0, }, | 277 | { 0, }, |
277 | }; | 278 | }; |
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c index 26823d97fd9f..9ea4627dc0c2 100644 --- a/drivers/bcma/sprom.c +++ b/drivers/bcma/sprom.c | |||
@@ -507,7 +507,9 @@ static bool bcma_sprom_onchip_available(struct bcma_bus *bus) | |||
507 | /* for these chips OTP is always available */ | 507 | /* for these chips OTP is always available */ |
508 | present = true; | 508 | present = true; |
509 | break; | 509 | break; |
510 | 510 | case BCMA_CHIP_ID_BCM43228: | |
511 | present = chip_status & BCMA_CC_CHIPST_43228_OTP_PRESENT; | ||
512 | break; | ||
511 | default: | 513 | default: |
512 | present = false; | 514 | present = false; |
513 | break; | 515 | break; |
diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c index 5405ec644db3..baf2686aa8eb 100644 --- a/drivers/isdn/isdnloop/isdnloop.c +++ b/drivers/isdn/isdnloop/isdnloop.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
17 | #include "isdnloop.h" | 17 | #include "isdnloop.h" |
18 | 18 | ||
19 | static char *revision = "$Revision: 1.11.6.7 $"; | ||
20 | static char *isdnloop_id = "loop0"; | 19 | static char *isdnloop_id = "loop0"; |
21 | 20 | ||
22 | MODULE_DESCRIPTION("ISDN4Linux: Pseudo Driver that simulates an ISDN card"); | 21 | MODULE_DESCRIPTION("ISDN4Linux: Pseudo Driver that simulates an ISDN card"); |
@@ -1494,17 +1493,6 @@ isdnloop_addcard(char *id1) | |||
1494 | static int __init | 1493 | static int __init |
1495 | isdnloop_init(void) | 1494 | isdnloop_init(void) |
1496 | { | 1495 | { |
1497 | char *p; | ||
1498 | char rev[10]; | ||
1499 | |||
1500 | if ((p = strchr(revision, ':'))) { | ||
1501 | strcpy(rev, p + 1); | ||
1502 | p = strchr(rev, '$'); | ||
1503 | *p = 0; | ||
1504 | } else | ||
1505 | strcpy(rev, " ??? "); | ||
1506 | printk(KERN_NOTICE "isdnloop-ISDN-driver Rev%s\n", rev); | ||
1507 | |||
1508 | if (isdnloop_id) | 1496 | if (isdnloop_id) |
1509 | return (isdnloop_addcard(isdnloop_id)); | 1497 | return (isdnloop_addcard(isdnloop_id)); |
1510 | 1498 | ||
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c index f0c8bd54ce29..021d69c5d9bc 100644 --- a/drivers/net/cris/eth_v10.c +++ b/drivers/net/cris/eth_v10.c | |||
@@ -1712,7 +1712,7 @@ e100_set_network_leds(int active) | |||
1712 | static void | 1712 | static void |
1713 | e100_netpoll(struct net_device* netdev) | 1713 | e100_netpoll(struct net_device* netdev) |
1714 | { | 1714 | { |
1715 | e100rxtx_interrupt(NETWORK_DMA_TX_IRQ_NBR, netdev, NULL); | 1715 | e100rxtx_interrupt(NETWORK_DMA_TX_IRQ_NBR, netdev); |
1716 | } | 1716 | } |
1717 | #endif | 1717 | #endif |
1718 | 1718 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 734fd87cd990..62f754bd0dfe 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | |||
@@ -2485,6 +2485,7 @@ static int bnx2x_mcast_enqueue_cmd(struct bnx2x *bp, | |||
2485 | break; | 2485 | break; |
2486 | 2486 | ||
2487 | default: | 2487 | default: |
2488 | kfree(new_cmd); | ||
2488 | BNX2X_ERR("Unknown command: %d\n", cmd); | 2489 | BNX2X_ERR("Unknown command: %d\n", cmd); |
2489 | return -EINVAL; | 2490 | return -EINVAL; |
2490 | } | 2491 | } |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index c60de89b6669..90a903d83d87 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -1948,7 +1948,7 @@ static int be_rx_cqs_create(struct be_adapter *adapter) | |||
1948 | 1948 | ||
1949 | if (adapter->num_rx_qs != MAX_RX_QS) | 1949 | if (adapter->num_rx_qs != MAX_RX_QS) |
1950 | dev_info(&adapter->pdev->dev, | 1950 | dev_info(&adapter->pdev->dev, |
1951 | "Created only %d receive queues", adapter->num_rx_qs); | 1951 | "Created only %d receive queues\n", adapter->num_rx_qs); |
1952 | 1952 | ||
1953 | return 0; | 1953 | return 0; |
1954 | } | 1954 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index f32e70300770..5aba5ecdf1e2 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c | |||
@@ -614,8 +614,8 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud | |||
614 | /* If source MAC is equal to our own MAC and not performing | 614 | /* If source MAC is equal to our own MAC and not performing |
615 | * the selftest or flb disabled - drop the packet */ | 615 | * the selftest or flb disabled - drop the packet */ |
616 | if (s_mac == priv->mac && | 616 | if (s_mac == priv->mac && |
617 | (!(dev->features & NETIF_F_LOOPBACK) || | 617 | !((dev->features & NETIF_F_LOOPBACK) || |
618 | !priv->validate_loopback)) | 618 | priv->validate_loopback)) |
619 | goto next; | 619 | goto next; |
620 | 620 | ||
621 | /* | 621 | /* |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index 019d856b1334..10bba09c44ea 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c | |||
@@ -164,7 +164,6 @@ int mlx4_en_activate_tx_ring(struct mlx4_en_priv *priv, | |||
164 | ring->cons = 0xffffffff; | 164 | ring->cons = 0xffffffff; |
165 | ring->last_nr_txbb = 1; | 165 | ring->last_nr_txbb = 1; |
166 | ring->poll_cnt = 0; | 166 | ring->poll_cnt = 0; |
167 | ring->blocked = 0; | ||
168 | memset(ring->tx_info, 0, ring->size * sizeof(struct mlx4_en_tx_info)); | 167 | memset(ring->tx_info, 0, ring->size * sizeof(struct mlx4_en_tx_info)); |
169 | memset(ring->buf, 0, ring->buf_size); | 168 | memset(ring->buf, 0, ring->buf_size); |
170 | 169 | ||
@@ -365,14 +364,13 @@ static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq) | |||
365 | ring->cons += txbbs_skipped; | 364 | ring->cons += txbbs_skipped; |
366 | netdev_tx_completed_queue(ring->tx_queue, packets, bytes); | 365 | netdev_tx_completed_queue(ring->tx_queue, packets, bytes); |
367 | 366 | ||
368 | /* Wakeup Tx queue if this ring stopped it */ | 367 | /* |
369 | if (unlikely(ring->blocked)) { | 368 | * Wakeup Tx queue if this stopped, and at least 1 packet |
370 | if ((u32) (ring->prod - ring->cons) <= | 369 | * was completed |
371 | ring->size - HEADROOM - MAX_DESC_TXBBS) { | 370 | */ |
372 | ring->blocked = 0; | 371 | if (netif_tx_queue_stopped(ring->tx_queue) && txbbs_skipped > 0) { |
373 | netif_tx_wake_queue(ring->tx_queue); | 372 | netif_tx_wake_queue(ring->tx_queue); |
374 | priv->port_stats.wake_queue++; | 373 | priv->port_stats.wake_queue++; |
375 | } | ||
376 | } | 374 | } |
377 | } | 375 | } |
378 | 376 | ||
@@ -592,7 +590,6 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) | |||
592 | ring->size - HEADROOM - MAX_DESC_TXBBS)) { | 590 | ring->size - HEADROOM - MAX_DESC_TXBBS)) { |
593 | /* every full Tx ring stops queue */ | 591 | /* every full Tx ring stops queue */ |
594 | netif_tx_stop_queue(ring->tx_queue); | 592 | netif_tx_stop_queue(ring->tx_queue); |
595 | ring->blocked = 1; | ||
596 | priv->port_stats.queue_stopped++; | 593 | priv->port_stats.queue_stopped++; |
597 | 594 | ||
598 | return NETDEV_TX_BUSY; | 595 | return NETDEV_TX_BUSY; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 48d0e90194cb..827b72dfce99 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -157,9 +157,6 @@ int mlx4_check_port_params(struct mlx4_dev *dev, | |||
157 | "on this HCA, aborting.\n"); | 157 | "on this HCA, aborting.\n"); |
158 | return -EINVAL; | 158 | return -EINVAL; |
159 | } | 159 | } |
160 | if (port_type[i] == MLX4_PORT_TYPE_ETH && | ||
161 | port_type[i + 1] == MLX4_PORT_TYPE_IB) | ||
162 | return -EINVAL; | ||
163 | } | 160 | } |
164 | } | 161 | } |
165 | 162 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 5f1ab105debc..9d27e42264e2 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | |||
@@ -248,7 +248,6 @@ struct mlx4_en_tx_ring { | |||
248 | u32 doorbell_qpn; | 248 | u32 doorbell_qpn; |
249 | void *buf; | 249 | void *buf; |
250 | u16 poll_cnt; | 250 | u16 poll_cnt; |
251 | int blocked; | ||
252 | struct mlx4_en_tx_info *tx_info; | 251 | struct mlx4_en_tx_info *tx_info; |
253 | u8 *bounce_buf; | 252 | u8 *bounce_buf; |
254 | u32 last_nr_txbb; | 253 | u32 last_nr_txbb; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/sense.c b/drivers/net/ethernet/mellanox/mlx4/sense.c index 802498293528..34ee09bae36e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/sense.c +++ b/drivers/net/ethernet/mellanox/mlx4/sense.c | |||
@@ -81,20 +81,6 @@ void mlx4_do_sense_ports(struct mlx4_dev *dev, | |||
81 | } | 81 | } |
82 | 82 | ||
83 | /* | 83 | /* |
84 | * Adjust port configuration: | ||
85 | * If port 1 sensed nothing and port 2 is IB, set both as IB | ||
86 | * If port 2 sensed nothing and port 1 is Eth, set both as Eth | ||
87 | */ | ||
88 | if (stype[0] == MLX4_PORT_TYPE_ETH) { | ||
89 | for (i = 1; i < dev->caps.num_ports; i++) | ||
90 | stype[i] = stype[i] ? stype[i] : MLX4_PORT_TYPE_ETH; | ||
91 | } | ||
92 | if (stype[dev->caps.num_ports - 1] == MLX4_PORT_TYPE_IB) { | ||
93 | for (i = 0; i < dev->caps.num_ports - 1; i++) | ||
94 | stype[i] = stype[i] ? stype[i] : MLX4_PORT_TYPE_IB; | ||
95 | } | ||
96 | |||
97 | /* | ||
98 | * If sensed nothing, remain in current configuration. | 84 | * If sensed nothing, remain in current configuration. |
99 | */ | 85 | */ |
100 | for (i = 0; i < dev->caps.num_ports; i++) | 86 | for (i = 0; i < dev->caps.num_ports; i++) |
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 70554a1b2b02..65a8d49106a4 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c | |||
@@ -1503,6 +1503,11 @@ static int efx_probe_all(struct efx_nic *efx) | |||
1503 | goto fail2; | 1503 | goto fail2; |
1504 | } | 1504 | } |
1505 | 1505 | ||
1506 | BUILD_BUG_ON(EFX_DEFAULT_DMAQ_SIZE < EFX_RXQ_MIN_ENT); | ||
1507 | if (WARN_ON(EFX_DEFAULT_DMAQ_SIZE < EFX_TXQ_MIN_ENT(efx))) { | ||
1508 | rc = -EINVAL; | ||
1509 | goto fail3; | ||
1510 | } | ||
1506 | efx->rxq_entries = efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE; | 1511 | efx->rxq_entries = efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE; |
1507 | 1512 | ||
1508 | rc = efx_probe_filters(efx); | 1513 | rc = efx_probe_filters(efx); |
@@ -2070,6 +2075,7 @@ static int efx_register_netdev(struct efx_nic *efx) | |||
2070 | net_dev->irq = efx->pci_dev->irq; | 2075 | net_dev->irq = efx->pci_dev->irq; |
2071 | net_dev->netdev_ops = &efx_netdev_ops; | 2076 | net_dev->netdev_ops = &efx_netdev_ops; |
2072 | SET_ETHTOOL_OPS(net_dev, &efx_ethtool_ops); | 2077 | SET_ETHTOOL_OPS(net_dev, &efx_ethtool_ops); |
2078 | net_dev->gso_max_segs = EFX_TSO_MAX_SEGS; | ||
2073 | 2079 | ||
2074 | rtnl_lock(); | 2080 | rtnl_lock(); |
2075 | 2081 | ||
diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h index be8f9158a714..70755c97251a 100644 --- a/drivers/net/ethernet/sfc/efx.h +++ b/drivers/net/ethernet/sfc/efx.h | |||
@@ -30,6 +30,7 @@ extern netdev_tx_t | |||
30 | efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb); | 30 | efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb); |
31 | extern void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index); | 31 | extern void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index); |
32 | extern int efx_setup_tc(struct net_device *net_dev, u8 num_tc); | 32 | extern int efx_setup_tc(struct net_device *net_dev, u8 num_tc); |
33 | extern unsigned int efx_tx_max_skb_descs(struct efx_nic *efx); | ||
33 | 34 | ||
34 | /* RX */ | 35 | /* RX */ |
35 | extern int efx_probe_rx_queue(struct efx_rx_queue *rx_queue); | 36 | extern int efx_probe_rx_queue(struct efx_rx_queue *rx_queue); |
@@ -52,10 +53,15 @@ extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue); | |||
52 | #define EFX_MAX_EVQ_SIZE 16384UL | 53 | #define EFX_MAX_EVQ_SIZE 16384UL |
53 | #define EFX_MIN_EVQ_SIZE 512UL | 54 | #define EFX_MIN_EVQ_SIZE 512UL |
54 | 55 | ||
55 | /* The smallest [rt]xq_entries that the driver supports. Callers of | 56 | /* Maximum number of TCP segments we support for soft-TSO */ |
56 | * efx_wake_queue() assume that they can subsequently send at least one | 57 | #define EFX_TSO_MAX_SEGS 100 |
57 | * skb. Falcon/A1 may require up to three descriptors per skb_frag. */ | 58 | |
58 | #define EFX_MIN_RING_SIZE (roundup_pow_of_two(2 * 3 * MAX_SKB_FRAGS)) | 59 | /* The smallest [rt]xq_entries that the driver supports. RX minimum |
60 | * is a bit arbitrary. For TX, we must have space for at least 2 | ||
61 | * TSO skbs. | ||
62 | */ | ||
63 | #define EFX_RXQ_MIN_ENT 128U | ||
64 | #define EFX_TXQ_MIN_ENT(efx) (2 * efx_tx_max_skb_descs(efx)) | ||
59 | 65 | ||
60 | /* Filters */ | 66 | /* Filters */ |
61 | extern int efx_probe_filters(struct efx_nic *efx); | 67 | extern int efx_probe_filters(struct efx_nic *efx); |
diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index 10536f93b561..8cba2df82b18 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c | |||
@@ -680,21 +680,27 @@ static int efx_ethtool_set_ringparam(struct net_device *net_dev, | |||
680 | struct ethtool_ringparam *ring) | 680 | struct ethtool_ringparam *ring) |
681 | { | 681 | { |
682 | struct efx_nic *efx = netdev_priv(net_dev); | 682 | struct efx_nic *efx = netdev_priv(net_dev); |
683 | u32 txq_entries; | ||
683 | 684 | ||
684 | if (ring->rx_mini_pending || ring->rx_jumbo_pending || | 685 | if (ring->rx_mini_pending || ring->rx_jumbo_pending || |
685 | ring->rx_pending > EFX_MAX_DMAQ_SIZE || | 686 | ring->rx_pending > EFX_MAX_DMAQ_SIZE || |
686 | ring->tx_pending > EFX_MAX_DMAQ_SIZE) | 687 | ring->tx_pending > EFX_MAX_DMAQ_SIZE) |
687 | return -EINVAL; | 688 | return -EINVAL; |
688 | 689 | ||
689 | if (ring->rx_pending < EFX_MIN_RING_SIZE || | 690 | if (ring->rx_pending < EFX_RXQ_MIN_ENT) { |
690 | ring->tx_pending < EFX_MIN_RING_SIZE) { | ||
691 | netif_err(efx, drv, efx->net_dev, | 691 | netif_err(efx, drv, efx->net_dev, |
692 | "TX and RX queues cannot be smaller than %ld\n", | 692 | "RX queues cannot be smaller than %u\n", |
693 | EFX_MIN_RING_SIZE); | 693 | EFX_RXQ_MIN_ENT); |
694 | return -EINVAL; | 694 | return -EINVAL; |
695 | } | 695 | } |
696 | 696 | ||
697 | return efx_realloc_channels(efx, ring->rx_pending, ring->tx_pending); | 697 | txq_entries = max(ring->tx_pending, EFX_TXQ_MIN_ENT(efx)); |
698 | if (txq_entries != ring->tx_pending) | ||
699 | netif_warn(efx, drv, efx->net_dev, | ||
700 | "increasing TX queue size to minimum of %u\n", | ||
701 | txq_entries); | ||
702 | |||
703 | return efx_realloc_channels(efx, ring->rx_pending, txq_entries); | ||
698 | } | 704 | } |
699 | 705 | ||
700 | static int efx_ethtool_set_pauseparam(struct net_device *net_dev, | 706 | static int efx_ethtool_set_pauseparam(struct net_device *net_dev, |
diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c index 9b225a7769f7..18713436b443 100644 --- a/drivers/net/ethernet/sfc/tx.c +++ b/drivers/net/ethernet/sfc/tx.c | |||
@@ -119,6 +119,25 @@ efx_max_tx_len(struct efx_nic *efx, dma_addr_t dma_addr) | |||
119 | return len; | 119 | return len; |
120 | } | 120 | } |
121 | 121 | ||
122 | unsigned int efx_tx_max_skb_descs(struct efx_nic *efx) | ||
123 | { | ||
124 | /* Header and payload descriptor for each output segment, plus | ||
125 | * one for every input fragment boundary within a segment | ||
126 | */ | ||
127 | unsigned int max_descs = EFX_TSO_MAX_SEGS * 2 + MAX_SKB_FRAGS; | ||
128 | |||
129 | /* Possibly one more per segment for the alignment workaround */ | ||
130 | if (EFX_WORKAROUND_5391(efx)) | ||
131 | max_descs += EFX_TSO_MAX_SEGS; | ||
132 | |||
133 | /* Possibly more for PCIe page boundaries within input fragments */ | ||
134 | if (PAGE_SIZE > EFX_PAGE_SIZE) | ||
135 | max_descs += max_t(unsigned int, MAX_SKB_FRAGS, | ||
136 | DIV_ROUND_UP(GSO_MAX_SIZE, EFX_PAGE_SIZE)); | ||
137 | |||
138 | return max_descs; | ||
139 | } | ||
140 | |||
122 | /* | 141 | /* |
123 | * Add a socket buffer to a TX queue | 142 | * Add a socket buffer to a TX queue |
124 | * | 143 | * |
diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig index 1b173a6145d6..b26cbda5efa9 100644 --- a/drivers/net/ethernet/ti/Kconfig +++ b/drivers/net/ethernet/ti/Kconfig | |||
@@ -32,7 +32,7 @@ config TI_DAVINCI_EMAC | |||
32 | 32 | ||
33 | config TI_DAVINCI_MDIO | 33 | config TI_DAVINCI_MDIO |
34 | tristate "TI DaVinci MDIO Support" | 34 | tristate "TI DaVinci MDIO Support" |
35 | depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 ) | 35 | depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 || SOC_AM33XX ) |
36 | select PHYLIB | 36 | select PHYLIB |
37 | ---help--- | 37 | ---help--- |
38 | This driver supports TI's DaVinci MDIO module. | 38 | This driver supports TI's DaVinci MDIO module. |
@@ -42,7 +42,7 @@ config TI_DAVINCI_MDIO | |||
42 | 42 | ||
43 | config TI_DAVINCI_CPDMA | 43 | config TI_DAVINCI_CPDMA |
44 | tristate "TI DaVinci CPDMA Support" | 44 | tristate "TI DaVinci CPDMA Support" |
45 | depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 ) | 45 | depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 || SOC_AM33XX ) |
46 | ---help--- | 46 | ---help--- |
47 | This driver supports TI's DaVinci CPDMA dma engine. | 47 | This driver supports TI's DaVinci CPDMA dma engine. |
48 | 48 | ||
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 1e5d85b06e71..0cbc0e59252c 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c | |||
@@ -28,6 +28,9 @@ | |||
28 | #include <linux/workqueue.h> | 28 | #include <linux/workqueue.h> |
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/pm_runtime.h> | 30 | #include <linux/pm_runtime.h> |
31 | #include <linux/of.h> | ||
32 | #include <linux/of_net.h> | ||
33 | #include <linux/of_device.h> | ||
31 | 34 | ||
32 | #include <linux/platform_data/cpsw.h> | 35 | #include <linux/platform_data/cpsw.h> |
33 | 36 | ||
@@ -709,6 +712,158 @@ static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv) | |||
709 | slave->sliver = regs + data->sliver_reg_ofs; | 712 | slave->sliver = regs + data->sliver_reg_ofs; |
710 | } | 713 | } |
711 | 714 | ||
715 | static int cpsw_probe_dt(struct cpsw_platform_data *data, | ||
716 | struct platform_device *pdev) | ||
717 | { | ||
718 | struct device_node *node = pdev->dev.of_node; | ||
719 | struct device_node *slave_node; | ||
720 | int i = 0, ret; | ||
721 | u32 prop; | ||
722 | |||
723 | if (!node) | ||
724 | return -EINVAL; | ||
725 | |||
726 | if (of_property_read_u32(node, "slaves", &prop)) { | ||
727 | pr_err("Missing slaves property in the DT.\n"); | ||
728 | return -EINVAL; | ||
729 | } | ||
730 | data->slaves = prop; | ||
731 | |||
732 | data->slave_data = kzalloc(sizeof(struct cpsw_slave_data) * | ||
733 | data->slaves, GFP_KERNEL); | ||
734 | if (!data->slave_data) { | ||
735 | pr_err("Could not allocate slave memory.\n"); | ||
736 | return -EINVAL; | ||
737 | } | ||
738 | |||
739 | data->no_bd_ram = of_property_read_bool(node, "no_bd_ram"); | ||
740 | |||
741 | if (of_property_read_u32(node, "cpdma_channels", &prop)) { | ||
742 | pr_err("Missing cpdma_channels property in the DT.\n"); | ||
743 | ret = -EINVAL; | ||
744 | goto error_ret; | ||
745 | } | ||
746 | data->channels = prop; | ||
747 | |||
748 | if (of_property_read_u32(node, "host_port_no", &prop)) { | ||
749 | pr_err("Missing host_port_no property in the DT.\n"); | ||
750 | ret = -EINVAL; | ||
751 | goto error_ret; | ||
752 | } | ||
753 | data->host_port_num = prop; | ||
754 | |||
755 | if (of_property_read_u32(node, "cpdma_reg_ofs", &prop)) { | ||
756 | pr_err("Missing cpdma_reg_ofs property in the DT.\n"); | ||
757 | ret = -EINVAL; | ||
758 | goto error_ret; | ||
759 | } | ||
760 | data->cpdma_reg_ofs = prop; | ||
761 | |||
762 | if (of_property_read_u32(node, "cpdma_sram_ofs", &prop)) { | ||
763 | pr_err("Missing cpdma_sram_ofs property in the DT.\n"); | ||
764 | ret = -EINVAL; | ||
765 | goto error_ret; | ||
766 | } | ||
767 | data->cpdma_sram_ofs = prop; | ||
768 | |||
769 | if (of_property_read_u32(node, "ale_reg_ofs", &prop)) { | ||
770 | pr_err("Missing ale_reg_ofs property in the DT.\n"); | ||
771 | ret = -EINVAL; | ||
772 | goto error_ret; | ||
773 | } | ||
774 | data->ale_reg_ofs = prop; | ||
775 | |||
776 | if (of_property_read_u32(node, "ale_entries", &prop)) { | ||
777 | pr_err("Missing ale_entries property in the DT.\n"); | ||
778 | ret = -EINVAL; | ||
779 | goto error_ret; | ||
780 | } | ||
781 | data->ale_entries = prop; | ||
782 | |||
783 | if (of_property_read_u32(node, "host_port_reg_ofs", &prop)) { | ||
784 | pr_err("Missing host_port_reg_ofs property in the DT.\n"); | ||
785 | ret = -EINVAL; | ||
786 | goto error_ret; | ||
787 | } | ||
788 | data->host_port_reg_ofs = prop; | ||
789 | |||
790 | if (of_property_read_u32(node, "hw_stats_reg_ofs", &prop)) { | ||
791 | pr_err("Missing hw_stats_reg_ofs property in the DT.\n"); | ||
792 | ret = -EINVAL; | ||
793 | goto error_ret; | ||
794 | } | ||
795 | data->hw_stats_reg_ofs = prop; | ||
796 | |||
797 | if (of_property_read_u32(node, "bd_ram_ofs", &prop)) { | ||
798 | pr_err("Missing bd_ram_ofs property in the DT.\n"); | ||
799 | ret = -EINVAL; | ||
800 | goto error_ret; | ||
801 | } | ||
802 | data->bd_ram_ofs = prop; | ||
803 | |||
804 | if (of_property_read_u32(node, "bd_ram_size", &prop)) { | ||
805 | pr_err("Missing bd_ram_size property in the DT.\n"); | ||
806 | ret = -EINVAL; | ||
807 | goto error_ret; | ||
808 | } | ||
809 | data->bd_ram_size = prop; | ||
810 | |||
811 | if (of_property_read_u32(node, "rx_descs", &prop)) { | ||
812 | pr_err("Missing rx_descs property in the DT.\n"); | ||
813 | ret = -EINVAL; | ||
814 | goto error_ret; | ||
815 | } | ||
816 | data->rx_descs = prop; | ||
817 | |||
818 | if (of_property_read_u32(node, "mac_control", &prop)) { | ||
819 | pr_err("Missing mac_control property in the DT.\n"); | ||
820 | ret = -EINVAL; | ||
821 | goto error_ret; | ||
822 | } | ||
823 | data->mac_control = prop; | ||
824 | |||
825 | for_each_child_of_node(node, slave_node) { | ||
826 | struct cpsw_slave_data *slave_data = data->slave_data + i; | ||
827 | const char *phy_id = NULL; | ||
828 | const void *mac_addr = NULL; | ||
829 | |||
830 | if (of_property_read_string(slave_node, "phy_id", &phy_id)) { | ||
831 | pr_err("Missing slave[%d] phy_id property\n", i); | ||
832 | ret = -EINVAL; | ||
833 | goto error_ret; | ||
834 | } | ||
835 | slave_data->phy_id = phy_id; | ||
836 | |||
837 | if (of_property_read_u32(slave_node, "slave_reg_ofs", &prop)) { | ||
838 | pr_err("Missing slave[%d] slave_reg_ofs property\n", i); | ||
839 | ret = -EINVAL; | ||
840 | goto error_ret; | ||
841 | } | ||
842 | slave_data->slave_reg_ofs = prop; | ||
843 | |||
844 | if (of_property_read_u32(slave_node, "sliver_reg_ofs", | ||
845 | &prop)) { | ||
846 | pr_err("Missing slave[%d] sliver_reg_ofs property\n", | ||
847 | i); | ||
848 | ret = -EINVAL; | ||
849 | goto error_ret; | ||
850 | } | ||
851 | slave_data->sliver_reg_ofs = prop; | ||
852 | |||
853 | mac_addr = of_get_mac_address(slave_node); | ||
854 | if (mac_addr) | ||
855 | memcpy(slave_data->mac_addr, mac_addr, ETH_ALEN); | ||
856 | |||
857 | i++; | ||
858 | } | ||
859 | |||
860 | return 0; | ||
861 | |||
862 | error_ret: | ||
863 | kfree(data->slave_data); | ||
864 | return ret; | ||
865 | } | ||
866 | |||
712 | static int __devinit cpsw_probe(struct platform_device *pdev) | 867 | static int __devinit cpsw_probe(struct platform_device *pdev) |
713 | { | 868 | { |
714 | struct cpsw_platform_data *data = pdev->dev.platform_data; | 869 | struct cpsw_platform_data *data = pdev->dev.platform_data; |
@@ -720,11 +875,6 @@ static int __devinit cpsw_probe(struct platform_device *pdev) | |||
720 | struct resource *res; | 875 | struct resource *res; |
721 | int ret = 0, i, k = 0; | 876 | int ret = 0, i, k = 0; |
722 | 877 | ||
723 | if (!data) { | ||
724 | pr_err("platform data missing\n"); | ||
725 | return -ENODEV; | ||
726 | } | ||
727 | |||
728 | ndev = alloc_etherdev(sizeof(struct cpsw_priv)); | 878 | ndev = alloc_etherdev(sizeof(struct cpsw_priv)); |
729 | if (!ndev) { | 879 | if (!ndev) { |
730 | pr_err("error allocating net_device\n"); | 880 | pr_err("error allocating net_device\n"); |
@@ -734,13 +884,19 @@ static int __devinit cpsw_probe(struct platform_device *pdev) | |||
734 | platform_set_drvdata(pdev, ndev); | 884 | platform_set_drvdata(pdev, ndev); |
735 | priv = netdev_priv(ndev); | 885 | priv = netdev_priv(ndev); |
736 | spin_lock_init(&priv->lock); | 886 | spin_lock_init(&priv->lock); |
737 | priv->data = *data; | ||
738 | priv->pdev = pdev; | 887 | priv->pdev = pdev; |
739 | priv->ndev = ndev; | 888 | priv->ndev = ndev; |
740 | priv->dev = &ndev->dev; | 889 | priv->dev = &ndev->dev; |
741 | priv->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG); | 890 | priv->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG); |
742 | priv->rx_packet_max = max(rx_packet_max, 128); | 891 | priv->rx_packet_max = max(rx_packet_max, 128); |
743 | 892 | ||
893 | if (cpsw_probe_dt(&priv->data, pdev)) { | ||
894 | pr_err("cpsw: platform data missing\n"); | ||
895 | ret = -ENODEV; | ||
896 | goto clean_ndev_ret; | ||
897 | } | ||
898 | data = &priv->data; | ||
899 | |||
744 | if (is_valid_ether_addr(data->slave_data[0].mac_addr)) { | 900 | if (is_valid_ether_addr(data->slave_data[0].mac_addr)) { |
745 | memcpy(priv->mac_addr, data->slave_data[0].mac_addr, ETH_ALEN); | 901 | memcpy(priv->mac_addr, data->slave_data[0].mac_addr, ETH_ALEN); |
746 | pr_info("Detected MACID = %pM", priv->mac_addr); | 902 | pr_info("Detected MACID = %pM", priv->mac_addr); |
@@ -996,11 +1152,17 @@ static const struct dev_pm_ops cpsw_pm_ops = { | |||
996 | .resume = cpsw_resume, | 1152 | .resume = cpsw_resume, |
997 | }; | 1153 | }; |
998 | 1154 | ||
1155 | static const struct of_device_id cpsw_of_mtable[] = { | ||
1156 | { .compatible = "ti,cpsw", }, | ||
1157 | { /* sentinel */ }, | ||
1158 | }; | ||
1159 | |||
999 | static struct platform_driver cpsw_driver = { | 1160 | static struct platform_driver cpsw_driver = { |
1000 | .driver = { | 1161 | .driver = { |
1001 | .name = "cpsw", | 1162 | .name = "cpsw", |
1002 | .owner = THIS_MODULE, | 1163 | .owner = THIS_MODULE, |
1003 | .pm = &cpsw_pm_ops, | 1164 | .pm = &cpsw_pm_ops, |
1165 | .of_match_table = of_match_ptr(cpsw_of_mtable), | ||
1004 | }, | 1166 | }, |
1005 | .probe = cpsw_probe, | 1167 | .probe = cpsw_probe, |
1006 | .remove = __devexit_p(cpsw_remove), | 1168 | .remove = __devexit_p(cpsw_remove), |
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 6cee2917eb02..4a1a5f58fa73 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c | |||
@@ -383,13 +383,6 @@ int netvsc_device_remove(struct hv_device *device) | |||
383 | unsigned long flags; | 383 | unsigned long flags; |
384 | 384 | ||
385 | net_device = hv_get_drvdata(device); | 385 | net_device = hv_get_drvdata(device); |
386 | spin_lock_irqsave(&device->channel->inbound_lock, flags); | ||
387 | net_device->destroy = true; | ||
388 | spin_unlock_irqrestore(&device->channel->inbound_lock, flags); | ||
389 | |||
390 | /* Wait for all send completions */ | ||
391 | wait_event(net_device->wait_drain, | ||
392 | atomic_read(&net_device->num_outstanding_sends) == 0); | ||
393 | 386 | ||
394 | netvsc_disconnect_vsp(net_device); | 387 | netvsc_disconnect_vsp(net_device); |
395 | 388 | ||
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index e5d6146937fa..1e88a1095934 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c | |||
@@ -718,6 +718,9 @@ static void rndis_filter_halt_device(struct rndis_device *dev) | |||
718 | { | 718 | { |
719 | struct rndis_request *request; | 719 | struct rndis_request *request; |
720 | struct rndis_halt_request *halt; | 720 | struct rndis_halt_request *halt; |
721 | struct netvsc_device *nvdev = dev->net_dev; | ||
722 | struct hv_device *hdev = nvdev->dev; | ||
723 | ulong flags; | ||
721 | 724 | ||
722 | /* Attempt to do a rndis device halt */ | 725 | /* Attempt to do a rndis device halt */ |
723 | request = get_rndis_request(dev, RNDIS_MSG_HALT, | 726 | request = get_rndis_request(dev, RNDIS_MSG_HALT, |
@@ -735,6 +738,14 @@ static void rndis_filter_halt_device(struct rndis_device *dev) | |||
735 | dev->state = RNDIS_DEV_UNINITIALIZED; | 738 | dev->state = RNDIS_DEV_UNINITIALIZED; |
736 | 739 | ||
737 | cleanup: | 740 | cleanup: |
741 | spin_lock_irqsave(&hdev->channel->inbound_lock, flags); | ||
742 | nvdev->destroy = true; | ||
743 | spin_unlock_irqrestore(&hdev->channel->inbound_lock, flags); | ||
744 | |||
745 | /* Wait for all send completions */ | ||
746 | wait_event(nvdev->wait_drain, | ||
747 | atomic_read(&nvdev->num_outstanding_sends) == 0); | ||
748 | |||
738 | if (request) | 749 | if (request) |
739 | put_rndis_request(dev, request); | 750 | put_rndis_request(dev, request); |
740 | return; | 751 | return; |
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index 5c0557222f20..eb3f5cefeba3 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c | |||
@@ -94,6 +94,18 @@ struct ppp_file { | |||
94 | #define PF_TO_CHANNEL(pf) PF_TO_X(pf, struct channel) | 94 | #define PF_TO_CHANNEL(pf) PF_TO_X(pf, struct channel) |
95 | 95 | ||
96 | /* | 96 | /* |
97 | * Data structure to hold primary network stats for which | ||
98 | * we want to use 64 bit storage. Other network stats | ||
99 | * are stored in dev->stats of the ppp strucute. | ||
100 | */ | ||
101 | struct ppp_link_stats { | ||
102 | u64 rx_packets; | ||
103 | u64 tx_packets; | ||
104 | u64 rx_bytes; | ||
105 | u64 tx_bytes; | ||
106 | }; | ||
107 | |||
108 | /* | ||
97 | * Data structure describing one ppp unit. | 109 | * Data structure describing one ppp unit. |
98 | * A ppp unit corresponds to a ppp network interface device | 110 | * A ppp unit corresponds to a ppp network interface device |
99 | * and represents a multilink bundle. | 111 | * and represents a multilink bundle. |
@@ -136,6 +148,7 @@ struct ppp { | |||
136 | unsigned pass_len, active_len; | 148 | unsigned pass_len, active_len; |
137 | #endif /* CONFIG_PPP_FILTER */ | 149 | #endif /* CONFIG_PPP_FILTER */ |
138 | struct net *ppp_net; /* the net we belong to */ | 150 | struct net *ppp_net; /* the net we belong to */ |
151 | struct ppp_link_stats stats64; /* 64 bit network stats */ | ||
139 | }; | 152 | }; |
140 | 153 | ||
141 | /* | 154 | /* |
@@ -1021,9 +1034,34 @@ ppp_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1021 | return err; | 1034 | return err; |
1022 | } | 1035 | } |
1023 | 1036 | ||
1037 | struct rtnl_link_stats64* | ||
1038 | ppp_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats64) | ||
1039 | { | ||
1040 | struct ppp *ppp = netdev_priv(dev); | ||
1041 | |||
1042 | ppp_recv_lock(ppp); | ||
1043 | stats64->rx_packets = ppp->stats64.rx_packets; | ||
1044 | stats64->rx_bytes = ppp->stats64.rx_bytes; | ||
1045 | ppp_recv_unlock(ppp); | ||
1046 | |||
1047 | ppp_xmit_lock(ppp); | ||
1048 | stats64->tx_packets = ppp->stats64.tx_packets; | ||
1049 | stats64->tx_bytes = ppp->stats64.tx_bytes; | ||
1050 | ppp_xmit_unlock(ppp); | ||
1051 | |||
1052 | stats64->rx_errors = dev->stats.rx_errors; | ||
1053 | stats64->tx_errors = dev->stats.tx_errors; | ||
1054 | stats64->rx_dropped = dev->stats.rx_dropped; | ||
1055 | stats64->tx_dropped = dev->stats.tx_dropped; | ||
1056 | stats64->rx_length_errors = dev->stats.rx_length_errors; | ||
1057 | |||
1058 | return stats64; | ||
1059 | } | ||
1060 | |||
1024 | static const struct net_device_ops ppp_netdev_ops = { | 1061 | static const struct net_device_ops ppp_netdev_ops = { |
1025 | .ndo_start_xmit = ppp_start_xmit, | 1062 | .ndo_start_xmit = ppp_start_xmit, |
1026 | .ndo_do_ioctl = ppp_net_ioctl, | 1063 | .ndo_do_ioctl = ppp_net_ioctl, |
1064 | .ndo_get_stats64 = ppp_get_stats64, | ||
1027 | }; | 1065 | }; |
1028 | 1066 | ||
1029 | static void ppp_setup(struct net_device *dev) | 1067 | static void ppp_setup(struct net_device *dev) |
@@ -1157,8 +1195,8 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) | |||
1157 | #endif /* CONFIG_PPP_FILTER */ | 1195 | #endif /* CONFIG_PPP_FILTER */ |
1158 | } | 1196 | } |
1159 | 1197 | ||
1160 | ++ppp->dev->stats.tx_packets; | 1198 | ++ppp->stats64.tx_packets; |
1161 | ppp->dev->stats.tx_bytes += skb->len - 2; | 1199 | ppp->stats64.tx_bytes += skb->len - 2; |
1162 | 1200 | ||
1163 | switch (proto) { | 1201 | switch (proto) { |
1164 | case PPP_IP: | 1202 | case PPP_IP: |
@@ -1745,8 +1783,8 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) | |||
1745 | break; | 1783 | break; |
1746 | } | 1784 | } |
1747 | 1785 | ||
1748 | ++ppp->dev->stats.rx_packets; | 1786 | ++ppp->stats64.rx_packets; |
1749 | ppp->dev->stats.rx_bytes += skb->len - 2; | 1787 | ppp->stats64.rx_bytes += skb->len - 2; |
1750 | 1788 | ||
1751 | npi = proto_to_npindex(proto); | 1789 | npi = proto_to_npindex(proto); |
1752 | if (npi < 0) { | 1790 | if (npi < 0) { |
@@ -2570,12 +2608,12 @@ ppp_get_stats(struct ppp *ppp, struct ppp_stats *st) | |||
2570 | struct slcompress *vj = ppp->vj; | 2608 | struct slcompress *vj = ppp->vj; |
2571 | 2609 | ||
2572 | memset(st, 0, sizeof(*st)); | 2610 | memset(st, 0, sizeof(*st)); |
2573 | st->p.ppp_ipackets = ppp->dev->stats.rx_packets; | 2611 | st->p.ppp_ipackets = ppp->stats64.rx_packets; |
2574 | st->p.ppp_ierrors = ppp->dev->stats.rx_errors; | 2612 | st->p.ppp_ierrors = ppp->dev->stats.rx_errors; |
2575 | st->p.ppp_ibytes = ppp->dev->stats.rx_bytes; | 2613 | st->p.ppp_ibytes = ppp->stats64.rx_bytes; |
2576 | st->p.ppp_opackets = ppp->dev->stats.tx_packets; | 2614 | st->p.ppp_opackets = ppp->stats64.tx_packets; |
2577 | st->p.ppp_oerrors = ppp->dev->stats.tx_errors; | 2615 | st->p.ppp_oerrors = ppp->dev->stats.tx_errors; |
2578 | st->p.ppp_obytes = ppp->dev->stats.tx_bytes; | 2616 | st->p.ppp_obytes = ppp->stats64.tx_bytes; |
2579 | if (!vj) | 2617 | if (!vj) |
2580 | return; | 2618 | return; |
2581 | st->vj.vjs_packets = vj->sls_o_compressed + vj->sls_o_uncompressed; | 2619 | st->vj.vjs_packets = vj->sls_o_compressed + vj->sls_o_uncompressed; |
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 87707ab39430..ba10c469b02b 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c | |||
@@ -658,6 +658,122 @@ static rx_handler_result_t team_handle_frame(struct sk_buff **pskb) | |||
658 | } | 658 | } |
659 | 659 | ||
660 | 660 | ||
661 | /************************************* | ||
662 | * Multiqueue Tx port select override | ||
663 | *************************************/ | ||
664 | |||
665 | static int team_queue_override_init(struct team *team) | ||
666 | { | ||
667 | struct list_head *listarr; | ||
668 | unsigned int queue_cnt = team->dev->num_tx_queues - 1; | ||
669 | unsigned int i; | ||
670 | |||
671 | if (!queue_cnt) | ||
672 | return 0; | ||
673 | listarr = kmalloc(sizeof(struct list_head) * queue_cnt, GFP_KERNEL); | ||
674 | if (!listarr) | ||
675 | return -ENOMEM; | ||
676 | team->qom_lists = listarr; | ||
677 | for (i = 0; i < queue_cnt; i++) | ||
678 | INIT_LIST_HEAD(listarr++); | ||
679 | return 0; | ||
680 | } | ||
681 | |||
682 | static void team_queue_override_fini(struct team *team) | ||
683 | { | ||
684 | kfree(team->qom_lists); | ||
685 | } | ||
686 | |||
687 | static struct list_head *__team_get_qom_list(struct team *team, u16 queue_id) | ||
688 | { | ||
689 | return &team->qom_lists[queue_id - 1]; | ||
690 | } | ||
691 | |||
692 | /* | ||
693 | * note: already called with rcu_read_lock | ||
694 | */ | ||
695 | static bool team_queue_override_transmit(struct team *team, struct sk_buff *skb) | ||
696 | { | ||
697 | struct list_head *qom_list; | ||
698 | struct team_port *port; | ||
699 | |||
700 | if (!team->queue_override_enabled || !skb->queue_mapping) | ||
701 | return false; | ||
702 | qom_list = __team_get_qom_list(team, skb->queue_mapping); | ||
703 | list_for_each_entry_rcu(port, qom_list, qom_list) { | ||
704 | if (!team_dev_queue_xmit(team, port, skb)) | ||
705 | return true; | ||
706 | } | ||
707 | return false; | ||
708 | } | ||
709 | |||
710 | static void __team_queue_override_port_del(struct team *team, | ||
711 | struct team_port *port) | ||
712 | { | ||
713 | list_del_rcu(&port->qom_list); | ||
714 | synchronize_rcu(); | ||
715 | INIT_LIST_HEAD(&port->qom_list); | ||
716 | } | ||
717 | |||
718 | static bool team_queue_override_port_has_gt_prio_than(struct team_port *port, | ||
719 | struct team_port *cur) | ||
720 | { | ||
721 | if (port->priority < cur->priority) | ||
722 | return true; | ||
723 | if (port->priority > cur->priority) | ||
724 | return false; | ||
725 | if (port->index < cur->index) | ||
726 | return true; | ||
727 | return false; | ||
728 | } | ||
729 | |||
730 | static void __team_queue_override_port_add(struct team *team, | ||
731 | struct team_port *port) | ||
732 | { | ||
733 | struct team_port *cur; | ||
734 | struct list_head *qom_list; | ||
735 | struct list_head *node; | ||
736 | |||
737 | if (!port->queue_id || !team_port_enabled(port)) | ||
738 | return; | ||
739 | |||
740 | qom_list = __team_get_qom_list(team, port->queue_id); | ||
741 | node = qom_list; | ||
742 | list_for_each_entry(cur, qom_list, qom_list) { | ||
743 | if (team_queue_override_port_has_gt_prio_than(port, cur)) | ||
744 | break; | ||
745 | node = &cur->qom_list; | ||
746 | } | ||
747 | list_add_tail_rcu(&port->qom_list, node); | ||
748 | } | ||
749 | |||
750 | static void __team_queue_override_enabled_check(struct team *team) | ||
751 | { | ||
752 | struct team_port *port; | ||
753 | bool enabled = false; | ||
754 | |||
755 | list_for_each_entry(port, &team->port_list, list) { | ||
756 | if (!list_empty(&port->qom_list)) { | ||
757 | enabled = true; | ||
758 | break; | ||
759 | } | ||
760 | } | ||
761 | if (enabled == team->queue_override_enabled) | ||
762 | return; | ||
763 | netdev_dbg(team->dev, "%s queue override\n", | ||
764 | enabled ? "Enabling" : "Disabling"); | ||
765 | team->queue_override_enabled = enabled; | ||
766 | } | ||
767 | |||
768 | static void team_queue_override_port_refresh(struct team *team, | ||
769 | struct team_port *port) | ||
770 | { | ||
771 | __team_queue_override_port_del(team, port); | ||
772 | __team_queue_override_port_add(team, port); | ||
773 | __team_queue_override_enabled_check(team); | ||
774 | } | ||
775 | |||
776 | |||
661 | /**************** | 777 | /**************** |
662 | * Port handling | 778 | * Port handling |
663 | ****************/ | 779 | ****************/ |
@@ -688,6 +804,7 @@ static void team_port_enable(struct team *team, | |||
688 | hlist_add_head_rcu(&port->hlist, | 804 | hlist_add_head_rcu(&port->hlist, |
689 | team_port_index_hash(team, port->index)); | 805 | team_port_index_hash(team, port->index)); |
690 | team_adjust_ops(team); | 806 | team_adjust_ops(team); |
807 | team_queue_override_port_refresh(team, port); | ||
691 | if (team->ops.port_enabled) | 808 | if (team->ops.port_enabled) |
692 | team->ops.port_enabled(team, port); | 809 | team->ops.port_enabled(team, port); |
693 | } | 810 | } |
@@ -716,6 +833,7 @@ static void team_port_disable(struct team *team, | |||
716 | hlist_del_rcu(&port->hlist); | 833 | hlist_del_rcu(&port->hlist); |
717 | __reconstruct_port_hlist(team, port->index); | 834 | __reconstruct_port_hlist(team, port->index); |
718 | port->index = -1; | 835 | port->index = -1; |
836 | team_queue_override_port_refresh(team, port); | ||
719 | __team_adjust_ops(team, team->en_port_count - 1); | 837 | __team_adjust_ops(team, team->en_port_count - 1); |
720 | /* | 838 | /* |
721 | * Wait until readers see adjusted ops. This ensures that | 839 | * Wait until readers see adjusted ops. This ensures that |
@@ -881,6 +999,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev) | |||
881 | 999 | ||
882 | port->dev = port_dev; | 1000 | port->dev = port_dev; |
883 | port->team = team; | 1001 | port->team = team; |
1002 | INIT_LIST_HEAD(&port->qom_list); | ||
884 | 1003 | ||
885 | port->orig.mtu = port_dev->mtu; | 1004 | port->orig.mtu = port_dev->mtu; |
886 | err = dev_set_mtu(port_dev, dev->mtu); | 1005 | err = dev_set_mtu(port_dev, dev->mtu); |
@@ -1092,6 +1211,49 @@ static int team_user_linkup_en_option_set(struct team *team, | |||
1092 | return 0; | 1211 | return 0; |
1093 | } | 1212 | } |
1094 | 1213 | ||
1214 | static int team_priority_option_get(struct team *team, | ||
1215 | struct team_gsetter_ctx *ctx) | ||
1216 | { | ||
1217 | struct team_port *port = ctx->info->port; | ||
1218 | |||
1219 | ctx->data.s32_val = port->priority; | ||
1220 | return 0; | ||
1221 | } | ||
1222 | |||
1223 | static int team_priority_option_set(struct team *team, | ||
1224 | struct team_gsetter_ctx *ctx) | ||
1225 | { | ||
1226 | struct team_port *port = ctx->info->port; | ||
1227 | |||
1228 | port->priority = ctx->data.s32_val; | ||
1229 | team_queue_override_port_refresh(team, port); | ||
1230 | return 0; | ||
1231 | } | ||
1232 | |||
1233 | static int team_queue_id_option_get(struct team *team, | ||
1234 | struct team_gsetter_ctx *ctx) | ||
1235 | { | ||
1236 | struct team_port *port = ctx->info->port; | ||
1237 | |||
1238 | ctx->data.u32_val = port->queue_id; | ||
1239 | return 0; | ||
1240 | } | ||
1241 | |||
1242 | static int team_queue_id_option_set(struct team *team, | ||
1243 | struct team_gsetter_ctx *ctx) | ||
1244 | { | ||
1245 | struct team_port *port = ctx->info->port; | ||
1246 | |||
1247 | if (port->queue_id == ctx->data.u32_val) | ||
1248 | return 0; | ||
1249 | if (ctx->data.u32_val >= team->dev->real_num_tx_queues) | ||
1250 | return -EINVAL; | ||
1251 | port->queue_id = ctx->data.u32_val; | ||
1252 | team_queue_override_port_refresh(team, port); | ||
1253 | return 0; | ||
1254 | } | ||
1255 | |||
1256 | |||
1095 | static const struct team_option team_options[] = { | 1257 | static const struct team_option team_options[] = { |
1096 | { | 1258 | { |
1097 | .name = "mode", | 1259 | .name = "mode", |
@@ -1120,6 +1282,20 @@ static const struct team_option team_options[] = { | |||
1120 | .getter = team_user_linkup_en_option_get, | 1282 | .getter = team_user_linkup_en_option_get, |
1121 | .setter = team_user_linkup_en_option_set, | 1283 | .setter = team_user_linkup_en_option_set, |
1122 | }, | 1284 | }, |
1285 | { | ||
1286 | .name = "priority", | ||
1287 | .type = TEAM_OPTION_TYPE_S32, | ||
1288 | .per_port = true, | ||
1289 | .getter = team_priority_option_get, | ||
1290 | .setter = team_priority_option_set, | ||
1291 | }, | ||
1292 | { | ||
1293 | .name = "queue_id", | ||
1294 | .type = TEAM_OPTION_TYPE_U32, | ||
1295 | .per_port = true, | ||
1296 | .getter = team_queue_id_option_get, | ||
1297 | .setter = team_queue_id_option_set, | ||
1298 | }, | ||
1123 | }; | 1299 | }; |
1124 | 1300 | ||
1125 | static struct lock_class_key team_netdev_xmit_lock_key; | 1301 | static struct lock_class_key team_netdev_xmit_lock_key; |
@@ -1155,6 +1331,9 @@ static int team_init(struct net_device *dev) | |||
1155 | for (i = 0; i < TEAM_PORT_HASHENTRIES; i++) | 1331 | for (i = 0; i < TEAM_PORT_HASHENTRIES; i++) |
1156 | INIT_HLIST_HEAD(&team->en_port_hlist[i]); | 1332 | INIT_HLIST_HEAD(&team->en_port_hlist[i]); |
1157 | INIT_LIST_HEAD(&team->port_list); | 1333 | INIT_LIST_HEAD(&team->port_list); |
1334 | err = team_queue_override_init(team); | ||
1335 | if (err) | ||
1336 | goto err_team_queue_override_init; | ||
1158 | 1337 | ||
1159 | team_adjust_ops(team); | 1338 | team_adjust_ops(team); |
1160 | 1339 | ||
@@ -1170,6 +1349,8 @@ static int team_init(struct net_device *dev) | |||
1170 | return 0; | 1349 | return 0; |
1171 | 1350 | ||
1172 | err_options_register: | 1351 | err_options_register: |
1352 | team_queue_override_fini(team); | ||
1353 | err_team_queue_override_init: | ||
1173 | free_percpu(team->pcpu_stats); | 1354 | free_percpu(team->pcpu_stats); |
1174 | 1355 | ||
1175 | return err; | 1356 | return err; |
@@ -1187,6 +1368,7 @@ static void team_uninit(struct net_device *dev) | |||
1187 | 1368 | ||
1188 | __team_change_mode(team, NULL); /* cleanup */ | 1369 | __team_change_mode(team, NULL); /* cleanup */ |
1189 | __team_options_unregister(team, team_options, ARRAY_SIZE(team_options)); | 1370 | __team_options_unregister(team, team_options, ARRAY_SIZE(team_options)); |
1371 | team_queue_override_fini(team); | ||
1190 | mutex_unlock(&team->lock); | 1372 | mutex_unlock(&team->lock); |
1191 | } | 1373 | } |
1192 | 1374 | ||
@@ -1216,10 +1398,12 @@ static int team_close(struct net_device *dev) | |||
1216 | static netdev_tx_t team_xmit(struct sk_buff *skb, struct net_device *dev) | 1398 | static netdev_tx_t team_xmit(struct sk_buff *skb, struct net_device *dev) |
1217 | { | 1399 | { |
1218 | struct team *team = netdev_priv(dev); | 1400 | struct team *team = netdev_priv(dev); |
1219 | bool tx_success = false; | 1401 | bool tx_success; |
1220 | unsigned int len = skb->len; | 1402 | unsigned int len = skb->len; |
1221 | 1403 | ||
1222 | tx_success = team->ops.transmit(team, skb); | 1404 | tx_success = team_queue_override_transmit(team, skb); |
1405 | if (!tx_success) | ||
1406 | tx_success = team->ops.transmit(team, skb); | ||
1223 | if (tx_success) { | 1407 | if (tx_success) { |
1224 | struct team_pcpu_stats *pcpu_stats; | 1408 | struct team_pcpu_stats *pcpu_stats; |
1225 | 1409 | ||
@@ -1787,6 +1971,12 @@ static int team_nl_fill_one_option_get(struct sk_buff *skb, struct team *team, | |||
1787 | nla_put_flag(skb, TEAM_ATTR_OPTION_DATA)) | 1971 | nla_put_flag(skb, TEAM_ATTR_OPTION_DATA)) |
1788 | goto nest_cancel; | 1972 | goto nest_cancel; |
1789 | break; | 1973 | break; |
1974 | case TEAM_OPTION_TYPE_S32: | ||
1975 | if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_S32)) | ||
1976 | goto nest_cancel; | ||
1977 | if (nla_put_s32(skb, TEAM_ATTR_OPTION_DATA, ctx.data.s32_val)) | ||
1978 | goto nest_cancel; | ||
1979 | break; | ||
1790 | default: | 1980 | default: |
1791 | BUG(); | 1981 | BUG(); |
1792 | } | 1982 | } |
@@ -1975,6 +2165,9 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info) | |||
1975 | case NLA_FLAG: | 2165 | case NLA_FLAG: |
1976 | opt_type = TEAM_OPTION_TYPE_BOOL; | 2166 | opt_type = TEAM_OPTION_TYPE_BOOL; |
1977 | break; | 2167 | break; |
2168 | case NLA_S32: | ||
2169 | opt_type = TEAM_OPTION_TYPE_S32; | ||
2170 | break; | ||
1978 | default: | 2171 | default: |
1979 | goto team_put; | 2172 | goto team_put; |
1980 | } | 2173 | } |
@@ -2031,6 +2224,9 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info) | |||
2031 | case TEAM_OPTION_TYPE_BOOL: | 2224 | case TEAM_OPTION_TYPE_BOOL: |
2032 | ctx.data.bool_val = attr_data ? true : false; | 2225 | ctx.data.bool_val = attr_data ? true : false; |
2033 | break; | 2226 | break; |
2227 | case TEAM_OPTION_TYPE_S32: | ||
2228 | ctx.data.s32_val = nla_get_s32(attr_data); | ||
2229 | break; | ||
2034 | default: | 2230 | default: |
2035 | BUG(); | 2231 | BUG(); |
2036 | } | 2232 | } |
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index f4ce5957df32..4cd582a4f625 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c | |||
@@ -1225,6 +1225,26 @@ static const struct usb_device_id cdc_devs[] = { | |||
1225 | .driver_info = (unsigned long) &wwan_info, | 1225 | .driver_info = (unsigned long) &wwan_info, |
1226 | }, | 1226 | }, |
1227 | 1227 | ||
1228 | /* Dell branded MBM devices like DW5550 */ | ||
1229 | { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | ||
1230 | | USB_DEVICE_ID_MATCH_VENDOR, | ||
1231 | .idVendor = 0x413c, | ||
1232 | .bInterfaceClass = USB_CLASS_COMM, | ||
1233 | .bInterfaceSubClass = USB_CDC_SUBCLASS_NCM, | ||
1234 | .bInterfaceProtocol = USB_CDC_PROTO_NONE, | ||
1235 | .driver_info = (unsigned long) &wwan_info, | ||
1236 | }, | ||
1237 | |||
1238 | /* Toshiba branded MBM devices */ | ||
1239 | { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | ||
1240 | | USB_DEVICE_ID_MATCH_VENDOR, | ||
1241 | .idVendor = 0x0930, | ||
1242 | .bInterfaceClass = USB_CLASS_COMM, | ||
1243 | .bInterfaceSubClass = USB_CDC_SUBCLASS_NCM, | ||
1244 | .bInterfaceProtocol = USB_CDC_PROTO_NONE, | ||
1245 | .driver_info = (unsigned long) &wwan_info, | ||
1246 | }, | ||
1247 | |||
1228 | /* Generic CDC-NCM devices */ | 1248 | /* Generic CDC-NCM devices */ |
1229 | { USB_INTERFACE_INFO(USB_CLASS_COMM, | 1249 | { USB_INTERFACE_INFO(USB_CLASS_COMM, |
1230 | USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE), | 1250 | USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE), |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index cfa91ab7acf8..60b6a9daff7e 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -730,6 +730,7 @@ int ath9k_hw_init(struct ath_hw *ah) | |||
730 | case AR9300_DEVID_QCA955X: | 730 | case AR9300_DEVID_QCA955X: |
731 | case AR9300_DEVID_AR9580: | 731 | case AR9300_DEVID_AR9580: |
732 | case AR9300_DEVID_AR9462: | 732 | case AR9300_DEVID_AR9462: |
733 | case AR9485_DEVID_AR1111: | ||
733 | break; | 734 | break; |
734 | default: | 735 | default: |
735 | if (common->bus_ops->ath_bus_type == ATH_USB) | 736 | if (common->bus_ops->ath_bus_type == ATH_USB) |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index dd0c146d81dc..ce7332c64efb 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -49,6 +49,7 @@ | |||
49 | #define AR9300_DEVID_AR9462 0x0034 | 49 | #define AR9300_DEVID_AR9462 0x0034 |
50 | #define AR9300_DEVID_AR9330 0x0035 | 50 | #define AR9300_DEVID_AR9330 0x0035 |
51 | #define AR9300_DEVID_QCA955X 0x0038 | 51 | #define AR9300_DEVID_QCA955X 0x0038 |
52 | #define AR9485_DEVID_AR1111 0x0037 | ||
52 | 53 | ||
53 | #define AR5416_AR9100_DEVID 0x000b | 54 | #define AR5416_AR9100_DEVID 0x000b |
54 | 55 | ||
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 87b89d55e637..d455de9162ec 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
@@ -37,6 +37,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = { | |||
37 | { PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E AR9485 */ | 37 | { PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E AR9485 */ |
38 | { PCI_VDEVICE(ATHEROS, 0x0033) }, /* PCI-E AR9580 */ | 38 | { PCI_VDEVICE(ATHEROS, 0x0033) }, /* PCI-E AR9580 */ |
39 | { PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9462 */ | 39 | { PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9462 */ |
40 | { PCI_VDEVICE(ATHEROS, 0x0037) }, /* PCI-E AR1111/AR9485 */ | ||
40 | { 0 } | 41 | { 0 } |
41 | }; | 42 | }; |
42 | 43 | ||
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index b80352b308d5..a140165dfee0 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -2719,32 +2719,37 @@ static int b43_gpio_init(struct b43_wldev *dev) | |||
2719 | if (dev->dev->chip_id == 0x4301) { | 2719 | if (dev->dev->chip_id == 0x4301) { |
2720 | mask |= 0x0060; | 2720 | mask |= 0x0060; |
2721 | set |= 0x0060; | 2721 | set |= 0x0060; |
2722 | } else if (dev->dev->chip_id == 0x5354) { | ||
2723 | /* Don't allow overtaking buttons GPIOs */ | ||
2724 | set &= 0x2; /* 0x2 is LED GPIO on BCM5354 */ | ||
2722 | } | 2725 | } |
2723 | if (dev->dev->chip_id == 0x5354) | 2726 | |
2724 | set &= 0xff02; | ||
2725 | if (0 /* FIXME: conditional unknown */ ) { | 2727 | if (0 /* FIXME: conditional unknown */ ) { |
2726 | b43_write16(dev, B43_MMIO_GPIO_MASK, | 2728 | b43_write16(dev, B43_MMIO_GPIO_MASK, |
2727 | b43_read16(dev, B43_MMIO_GPIO_MASK) | 2729 | b43_read16(dev, B43_MMIO_GPIO_MASK) |
2728 | | 0x0100); | 2730 | | 0x0100); |
2729 | mask |= 0x0180; | 2731 | /* BT Coexistance Input */ |
2730 | set |= 0x0180; | 2732 | mask |= 0x0080; |
2733 | set |= 0x0080; | ||
2734 | /* BT Coexistance Out */ | ||
2735 | mask |= 0x0100; | ||
2736 | set |= 0x0100; | ||
2731 | } | 2737 | } |
2732 | if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL) { | 2738 | if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL) { |
2739 | /* PA is controlled by gpio 9, let ucode handle it */ | ||
2733 | b43_write16(dev, B43_MMIO_GPIO_MASK, | 2740 | b43_write16(dev, B43_MMIO_GPIO_MASK, |
2734 | b43_read16(dev, B43_MMIO_GPIO_MASK) | 2741 | b43_read16(dev, B43_MMIO_GPIO_MASK) |
2735 | | 0x0200); | 2742 | | 0x0200); |
2736 | mask |= 0x0200; | 2743 | mask |= 0x0200; |
2737 | set |= 0x0200; | 2744 | set |= 0x0200; |
2738 | } | 2745 | } |
2739 | if (dev->dev->core_rev >= 2) | ||
2740 | mask |= 0x0010; /* FIXME: This is redundant. */ | ||
2741 | 2746 | ||
2742 | switch (dev->dev->bus_type) { | 2747 | switch (dev->dev->bus_type) { |
2743 | #ifdef CONFIG_B43_BCMA | 2748 | #ifdef CONFIG_B43_BCMA |
2744 | case B43_BUS_BCMA: | 2749 | case B43_BUS_BCMA: |
2745 | bcma_cc_write32(&dev->dev->bdev->bus->drv_cc, BCMA_CC_GPIOCTL, | 2750 | bcma_cc_write32(&dev->dev->bdev->bus->drv_cc, BCMA_CC_GPIOCTL, |
2746 | (bcma_cc_read32(&dev->dev->bdev->bus->drv_cc, | 2751 | (bcma_cc_read32(&dev->dev->bdev->bus->drv_cc, |
2747 | BCMA_CC_GPIOCTL) & mask) | set); | 2752 | BCMA_CC_GPIOCTL) & ~mask) | set); |
2748 | break; | 2753 | break; |
2749 | #endif | 2754 | #endif |
2750 | #ifdef CONFIG_B43_SSB | 2755 | #ifdef CONFIG_B43_SSB |
@@ -2753,7 +2758,7 @@ static int b43_gpio_init(struct b43_wldev *dev) | |||
2753 | if (gpiodev) | 2758 | if (gpiodev) |
2754 | ssb_write32(gpiodev, B43_GPIO_CONTROL, | 2759 | ssb_write32(gpiodev, B43_GPIO_CONTROL, |
2755 | (ssb_read32(gpiodev, B43_GPIO_CONTROL) | 2760 | (ssb_read32(gpiodev, B43_GPIO_CONTROL) |
2756 | & mask) | set); | 2761 | & ~mask) | set); |
2757 | break; | 2762 | break; |
2758 | #endif | 2763 | #endif |
2759 | } | 2764 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c index 9a4c63f927cb..7ed7d7577024 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c | |||
@@ -382,9 +382,7 @@ brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec, | |||
382 | { | 382 | { |
383 | struct brcms_c_info *wlc = wlc_cm->wlc; | 383 | struct brcms_c_info *wlc = wlc_cm->wlc; |
384 | struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; | 384 | struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; |
385 | const struct ieee80211_reg_rule *reg_rule; | ||
386 | struct txpwr_limits txpwr; | 385 | struct txpwr_limits txpwr; |
387 | int ret; | ||
388 | 386 | ||
389 | brcms_c_channel_reg_limits(wlc_cm, chanspec, &txpwr); | 387 | brcms_c_channel_reg_limits(wlc_cm, chanspec, &txpwr); |
390 | 388 | ||
@@ -393,8 +391,7 @@ brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec, | |||
393 | ); | 391 | ); |
394 | 392 | ||
395 | /* set or restore gmode as required by regulatory */ | 393 | /* set or restore gmode as required by regulatory */ |
396 | ret = freq_reg_info(wlc->wiphy, ch->center_freq, 0, ®_rule); | 394 | if (ch->flags & IEEE80211_CHAN_NO_OFDM) |
397 | if (!ret && (reg_rule->flags & NL80211_RRF_NO_OFDM)) | ||
398 | brcms_c_set_gmode(wlc, GMODE_LEGACY_B, false); | 395 | brcms_c_set_gmode(wlc, GMODE_LEGACY_B, false); |
399 | else | 396 | else |
400 | brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false); | 397 | brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false); |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 9e79d47e077f..192ad5c1fcc8 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | |||
@@ -121,7 +121,8 @@ static struct ieee80211_channel brcms_2ghz_chantable[] = { | |||
121 | IEEE80211_CHAN_NO_HT40PLUS), | 121 | IEEE80211_CHAN_NO_HT40PLUS), |
122 | CHAN2GHZ(14, 2484, | 122 | CHAN2GHZ(14, 2484, |
123 | IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | | 123 | IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | |
124 | IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS) | 124 | IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS | |
125 | IEEE80211_CHAN_NO_OFDM) | ||
125 | }; | 126 | }; |
126 | 127 | ||
127 | static struct ieee80211_channel brcms_5ghz_nphy_chantable[] = { | 128 | static struct ieee80211_channel brcms_5ghz_nphy_chantable[] = { |
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index eb5de800ed90..1c10b542ab23 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
@@ -1254,6 +1254,7 @@ static int lbs_associate(struct lbs_private *priv, | |||
1254 | netif_tx_wake_all_queues(priv->dev); | 1254 | netif_tx_wake_all_queues(priv->dev); |
1255 | } | 1255 | } |
1256 | 1256 | ||
1257 | kfree(cmd); | ||
1257 | done: | 1258 | done: |
1258 | lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); | 1259 | lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); |
1259 | return ret; | 1260 | return ret; |
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 76caebaa4397..e970897f6ab5 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c | |||
@@ -1314,6 +1314,7 @@ static void if_sdio_remove(struct sdio_func *func) | |||
1314 | kfree(packet); | 1314 | kfree(packet); |
1315 | } | 1315 | } |
1316 | 1316 | ||
1317 | kfree(card); | ||
1317 | lbs_deb_leave(LBS_DEB_SDIO); | 1318 | lbs_deb_leave(LBS_DEB_SDIO); |
1318 | } | 1319 | } |
1319 | 1320 | ||
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 58048189bd24..fe1ea43c5149 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c | |||
@@ -571,7 +571,10 @@ static int lbs_thread(void *data) | |||
571 | netdev_info(dev, "Timeout submitting command 0x%04x\n", | 571 | netdev_info(dev, "Timeout submitting command 0x%04x\n", |
572 | le16_to_cpu(cmdnode->cmdbuf->command)); | 572 | le16_to_cpu(cmdnode->cmdbuf->command)); |
573 | lbs_complete_command(priv, cmdnode, -ETIMEDOUT); | 573 | lbs_complete_command(priv, cmdnode, -ETIMEDOUT); |
574 | if (priv->reset_card) | 574 | |
575 | /* Reset card, but only when it isn't in the process | ||
576 | * of being shutdown anyway. */ | ||
577 | if (!dev->dismantle && priv->reset_card) | ||
575 | priv->reset_card(priv); | 578 | priv->reset_card(priv); |
576 | } | 579 | } |
577 | priv->cmd_timed_out = 0; | 580 | priv->cmd_timed_out = 0; |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 88455b1b9fe0..cb8c2aca54e4 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -221,6 +221,67 @@ static void rt2800_rf_write(struct rt2x00_dev *rt2x00dev, | |||
221 | mutex_unlock(&rt2x00dev->csr_mutex); | 221 | mutex_unlock(&rt2x00dev->csr_mutex); |
222 | } | 222 | } |
223 | 223 | ||
224 | static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev) | ||
225 | { | ||
226 | u32 reg; | ||
227 | int i, count; | ||
228 | |||
229 | rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®); | ||
230 | if (rt2x00_get_field32(reg, WLAN_EN)) | ||
231 | return 0; | ||
232 | |||
233 | rt2x00_set_field32(®, WLAN_GPIO_OUT_OE_BIT_ALL, 0xff); | ||
234 | rt2x00_set_field32(®, FRC_WL_ANT_SET, 1); | ||
235 | rt2x00_set_field32(®, WLAN_CLK_EN, 0); | ||
236 | rt2x00_set_field32(®, WLAN_EN, 1); | ||
237 | rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg); | ||
238 | |||
239 | udelay(REGISTER_BUSY_DELAY); | ||
240 | |||
241 | count = 0; | ||
242 | do { | ||
243 | /* | ||
244 | * Check PLL_LD & XTAL_RDY. | ||
245 | */ | ||
246 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
247 | rt2800_register_read(rt2x00dev, CMB_CTRL, ®); | ||
248 | if (rt2x00_get_field32(reg, PLL_LD) && | ||
249 | rt2x00_get_field32(reg, XTAL_RDY)) | ||
250 | break; | ||
251 | udelay(REGISTER_BUSY_DELAY); | ||
252 | } | ||
253 | |||
254 | if (i >= REGISTER_BUSY_COUNT) { | ||
255 | |||
256 | if (count >= 10) | ||
257 | return -EIO; | ||
258 | |||
259 | rt2800_register_write(rt2x00dev, 0x58, 0x018); | ||
260 | udelay(REGISTER_BUSY_DELAY); | ||
261 | rt2800_register_write(rt2x00dev, 0x58, 0x418); | ||
262 | udelay(REGISTER_BUSY_DELAY); | ||
263 | rt2800_register_write(rt2x00dev, 0x58, 0x618); | ||
264 | udelay(REGISTER_BUSY_DELAY); | ||
265 | count++; | ||
266 | } else { | ||
267 | count = 0; | ||
268 | } | ||
269 | |||
270 | rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®); | ||
271 | rt2x00_set_field32(®, PCIE_APP0_CLK_REQ, 0); | ||
272 | rt2x00_set_field32(®, WLAN_CLK_EN, 1); | ||
273 | rt2x00_set_field32(®, WLAN_RESET, 1); | ||
274 | rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg); | ||
275 | udelay(10); | ||
276 | rt2x00_set_field32(®, WLAN_RESET, 0); | ||
277 | rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg); | ||
278 | udelay(10); | ||
279 | rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, 0x7fffffff); | ||
280 | } while (count != 0); | ||
281 | |||
282 | return 0; | ||
283 | } | ||
284 | |||
224 | void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, | 285 | void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, |
225 | const u8 command, const u8 token, | 286 | const u8 command, const u8 token, |
226 | const u8 arg0, const u8 arg1) | 287 | const u8 arg0, const u8 arg1) |
@@ -400,6 +461,13 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
400 | { | 461 | { |
401 | unsigned int i; | 462 | unsigned int i; |
402 | u32 reg; | 463 | u32 reg; |
464 | int retval; | ||
465 | |||
466 | if (rt2x00_rt(rt2x00dev, RT3290)) { | ||
467 | retval = rt2800_enable_wlan_rt3290(rt2x00dev); | ||
468 | if (retval) | ||
469 | return -EBUSY; | ||
470 | } | ||
403 | 471 | ||
404 | /* | 472 | /* |
405 | * If driver doesn't wake up firmware here, | 473 | * If driver doesn't wake up firmware here, |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 235376e9cb04..98aa426a3564 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -980,66 +980,6 @@ static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
980 | return rt2800_validate_eeprom(rt2x00dev); | 980 | return rt2800_validate_eeprom(rt2x00dev); |
981 | } | 981 | } |
982 | 982 | ||
983 | static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev) | ||
984 | { | ||
985 | u32 reg; | ||
986 | int i, count; | ||
987 | |||
988 | rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®); | ||
989 | if (rt2x00_get_field32(reg, WLAN_EN)) | ||
990 | return 0; | ||
991 | |||
992 | rt2x00_set_field32(®, WLAN_GPIO_OUT_OE_BIT_ALL, 0xff); | ||
993 | rt2x00_set_field32(®, FRC_WL_ANT_SET, 1); | ||
994 | rt2x00_set_field32(®, WLAN_CLK_EN, 0); | ||
995 | rt2x00_set_field32(®, WLAN_EN, 1); | ||
996 | rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg); | ||
997 | |||
998 | udelay(REGISTER_BUSY_DELAY); | ||
999 | |||
1000 | count = 0; | ||
1001 | do { | ||
1002 | /* | ||
1003 | * Check PLL_LD & XTAL_RDY. | ||
1004 | */ | ||
1005 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
1006 | rt2800_register_read(rt2x00dev, CMB_CTRL, ®); | ||
1007 | if (rt2x00_get_field32(reg, PLL_LD) && | ||
1008 | rt2x00_get_field32(reg, XTAL_RDY)) | ||
1009 | break; | ||
1010 | udelay(REGISTER_BUSY_DELAY); | ||
1011 | } | ||
1012 | |||
1013 | if (i >= REGISTER_BUSY_COUNT) { | ||
1014 | |||
1015 | if (count >= 10) | ||
1016 | return -EIO; | ||
1017 | |||
1018 | rt2800_register_write(rt2x00dev, 0x58, 0x018); | ||
1019 | udelay(REGISTER_BUSY_DELAY); | ||
1020 | rt2800_register_write(rt2x00dev, 0x58, 0x418); | ||
1021 | udelay(REGISTER_BUSY_DELAY); | ||
1022 | rt2800_register_write(rt2x00dev, 0x58, 0x618); | ||
1023 | udelay(REGISTER_BUSY_DELAY); | ||
1024 | count++; | ||
1025 | } else { | ||
1026 | count = 0; | ||
1027 | } | ||
1028 | |||
1029 | rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®); | ||
1030 | rt2x00_set_field32(®, PCIE_APP0_CLK_REQ, 0); | ||
1031 | rt2x00_set_field32(®, WLAN_CLK_EN, 1); | ||
1032 | rt2x00_set_field32(®, WLAN_RESET, 1); | ||
1033 | rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg); | ||
1034 | udelay(10); | ||
1035 | rt2x00_set_field32(®, WLAN_RESET, 0); | ||
1036 | rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg); | ||
1037 | udelay(10); | ||
1038 | rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, 0x7fffffff); | ||
1039 | } while (count != 0); | ||
1040 | |||
1041 | return 0; | ||
1042 | } | ||
1043 | static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) | 983 | static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) |
1044 | { | 984 | { |
1045 | int retval; | 985 | int retval; |
@@ -1063,17 +1003,6 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1063 | return retval; | 1003 | return retval; |
1064 | 1004 | ||
1065 | /* | 1005 | /* |
1066 | * In probe phase call rt2800_enable_wlan_rt3290 to enable wlan | ||
1067 | * clk for rt3290. That avoid the MCU fail in start phase. | ||
1068 | */ | ||
1069 | if (rt2x00_rt(rt2x00dev, RT3290)) { | ||
1070 | retval = rt2800_enable_wlan_rt3290(rt2x00dev); | ||
1071 | |||
1072 | if (retval) | ||
1073 | return retval; | ||
1074 | } | ||
1075 | |||
1076 | /* | ||
1077 | * This device has multiple filters for control frames | 1006 | * This device has multiple filters for control frames |
1078 | * and has a separate filter for PS Poll frames. | 1007 | * and has a separate filter for PS Poll frames. |
1079 | */ | 1008 | */ |