diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-18 17:07:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-18 17:07:15 -0400 |
commit | d2aa4550379f92e929af7ed1dd4f55e6a1e331f8 (patch) | |
tree | 5ef0fc69a507f0d701fd157b6652427eabd5efdd | |
parent | 9e3e4b1d2d13bead8d52703c82a02b55f108b491 (diff) | |
parent | cb2107be43d2fc5eadec58b92b54bf32c00bfff3 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (55 commits)
netxen: fix tx ring accounting
netxen: fix detection of cut-thru firmware mode
forcedeth: fix dma api mismatches
atm: sk_wmem_alloc initial value is one
net: correct off-by-one write allocations reports
via-velocity : fix no link detection on boot
Net / e100: Fix suspend of devices that cannot be power managed
TI DaVinci EMAC : Fix rmmod error
net: group address list and its count
ipv4: Fix fib_trie rebalancing, part 2
pkt_sched: Update drops stats in act_police
sky2: version 1.23
sky2: add GRO support
sky2: skb recycling
sky2: reduce default transmit ring
sky2: receive counter update
sky2: fix shutdown synchronization
sky2: PCI irq issues
sky2: more receive shutdown
sky2: turn off pause during shutdown
...
Manually fix trivial conflict in net/core/skbuff.c due to kmemcheck
89 files changed, 833 insertions, 713 deletions
diff --git a/Documentation/rfkill.txt b/Documentation/rfkill.txt index 1b74b5f30af4..c8acd8659e91 100644 --- a/Documentation/rfkill.txt +++ b/Documentation/rfkill.txt | |||
@@ -3,9 +3,8 @@ rfkill - RF kill switch support | |||
3 | 3 | ||
4 | 1. Introduction | 4 | 1. Introduction |
5 | 2. Implementation details | 5 | 2. Implementation details |
6 | 3. Kernel driver guidelines | 6 | 3. Kernel API |
7 | 4. Kernel API | 7 | 4. Userspace support |
8 | 5. Userspace support | ||
9 | 8 | ||
10 | 9 | ||
11 | 1. Introduction | 10 | 1. Introduction |
@@ -19,82 +18,62 @@ disable all transmitters of a certain type (or all). This is intended for | |||
19 | situations where transmitters need to be turned off, for example on | 18 | situations where transmitters need to be turned off, for example on |
20 | aircraft. | 19 | aircraft. |
21 | 20 | ||
21 | The rfkill subsystem has a concept of "hard" and "soft" block, which | ||
22 | differ little in their meaning (block == transmitters off) but rather in | ||
23 | whether they can be changed or not: | ||
24 | - hard block: read-only radio block that cannot be overriden by software | ||
25 | - soft block: writable radio block (need not be readable) that is set by | ||
26 | the system software. | ||
22 | 27 | ||
23 | 28 | ||
24 | 2. Implementation details | 29 | 2. Implementation details |
25 | 30 | ||
26 | The rfkill subsystem is composed of various components: the rfkill class, the | 31 | The rfkill subsystem is composed of three main components: |
27 | rfkill-input module (an input layer handler), and some specific input layer | 32 | * the rfkill core, |
28 | events. | 33 | * the deprecated rfkill-input module (an input layer handler, being |
29 | 34 | replaced by userspace policy code) and | |
30 | The rfkill class is provided for kernel drivers to register their radio | 35 | * the rfkill drivers. |
31 | transmitter with the kernel, provide methods for turning it on and off and, | ||
32 | optionally, letting the system know about hardware-disabled states that may | ||
33 | be implemented on the device. This code is enabled with the CONFIG_RFKILL | ||
34 | Kconfig option, which drivers can "select". | ||
35 | |||
36 | The rfkill class code also notifies userspace of state changes, this is | ||
37 | achieved via uevents. It also provides some sysfs files for userspace to | ||
38 | check the status of radio transmitters. See the "Userspace support" section | ||
39 | below. | ||
40 | 36 | ||
37 | The rfkill core provides API for kernel drivers to register their radio | ||
38 | transmitter with the kernel, methods for turning it on and off and, letting | ||
39 | the system know about hardware-disabled states that may be implemented on | ||
40 | the device. | ||
41 | 41 | ||
42 | The rfkill-input code implements a basic response to rfkill buttons -- it | 42 | The rfkill core code also notifies userspace of state changes, and provides |
43 | implements turning on/off all devices of a certain class (or all). | 43 | ways for userspace to query the current states. See the "Userspace support" |
44 | section below. | ||
44 | 45 | ||
45 | When the device is hard-blocked (either by a call to rfkill_set_hw_state() | 46 | When the device is hard-blocked (either by a call to rfkill_set_hw_state() |
46 | or from query_hw_block) set_block() will be invoked but drivers can well | 47 | or from query_hw_block) set_block() will be invoked for additional software |
47 | ignore the method call since they can use the return value of the function | 48 | block, but drivers can ignore the method call since they can use the return |
48 | rfkill_set_hw_state() to sync the software state instead of keeping track | 49 | value of the function rfkill_set_hw_state() to sync the software state |
49 | of calls to set_block(). | 50 | instead of keeping track of calls to set_block(). In fact, drivers should |
50 | 51 | use the return value of rfkill_set_hw_state() unless the hardware actually | |
51 | 52 | keeps track of soft and hard block separately. | |
52 | The entire functionality is spread over more than one subsystem: | ||
53 | |||
54 | * The kernel input layer generates KEY_WWAN, KEY_WLAN etc. and | ||
55 | SW_RFKILL_ALL -- when the user presses a button. Drivers for radio | ||
56 | transmitters generally do not register to the input layer, unless the | ||
57 | device really provides an input device (i.e. a button that has no | ||
58 | effect other than generating a button press event) | ||
59 | |||
60 | * The rfkill-input code hooks up to these events and switches the soft-block | ||
61 | of the various radio transmitters, depending on the button type. | ||
62 | |||
63 | * The rfkill drivers turn off/on their transmitters as requested. | ||
64 | |||
65 | * The rfkill class will generate userspace notifications (uevents) to tell | ||
66 | userspace what the current state is. | ||
67 | 53 | ||
68 | 54 | ||
55 | 3. Kernel API | ||
69 | 56 | ||
70 | 3. Kernel driver guidelines | ||
71 | 57 | ||
72 | 58 | Drivers for radio transmitters normally implement an rfkill driver. | |
73 | Drivers for radio transmitters normally implement only the rfkill class. | ||
74 | These drivers may not unblock the transmitter based on own decisions, they | ||
75 | should act on information provided by the rfkill class only. | ||
76 | 59 | ||
77 | Platform drivers might implement input devices if the rfkill button is just | 60 | Platform drivers might implement input devices if the rfkill button is just |
78 | that, a button. If that button influences the hardware then you need to | 61 | that, a button. If that button influences the hardware then you need to |
79 | implement an rfkill class instead. This also applies if the platform provides | 62 | implement an rfkill driver instead. This also applies if the platform provides |
80 | a way to turn on/off the transmitter(s). | 63 | a way to turn on/off the transmitter(s). |
81 | 64 | ||
82 | During suspend/hibernation, transmitters should only be left enabled when | 65 | For some platforms, it is possible that the hardware state changes during |
83 | wake-on wlan or similar functionality requires it and the device wasn't | 66 | suspend/hibernation, in which case it will be necessary to update the rfkill |
84 | blocked before suspend/hibernate. Note that it may be necessary to update | 67 | core with the current state is at resume time. |
85 | the rfkill subsystem's idea of what the current state is at resume time if | ||
86 | the state may have changed over suspend. | ||
87 | |||
88 | 68 | ||
69 | To create an rfkill driver, driver's Kconfig needs to have | ||
89 | 70 | ||
90 | 4. Kernel API | 71 | depends on RFKILL || !RFKILL |
91 | 72 | ||
92 | To build a driver with rfkill subsystem support, the driver should depend on | 73 | to ensure the driver cannot be built-in when rfkill is modular. The !RFKILL |
93 | (or select) the Kconfig symbol RFKILL. | 74 | case allows the driver to be built when rfkill is not configured, which which |
94 | 75 | case all rfkill API can still be used but will be provided by static inlines | |
95 | The hardware the driver talks to may be write-only (where the current state | 76 | which compile to almost nothing. |
96 | of the hardware is unknown), or read-write (where the hardware can be queried | ||
97 | about its current state). | ||
98 | 77 | ||
99 | Calling rfkill_set_hw_state() when a state change happens is required from | 78 | Calling rfkill_set_hw_state() when a state change happens is required from |
100 | rfkill drivers that control devices that can be hard-blocked unless they also | 79 | rfkill drivers that control devices that can be hard-blocked unless they also |
@@ -105,10 +84,33 @@ device). Don't do this unless you cannot get the event in any other way. | |||
105 | 84 | ||
106 | 5. Userspace support | 85 | 5. Userspace support |
107 | 86 | ||
108 | The following sysfs entries exist for every rfkill device: | 87 | The recommended userspace interface to use is /dev/rfkill, which is a misc |
88 | character device that allows userspace to obtain and set the state of rfkill | ||
89 | devices and sets of devices. It also notifies userspace about device addition | ||
90 | and removal. The API is a simple read/write API that is defined in | ||
91 | linux/rfkill.h, with one ioctl that allows turning off the deprecated input | ||
92 | handler in the kernel for the transition period. | ||
93 | |||
94 | Except for the one ioctl, communication with the kernel is done via read() | ||
95 | and write() of instances of 'struct rfkill_event'. In this structure, the | ||
96 | soft and hard block are properly separated (unlike sysfs, see below) and | ||
97 | userspace is able to get a consistent snapshot of all rfkill devices in the | ||
98 | system. Also, it is possible to switch all rfkill drivers (or all drivers of | ||
99 | a specified type) into a state which also updates the default state for | ||
100 | hotplugged devices. | ||
101 | |||
102 | After an application opens /dev/rfkill, it can read the current state of | ||
103 | all devices, and afterwards can poll the descriptor for hotplug or state | ||
104 | change events. | ||
105 | |||
106 | Applications must ignore operations (the "op" field) they do not handle, | ||
107 | this allows the API to be extended in the future. | ||
108 | |||
109 | Additionally, each rfkill device is registered in sysfs and there has the | ||
110 | following attributes: | ||
109 | 111 | ||
110 | name: Name assigned by driver to this key (interface or driver name). | 112 | name: Name assigned by driver to this key (interface or driver name). |
111 | type: Name of the key type ("wlan", "bluetooth", etc). | 113 | type: Driver type string ("wlan", "bluetooth", etc). |
112 | state: Current state of the transmitter | 114 | state: Current state of the transmitter |
113 | 0: RFKILL_STATE_SOFT_BLOCKED | 115 | 0: RFKILL_STATE_SOFT_BLOCKED |
114 | transmitter is turned off by software | 116 | transmitter is turned off by software |
@@ -117,7 +119,12 @@ The following sysfs entries exist for every rfkill device: | |||
117 | 2: RFKILL_STATE_HARD_BLOCKED | 119 | 2: RFKILL_STATE_HARD_BLOCKED |
118 | transmitter is forced off by something outside of | 120 | transmitter is forced off by something outside of |
119 | the driver's control. | 121 | the driver's control. |
120 | claim: 0: Kernel handles events (currently always reads that value) | 122 | This file is deprecated because it can only properly show |
123 | three of the four possible states, soft-and-hard-blocked is | ||
124 | missing. | ||
125 | claim: 0: Kernel handles events | ||
126 | This file is deprecated because there no longer is a way to | ||
127 | claim just control over a single rfkill instance. | ||
121 | 128 | ||
122 | rfkill devices also issue uevents (with an action of "change"), with the | 129 | rfkill devices also issue uevents (with an action of "change"), with the |
123 | following environment variables set: | 130 | following environment variables set: |
@@ -128,9 +135,3 @@ RFKILL_TYPE | |||
128 | 135 | ||
129 | The contents of these variables corresponds to the "name", "state" and | 136 | The contents of these variables corresponds to the "name", "state" and |
130 | "type" sysfs files explained above. | 137 | "type" sysfs files explained above. |
131 | |||
132 | An alternative userspace interface exists as a misc device /dev/rfkill, | ||
133 | which allows userspace to obtain and set the state of rfkill devices and | ||
134 | sets of devices. It also notifies userspace about device addition and | ||
135 | removal. The API is a simple read/write API that is defined in | ||
136 | linux/rfkill.h. | ||
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c index 34d54e7281fd..de4aad076ebc 100644 --- a/drivers/isdn/i4l/isdn_net.c +++ b/drivers/isdn/i4l/isdn_net.c | |||
@@ -1300,7 +1300,7 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
1300 | netif_stop_queue(ndev); | 1300 | netif_stop_queue(ndev); |
1301 | } | 1301 | } |
1302 | } | 1302 | } |
1303 | return 1; | 1303 | return NETDEV_TX_BUSY; |
1304 | } | 1304 | } |
1305 | 1305 | ||
1306 | /* | 1306 | /* |
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 7e3738112c4e..38f1c3375d7f 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -3552,14 +3552,14 @@ bnx2_set_rx_mode(struct net_device *dev) | |||
3552 | sort_mode |= BNX2_RPM_SORT_USER0_MC_HSH_EN; | 3552 | sort_mode |= BNX2_RPM_SORT_USER0_MC_HSH_EN; |
3553 | } | 3553 | } |
3554 | 3554 | ||
3555 | if (dev->uc_count > BNX2_MAX_UNICAST_ADDRESSES) { | 3555 | if (dev->uc.count > BNX2_MAX_UNICAST_ADDRESSES) { |
3556 | rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS; | 3556 | rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS; |
3557 | sort_mode |= BNX2_RPM_SORT_USER0_PROM_EN | | 3557 | sort_mode |= BNX2_RPM_SORT_USER0_PROM_EN | |
3558 | BNX2_RPM_SORT_USER0_PROM_VLAN; | 3558 | BNX2_RPM_SORT_USER0_PROM_VLAN; |
3559 | } else if (!(dev->flags & IFF_PROMISC)) { | 3559 | } else if (!(dev->flags & IFF_PROMISC)) { |
3560 | /* Add all entries into to the match filter list */ | 3560 | /* Add all entries into to the match filter list */ |
3561 | i = 0; | 3561 | i = 0; |
3562 | list_for_each_entry(ha, &dev->uc_list, list) { | 3562 | list_for_each_entry(ha, &dev->uc.list, list) { |
3563 | bnx2_set_mac_addr(bp, ha->addr, | 3563 | bnx2_set_mac_addr(bp, ha->addr, |
3564 | i + BNX2_START_UNICAST_ADDRESS_INDEX); | 3564 | i + BNX2_START_UNICAST_ADDRESS_INDEX); |
3565 | sort_mode |= (1 << | 3565 | sort_mode |= (1 << |
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 0e9b9f9632c1..2df8fb0af701 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c | |||
@@ -2767,7 +2767,6 @@ static int __devexit davinci_emac_remove(struct platform_device *pdev) | |||
2767 | 2767 | ||
2768 | dev_notice(&ndev->dev, "DaVinci EMAC: davinci_emac_remove()\n"); | 2768 | dev_notice(&ndev->dev, "DaVinci EMAC: davinci_emac_remove()\n"); |
2769 | 2769 | ||
2770 | clk_disable(emac_clk); | ||
2771 | platform_set_drvdata(pdev, NULL); | 2770 | platform_set_drvdata(pdev, NULL); |
2772 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2771 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2773 | mdiobus_unregister(priv->mii_bus); | 2772 | mdiobus_unregister(priv->mii_bus); |
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index f7929e89eb03..efa680f4b8dd 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
@@ -2895,12 +2895,13 @@ static void __e100_shutdown(struct pci_dev *pdev, bool *enable_wake) | |||
2895 | 2895 | ||
2896 | static int __e100_power_off(struct pci_dev *pdev, bool wake) | 2896 | static int __e100_power_off(struct pci_dev *pdev, bool wake) |
2897 | { | 2897 | { |
2898 | if (wake) { | 2898 | if (wake) |
2899 | return pci_prepare_to_sleep(pdev); | 2899 | return pci_prepare_to_sleep(pdev); |
2900 | } else { | 2900 | |
2901 | pci_wake_from_d3(pdev, false); | 2901 | pci_wake_from_d3(pdev, false); |
2902 | return pci_set_power_state(pdev, PCI_D3hot); | 2902 | pci_set_power_state(pdev, PCI_D3hot); |
2903 | } | 2903 | |
2904 | return 0; | ||
2904 | } | 2905 | } |
2905 | 2906 | ||
2906 | #ifdef CONFIG_PM | 2907 | #ifdef CONFIG_PM |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 8d36743c8140..5e3356f8eb5a 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -2370,7 +2370,7 @@ static void e1000_set_rx_mode(struct net_device *netdev) | |||
2370 | rctl |= E1000_RCTL_VFE; | 2370 | rctl |= E1000_RCTL_VFE; |
2371 | } | 2371 | } |
2372 | 2372 | ||
2373 | if (netdev->uc_count > rar_entries - 1) { | 2373 | if (netdev->uc.count > rar_entries - 1) { |
2374 | rctl |= E1000_RCTL_UPE; | 2374 | rctl |= E1000_RCTL_UPE; |
2375 | } else if (!(netdev->flags & IFF_PROMISC)) { | 2375 | } else if (!(netdev->flags & IFF_PROMISC)) { |
2376 | rctl &= ~E1000_RCTL_UPE; | 2376 | rctl &= ~E1000_RCTL_UPE; |
@@ -2394,7 +2394,7 @@ static void e1000_set_rx_mode(struct net_device *netdev) | |||
2394 | */ | 2394 | */ |
2395 | i = 1; | 2395 | i = 1; |
2396 | if (use_uc) | 2396 | if (use_uc) |
2397 | list_for_each_entry(ha, &netdev->uc_list, list) { | 2397 | list_for_each_entry(ha, &netdev->uc.list, list) { |
2398 | if (i == rar_entries) | 2398 | if (i == rar_entries) |
2399 | break; | 2399 | break; |
2400 | e1000_rar_set(hw, ha->addr, i++); | 2400 | e1000_rar_set(hw, ha->addr, i++); |
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index b60a3041b64c..1094d292630f 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
@@ -719,7 +719,8 @@ static const struct register_test nv_registers_test[] = { | |||
719 | struct nv_skb_map { | 719 | struct nv_skb_map { |
720 | struct sk_buff *skb; | 720 | struct sk_buff *skb; |
721 | dma_addr_t dma; | 721 | dma_addr_t dma; |
722 | unsigned int dma_len; | 722 | unsigned int dma_len:31; |
723 | unsigned int dma_single:1; | ||
723 | struct ring_desc_ex *first_tx_desc; | 724 | struct ring_desc_ex *first_tx_desc; |
724 | struct nv_skb_map *next_tx_ctx; | 725 | struct nv_skb_map *next_tx_ctx; |
725 | }; | 726 | }; |
@@ -1912,6 +1913,7 @@ static void nv_init_tx(struct net_device *dev) | |||
1912 | np->tx_skb[i].skb = NULL; | 1913 | np->tx_skb[i].skb = NULL; |
1913 | np->tx_skb[i].dma = 0; | 1914 | np->tx_skb[i].dma = 0; |
1914 | np->tx_skb[i].dma_len = 0; | 1915 | np->tx_skb[i].dma_len = 0; |
1916 | np->tx_skb[i].dma_single = 0; | ||
1915 | np->tx_skb[i].first_tx_desc = NULL; | 1917 | np->tx_skb[i].first_tx_desc = NULL; |
1916 | np->tx_skb[i].next_tx_ctx = NULL; | 1918 | np->tx_skb[i].next_tx_ctx = NULL; |
1917 | } | 1919 | } |
@@ -1930,23 +1932,30 @@ static int nv_init_ring(struct net_device *dev) | |||
1930 | return nv_alloc_rx_optimized(dev); | 1932 | return nv_alloc_rx_optimized(dev); |
1931 | } | 1933 | } |
1932 | 1934 | ||
1933 | static int nv_release_txskb(struct net_device *dev, struct nv_skb_map* tx_skb) | 1935 | static void nv_unmap_txskb(struct fe_priv *np, struct nv_skb_map *tx_skb) |
1934 | { | 1936 | { |
1935 | struct fe_priv *np = netdev_priv(dev); | ||
1936 | |||
1937 | if (tx_skb->dma) { | 1937 | if (tx_skb->dma) { |
1938 | pci_unmap_page(np->pci_dev, tx_skb->dma, | 1938 | if (tx_skb->dma_single) |
1939 | tx_skb->dma_len, | 1939 | pci_unmap_single(np->pci_dev, tx_skb->dma, |
1940 | PCI_DMA_TODEVICE); | 1940 | tx_skb->dma_len, |
1941 | PCI_DMA_TODEVICE); | ||
1942 | else | ||
1943 | pci_unmap_page(np->pci_dev, tx_skb->dma, | ||
1944 | tx_skb->dma_len, | ||
1945 | PCI_DMA_TODEVICE); | ||
1941 | tx_skb->dma = 0; | 1946 | tx_skb->dma = 0; |
1942 | } | 1947 | } |
1948 | } | ||
1949 | |||
1950 | static int nv_release_txskb(struct fe_priv *np, struct nv_skb_map *tx_skb) | ||
1951 | { | ||
1952 | nv_unmap_txskb(np, tx_skb); | ||
1943 | if (tx_skb->skb) { | 1953 | if (tx_skb->skb) { |
1944 | dev_kfree_skb_any(tx_skb->skb); | 1954 | dev_kfree_skb_any(tx_skb->skb); |
1945 | tx_skb->skb = NULL; | 1955 | tx_skb->skb = NULL; |
1946 | return 1; | 1956 | return 1; |
1947 | } else { | ||
1948 | return 0; | ||
1949 | } | 1957 | } |
1958 | return 0; | ||
1950 | } | 1959 | } |
1951 | 1960 | ||
1952 | static void nv_drain_tx(struct net_device *dev) | 1961 | static void nv_drain_tx(struct net_device *dev) |
@@ -1964,10 +1973,11 @@ static void nv_drain_tx(struct net_device *dev) | |||
1964 | np->tx_ring.ex[i].bufhigh = 0; | 1973 | np->tx_ring.ex[i].bufhigh = 0; |
1965 | np->tx_ring.ex[i].buflow = 0; | 1974 | np->tx_ring.ex[i].buflow = 0; |
1966 | } | 1975 | } |
1967 | if (nv_release_txskb(dev, &np->tx_skb[i])) | 1976 | if (nv_release_txskb(np, &np->tx_skb[i])) |
1968 | dev->stats.tx_dropped++; | 1977 | dev->stats.tx_dropped++; |
1969 | np->tx_skb[i].dma = 0; | 1978 | np->tx_skb[i].dma = 0; |
1970 | np->tx_skb[i].dma_len = 0; | 1979 | np->tx_skb[i].dma_len = 0; |
1980 | np->tx_skb[i].dma_single = 0; | ||
1971 | np->tx_skb[i].first_tx_desc = NULL; | 1981 | np->tx_skb[i].first_tx_desc = NULL; |
1972 | np->tx_skb[i].next_tx_ctx = NULL; | 1982 | np->tx_skb[i].next_tx_ctx = NULL; |
1973 | } | 1983 | } |
@@ -2171,6 +2181,7 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2171 | np->put_tx_ctx->dma = pci_map_single(np->pci_dev, skb->data + offset, bcnt, | 2181 | np->put_tx_ctx->dma = pci_map_single(np->pci_dev, skb->data + offset, bcnt, |
2172 | PCI_DMA_TODEVICE); | 2182 | PCI_DMA_TODEVICE); |
2173 | np->put_tx_ctx->dma_len = bcnt; | 2183 | np->put_tx_ctx->dma_len = bcnt; |
2184 | np->put_tx_ctx->dma_single = 1; | ||
2174 | put_tx->buf = cpu_to_le32(np->put_tx_ctx->dma); | 2185 | put_tx->buf = cpu_to_le32(np->put_tx_ctx->dma); |
2175 | put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags); | 2186 | put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags); |
2176 | 2187 | ||
@@ -2196,6 +2207,7 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2196 | np->put_tx_ctx->dma = pci_map_page(np->pci_dev, frag->page, frag->page_offset+offset, bcnt, | 2207 | np->put_tx_ctx->dma = pci_map_page(np->pci_dev, frag->page, frag->page_offset+offset, bcnt, |
2197 | PCI_DMA_TODEVICE); | 2208 | PCI_DMA_TODEVICE); |
2198 | np->put_tx_ctx->dma_len = bcnt; | 2209 | np->put_tx_ctx->dma_len = bcnt; |
2210 | np->put_tx_ctx->dma_single = 0; | ||
2199 | put_tx->buf = cpu_to_le32(np->put_tx_ctx->dma); | 2211 | put_tx->buf = cpu_to_le32(np->put_tx_ctx->dma); |
2200 | put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags); | 2212 | put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags); |
2201 | 2213 | ||
@@ -2291,6 +2303,7 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev) | |||
2291 | np->put_tx_ctx->dma = pci_map_single(np->pci_dev, skb->data + offset, bcnt, | 2303 | np->put_tx_ctx->dma = pci_map_single(np->pci_dev, skb->data + offset, bcnt, |
2292 | PCI_DMA_TODEVICE); | 2304 | PCI_DMA_TODEVICE); |
2293 | np->put_tx_ctx->dma_len = bcnt; | 2305 | np->put_tx_ctx->dma_len = bcnt; |
2306 | np->put_tx_ctx->dma_single = 1; | ||
2294 | put_tx->bufhigh = cpu_to_le32(dma_high(np->put_tx_ctx->dma)); | 2307 | put_tx->bufhigh = cpu_to_le32(dma_high(np->put_tx_ctx->dma)); |
2295 | put_tx->buflow = cpu_to_le32(dma_low(np->put_tx_ctx->dma)); | 2308 | put_tx->buflow = cpu_to_le32(dma_low(np->put_tx_ctx->dma)); |
2296 | put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags); | 2309 | put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags); |
@@ -2317,6 +2330,7 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev) | |||
2317 | np->put_tx_ctx->dma = pci_map_page(np->pci_dev, frag->page, frag->page_offset+offset, bcnt, | 2330 | np->put_tx_ctx->dma = pci_map_page(np->pci_dev, frag->page, frag->page_offset+offset, bcnt, |
2318 | PCI_DMA_TODEVICE); | 2331 | PCI_DMA_TODEVICE); |
2319 | np->put_tx_ctx->dma_len = bcnt; | 2332 | np->put_tx_ctx->dma_len = bcnt; |
2333 | np->put_tx_ctx->dma_single = 0; | ||
2320 | put_tx->bufhigh = cpu_to_le32(dma_high(np->put_tx_ctx->dma)); | 2334 | put_tx->bufhigh = cpu_to_le32(dma_high(np->put_tx_ctx->dma)); |
2321 | put_tx->buflow = cpu_to_le32(dma_low(np->put_tx_ctx->dma)); | 2335 | put_tx->buflow = cpu_to_le32(dma_low(np->put_tx_ctx->dma)); |
2322 | put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags); | 2336 | put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags); |
@@ -2434,10 +2448,7 @@ static int nv_tx_done(struct net_device *dev, int limit) | |||
2434 | dprintk(KERN_DEBUG "%s: nv_tx_done: flags 0x%x.\n", | 2448 | dprintk(KERN_DEBUG "%s: nv_tx_done: flags 0x%x.\n", |
2435 | dev->name, flags); | 2449 | dev->name, flags); |
2436 | 2450 | ||
2437 | pci_unmap_page(np->pci_dev, np->get_tx_ctx->dma, | 2451 | nv_unmap_txskb(np, np->get_tx_ctx); |
2438 | np->get_tx_ctx->dma_len, | ||
2439 | PCI_DMA_TODEVICE); | ||
2440 | np->get_tx_ctx->dma = 0; | ||
2441 | 2452 | ||
2442 | if (np->desc_ver == DESC_VER_1) { | 2453 | if (np->desc_ver == DESC_VER_1) { |
2443 | if (flags & NV_TX_LASTPACKET) { | 2454 | if (flags & NV_TX_LASTPACKET) { |
@@ -2502,10 +2513,7 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit) | |||
2502 | dprintk(KERN_DEBUG "%s: nv_tx_done_optimized: flags 0x%x.\n", | 2513 | dprintk(KERN_DEBUG "%s: nv_tx_done_optimized: flags 0x%x.\n", |
2503 | dev->name, flags); | 2514 | dev->name, flags); |
2504 | 2515 | ||
2505 | pci_unmap_page(np->pci_dev, np->get_tx_ctx->dma, | 2516 | nv_unmap_txskb(np, np->get_tx_ctx); |
2506 | np->get_tx_ctx->dma_len, | ||
2507 | PCI_DMA_TODEVICE); | ||
2508 | np->get_tx_ctx->dma = 0; | ||
2509 | 2517 | ||
2510 | if (flags & NV_TX2_LASTPACKET) { | 2518 | if (flags & NV_TX2_LASTPACKET) { |
2511 | if (!(flags & NV_TX2_ERROR)) | 2519 | if (!(flags & NV_TX2_ERROR)) |
@@ -5091,7 +5099,7 @@ static int nv_loopback_test(struct net_device *dev) | |||
5091 | dprintk(KERN_DEBUG "%s: loopback - did not receive test packet\n", dev->name); | 5099 | dprintk(KERN_DEBUG "%s: loopback - did not receive test packet\n", dev->name); |
5092 | } | 5100 | } |
5093 | 5101 | ||
5094 | pci_unmap_page(np->pci_dev, test_dma_addr, | 5102 | pci_unmap_single(np->pci_dev, test_dma_addr, |
5095 | (skb_end_pointer(tx_skb) - tx_skb->data), | 5103 | (skb_end_pointer(tx_skb) - tx_skb->data), |
5096 | PCI_DMA_TODEVICE); | 5104 | PCI_DMA_TODEVICE); |
5097 | dev_kfree_skb_any(tx_skb); | 5105 | dev_kfree_skb_any(tx_skb); |
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c index 5105548ad50c..abcd19a8bff9 100644 --- a/drivers/net/hamradio/bpqether.c +++ b/drivers/net/hamradio/bpqether.c | |||
@@ -260,7 +260,7 @@ static int bpq_xmit(struct sk_buff *skb, struct net_device *dev) | |||
260 | */ | 260 | */ |
261 | if (!netif_running(dev)) { | 261 | if (!netif_running(dev)) { |
262 | kfree_skb(skb); | 262 | kfree_skb(skb); |
263 | return -ENODEV; | 263 | return NETDEV_TX_OK; |
264 | } | 264 | } |
265 | 265 | ||
266 | skb_pull(skb, 1); | 266 | skb_pull(skb, 1); |
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index 8feda9fe8297..1d3429a415e6 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c | |||
@@ -1495,13 +1495,8 @@ static int hp100_start_xmit_bm(struct sk_buff *skb, struct net_device *dev) | |||
1495 | hp100_outw(0x4210, TRACE); | 1495 | hp100_outw(0x4210, TRACE); |
1496 | printk("hp100: %s: start_xmit_bm\n", dev->name); | 1496 | printk("hp100: %s: start_xmit_bm\n", dev->name); |
1497 | #endif | 1497 | #endif |
1498 | |||
1499 | if (skb == NULL) { | ||
1500 | return 0; | ||
1501 | } | ||
1502 | |||
1503 | if (skb->len <= 0) | 1498 | if (skb->len <= 0) |
1504 | return 0; | 1499 | goto drop; |
1505 | 1500 | ||
1506 | if (lp->chip == HP100_CHIPID_SHASTA && skb_padto(skb, ETH_ZLEN)) | 1501 | if (lp->chip == HP100_CHIPID_SHASTA && skb_padto(skb, ETH_ZLEN)) |
1507 | return 0; | 1502 | return 0; |
@@ -1514,10 +1509,10 @@ static int hp100_start_xmit_bm(struct sk_buff *skb, struct net_device *dev) | |||
1514 | #endif | 1509 | #endif |
1515 | /* not waited long enough since last tx? */ | 1510 | /* not waited long enough since last tx? */ |
1516 | if (time_before(jiffies, dev->trans_start + HZ)) | 1511 | if (time_before(jiffies, dev->trans_start + HZ)) |
1517 | return -EAGAIN; | 1512 | goto drop; |
1518 | 1513 | ||
1519 | if (hp100_check_lan(dev)) | 1514 | if (hp100_check_lan(dev)) |
1520 | return -EIO; | 1515 | goto drop; |
1521 | 1516 | ||
1522 | if (lp->lan_type == HP100_LAN_100 && lp->hub_status < 0) { | 1517 | if (lp->lan_type == HP100_LAN_100 && lp->hub_status < 0) { |
1523 | /* we have a 100Mb/s adapter but it isn't connected to hub */ | 1518 | /* we have a 100Mb/s adapter but it isn't connected to hub */ |
@@ -1551,7 +1546,7 @@ static int hp100_start_xmit_bm(struct sk_buff *skb, struct net_device *dev) | |||
1551 | } | 1546 | } |
1552 | 1547 | ||
1553 | dev->trans_start = jiffies; | 1548 | dev->trans_start = jiffies; |
1554 | return -EAGAIN; | 1549 | goto drop; |
1555 | } | 1550 | } |
1556 | 1551 | ||
1557 | /* | 1552 | /* |
@@ -1591,6 +1586,10 @@ static int hp100_start_xmit_bm(struct sk_buff *skb, struct net_device *dev) | |||
1591 | dev->trans_start = jiffies; | 1586 | dev->trans_start = jiffies; |
1592 | 1587 | ||
1593 | return 0; | 1588 | return 0; |
1589 | |||
1590 | drop: | ||
1591 | dev_kfree_skb(skb); | ||
1592 | return NETDEV_TX_OK; | ||
1594 | } | 1593 | } |
1595 | 1594 | ||
1596 | 1595 | ||
@@ -1648,16 +1647,11 @@ static int hp100_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1648 | hp100_outw(0x4212, TRACE); | 1647 | hp100_outw(0x4212, TRACE); |
1649 | printk("hp100: %s: start_xmit\n", dev->name); | 1648 | printk("hp100: %s: start_xmit\n", dev->name); |
1650 | #endif | 1649 | #endif |
1651 | |||
1652 | if (skb == NULL) { | ||
1653 | return 0; | ||
1654 | } | ||
1655 | |||
1656 | if (skb->len <= 0) | 1650 | if (skb->len <= 0) |
1657 | return 0; | 1651 | goto drop; |
1658 | 1652 | ||
1659 | if (hp100_check_lan(dev)) | 1653 | if (hp100_check_lan(dev)) |
1660 | return -EIO; | 1654 | goto drop; |
1661 | 1655 | ||
1662 | /* If there is not enough free memory on the card... */ | 1656 | /* If there is not enough free memory on the card... */ |
1663 | i = hp100_inl(TX_MEM_FREE) & 0x7fffffff; | 1657 | i = hp100_inl(TX_MEM_FREE) & 0x7fffffff; |
@@ -1671,7 +1665,7 @@ static int hp100_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1671 | printk("hp100: %s: trans_start timing problem\n", | 1665 | printk("hp100: %s: trans_start timing problem\n", |
1672 | dev->name); | 1666 | dev->name); |
1673 | #endif | 1667 | #endif |
1674 | return -EAGAIN; | 1668 | goto drop; |
1675 | } | 1669 | } |
1676 | if (lp->lan_type == HP100_LAN_100 && lp->hub_status < 0) { | 1670 | if (lp->lan_type == HP100_LAN_100 && lp->hub_status < 0) { |
1677 | /* we have a 100Mb/s adapter but it isn't connected to hub */ | 1671 | /* we have a 100Mb/s adapter but it isn't connected to hub */ |
@@ -1705,7 +1699,7 @@ static int hp100_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1705 | } | 1699 | } |
1706 | } | 1700 | } |
1707 | dev->trans_start = jiffies; | 1701 | dev->trans_start = jiffies; |
1708 | return -EAGAIN; | 1702 | goto drop; |
1709 | } | 1703 | } |
1710 | 1704 | ||
1711 | for (i = 0; i < 6000 && (hp100_inb(OPTION_MSW) & HP100_TX_CMD); i++) { | 1705 | for (i = 0; i < 6000 && (hp100_inb(OPTION_MSW) & HP100_TX_CMD); i++) { |
@@ -1759,6 +1753,11 @@ static int hp100_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1759 | #endif | 1753 | #endif |
1760 | 1754 | ||
1761 | return 0; | 1755 | return 0; |
1756 | |||
1757 | drop: | ||
1758 | dev_kfree_skb(skb); | ||
1759 | return NETDEV_TX_OK; | ||
1760 | |||
1762 | } | 1761 | } |
1763 | 1762 | ||
1764 | 1763 | ||
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index a551a96ce676..e756e220db32 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -2321,7 +2321,7 @@ static void ixgbe_set_rx_mode(struct net_device *netdev) | |||
2321 | IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); | 2321 | IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); |
2322 | 2322 | ||
2323 | /* reprogram secondary unicast list */ | 2323 | /* reprogram secondary unicast list */ |
2324 | hw->mac.ops.update_uc_addr_list(hw, &netdev->uc_list); | 2324 | hw->mac.ops.update_uc_addr_list(hw, &netdev->uc.list); |
2325 | 2325 | ||
2326 | /* reprogram multicast list */ | 2326 | /* reprogram multicast list */ |
2327 | addr_count = netdev->mc_count; | 2327 | addr_count = netdev->mc_count; |
@@ -5261,7 +5261,7 @@ static int ixgbe_ioctl(struct net_device *netdev, struct ifreq *req, int cmd) | |||
5261 | 5261 | ||
5262 | /** | 5262 | /** |
5263 | * ixgbe_add_sanmac_netdev - Add the SAN MAC address to the corresponding | 5263 | * ixgbe_add_sanmac_netdev - Add the SAN MAC address to the corresponding |
5264 | * netdev->dev_addr_list | 5264 | * netdev->dev_addrs |
5265 | * @netdev: network interface device structure | 5265 | * @netdev: network interface device structure |
5266 | * | 5266 | * |
5267 | * Returns non-zero on failure | 5267 | * Returns non-zero on failure |
@@ -5282,7 +5282,7 @@ static int ixgbe_add_sanmac_netdev(struct net_device *dev) | |||
5282 | 5282 | ||
5283 | /** | 5283 | /** |
5284 | * ixgbe_del_sanmac_netdev - Removes the SAN MAC address to the corresponding | 5284 | * ixgbe_del_sanmac_netdev - Removes the SAN MAC address to the corresponding |
5285 | * netdev->dev_addr_list | 5285 | * netdev->dev_addrs |
5286 | * @netdev: network interface device structure | 5286 | * @netdev: network interface device structure |
5287 | * | 5287 | * |
5288 | * Returns non-zero on failure | 5288 | * Returns non-zero on failure |
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index b4e18a58cb1b..745ae8b4a2e8 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -1729,7 +1729,7 @@ static u32 uc_addr_filter_mask(struct net_device *dev) | |||
1729 | return 0; | 1729 | return 0; |
1730 | 1730 | ||
1731 | nibbles = 1 << (dev->dev_addr[5] & 0x0f); | 1731 | nibbles = 1 << (dev->dev_addr[5] & 0x0f); |
1732 | list_for_each_entry(ha, &dev->uc_list, list) { | 1732 | list_for_each_entry(ha, &dev->uc.list, list) { |
1733 | if (memcmp(dev->dev_addr, ha->addr, 5)) | 1733 | if (memcmp(dev->dev_addr, ha->addr, 5)) |
1734 | return 0; | 1734 | return 0; |
1735 | if ((dev->dev_addr[5] ^ ha->addr[5]) & 0xf0) | 1735 | if ((dev->dev_addr[5] ^ ha->addr[5]) & 0xf0) |
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index ab11c2b3f0fe..970cedeb5f37 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -169,6 +169,7 @@ | |||
169 | #define MAX_NUM_CARDS 4 | 169 | #define MAX_NUM_CARDS 4 |
170 | 170 | ||
171 | #define MAX_BUFFERS_PER_CMD 32 | 171 | #define MAX_BUFFERS_PER_CMD 32 |
172 | #define TX_STOP_THRESH ((MAX_SKB_FRAGS >> 2) + 4) | ||
172 | 173 | ||
173 | /* | 174 | /* |
174 | * Following are the states of the Phantom. Phantom will set them and | 175 | * Following are the states of the Phantom. Phantom will set them and |
@@ -1436,7 +1437,7 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p); | |||
1436 | struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev); | 1437 | struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev); |
1437 | 1438 | ||
1438 | void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, | 1439 | void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, |
1439 | struct nx_host_tx_ring *tx_ring, uint32_t crb_producer); | 1440 | struct nx_host_tx_ring *tx_ring); |
1440 | 1441 | ||
1441 | /* | 1442 | /* |
1442 | * NetXen Board information | 1443 | * NetXen Board information |
@@ -1538,6 +1539,14 @@ dma_watchdog_wakeup(struct netxen_adapter *adapter) | |||
1538 | } | 1539 | } |
1539 | 1540 | ||
1540 | 1541 | ||
1542 | static inline u32 netxen_tx_avail(struct nx_host_tx_ring *tx_ring) | ||
1543 | { | ||
1544 | smp_mb(); | ||
1545 | return find_diff_among(tx_ring->producer, | ||
1546 | tx_ring->sw_consumer, tx_ring->num_desc); | ||
1547 | |||
1548 | } | ||
1549 | |||
1541 | int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac); | 1550 | int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac); |
1542 | int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac); | 1551 | int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac); |
1543 | extern void netxen_change_ringparam(struct netxen_adapter *adapter); | 1552 | extern void netxen_change_ringparam(struct netxen_adapter *adapter); |
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h index 7f0ddbfa7b28..3cc047844af3 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h | |||
@@ -355,6 +355,7 @@ enum { | |||
355 | #define NETXEN_HW_CRB_HUB_AGT_ADR_LPC \ | 355 | #define NETXEN_HW_CRB_HUB_AGT_ADR_LPC \ |
356 | ((NETXEN_HW_H6_CH_HUB_ADR << 7) | NETXEN_HW_LPC_CRB_AGT_ADR) | 356 | ((NETXEN_HW_H6_CH_HUB_ADR << 7) | NETXEN_HW_LPC_CRB_AGT_ADR) |
357 | 357 | ||
358 | #define NETXEN_SRE_MISC (NETXEN_CRB_SRE + 0x0002c) | ||
358 | #define NETXEN_SRE_INT_STATUS (NETXEN_CRB_SRE + 0x00034) | 359 | #define NETXEN_SRE_INT_STATUS (NETXEN_CRB_SRE + 0x00034) |
359 | #define NETXEN_SRE_PBI_ACTIVE_STATUS (NETXEN_CRB_SRE + 0x01014) | 360 | #define NETXEN_SRE_PBI_ACTIVE_STATUS (NETXEN_CRB_SRE + 0x01014) |
360 | #define NETXEN_SRE_L1RE_CTL (NETXEN_CRB_SRE + 0x03000) | 361 | #define NETXEN_SRE_L1RE_CTL (NETXEN_CRB_SRE + 0x03000) |
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 42ffb825ebf1..ce3b89d2cbb6 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
@@ -488,7 +488,7 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter, | |||
488 | 488 | ||
489 | tx_ring->producer = producer; | 489 | tx_ring->producer = producer; |
490 | 490 | ||
491 | netxen_nic_update_cmd_producer(adapter, tx_ring, producer); | 491 | netxen_nic_update_cmd_producer(adapter, tx_ring); |
492 | 492 | ||
493 | netif_tx_unlock_bh(adapter->netdev); | 493 | netif_tx_unlock_bh(adapter->netdev); |
494 | 494 | ||
@@ -2041,8 +2041,8 @@ void netxen_nic_get_firmware_info(struct netxen_adapter *adapter) | |||
2041 | fw_major, fw_minor, fw_build); | 2041 | fw_major, fw_minor, fw_build); |
2042 | 2042 | ||
2043 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { | 2043 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { |
2044 | i = NXRD32(adapter, NETXEN_MIU_MN_CONTROL); | 2044 | i = NXRD32(adapter, NETXEN_SRE_MISC); |
2045 | adapter->ahw.cut_through = (i & 0x4) ? 1 : 0; | 2045 | adapter->ahw.cut_through = (i & 0x8000) ? 1 : 0; |
2046 | dev_info(&pdev->dev, "firmware running in %s mode\n", | 2046 | dev_info(&pdev->dev, "firmware running in %s mode\n", |
2047 | adapter->ahw.cut_through ? "cut-through" : "legacy"); | 2047 | adapter->ahw.cut_through ? "cut-through" : "legacy"); |
2048 | } | 2048 | } |
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 6f77ad58e3b3..bdb143d2b5c7 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -1292,7 +1292,6 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter) | |||
1292 | return 1; | 1292 | return 1; |
1293 | 1293 | ||
1294 | sw_consumer = tx_ring->sw_consumer; | 1294 | sw_consumer = tx_ring->sw_consumer; |
1295 | barrier(); /* hw_consumer can change underneath */ | ||
1296 | hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer)); | 1295 | hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer)); |
1297 | 1296 | ||
1298 | while (sw_consumer != hw_consumer) { | 1297 | while (sw_consumer != hw_consumer) { |
@@ -1319,14 +1318,15 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter) | |||
1319 | break; | 1318 | break; |
1320 | } | 1319 | } |
1321 | 1320 | ||
1322 | tx_ring->sw_consumer = sw_consumer; | ||
1323 | |||
1324 | if (count && netif_running(netdev)) { | 1321 | if (count && netif_running(netdev)) { |
1322 | tx_ring->sw_consumer = sw_consumer; | ||
1323 | |||
1325 | smp_mb(); | 1324 | smp_mb(); |
1325 | |||
1326 | if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) { | 1326 | if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) { |
1327 | netif_tx_lock(netdev); | 1327 | netif_tx_lock(netdev); |
1328 | netif_wake_queue(netdev); | 1328 | if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH) |
1329 | smp_mb(); | 1329 | netif_wake_queue(netdev); |
1330 | netif_tx_unlock(netdev); | 1330 | netif_tx_unlock(netdev); |
1331 | } | 1331 | } |
1332 | } | 1332 | } |
@@ -1343,7 +1343,6 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter) | |||
1343 | * There is still a possible race condition and the host could miss an | 1343 | * There is still a possible race condition and the host could miss an |
1344 | * interrupt. The card has to take care of this. | 1344 | * interrupt. The card has to take care of this. |
1345 | */ | 1345 | */ |
1346 | barrier(); /* hw_consumer can change underneath */ | ||
1347 | hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer)); | 1346 | hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer)); |
1348 | done = (sw_consumer == hw_consumer); | 1347 | done = (sw_consumer == hw_consumer); |
1349 | spin_unlock(&adapter->tx_clean_lock); | 1348 | spin_unlock(&adapter->tx_clean_lock); |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 98737ef72936..71daa3d5f114 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -107,9 +107,14 @@ static uint32_t crb_cmd_producer[4] = { | |||
107 | 107 | ||
108 | void | 108 | void |
109 | netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, | 109 | netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, |
110 | struct nx_host_tx_ring *tx_ring, u32 producer) | 110 | struct nx_host_tx_ring *tx_ring) |
111 | { | 111 | { |
112 | NXWR32(adapter, tx_ring->crb_cmd_producer, producer); | 112 | NXWR32(adapter, tx_ring->crb_cmd_producer, tx_ring->producer); |
113 | |||
114 | if (netxen_tx_avail(tx_ring) <= TX_STOP_THRESH) { | ||
115 | netif_stop_queue(adapter->netdev); | ||
116 | smp_mb(); | ||
117 | } | ||
113 | } | 118 | } |
114 | 119 | ||
115 | static uint32_t crb_cmd_consumer[4] = { | 120 | static uint32_t crb_cmd_consumer[4] = { |
@@ -119,9 +124,9 @@ static uint32_t crb_cmd_consumer[4] = { | |||
119 | 124 | ||
120 | static inline void | 125 | static inline void |
121 | netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter, | 126 | netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter, |
122 | struct nx_host_tx_ring *tx_ring, u32 consumer) | 127 | struct nx_host_tx_ring *tx_ring) |
123 | { | 128 | { |
124 | NXWR32(adapter, tx_ring->crb_cmd_consumer, consumer); | 129 | NXWR32(adapter, tx_ring->crb_cmd_consumer, tx_ring->sw_consumer); |
125 | } | 130 | } |
126 | 131 | ||
127 | static uint32_t msi_tgt_status[8] = { | 132 | static uint32_t msi_tgt_status[8] = { |
@@ -900,8 +905,11 @@ netxen_nic_attach(struct netxen_adapter *adapter) | |||
900 | tx_ring->crb_cmd_producer = crb_cmd_producer[adapter->portnum]; | 905 | tx_ring->crb_cmd_producer = crb_cmd_producer[adapter->portnum]; |
901 | tx_ring->crb_cmd_consumer = crb_cmd_consumer[adapter->portnum]; | 906 | tx_ring->crb_cmd_consumer = crb_cmd_consumer[adapter->portnum]; |
902 | 907 | ||
903 | netxen_nic_update_cmd_producer(adapter, tx_ring, 0); | 908 | tx_ring->producer = 0; |
904 | netxen_nic_update_cmd_consumer(adapter, tx_ring, 0); | 909 | tx_ring->sw_consumer = 0; |
910 | |||
911 | netxen_nic_update_cmd_producer(adapter, tx_ring); | ||
912 | netxen_nic_update_cmd_consumer(adapter, tx_ring); | ||
905 | } | 913 | } |
906 | 914 | ||
907 | for (ring = 0; ring < adapter->max_rds_rings; ring++) { | 915 | for (ring = 0; ring < adapter->max_rds_rings; ring++) { |
@@ -1362,7 +1370,7 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1362 | dma_addr_t temp_dma; | 1370 | dma_addr_t temp_dma; |
1363 | int i, k; | 1371 | int i, k; |
1364 | 1372 | ||
1365 | u32 producer, consumer; | 1373 | u32 producer; |
1366 | int frag_count, no_of_desc; | 1374 | int frag_count, no_of_desc; |
1367 | u32 num_txd = tx_ring->num_desc; | 1375 | u32 num_txd = tx_ring->num_desc; |
1368 | bool is_tso = false; | 1376 | bool is_tso = false; |
@@ -1372,15 +1380,13 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1372 | /* 4 fragments per cmd des */ | 1380 | /* 4 fragments per cmd des */ |
1373 | no_of_desc = (frag_count + 3) >> 2; | 1381 | no_of_desc = (frag_count + 3) >> 2; |
1374 | 1382 | ||
1375 | producer = tx_ring->producer; | 1383 | if (unlikely(no_of_desc + 2) > netxen_tx_avail(tx_ring)) { |
1376 | smp_mb(); | ||
1377 | consumer = tx_ring->sw_consumer; | ||
1378 | if ((no_of_desc+2) >= find_diff_among(producer, consumer, num_txd)) { | ||
1379 | netif_stop_queue(netdev); | 1384 | netif_stop_queue(netdev); |
1380 | smp_mb(); | ||
1381 | return NETDEV_TX_BUSY; | 1385 | return NETDEV_TX_BUSY; |
1382 | } | 1386 | } |
1383 | 1387 | ||
1388 | producer = tx_ring->producer; | ||
1389 | |||
1384 | hwdesc = &tx_ring->desc_head[producer]; | 1390 | hwdesc = &tx_ring->desc_head[producer]; |
1385 | netxen_clear_cmddesc((u64 *)hwdesc); | 1391 | netxen_clear_cmddesc((u64 *)hwdesc); |
1386 | pbuf = &tx_ring->cmd_buf_arr[producer]; | 1392 | pbuf = &tx_ring->cmd_buf_arr[producer]; |
@@ -1493,7 +1499,7 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1493 | tx_ring->producer = producer; | 1499 | tx_ring->producer = producer; |
1494 | adapter->stats.txbytes += skb->len; | 1500 | adapter->stats.txbytes += skb->len; |
1495 | 1501 | ||
1496 | netxen_nic_update_cmd_producer(adapter, tx_ring, producer); | 1502 | netxen_nic_update_cmd_producer(adapter, tx_ring); |
1497 | 1503 | ||
1498 | adapter->stats.xmitcalled++; | 1504 | adapter->stats.xmitcalled++; |
1499 | 1505 | ||
diff --git a/drivers/net/niu.c b/drivers/net/niu.c index fa61a12c5e15..d2146d4a10f3 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c | |||
@@ -6376,7 +6376,7 @@ static void niu_set_rx_mode(struct net_device *dev) | |||
6376 | if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 0)) | 6376 | if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 0)) |
6377 | np->flags |= NIU_FLAGS_MCAST; | 6377 | np->flags |= NIU_FLAGS_MCAST; |
6378 | 6378 | ||
6379 | alt_cnt = dev->uc_count; | 6379 | alt_cnt = dev->uc.count; |
6380 | if (alt_cnt > niu_num_alt_addr(np)) { | 6380 | if (alt_cnt > niu_num_alt_addr(np)) { |
6381 | alt_cnt = 0; | 6381 | alt_cnt = 0; |
6382 | np->flags |= NIU_FLAGS_PROMISC; | 6382 | np->flags |= NIU_FLAGS_PROMISC; |
@@ -6385,7 +6385,7 @@ static void niu_set_rx_mode(struct net_device *dev) | |||
6385 | if (alt_cnt) { | 6385 | if (alt_cnt) { |
6386 | int index = 0; | 6386 | int index = 0; |
6387 | 6387 | ||
6388 | list_for_each_entry(ha, &dev->uc_list, list) { | 6388 | list_for_each_entry(ha, &dev->uc.list, list) { |
6389 | err = niu_set_alt_mac(np, index, ha->addr); | 6389 | err = niu_set_alt_mac(np, index, ha->addr); |
6390 | if (err) | 6390 | if (err) |
6391 | printk(KERN_WARNING PFX "%s: Error %d " | 6391 | printk(KERN_WARNING PFX "%s: Error %d " |
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index a2ece89622d6..eba937c46376 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
@@ -244,7 +244,7 @@ EXPORT_SYMBOL(get_phy_device); | |||
244 | 244 | ||
245 | /** | 245 | /** |
246 | * phy_device_register - Register the phy device on the MDIO bus | 246 | * phy_device_register - Register the phy device on the MDIO bus |
247 | * @phy_device: phy_device structure to be added to the MDIO bus | 247 | * @phydev: phy_device structure to be added to the MDIO bus |
248 | */ | 248 | */ |
249 | int phy_device_register(struct phy_device *phydev) | 249 | int phy_device_register(struct phy_device *phydev) |
250 | { | 250 | { |
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 35196faa084e..4e22462684c9 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -3811,22 +3811,11 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev) | |||
3811 | 3811 | ||
3812 | static void rtl8169_net_suspend(struct net_device *dev) | 3812 | static void rtl8169_net_suspend(struct net_device *dev) |
3813 | { | 3813 | { |
3814 | struct rtl8169_private *tp = netdev_priv(dev); | ||
3815 | void __iomem *ioaddr = tp->mmio_addr; | ||
3816 | |||
3817 | if (!netif_running(dev)) | 3814 | if (!netif_running(dev)) |
3818 | return; | 3815 | return; |
3819 | 3816 | ||
3820 | netif_device_detach(dev); | 3817 | netif_device_detach(dev); |
3821 | netif_stop_queue(dev); | 3818 | netif_stop_queue(dev); |
3822 | |||
3823 | spin_lock_irq(&tp->lock); | ||
3824 | |||
3825 | rtl8169_asic_down(ioaddr); | ||
3826 | |||
3827 | rtl8169_rx_missed(dev, ioaddr); | ||
3828 | |||
3829 | spin_unlock_irq(&tp->lock); | ||
3830 | } | 3819 | } |
3831 | 3820 | ||
3832 | #ifdef CONFIG_PM | 3821 | #ifdef CONFIG_PM |
@@ -3876,9 +3865,17 @@ static struct dev_pm_ops rtl8169_pm_ops = { | |||
3876 | static void rtl_shutdown(struct pci_dev *pdev) | 3865 | static void rtl_shutdown(struct pci_dev *pdev) |
3877 | { | 3866 | { |
3878 | struct net_device *dev = pci_get_drvdata(pdev); | 3867 | struct net_device *dev = pci_get_drvdata(pdev); |
3868 | struct rtl8169_private *tp = netdev_priv(dev); | ||
3869 | void __iomem *ioaddr = tp->mmio_addr; | ||
3879 | 3870 | ||
3880 | rtl8169_net_suspend(dev); | 3871 | rtl8169_net_suspend(dev); |
3881 | 3872 | ||
3873 | spin_lock_irq(&tp->lock); | ||
3874 | |||
3875 | rtl8169_asic_down(ioaddr); | ||
3876 | |||
3877 | spin_unlock_irq(&tp->lock); | ||
3878 | |||
3882 | if (system_state == SYSTEM_POWER_OFF) { | 3879 | if (system_state == SYSTEM_POWER_OFF) { |
3883 | pci_wake_from_d3(pdev, true); | 3880 | pci_wake_from_d3(pdev, true); |
3884 | pci_set_power_state(pdev, PCI_D3hot); | 3881 | pci_set_power_state(pdev, PCI_D3hot); |
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index e2247669a495..1f040e8a000b 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c | |||
@@ -1281,7 +1281,7 @@ static u16 sis190_default_phy(struct net_device *dev) | |||
1281 | else if (phy_lan) | 1281 | else if (phy_lan) |
1282 | phy_default = phy_lan; | 1282 | phy_default = phy_lan; |
1283 | else | 1283 | else |
1284 | phy_default = list_entry(&tp->first_phy, | 1284 | phy_default = list_first_entry(&tp->first_phy, |
1285 | struct sis190_phy, list); | 1285 | struct sis190_phy, list); |
1286 | } | 1286 | } |
1287 | 1287 | ||
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 6b5946fe8ae2..7681d28c53d7 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -50,7 +50,7 @@ | |||
50 | #include "sky2.h" | 50 | #include "sky2.h" |
51 | 51 | ||
52 | #define DRV_NAME "sky2" | 52 | #define DRV_NAME "sky2" |
53 | #define DRV_VERSION "1.22" | 53 | #define DRV_VERSION "1.23" |
54 | #define PFX DRV_NAME " " | 54 | #define PFX DRV_NAME " " |
55 | 55 | ||
56 | /* | 56 | /* |
@@ -65,9 +65,9 @@ | |||
65 | #define RX_DEF_PENDING RX_MAX_PENDING | 65 | #define RX_DEF_PENDING RX_MAX_PENDING |
66 | 66 | ||
67 | #define TX_RING_SIZE 512 | 67 | #define TX_RING_SIZE 512 |
68 | #define TX_DEF_PENDING (TX_RING_SIZE - 1) | 68 | #define TX_DEF_PENDING 128 |
69 | #define TX_MIN_PENDING 64 | ||
70 | #define MAX_SKB_TX_LE (4 + (sizeof(dma_addr_t)/sizeof(u32))*MAX_SKB_FRAGS) | 69 | #define MAX_SKB_TX_LE (4 + (sizeof(dma_addr_t)/sizeof(u32))*MAX_SKB_FRAGS) |
70 | #define TX_MIN_PENDING (MAX_SKB_TX_LE+1) | ||
71 | 71 | ||
72 | #define STATUS_RING_SIZE 2048 /* 2 ports * (TX + 2*RX) */ | 72 | #define STATUS_RING_SIZE 2048 /* 2 ports * (TX + 2*RX) */ |
73 | #define STATUS_LE_BYTES (STATUS_RING_SIZE*sizeof(struct sky2_status_le)) | 73 | #define STATUS_LE_BYTES (STATUS_RING_SIZE*sizeof(struct sky2_status_le)) |
@@ -1151,7 +1151,14 @@ stopped: | |||
1151 | 1151 | ||
1152 | /* reset the Rx prefetch unit */ | 1152 | /* reset the Rx prefetch unit */ |
1153 | sky2_write32(hw, Y2_QADDR(rxq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET); | 1153 | sky2_write32(hw, Y2_QADDR(rxq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET); |
1154 | mmiowb(); | 1154 | |
1155 | /* Reset the RAM Buffer receive queue */ | ||
1156 | sky2_write8(hw, RB_ADDR(rxq, RB_CTRL), RB_RST_SET); | ||
1157 | |||
1158 | /* Reset Rx MAC FIFO */ | ||
1159 | sky2_write8(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), GMF_RST_SET); | ||
1160 | |||
1161 | sky2_read8(hw, B0_CTST); | ||
1155 | } | 1162 | } |
1156 | 1163 | ||
1157 | /* Clean out receive buffer area, assumes receiver hardware stopped */ | 1164 | /* Clean out receive buffer area, assumes receiver hardware stopped */ |
@@ -1169,6 +1176,7 @@ static void sky2_rx_clean(struct sky2_port *sky2) | |||
1169 | re->skb = NULL; | 1176 | re->skb = NULL; |
1170 | } | 1177 | } |
1171 | } | 1178 | } |
1179 | skb_queue_purge(&sky2->rx_recycle); | ||
1172 | } | 1180 | } |
1173 | 1181 | ||
1174 | /* Basic MII support */ | 1182 | /* Basic MII support */ |
@@ -1245,6 +1253,12 @@ static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp | |||
1245 | } | 1253 | } |
1246 | #endif | 1254 | #endif |
1247 | 1255 | ||
1256 | /* Amount of required worst case padding in rx buffer */ | ||
1257 | static inline unsigned sky2_rx_pad(const struct sky2_hw *hw) | ||
1258 | { | ||
1259 | return (hw->flags & SKY2_HW_RAM_BUFFER) ? 8 : 2; | ||
1260 | } | ||
1261 | |||
1248 | /* | 1262 | /* |
1249 | * Allocate an skb for receiving. If the MTU is large enough | 1263 | * Allocate an skb for receiving. If the MTU is large enough |
1250 | * make the skb non-linear with a fragment list of pages. | 1264 | * make the skb non-linear with a fragment list of pages. |
@@ -1254,6 +1268,13 @@ static struct sk_buff *sky2_rx_alloc(struct sky2_port *sky2) | |||
1254 | struct sk_buff *skb; | 1268 | struct sk_buff *skb; |
1255 | int i; | 1269 | int i; |
1256 | 1270 | ||
1271 | skb = __skb_dequeue(&sky2->rx_recycle); | ||
1272 | if (!skb) | ||
1273 | skb = netdev_alloc_skb(sky2->netdev, sky2->rx_data_size | ||
1274 | + sky2_rx_pad(sky2->hw)); | ||
1275 | if (!skb) | ||
1276 | goto nomem; | ||
1277 | |||
1257 | if (sky2->hw->flags & SKY2_HW_RAM_BUFFER) { | 1278 | if (sky2->hw->flags & SKY2_HW_RAM_BUFFER) { |
1258 | unsigned char *start; | 1279 | unsigned char *start; |
1259 | /* | 1280 | /* |
@@ -1262,18 +1283,10 @@ static struct sk_buff *sky2_rx_alloc(struct sky2_port *sky2) | |||
1262 | * The buffer returned from netdev_alloc_skb is | 1283 | * The buffer returned from netdev_alloc_skb is |
1263 | * aligned except if slab debugging is enabled. | 1284 | * aligned except if slab debugging is enabled. |
1264 | */ | 1285 | */ |
1265 | skb = netdev_alloc_skb(sky2->netdev, sky2->rx_data_size + 8); | ||
1266 | if (!skb) | ||
1267 | goto nomem; | ||
1268 | start = PTR_ALIGN(skb->data, 8); | 1286 | start = PTR_ALIGN(skb->data, 8); |
1269 | skb_reserve(skb, start - skb->data); | 1287 | skb_reserve(skb, start - skb->data); |
1270 | } else { | 1288 | } else |
1271 | skb = netdev_alloc_skb(sky2->netdev, | ||
1272 | sky2->rx_data_size + NET_IP_ALIGN); | ||
1273 | if (!skb) | ||
1274 | goto nomem; | ||
1275 | skb_reserve(skb, NET_IP_ALIGN); | 1289 | skb_reserve(skb, NET_IP_ALIGN); |
1276 | } | ||
1277 | 1290 | ||
1278 | for (i = 0; i < sky2->rx_nfrags; i++) { | 1291 | for (i = 0; i < sky2->rx_nfrags; i++) { |
1279 | struct page *page = alloc_page(GFP_ATOMIC); | 1292 | struct page *page = alloc_page(GFP_ATOMIC); |
@@ -1350,6 +1363,8 @@ static int sky2_rx_start(struct sky2_port *sky2) | |||
1350 | 1363 | ||
1351 | sky2->rx_data_size = size; | 1364 | sky2->rx_data_size = size; |
1352 | 1365 | ||
1366 | skb_queue_head_init(&sky2->rx_recycle); | ||
1367 | |||
1353 | /* Fill Rx ring */ | 1368 | /* Fill Rx ring */ |
1354 | for (i = 0; i < sky2->rx_pending; i++) { | 1369 | for (i = 0; i < sky2->rx_pending; i++) { |
1355 | re = sky2->rx_ring + i; | 1370 | re = sky2->rx_ring + i; |
@@ -1488,6 +1503,7 @@ static int sky2_up(struct net_device *dev) | |||
1488 | imask = sky2_read32(hw, B0_IMSK); | 1503 | imask = sky2_read32(hw, B0_IMSK); |
1489 | imask |= portirq_msk[port]; | 1504 | imask |= portirq_msk[port]; |
1490 | sky2_write32(hw, B0_IMSK, imask); | 1505 | sky2_write32(hw, B0_IMSK, imask); |
1506 | sky2_read32(hw, B0_IMSK); | ||
1491 | 1507 | ||
1492 | sky2_set_multicast(dev); | 1508 | sky2_set_multicast(dev); |
1493 | 1509 | ||
@@ -1756,14 +1772,22 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) | |||
1756 | } | 1772 | } |
1757 | 1773 | ||
1758 | if (le->ctrl & EOP) { | 1774 | if (le->ctrl & EOP) { |
1775 | struct sk_buff *skb = re->skb; | ||
1776 | |||
1759 | if (unlikely(netif_msg_tx_done(sky2))) | 1777 | if (unlikely(netif_msg_tx_done(sky2))) |
1760 | printk(KERN_DEBUG "%s: tx done %u\n", | 1778 | printk(KERN_DEBUG "%s: tx done %u\n", |
1761 | dev->name, idx); | 1779 | dev->name, idx); |
1762 | 1780 | ||
1763 | dev->stats.tx_packets++; | 1781 | dev->stats.tx_packets++; |
1764 | dev->stats.tx_bytes += re->skb->len; | 1782 | dev->stats.tx_bytes += skb->len; |
1783 | |||
1784 | if (skb_queue_len(&sky2->rx_recycle) < sky2->rx_pending | ||
1785 | && skb_recycle_check(skb, sky2->rx_data_size | ||
1786 | + sky2_rx_pad(sky2->hw))) | ||
1787 | __skb_queue_head(&sky2->rx_recycle, skb); | ||
1788 | else | ||
1789 | dev_kfree_skb_any(skb); | ||
1765 | 1790 | ||
1766 | dev_kfree_skb_any(re->skb); | ||
1767 | sky2->tx_next = RING_NEXT(idx, TX_RING_SIZE); | 1791 | sky2->tx_next = RING_NEXT(idx, TX_RING_SIZE); |
1768 | } | 1792 | } |
1769 | } | 1793 | } |
@@ -1805,10 +1829,10 @@ static int sky2_down(struct net_device *dev) | |||
1805 | imask = sky2_read32(hw, B0_IMSK); | 1829 | imask = sky2_read32(hw, B0_IMSK); |
1806 | imask &= ~portirq_msk[port]; | 1830 | imask &= ~portirq_msk[port]; |
1807 | sky2_write32(hw, B0_IMSK, imask); | 1831 | sky2_write32(hw, B0_IMSK, imask); |
1832 | sky2_read32(hw, B0_IMSK); | ||
1808 | 1833 | ||
1809 | synchronize_irq(hw->pdev->irq); | 1834 | /* Force flow control off */ |
1810 | 1835 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); | |
1811 | sky2_gmac_reset(hw, port); | ||
1812 | 1836 | ||
1813 | /* Stop transmitter */ | 1837 | /* Stop transmitter */ |
1814 | sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_STOP); | 1838 | sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_STOP); |
@@ -1821,9 +1845,6 @@ static int sky2_down(struct net_device *dev) | |||
1821 | ctrl &= ~(GM_GPCR_TX_ENA | GM_GPCR_RX_ENA); | 1845 | ctrl &= ~(GM_GPCR_TX_ENA | GM_GPCR_RX_ENA); |
1822 | gma_write16(hw, port, GM_GP_CTRL, ctrl); | 1846 | gma_write16(hw, port, GM_GP_CTRL, ctrl); |
1823 | 1847 | ||
1824 | /* Make sure no packets are pending */ | ||
1825 | napi_synchronize(&hw->napi); | ||
1826 | |||
1827 | sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); | 1848 | sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); |
1828 | 1849 | ||
1829 | /* Workaround shared GMAC reset */ | 1850 | /* Workaround shared GMAC reset */ |
@@ -1854,6 +1875,15 @@ static int sky2_down(struct net_device *dev) | |||
1854 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); | 1875 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); |
1855 | sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); | 1876 | sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); |
1856 | 1877 | ||
1878 | /* Force any delayed status interrrupt and NAPI */ | ||
1879 | sky2_write32(hw, STAT_LEV_TIMER_CNT, 0); | ||
1880 | sky2_write32(hw, STAT_TX_TIMER_CNT, 0); | ||
1881 | sky2_write32(hw, STAT_ISR_TIMER_CNT, 0); | ||
1882 | sky2_read8(hw, STAT_ISR_TIMER_CTRL); | ||
1883 | |||
1884 | synchronize_irq(hw->pdev->irq); | ||
1885 | napi_synchronize(&hw->napi); | ||
1886 | |||
1857 | sky2_phy_power_down(hw, port); | 1887 | sky2_phy_power_down(hw, port); |
1858 | 1888 | ||
1859 | /* turn off LED's */ | 1889 | /* turn off LED's */ |
@@ -2343,11 +2373,45 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last) | |||
2343 | } | 2373 | } |
2344 | } | 2374 | } |
2345 | 2375 | ||
2376 | static inline void sky2_skb_rx(const struct sky2_port *sky2, | ||
2377 | u32 status, struct sk_buff *skb) | ||
2378 | { | ||
2379 | #ifdef SKY2_VLAN_TAG_USED | ||
2380 | u16 vlan_tag = be16_to_cpu(sky2->rx_tag); | ||
2381 | if (sky2->vlgrp && (status & GMR_FS_VLAN)) { | ||
2382 | if (skb->ip_summed == CHECKSUM_NONE) | ||
2383 | vlan_hwaccel_receive_skb(skb, sky2->vlgrp, vlan_tag); | ||
2384 | else | ||
2385 | vlan_gro_receive(&sky2->hw->napi, sky2->vlgrp, | ||
2386 | vlan_tag, skb); | ||
2387 | return; | ||
2388 | } | ||
2389 | #endif | ||
2390 | if (skb->ip_summed == CHECKSUM_NONE) | ||
2391 | netif_receive_skb(skb); | ||
2392 | else | ||
2393 | napi_gro_receive(&sky2->hw->napi, skb); | ||
2394 | } | ||
2395 | |||
2396 | static inline void sky2_rx_done(struct sky2_hw *hw, unsigned port, | ||
2397 | unsigned packets, unsigned bytes) | ||
2398 | { | ||
2399 | if (packets) { | ||
2400 | struct net_device *dev = hw->dev[port]; | ||
2401 | |||
2402 | dev->stats.rx_packets += packets; | ||
2403 | dev->stats.rx_bytes += bytes; | ||
2404 | dev->last_rx = jiffies; | ||
2405 | sky2_rx_update(netdev_priv(dev), rxqaddr[port]); | ||
2406 | } | ||
2407 | } | ||
2408 | |||
2346 | /* Process status response ring */ | 2409 | /* Process status response ring */ |
2347 | static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | 2410 | static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) |
2348 | { | 2411 | { |
2349 | int work_done = 0; | 2412 | int work_done = 0; |
2350 | unsigned rx[2] = { 0, 0 }; | 2413 | unsigned int total_bytes[2] = { 0 }; |
2414 | unsigned int total_packets[2] = { 0 }; | ||
2351 | 2415 | ||
2352 | rmb(); | 2416 | rmb(); |
2353 | do { | 2417 | do { |
@@ -2374,7 +2438,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | |||
2374 | le->opcode = 0; | 2438 | le->opcode = 0; |
2375 | switch (opcode & ~HW_OWNER) { | 2439 | switch (opcode & ~HW_OWNER) { |
2376 | case OP_RXSTAT: | 2440 | case OP_RXSTAT: |
2377 | ++rx[port]; | 2441 | total_packets[port]++; |
2442 | total_bytes[port] += length; | ||
2378 | skb = sky2_receive(dev, length, status); | 2443 | skb = sky2_receive(dev, length, status); |
2379 | if (unlikely(!skb)) { | 2444 | if (unlikely(!skb)) { |
2380 | dev->stats.rx_dropped++; | 2445 | dev->stats.rx_dropped++; |
@@ -2392,18 +2457,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | |||
2392 | } | 2457 | } |
2393 | 2458 | ||
2394 | skb->protocol = eth_type_trans(skb, dev); | 2459 | skb->protocol = eth_type_trans(skb, dev); |
2395 | dev->stats.rx_packets++; | ||
2396 | dev->stats.rx_bytes += skb->len; | ||
2397 | dev->last_rx = jiffies; | ||
2398 | 2460 | ||
2399 | #ifdef SKY2_VLAN_TAG_USED | 2461 | sky2_skb_rx(sky2, status, skb); |
2400 | if (sky2->vlgrp && (status & GMR_FS_VLAN)) { | ||
2401 | vlan_hwaccel_receive_skb(skb, | ||
2402 | sky2->vlgrp, | ||
2403 | be16_to_cpu(sky2->rx_tag)); | ||
2404 | } else | ||
2405 | #endif | ||
2406 | netif_receive_skb(skb); | ||
2407 | 2462 | ||
2408 | /* Stop after net poll weight */ | 2463 | /* Stop after net poll weight */ |
2409 | if (++work_done >= to_do) | 2464 | if (++work_done >= to_do) |
@@ -2473,11 +2528,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | |||
2473 | sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); | 2528 | sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); |
2474 | 2529 | ||
2475 | exit_loop: | 2530 | exit_loop: |
2476 | if (rx[0]) | 2531 | sky2_rx_done(hw, 0, total_packets[0], total_bytes[0]); |
2477 | sky2_rx_update(netdev_priv(hw->dev[0]), Q_R1); | 2532 | sky2_rx_done(hw, 1, total_packets[1], total_bytes[1]); |
2478 | |||
2479 | if (rx[1]) | ||
2480 | sky2_rx_update(netdev_priv(hw->dev[1]), Q_R2); | ||
2481 | 2533 | ||
2482 | return work_done; | 2534 | return work_done; |
2483 | } | 2535 | } |
@@ -4364,6 +4416,22 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
4364 | goto err_out; | 4416 | goto err_out; |
4365 | } | 4417 | } |
4366 | 4418 | ||
4419 | /* Get configuration information | ||
4420 | * Note: only regular PCI config access once to test for HW issues | ||
4421 | * other PCI access through shared memory for speed and to | ||
4422 | * avoid MMCONFIG problems. | ||
4423 | */ | ||
4424 | err = pci_read_config_dword(pdev, PCI_DEV_REG2, ®); | ||
4425 | if (err) { | ||
4426 | dev_err(&pdev->dev, "PCI read config failed\n"); | ||
4427 | goto err_out; | ||
4428 | } | ||
4429 | |||
4430 | if (~reg == 0) { | ||
4431 | dev_err(&pdev->dev, "PCI configuration read error\n"); | ||
4432 | goto err_out; | ||
4433 | } | ||
4434 | |||
4367 | err = pci_request_regions(pdev, DRV_NAME); | 4435 | err = pci_request_regions(pdev, DRV_NAME); |
4368 | if (err) { | 4436 | if (err) { |
4369 | dev_err(&pdev->dev, "cannot obtain PCI resources\n"); | 4437 | dev_err(&pdev->dev, "cannot obtain PCI resources\n"); |
@@ -4389,21 +4457,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
4389 | } | 4457 | } |
4390 | } | 4458 | } |
4391 | 4459 | ||
4392 | /* Get configuration information | ||
4393 | * Note: only regular PCI config access once to test for HW issues | ||
4394 | * other PCI access through shared memory for speed and to | ||
4395 | * avoid MMCONFIG problems. | ||
4396 | */ | ||
4397 | err = pci_read_config_dword(pdev, PCI_DEV_REG2, ®); | ||
4398 | if (err) { | ||
4399 | dev_err(&pdev->dev, "PCI read config failed\n"); | ||
4400 | goto err_out_free_regions; | ||
4401 | } | ||
4402 | |||
4403 | /* size of available VPD, only impact sysfs */ | ||
4404 | err = pci_vpd_truncate(pdev, 1ul << (((reg & PCI_VPD_ROM_SZ) >> 14) + 8)); | ||
4405 | if (err) | ||
4406 | dev_warn(&pdev->dev, "Can't set VPD size\n"); | ||
4407 | 4460 | ||
4408 | #ifdef __BIG_ENDIAN | 4461 | #ifdef __BIG_ENDIAN |
4409 | /* The sk98lin vendor driver uses hardware byte swapping but | 4462 | /* The sk98lin vendor driver uses hardware byte swapping but |
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 92fb24b27d45..b5549c9e5107 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h | |||
@@ -2028,6 +2028,7 @@ struct sky2_port { | |||
2028 | u16 rx_pending; | 2028 | u16 rx_pending; |
2029 | u16 rx_data_size; | 2029 | u16 rx_data_size; |
2030 | u16 rx_nfrags; | 2030 | u16 rx_nfrags; |
2031 | struct sk_buff_head rx_recycle; | ||
2031 | 2032 | ||
2032 | #ifdef SKY2_VLAN_TAG_USED | 2033 | #ifdef SKY2_VLAN_TAG_USED |
2033 | u16 rx_tag; | 2034 | u16 rx_tag; |
diff --git a/drivers/net/sonic.c b/drivers/net/sonic.c index e4255d829380..753a1fba4609 100644 --- a/drivers/net/sonic.c +++ b/drivers/net/sonic.c | |||
@@ -223,7 +223,7 @@ static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
223 | if (!laddr) { | 223 | if (!laddr) { |
224 | printk(KERN_ERR "%s: failed to map tx DMA buffer.\n", dev->name); | 224 | printk(KERN_ERR "%s: failed to map tx DMA buffer.\n", dev->name); |
225 | dev_kfree_skb(skb); | 225 | dev_kfree_skb(skb); |
226 | return NETDEV_TX_BUSY | 226 | return NETDEV_TX_BUSY; |
227 | } | 227 | } |
228 | 228 | ||
229 | sonic_tda_put(dev, entry, SONIC_TD_STATUS, 0); /* clear status */ | 229 | sonic_tda_put(dev, entry, SONIC_TD_STATUS, 0); /* clear status */ |
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index e2f2e91cfdd2..40c6eba775ce 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c | |||
@@ -65,8 +65,6 @@ | |||
65 | 65 | ||
66 | static DEFINE_SPINLOCK(ugeth_lock); | 66 | static DEFINE_SPINLOCK(ugeth_lock); |
67 | 67 | ||
68 | static void uec_configure_serdes(struct net_device *dev); | ||
69 | |||
70 | static struct { | 68 | static struct { |
71 | u32 msg_enable; | 69 | u32 msg_enable; |
72 | } debug = { -1 }; | 70 | } debug = { -1 }; |
@@ -1536,6 +1534,49 @@ static void adjust_link(struct net_device *dev) | |||
1536 | spin_unlock_irqrestore(&ugeth->lock, flags); | 1534 | spin_unlock_irqrestore(&ugeth->lock, flags); |
1537 | } | 1535 | } |
1538 | 1536 | ||
1537 | /* Initialize TBI PHY interface for communicating with the | ||
1538 | * SERDES lynx PHY on the chip. We communicate with this PHY | ||
1539 | * through the MDIO bus on each controller, treating it as a | ||
1540 | * "normal" PHY at the address found in the UTBIPA register. We assume | ||
1541 | * that the UTBIPA register is valid. Either the MDIO bus code will set | ||
1542 | * it to a value that doesn't conflict with other PHYs on the bus, or the | ||
1543 | * value doesn't matter, as there are no other PHYs on the bus. | ||
1544 | */ | ||
1545 | static void uec_configure_serdes(struct net_device *dev) | ||
1546 | { | ||
1547 | struct ucc_geth_private *ugeth = netdev_priv(dev); | ||
1548 | struct ucc_geth_info *ug_info = ugeth->ug_info; | ||
1549 | struct phy_device *tbiphy; | ||
1550 | |||
1551 | if (!ug_info->tbi_node) { | ||
1552 | dev_warn(&dev->dev, "SGMII mode requires that the device " | ||
1553 | "tree specify a tbi-handle\n"); | ||
1554 | return; | ||
1555 | } | ||
1556 | |||
1557 | tbiphy = of_phy_find_device(ug_info->tbi_node); | ||
1558 | if (!tbiphy) { | ||
1559 | dev_err(&dev->dev, "error: Could not get TBI device\n"); | ||
1560 | return; | ||
1561 | } | ||
1562 | |||
1563 | /* | ||
1564 | * If the link is already up, we must already be ok, and don't need to | ||
1565 | * configure and reset the TBI<->SerDes link. Maybe U-Boot configured | ||
1566 | * everything for us? Resetting it takes the link down and requires | ||
1567 | * several seconds for it to come back. | ||
1568 | */ | ||
1569 | if (phy_read(tbiphy, ENET_TBI_MII_SR) & TBISR_LSTATUS) | ||
1570 | return; | ||
1571 | |||
1572 | /* Single clk mode, mii mode off(for serdes communication) */ | ||
1573 | phy_write(tbiphy, ENET_TBI_MII_ANA, TBIANA_SETTINGS); | ||
1574 | |||
1575 | phy_write(tbiphy, ENET_TBI_MII_TBICON, TBICON_CLK_SELECT); | ||
1576 | |||
1577 | phy_write(tbiphy, ENET_TBI_MII_CR, TBICR_SETTINGS); | ||
1578 | } | ||
1579 | |||
1539 | /* Configure the PHY for dev. | 1580 | /* Configure the PHY for dev. |
1540 | * returns 0 if success. -1 if failure | 1581 | * returns 0 if success. -1 if failure |
1541 | */ | 1582 | */ |
@@ -1577,41 +1618,7 @@ static int init_phy(struct net_device *dev) | |||
1577 | return 0; | 1618 | return 0; |
1578 | } | 1619 | } |
1579 | 1620 | ||
1580 | /* Initialize TBI PHY interface for communicating with the | ||
1581 | * SERDES lynx PHY on the chip. We communicate with this PHY | ||
1582 | * through the MDIO bus on each controller, treating it as a | ||
1583 | * "normal" PHY at the address found in the UTBIPA register. We assume | ||
1584 | * that the UTBIPA register is valid. Either the MDIO bus code will set | ||
1585 | * it to a value that doesn't conflict with other PHYs on the bus, or the | ||
1586 | * value doesn't matter, as there are no other PHYs on the bus. | ||
1587 | */ | ||
1588 | static void uec_configure_serdes(struct net_device *dev) | ||
1589 | { | ||
1590 | struct ucc_geth_private *ugeth = netdev_priv(dev); | ||
1591 | |||
1592 | if (!ugeth->tbiphy) { | ||
1593 | printk(KERN_WARNING "SGMII mode requires that the device " | ||
1594 | "tree specify a tbi-handle\n"); | ||
1595 | return; | ||
1596 | } | ||
1597 | 1621 | ||
1598 | /* | ||
1599 | * If the link is already up, we must already be ok, and don't need to | ||
1600 | * configure and reset the TBI<->SerDes link. Maybe U-Boot configured | ||
1601 | * everything for us? Resetting it takes the link down and requires | ||
1602 | * several seconds for it to come back. | ||
1603 | */ | ||
1604 | if (phy_read(ugeth->tbiphy, ENET_TBI_MII_SR) & TBISR_LSTATUS) | ||
1605 | return; | ||
1606 | |||
1607 | /* Single clk mode, mii mode off(for serdes communication) */ | ||
1608 | phy_write(ugeth->tbiphy, ENET_TBI_MII_ANA, TBIANA_SETTINGS); | ||
1609 | |||
1610 | phy_write(ugeth->tbiphy, ENET_TBI_MII_TBICON, TBICON_CLK_SELECT); | ||
1611 | |||
1612 | phy_write(ugeth->tbiphy, ENET_TBI_MII_CR, TBICR_SETTINGS); | ||
1613 | |||
1614 | } | ||
1615 | 1622 | ||
1616 | static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth) | 1623 | static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth) |
1617 | { | 1624 | { |
@@ -3711,6 +3718,9 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma | |||
3711 | } | 3718 | } |
3712 | ug_info->phy_node = phy; | 3719 | ug_info->phy_node = phy; |
3713 | 3720 | ||
3721 | /* Find the TBI PHY node. If it's not there, we don't support SGMII */ | ||
3722 | ug_info->tbi_node = of_parse_phandle(np, "tbi-handle", 0); | ||
3723 | |||
3714 | /* get the phy interface type, or default to MII */ | 3724 | /* get the phy interface type, or default to MII */ |
3715 | prop = of_get_property(np, "phy-connection-type", NULL); | 3725 | prop = of_get_property(np, "phy-connection-type", NULL); |
3716 | if (!prop) { | 3726 | if (!prop) { |
@@ -3818,37 +3828,6 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma | |||
3818 | ugeth->ndev = dev; | 3828 | ugeth->ndev = dev; |
3819 | ugeth->node = np; | 3829 | ugeth->node = np; |
3820 | 3830 | ||
3821 | /* Find the TBI PHY. If it's not there, we don't support SGMII */ | ||
3822 | ph = of_get_property(np, "tbi-handle", NULL); | ||
3823 | if (ph) { | ||
3824 | struct device_node *tbi = of_find_node_by_phandle(*ph); | ||
3825 | struct of_device *ofdev; | ||
3826 | struct mii_bus *bus; | ||
3827 | const unsigned int *id; | ||
3828 | |||
3829 | if (!tbi) | ||
3830 | return 0; | ||
3831 | |||
3832 | mdio = of_get_parent(tbi); | ||
3833 | if (!mdio) | ||
3834 | return 0; | ||
3835 | |||
3836 | ofdev = of_find_device_by_node(mdio); | ||
3837 | |||
3838 | of_node_put(mdio); | ||
3839 | |||
3840 | id = of_get_property(tbi, "reg", NULL); | ||
3841 | if (!id) | ||
3842 | return 0; | ||
3843 | of_node_put(tbi); | ||
3844 | |||
3845 | bus = dev_get_drvdata(&ofdev->dev); | ||
3846 | if (!bus) | ||
3847 | return 0; | ||
3848 | |||
3849 | ugeth->tbiphy = bus->phy_map[*id]; | ||
3850 | } | ||
3851 | |||
3852 | return 0; | 3831 | return 0; |
3853 | } | 3832 | } |
3854 | 3833 | ||
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h index 5beba4c14532..195ab267ead7 100644 --- a/drivers/net/ucc_geth.h +++ b/drivers/net/ucc_geth.h | |||
@@ -1125,6 +1125,7 @@ struct ucc_geth_info { | |||
1125 | u16 pausePeriod; | 1125 | u16 pausePeriod; |
1126 | u16 extensionField; | 1126 | u16 extensionField; |
1127 | struct device_node *phy_node; | 1127 | struct device_node *phy_node; |
1128 | struct device_node *tbi_node; | ||
1128 | u8 weightfactor[NUM_TX_QUEUES]; | 1129 | u8 weightfactor[NUM_TX_QUEUES]; |
1129 | u8 interruptcoalescingmaxvalue[NUM_RX_QUEUES]; | 1130 | u8 interruptcoalescingmaxvalue[NUM_RX_QUEUES]; |
1130 | u8 l2qt[UCC_GETH_VLAN_PRIORITY_MAX]; | 1131 | u8 l2qt[UCC_GETH_VLAN_PRIORITY_MAX]; |
@@ -1213,7 +1214,6 @@ struct ucc_geth_private { | |||
1213 | 1214 | ||
1214 | struct ugeth_mii_info *mii_info; | 1215 | struct ugeth_mii_info *mii_info; |
1215 | struct phy_device *phydev; | 1216 | struct phy_device *phydev; |
1216 | struct phy_device *tbiphy; | ||
1217 | phy_interface_t phy_interface; | 1217 | phy_interface_t phy_interface; |
1218 | int max_speed; | 1218 | int max_speed; |
1219 | uint32_t msg_enable; | 1219 | uint32_t msg_enable; |
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index e2a7725e567e..b02f7adff5dc 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c | |||
@@ -989,8 +989,10 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi | |||
989 | if (ret < 0) | 989 | if (ret < 0) |
990 | goto err_iounmap; | 990 | goto err_iounmap; |
991 | 991 | ||
992 | if (velocity_get_link(dev)) | 992 | if (!velocity_get_link(dev)) { |
993 | netif_carrier_off(dev); | 993 | netif_carrier_off(dev); |
994 | vptr->mii_status |= VELOCITY_LINK_FAIL; | ||
995 | } | ||
994 | 996 | ||
995 | velocity_print_info(vptr); | 997 | velocity_print_info(vptr); |
996 | pci_set_drvdata(pdev, dev); | 998 | pci_set_drvdata(pdev, dev); |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 52198f6797a4..2a6e81d5b579 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -709,7 +709,7 @@ static void virtnet_set_rx_mode(struct net_device *dev) | |||
709 | allmulti ? "en" : "dis"); | 709 | allmulti ? "en" : "dis"); |
710 | 710 | ||
711 | /* MAC filter - use one buffer for both lists */ | 711 | /* MAC filter - use one buffer for both lists */ |
712 | mac_data = buf = kzalloc(((dev->uc_count + dev->mc_count) * ETH_ALEN) + | 712 | mac_data = buf = kzalloc(((dev->uc.count + dev->mc_count) * ETH_ALEN) + |
713 | (2 * sizeof(mac_data->entries)), GFP_ATOMIC); | 713 | (2 * sizeof(mac_data->entries)), GFP_ATOMIC); |
714 | if (!buf) { | 714 | if (!buf) { |
715 | dev_warn(&dev->dev, "No memory for MAC address buffer\n"); | 715 | dev_warn(&dev->dev, "No memory for MAC address buffer\n"); |
@@ -719,16 +719,16 @@ static void virtnet_set_rx_mode(struct net_device *dev) | |||
719 | sg_init_table(sg, 2); | 719 | sg_init_table(sg, 2); |
720 | 720 | ||
721 | /* Store the unicast list and count in the front of the buffer */ | 721 | /* Store the unicast list and count in the front of the buffer */ |
722 | mac_data->entries = dev->uc_count; | 722 | mac_data->entries = dev->uc.count; |
723 | i = 0; | 723 | i = 0; |
724 | list_for_each_entry(ha, &dev->uc_list, list) | 724 | list_for_each_entry(ha, &dev->uc.list, list) |
725 | memcpy(&mac_data->macs[i++][0], ha->addr, ETH_ALEN); | 725 | memcpy(&mac_data->macs[i++][0], ha->addr, ETH_ALEN); |
726 | 726 | ||
727 | sg_set_buf(&sg[0], mac_data, | 727 | sg_set_buf(&sg[0], mac_data, |
728 | sizeof(mac_data->entries) + (dev->uc_count * ETH_ALEN)); | 728 | sizeof(mac_data->entries) + (dev->uc.count * ETH_ALEN)); |
729 | 729 | ||
730 | /* multicast list and count fill the end */ | 730 | /* multicast list and count fill the end */ |
731 | mac_data = (void *)&mac_data->macs[dev->uc_count][0]; | 731 | mac_data = (void *)&mac_data->macs[dev->uc.count][0]; |
732 | 732 | ||
733 | mac_data->entries = dev->mc_count; | 733 | mac_data->entries = dev->mc_count; |
734 | addr = dev->mc_list; | 734 | addr = dev->mc_list; |
diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c index 26cde573af43..58d2551c78ed 100644 --- a/drivers/net/vxge/vxge-config.c +++ b/drivers/net/vxge/vxge-config.c | |||
@@ -454,7 +454,7 @@ __vxge_hw_verify_pci_e_info(struct __vxge_hw_device *hldev) | |||
454 | return VXGE_HW_OK; | 454 | return VXGE_HW_OK; |
455 | } | 455 | } |
456 | 456 | ||
457 | static enum vxge_hw_status | 457 | enum vxge_hw_status |
458 | __vxge_hw_device_is_privilaged(struct __vxge_hw_device *hldev) | 458 | __vxge_hw_device_is_privilaged(struct __vxge_hw_device *hldev) |
459 | { | 459 | { |
460 | if ((hldev->host_type == VXGE_HW_NO_MR_NO_SR_NORMAL_FUNCTION || | 460 | if ((hldev->host_type == VXGE_HW_NO_MR_NO_SR_NORMAL_FUNCTION || |
@@ -676,10 +676,12 @@ enum vxge_hw_status __vxge_hw_device_initialize(struct __vxge_hw_device *hldev) | |||
676 | { | 676 | { |
677 | enum vxge_hw_status status = VXGE_HW_OK; | 677 | enum vxge_hw_status status = VXGE_HW_OK; |
678 | 678 | ||
679 | /* Validate the pci-e link width and speed */ | 679 | if (VXGE_HW_OK == __vxge_hw_device_is_privilaged(hldev)) { |
680 | status = __vxge_hw_verify_pci_e_info(hldev); | 680 | /* Validate the pci-e link width and speed */ |
681 | if (status != VXGE_HW_OK) | 681 | status = __vxge_hw_verify_pci_e_info(hldev); |
682 | goto exit; | 682 | if (status != VXGE_HW_OK) |
683 | goto exit; | ||
684 | } | ||
683 | 685 | ||
684 | vxge_hw_wrr_rebalance(hldev); | 686 | vxge_hw_wrr_rebalance(hldev); |
685 | exit: | 687 | exit: |
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index 6c838b3e063a..6034497536a4 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c | |||
@@ -4203,6 +4203,16 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4203 | max_vpath_supported++; | 4203 | max_vpath_supported++; |
4204 | } | 4204 | } |
4205 | 4205 | ||
4206 | /* Enable SRIOV mode, if firmware has SRIOV support and if it is a PF */ | ||
4207 | if ((VXGE_HW_FUNCTION_MODE_SRIOV == | ||
4208 | ll_config.device_hw_info.function_mode) && | ||
4209 | (max_config_dev > 1) && (pdev->is_physfn)) { | ||
4210 | ret = pci_enable_sriov(pdev, max_config_dev - 1); | ||
4211 | if (ret) | ||
4212 | vxge_debug_ll_config(VXGE_ERR, | ||
4213 | "Failed to enable SRIOV: %d \n", ret); | ||
4214 | } | ||
4215 | |||
4206 | /* | 4216 | /* |
4207 | * Configure vpaths and get driver configured number of vpaths | 4217 | * Configure vpaths and get driver configured number of vpaths |
4208 | * which is less than or equal to the maximum vpaths per function. | 4218 | * which is less than or equal to the maximum vpaths per function. |
@@ -4366,6 +4376,7 @@ _exit6: | |||
4366 | 4376 | ||
4367 | vxge_device_unregister(hldev); | 4377 | vxge_device_unregister(hldev); |
4368 | _exit5: | 4378 | _exit5: |
4379 | pci_disable_sriov(pdev); | ||
4369 | vxge_hw_device_terminate(hldev); | 4380 | vxge_hw_device_terminate(hldev); |
4370 | _exit4: | 4381 | _exit4: |
4371 | iounmap(attr.bar1); | 4382 | iounmap(attr.bar1); |
@@ -4429,6 +4440,8 @@ vxge_remove(struct pci_dev *pdev) | |||
4429 | iounmap(vdev->bar0); | 4440 | iounmap(vdev->bar0); |
4430 | iounmap(vdev->bar1); | 4441 | iounmap(vdev->bar1); |
4431 | 4442 | ||
4443 | pci_disable_sriov(pdev); | ||
4444 | |||
4432 | /* we are safe to free it now */ | 4445 | /* we are safe to free it now */ |
4433 | free_netdev(dev); | 4446 | free_netdev(dev); |
4434 | 4447 | ||
diff --git a/drivers/net/vxge/vxge-version.h b/drivers/net/vxge/vxge-version.h index 7da02c545ed5..82786ffb7dd9 100644 --- a/drivers/net/vxge/vxge-version.h +++ b/drivers/net/vxge/vxge-version.h | |||
@@ -17,7 +17,7 @@ | |||
17 | 17 | ||
18 | #define VXGE_VERSION_MAJOR "2" | 18 | #define VXGE_VERSION_MAJOR "2" |
19 | #define VXGE_VERSION_MINOR "0" | 19 | #define VXGE_VERSION_MINOR "0" |
20 | #define VXGE_VERSION_FIX "1" | 20 | #define VXGE_VERSION_FIX "4" |
21 | #define VXGE_VERSION_BUILD "17129" | 21 | #define VXGE_VERSION_BUILD "17795" |
22 | #define VXGE_VERSION_FOR "k" | 22 | #define VXGE_VERSION_FOR "k" |
23 | #endif | 23 | #endif |
diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c index 2dd78d20eb05..aff4f6bdf3d5 100644 --- a/drivers/net/wan/lapbether.c +++ b/drivers/net/wan/lapbether.c | |||
@@ -149,46 +149,40 @@ static int lapbeth_data_indication(struct net_device *dev, struct sk_buff *skb) | |||
149 | */ | 149 | */ |
150 | static int lapbeth_xmit(struct sk_buff *skb, struct net_device *dev) | 150 | static int lapbeth_xmit(struct sk_buff *skb, struct net_device *dev) |
151 | { | 151 | { |
152 | int err = -ENODEV; | 152 | int err; |
153 | 153 | ||
154 | /* | 154 | /* |
155 | * Just to be *really* sure not to send anything if the interface | 155 | * Just to be *really* sure not to send anything if the interface |
156 | * is down, the ethernet device may have gone. | 156 | * is down, the ethernet device may have gone. |
157 | */ | 157 | */ |
158 | if (!netif_running(dev)) { | 158 | if (!netif_running(dev)) |
159 | goto drop; | 159 | goto drop; |
160 | } | ||
161 | 160 | ||
162 | switch (skb->data[0]) { | 161 | switch (skb->data[0]) { |
163 | case 0x00: | 162 | case 0x00: |
164 | err = 0; | ||
165 | break; | 163 | break; |
166 | case 0x01: | 164 | case 0x01: |
167 | if ((err = lapb_connect_request(dev)) != LAPB_OK) | 165 | if ((err = lapb_connect_request(dev)) != LAPB_OK) |
168 | printk(KERN_ERR "lapbeth: lapb_connect_request " | 166 | printk(KERN_ERR "lapbeth: lapb_connect_request " |
169 | "error: %d\n", err); | 167 | "error: %d\n", err); |
170 | goto drop_ok; | 168 | goto drop; |
171 | case 0x02: | 169 | case 0x02: |
172 | if ((err = lapb_disconnect_request(dev)) != LAPB_OK) | 170 | if ((err = lapb_disconnect_request(dev)) != LAPB_OK) |
173 | printk(KERN_ERR "lapbeth: lapb_disconnect_request " | 171 | printk(KERN_ERR "lapbeth: lapb_disconnect_request " |
174 | "err: %d\n", err); | 172 | "err: %d\n", err); |
175 | /* Fall thru */ | 173 | /* Fall thru */ |
176 | default: | 174 | default: |
177 | goto drop_ok; | 175 | goto drop; |
178 | } | 176 | } |
179 | 177 | ||
180 | skb_pull(skb, 1); | 178 | skb_pull(skb, 1); |
181 | 179 | ||
182 | if ((err = lapb_data_request(dev, skb)) != LAPB_OK) { | 180 | if ((err = lapb_data_request(dev, skb)) != LAPB_OK) { |
183 | printk(KERN_ERR "lapbeth: lapb_data_request error - %d\n", err); | 181 | printk(KERN_ERR "lapbeth: lapb_data_request error - %d\n", err); |
184 | err = -ENOMEM; | ||
185 | goto drop; | 182 | goto drop; |
186 | } | 183 | } |
187 | err = 0; | ||
188 | out: | 184 | out: |
189 | return err; | 185 | return NETDEV_TX_OK; |
190 | drop_ok: | ||
191 | err = 0; | ||
192 | drop: | 186 | drop: |
193 | kfree_skb(skb); | 187 | kfree_skb(skb); |
194 | goto out; | 188 | goto out; |
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index ec35503f6a40..2942f13c9c4a 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c | |||
@@ -733,8 +733,9 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval) | |||
733 | /* | 733 | /* |
734 | * Set the beacon register and enable all timers. | 734 | * Set the beacon register and enable all timers. |
735 | */ | 735 | */ |
736 | /* When in AP mode zero timer0 to start TSF */ | 736 | /* When in AP or Mesh Point mode zero timer0 to start TSF */ |
737 | if (ah->ah_op_mode == NL80211_IFTYPE_AP) | 737 | if (ah->ah_op_mode == NL80211_IFTYPE_AP || |
738 | ah->ah_op_mode == NL80211_IFTYPE_MESH_POINT) | ||
738 | ath5k_hw_reg_write(ah, 0, AR5K_TIMER0); | 739 | ath5k_hw_reg_write(ah, 0, AR5K_TIMER0); |
739 | 740 | ||
740 | ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0); | 741 | ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0); |
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index 0ed1ac312aa6..2d79610bce12 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig | |||
@@ -1,7 +1,6 @@ | |||
1 | config ATH9K | 1 | config ATH9K |
2 | tristate "Atheros 802.11n wireless cards support" | 2 | tristate "Atheros 802.11n wireless cards support" |
3 | depends on PCI && MAC80211 && WLAN_80211 | 3 | depends on PCI && MAC80211 && WLAN_80211 |
4 | depends on RFKILL || RFKILL=n | ||
5 | select ATH_COMMON | 4 | select ATH_COMMON |
6 | select MAC80211_LEDS | 5 | select MAC80211_LEDS |
7 | select LEDS_CLASS | 6 | select LEDS_CLASS |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 515880aa2116..5efc9345ca0d 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/device.h> | 21 | #include <linux/device.h> |
22 | #include <net/mac80211.h> | 22 | #include <net/mac80211.h> |
23 | #include <linux/leds.h> | 23 | #include <linux/leds.h> |
24 | #include <linux/rfkill.h> | ||
25 | 24 | ||
26 | #include "hw.h" | 25 | #include "hw.h" |
27 | #include "rc.h" | 26 | #include "rc.h" |
@@ -460,12 +459,6 @@ struct ath_led { | |||
460 | bool registered; | 459 | bool registered; |
461 | }; | 460 | }; |
462 | 461 | ||
463 | struct ath_rfkill { | ||
464 | struct rfkill *rfkill; | ||
465 | struct rfkill_ops ops; | ||
466 | char rfkill_name[32]; | ||
467 | }; | ||
468 | |||
469 | /********************/ | 462 | /********************/ |
470 | /* Main driver core */ | 463 | /* Main driver core */ |
471 | /********************/ | 464 | /********************/ |
@@ -505,7 +498,6 @@ struct ath_rfkill { | |||
505 | #define SC_OP_PROTECT_ENABLE BIT(6) | 498 | #define SC_OP_PROTECT_ENABLE BIT(6) |
506 | #define SC_OP_RXFLUSH BIT(7) | 499 | #define SC_OP_RXFLUSH BIT(7) |
507 | #define SC_OP_LED_ASSOCIATED BIT(8) | 500 | #define SC_OP_LED_ASSOCIATED BIT(8) |
508 | #define SC_OP_RFKILL_REGISTERED BIT(9) | ||
509 | #define SC_OP_WAIT_FOR_BEACON BIT(12) | 501 | #define SC_OP_WAIT_FOR_BEACON BIT(12) |
510 | #define SC_OP_LED_ON BIT(13) | 502 | #define SC_OP_LED_ON BIT(13) |
511 | #define SC_OP_SCANNING BIT(14) | 503 | #define SC_OP_SCANNING BIT(14) |
@@ -591,7 +583,6 @@ struct ath_softc { | |||
591 | 583 | ||
592 | int beacon_interval; | 584 | int beacon_interval; |
593 | 585 | ||
594 | struct ath_rfkill rf_kill; | ||
595 | struct ath_ani ani; | 586 | struct ath_ani ani; |
596 | struct ath9k_node_stats nodestats; | 587 | struct ath9k_node_stats nodestats; |
597 | #ifdef CONFIG_ATH9K_DEBUG | 588 | #ifdef CONFIG_ATH9K_DEBUG |
@@ -677,6 +668,7 @@ static inline void ath9k_ps_restore(struct ath_softc *sc) | |||
677 | if (atomic_dec_and_test(&sc->ps_usecount)) | 668 | if (atomic_dec_and_test(&sc->ps_usecount)) |
678 | if ((sc->hw->conf.flags & IEEE80211_CONF_PS) && | 669 | if ((sc->hw->conf.flags & IEEE80211_CONF_PS) && |
679 | !(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | | 670 | !(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | |
671 | SC_OP_WAIT_FOR_CAB | | ||
680 | SC_OP_WAIT_FOR_PSPOLL_DATA | | 672 | SC_OP_WAIT_FOR_PSPOLL_DATA | |
681 | SC_OP_WAIT_FOR_TX_ACK))) | 673 | SC_OP_WAIT_FOR_TX_ACK))) |
682 | ath9k_hw_setpower(sc->sc_ah, | 674 | ath9k_hw_setpower(sc->sc_ah, |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 1579c9407ed5..34935a8ee59d 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -2186,6 +2186,18 @@ static void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan | |||
2186 | REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); | 2186 | REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); |
2187 | } | 2187 | } |
2188 | 2188 | ||
2189 | static void ath9k_enable_rfkill(struct ath_hw *ah) | ||
2190 | { | ||
2191 | REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, | ||
2192 | AR_GPIO_INPUT_EN_VAL_RFSILENT_BB); | ||
2193 | |||
2194 | REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2, | ||
2195 | AR_GPIO_INPUT_MUX2_RFSILENT); | ||
2196 | |||
2197 | ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio); | ||
2198 | REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB); | ||
2199 | } | ||
2200 | |||
2189 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | 2201 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, |
2190 | bool bChannelChange) | 2202 | bool bChannelChange) |
2191 | { | 2203 | { |
@@ -2313,10 +2325,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2313 | ath9k_hw_init_interrupt_masks(ah, ah->opmode); | 2325 | ath9k_hw_init_interrupt_masks(ah, ah->opmode); |
2314 | ath9k_hw_init_qos(ah); | 2326 | ath9k_hw_init_qos(ah); |
2315 | 2327 | ||
2316 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
2317 | if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | 2328 | if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) |
2318 | ath9k_enable_rfkill(ah); | 2329 | ath9k_enable_rfkill(ah); |
2319 | #endif | 2330 | |
2320 | ath9k_hw_init_user_settings(ah); | 2331 | ath9k_hw_init_user_settings(ah); |
2321 | 2332 | ||
2322 | REG_WRITE(ah, AR_STA_ID1, | 2333 | REG_WRITE(ah, AR_STA_ID1, |
@@ -3613,20 +3624,6 @@ void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val) | |||
3613 | AR_GPIO_BIT(gpio)); | 3624 | AR_GPIO_BIT(gpio)); |
3614 | } | 3625 | } |
3615 | 3626 | ||
3616 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
3617 | void ath9k_enable_rfkill(struct ath_hw *ah) | ||
3618 | { | ||
3619 | REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, | ||
3620 | AR_GPIO_INPUT_EN_VAL_RFSILENT_BB); | ||
3621 | |||
3622 | REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2, | ||
3623 | AR_GPIO_INPUT_MUX2_RFSILENT); | ||
3624 | |||
3625 | ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio); | ||
3626 | REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB); | ||
3627 | } | ||
3628 | #endif | ||
3629 | |||
3630 | u32 ath9k_hw_getdefantenna(struct ath_hw *ah) | 3627 | u32 ath9k_hw_getdefantenna(struct ath_hw *ah) |
3631 | { | 3628 | { |
3632 | return REG_READ(ah, AR_DEF_ANTENNA) & 0x7; | 3629 | return REG_READ(ah, AR_DEF_ANTENNA) & 0x7; |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index dd8508ef6e05..9d0b31ad4603 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -565,9 +565,6 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio); | |||
565 | void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio, | 565 | void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio, |
566 | u32 ah_signal_type); | 566 | u32 ah_signal_type); |
567 | void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val); | 567 | void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val); |
568 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
569 | void ath9k_enable_rfkill(struct ath_hw *ah); | ||
570 | #endif | ||
571 | u32 ath9k_hw_getdefantenna(struct ath_hw *ah); | 568 | u32 ath9k_hw_getdefantenna(struct ath_hw *ah); |
572 | void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); | 569 | void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); |
573 | bool ath9k_hw_setantennaswitch(struct ath_hw *ah, | 570 | bool ath9k_hw_setantennaswitch(struct ath_hw *ah, |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index f7baa406918b..9f49a3251d4d 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -231,6 +231,19 @@ static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band) | |||
231 | } | 231 | } |
232 | } | 232 | } |
233 | 233 | ||
234 | static struct ath9k_channel *ath_get_curchannel(struct ath_softc *sc, | ||
235 | struct ieee80211_hw *hw) | ||
236 | { | ||
237 | struct ieee80211_channel *curchan = hw->conf.channel; | ||
238 | struct ath9k_channel *channel; | ||
239 | u8 chan_idx; | ||
240 | |||
241 | chan_idx = curchan->hw_value; | ||
242 | channel = &sc->sc_ah->channels[chan_idx]; | ||
243 | ath9k_update_ichannel(sc, hw, channel); | ||
244 | return channel; | ||
245 | } | ||
246 | |||
234 | /* | 247 | /* |
235 | * Set/change channels. If the channel is really being changed, it's done | 248 | * Set/change channels. If the channel is really being changed, it's done |
236 | * by reseting the chip. To accomplish this we must first cleanup any pending | 249 | * by reseting the chip. To accomplish this we must first cleanup any pending |
@@ -283,7 +296,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
283 | "reset status %d\n", | 296 | "reset status %d\n", |
284 | channel->center_freq, r); | 297 | channel->center_freq, r); |
285 | spin_unlock_bh(&sc->sc_resetlock); | 298 | spin_unlock_bh(&sc->sc_resetlock); |
286 | return r; | 299 | goto ps_restore; |
287 | } | 300 | } |
288 | spin_unlock_bh(&sc->sc_resetlock); | 301 | spin_unlock_bh(&sc->sc_resetlock); |
289 | 302 | ||
@@ -292,14 +305,17 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
292 | if (ath_startrecv(sc) != 0) { | 305 | if (ath_startrecv(sc) != 0) { |
293 | DPRINTF(sc, ATH_DBG_FATAL, | 306 | DPRINTF(sc, ATH_DBG_FATAL, |
294 | "Unable to restart recv logic\n"); | 307 | "Unable to restart recv logic\n"); |
295 | return -EIO; | 308 | r = -EIO; |
309 | goto ps_restore; | ||
296 | } | 310 | } |
297 | 311 | ||
298 | ath_cache_conf_rate(sc, &hw->conf); | 312 | ath_cache_conf_rate(sc, &hw->conf); |
299 | ath_update_txpow(sc); | 313 | ath_update_txpow(sc); |
300 | ath9k_hw_set_interrupts(ah, sc->imask); | 314 | ath9k_hw_set_interrupts(ah, sc->imask); |
315 | |||
316 | ps_restore: | ||
301 | ath9k_ps_restore(sc); | 317 | ath9k_ps_restore(sc); |
302 | return 0; | 318 | return r; |
303 | } | 319 | } |
304 | 320 | ||
305 | /* | 321 | /* |
@@ -1110,6 +1126,9 @@ void ath_radio_enable(struct ath_softc *sc) | |||
1110 | ath9k_ps_wakeup(sc); | 1126 | ath9k_ps_wakeup(sc); |
1111 | ath9k_hw_configpcipowersave(ah, 0); | 1127 | ath9k_hw_configpcipowersave(ah, 0); |
1112 | 1128 | ||
1129 | if (!ah->curchan) | ||
1130 | ah->curchan = ath_get_curchannel(sc, sc->hw); | ||
1131 | |||
1113 | spin_lock_bh(&sc->sc_resetlock); | 1132 | spin_lock_bh(&sc->sc_resetlock); |
1114 | r = ath9k_hw_reset(ah, ah->curchan, false); | 1133 | r = ath9k_hw_reset(ah, ah->curchan, false); |
1115 | if (r) { | 1134 | if (r) { |
@@ -1162,6 +1181,9 @@ void ath_radio_disable(struct ath_softc *sc) | |||
1162 | ath_stoprecv(sc); /* turn off frame recv */ | 1181 | ath_stoprecv(sc); /* turn off frame recv */ |
1163 | ath_flushrecv(sc); /* flush recv queue */ | 1182 | ath_flushrecv(sc); /* flush recv queue */ |
1164 | 1183 | ||
1184 | if (!ah->curchan) | ||
1185 | ah->curchan = ath_get_curchannel(sc, sc->hw); | ||
1186 | |||
1165 | spin_lock_bh(&sc->sc_resetlock); | 1187 | spin_lock_bh(&sc->sc_resetlock); |
1166 | r = ath9k_hw_reset(ah, ah->curchan, false); | 1188 | r = ath9k_hw_reset(ah, ah->curchan, false); |
1167 | if (r) { | 1189 | if (r) { |
@@ -1178,8 +1200,6 @@ void ath_radio_disable(struct ath_softc *sc) | |||
1178 | ath9k_ps_restore(sc); | 1200 | ath9k_ps_restore(sc); |
1179 | } | 1201 | } |
1180 | 1202 | ||
1181 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
1182 | |||
1183 | /*******************/ | 1203 | /*******************/ |
1184 | /* Rfkill */ | 1204 | /* Rfkill */ |
1185 | /*******************/ | 1205 | /*******************/ |
@@ -1192,81 +1212,27 @@ static bool ath_is_rfkill_set(struct ath_softc *sc) | |||
1192 | ah->rfkill_polarity; | 1212 | ah->rfkill_polarity; |
1193 | } | 1213 | } |
1194 | 1214 | ||
1195 | /* s/w rfkill handlers */ | 1215 | static void ath9k_rfkill_poll_state(struct ieee80211_hw *hw) |
1196 | static int ath_rfkill_set_block(void *data, bool blocked) | ||
1197 | { | 1216 | { |
1198 | struct ath_softc *sc = data; | 1217 | struct ath_wiphy *aphy = hw->priv; |
1199 | 1218 | struct ath_softc *sc = aphy->sc; | |
1200 | if (blocked) | ||
1201 | ath_radio_disable(sc); | ||
1202 | else | ||
1203 | ath_radio_enable(sc); | ||
1204 | |||
1205 | return 0; | ||
1206 | } | ||
1207 | |||
1208 | static void ath_rfkill_poll_state(struct rfkill *rfkill, void *data) | ||
1209 | { | ||
1210 | struct ath_softc *sc = data; | ||
1211 | bool blocked = !!ath_is_rfkill_set(sc); | 1219 | bool blocked = !!ath_is_rfkill_set(sc); |
1212 | 1220 | ||
1213 | if (rfkill_set_hw_state(rfkill, blocked)) | 1221 | wiphy_rfkill_set_hw_state(hw->wiphy, blocked); |
1222 | |||
1223 | if (blocked) | ||
1214 | ath_radio_disable(sc); | 1224 | ath_radio_disable(sc); |
1215 | else | 1225 | else |
1216 | ath_radio_enable(sc); | 1226 | ath_radio_enable(sc); |
1217 | } | 1227 | } |
1218 | 1228 | ||
1219 | /* Init s/w rfkill */ | 1229 | static void ath_start_rfkill_poll(struct ath_softc *sc) |
1220 | static int ath_init_sw_rfkill(struct ath_softc *sc) | ||
1221 | { | ||
1222 | sc->rf_kill.ops.set_block = ath_rfkill_set_block; | ||
1223 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | ||
1224 | sc->rf_kill.ops.poll = ath_rfkill_poll_state; | ||
1225 | |||
1226 | snprintf(sc->rf_kill.rfkill_name, sizeof(sc->rf_kill.rfkill_name), | ||
1227 | "ath9k-%s::rfkill", wiphy_name(sc->hw->wiphy)); | ||
1228 | |||
1229 | sc->rf_kill.rfkill = rfkill_alloc(sc->rf_kill.rfkill_name, | ||
1230 | wiphy_dev(sc->hw->wiphy), | ||
1231 | RFKILL_TYPE_WLAN, | ||
1232 | &sc->rf_kill.ops, sc); | ||
1233 | if (!sc->rf_kill.rfkill) { | ||
1234 | DPRINTF(sc, ATH_DBG_FATAL, "Failed to allocate rfkill\n"); | ||
1235 | return -ENOMEM; | ||
1236 | } | ||
1237 | |||
1238 | return 0; | ||
1239 | } | ||
1240 | |||
1241 | /* Deinitialize rfkill */ | ||
1242 | static void ath_deinit_rfkill(struct ath_softc *sc) | ||
1243 | { | ||
1244 | if (sc->sc_flags & SC_OP_RFKILL_REGISTERED) { | ||
1245 | rfkill_unregister(sc->rf_kill.rfkill); | ||
1246 | rfkill_destroy(sc->rf_kill.rfkill); | ||
1247 | sc->sc_flags &= ~SC_OP_RFKILL_REGISTERED; | ||
1248 | } | ||
1249 | } | ||
1250 | |||
1251 | static int ath_start_rfkill_poll(struct ath_softc *sc) | ||
1252 | { | 1230 | { |
1253 | if (!(sc->sc_flags & SC_OP_RFKILL_REGISTERED)) { | 1231 | struct ath_hw *ah = sc->sc_ah; |
1254 | if (rfkill_register(sc->rf_kill.rfkill)) { | ||
1255 | DPRINTF(sc, ATH_DBG_FATAL, | ||
1256 | "Unable to register rfkill\n"); | ||
1257 | rfkill_destroy(sc->rf_kill.rfkill); | ||
1258 | |||
1259 | /* Deinitialize the device */ | ||
1260 | ath_cleanup(sc); | ||
1261 | return -EIO; | ||
1262 | } else { | ||
1263 | sc->sc_flags |= SC_OP_RFKILL_REGISTERED; | ||
1264 | } | ||
1265 | } | ||
1266 | 1232 | ||
1267 | return 0; | 1233 | if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) |
1234 | wiphy_rfkill_start_polling(sc->hw->wiphy); | ||
1268 | } | 1235 | } |
1269 | #endif /* CONFIG_RFKILL */ | ||
1270 | 1236 | ||
1271 | void ath_cleanup(struct ath_softc *sc) | 1237 | void ath_cleanup(struct ath_softc *sc) |
1272 | { | 1238 | { |
@@ -1286,9 +1252,6 @@ void ath_detach(struct ath_softc *sc) | |||
1286 | 1252 | ||
1287 | DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n"); | 1253 | DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n"); |
1288 | 1254 | ||
1289 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
1290 | ath_deinit_rfkill(sc); | ||
1291 | #endif | ||
1292 | ath_deinit_leds(sc); | 1255 | ath_deinit_leds(sc); |
1293 | cancel_work_sync(&sc->chan_work); | 1256 | cancel_work_sync(&sc->chan_work); |
1294 | cancel_delayed_work_sync(&sc->wiphy_work); | 1257 | cancel_delayed_work_sync(&sc->wiphy_work); |
@@ -1626,13 +1589,6 @@ int ath_attach(u16 devid, struct ath_softc *sc) | |||
1626 | if (error != 0) | 1589 | if (error != 0) |
1627 | goto error_attach; | 1590 | goto error_attach; |
1628 | 1591 | ||
1629 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
1630 | /* Initialize s/w rfkill */ | ||
1631 | error = ath_init_sw_rfkill(sc); | ||
1632 | if (error) | ||
1633 | goto error_attach; | ||
1634 | #endif | ||
1635 | |||
1636 | INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); | 1592 | INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); |
1637 | INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); | 1593 | INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); |
1638 | sc->wiphy_scheduler_int = msecs_to_jiffies(500); | 1594 | sc->wiphy_scheduler_int = msecs_to_jiffies(500); |
@@ -1648,6 +1604,7 @@ int ath_attach(u16 devid, struct ath_softc *sc) | |||
1648 | /* Initialize LED control */ | 1604 | /* Initialize LED control */ |
1649 | ath_init_leds(sc); | 1605 | ath_init_leds(sc); |
1650 | 1606 | ||
1607 | ath_start_rfkill_poll(sc); | ||
1651 | 1608 | ||
1652 | return 0; | 1609 | return 0; |
1653 | 1610 | ||
@@ -1920,7 +1877,7 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1920 | struct ath_softc *sc = aphy->sc; | 1877 | struct ath_softc *sc = aphy->sc; |
1921 | struct ieee80211_channel *curchan = hw->conf.channel; | 1878 | struct ieee80211_channel *curchan = hw->conf.channel; |
1922 | struct ath9k_channel *init_channel; | 1879 | struct ath9k_channel *init_channel; |
1923 | int r, pos; | 1880 | int r; |
1924 | 1881 | ||
1925 | DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with " | 1882 | DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with " |
1926 | "initial channel: %d MHz\n", curchan->center_freq); | 1883 | "initial channel: %d MHz\n", curchan->center_freq); |
@@ -1950,11 +1907,9 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1950 | 1907 | ||
1951 | /* setup initial channel */ | 1908 | /* setup initial channel */ |
1952 | 1909 | ||
1953 | pos = curchan->hw_value; | 1910 | sc->chan_idx = curchan->hw_value; |
1954 | 1911 | ||
1955 | sc->chan_idx = pos; | 1912 | init_channel = ath_get_curchannel(sc, hw); |
1956 | init_channel = &sc->sc_ah->channels[pos]; | ||
1957 | ath9k_update_ichannel(sc, hw, init_channel); | ||
1958 | 1913 | ||
1959 | /* Reset SERDES registers */ | 1914 | /* Reset SERDES registers */ |
1960 | ath9k_hw_configpcipowersave(sc->sc_ah, 0); | 1915 | ath9k_hw_configpcipowersave(sc->sc_ah, 0); |
@@ -2018,10 +1973,6 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
2018 | 1973 | ||
2019 | ieee80211_wake_queues(hw); | 1974 | ieee80211_wake_queues(hw); |
2020 | 1975 | ||
2021 | #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||
2022 | r = ath_start_rfkill_poll(sc); | ||
2023 | #endif | ||
2024 | |||
2025 | mutex_unlock: | 1976 | mutex_unlock: |
2026 | mutex_unlock(&sc->mutex); | 1977 | mutex_unlock(&sc->mutex); |
2027 | 1978 | ||
@@ -2159,7 +2110,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
2159 | } else | 2110 | } else |
2160 | sc->rx.rxlink = NULL; | 2111 | sc->rx.rxlink = NULL; |
2161 | 2112 | ||
2162 | rfkill_pause_polling(sc->rf_kill.rfkill); | 2113 | wiphy_rfkill_stop_polling(sc->hw->wiphy); |
2163 | 2114 | ||
2164 | /* disable HAL and put h/w to sleep */ | 2115 | /* disable HAL and put h/w to sleep */ |
2165 | ath9k_hw_disable(sc->sc_ah); | 2116 | ath9k_hw_disable(sc->sc_ah); |
@@ -2765,6 +2716,7 @@ struct ieee80211_ops ath9k_ops = { | |||
2765 | .ampdu_action = ath9k_ampdu_action, | 2716 | .ampdu_action = ath9k_ampdu_action, |
2766 | .sw_scan_start = ath9k_sw_scan_start, | 2717 | .sw_scan_start = ath9k_sw_scan_start, |
2767 | .sw_scan_complete = ath9k_sw_scan_complete, | 2718 | .sw_scan_complete = ath9k_sw_scan_complete, |
2719 | .rfkill_poll = ath9k_rfkill_poll_state, | ||
2768 | }; | 2720 | }; |
2769 | 2721 | ||
2770 | static struct { | 2722 | static struct { |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 5014a19b0f75..f99f3a76df3f 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -817,6 +817,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
817 | } | 817 | } |
818 | 818 | ||
819 | if (unlikely(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | | 819 | if (unlikely(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | |
820 | SC_OP_WAIT_FOR_CAB | | ||
820 | SC_OP_WAIT_FOR_PSPOLL_DATA))) | 821 | SC_OP_WAIT_FOR_PSPOLL_DATA))) |
821 | ath_rx_ps(sc, skb); | 822 | ath_rx_ps(sc, skb); |
822 | 823 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index a5637c4aa85d..6d1519e1f011 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -2152,7 +2152,6 @@ static int iwl_mac_start(struct ieee80211_hw *hw) | |||
2152 | /* we should be verifying the device is ready to be opened */ | 2152 | /* we should be verifying the device is ready to be opened */ |
2153 | mutex_lock(&priv->mutex); | 2153 | mutex_lock(&priv->mutex); |
2154 | 2154 | ||
2155 | memset(&priv->staging_rxon, 0, sizeof(struct iwl_rxon_cmd)); | ||
2156 | /* fetch ucode file from disk, alloc and copy to bus-master buffers ... | 2155 | /* fetch ucode file from disk, alloc and copy to bus-master buffers ... |
2157 | * ucode filename and max sizes are card-specific. */ | 2156 | * ucode filename and max sizes are card-specific. */ |
2158 | 2157 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index f9d16ca5b3d9..6ab07165ea28 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -629,13 +629,9 @@ u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv, | |||
629 | if (!sta_ht_inf->ht_supported) | 629 | if (!sta_ht_inf->ht_supported) |
630 | return 0; | 630 | return 0; |
631 | } | 631 | } |
632 | 632 | return iwl_is_channel_extension(priv, priv->band, | |
633 | if (iwl_ht_conf->ht_protection & IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) | 633 | le16_to_cpu(priv->staging_rxon.channel), |
634 | return 1; | 634 | iwl_ht_conf->extension_chan_offset); |
635 | else | ||
636 | return iwl_is_channel_extension(priv, priv->band, | ||
637 | le16_to_cpu(priv->staging_rxon.channel), | ||
638 | iwl_ht_conf->extension_chan_offset); | ||
639 | } | 635 | } |
640 | EXPORT_SYMBOL(iwl_is_fat_tx_allowed); | 636 | EXPORT_SYMBOL(iwl_is_fat_tx_allowed); |
641 | 637 | ||
@@ -826,9 +822,18 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info) | |||
826 | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); | 822 | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); |
827 | if (iwl_is_fat_tx_allowed(priv, NULL)) { | 823 | if (iwl_is_fat_tx_allowed(priv, NULL)) { |
828 | /* pure 40 fat */ | 824 | /* pure 40 fat */ |
829 | if (rxon->flags & RXON_FLG_FAT_PROT_MSK) | 825 | if (ht_info->ht_protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) { |
830 | rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40; | 826 | rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40; |
831 | else { | 827 | /* Note: control channel is opposite of extension channel */ |
828 | switch (ht_info->extension_chan_offset) { | ||
829 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | ||
830 | rxon->flags &= ~RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; | ||
831 | break; | ||
832 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: | ||
833 | rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; | ||
834 | break; | ||
835 | } | ||
836 | } else { | ||
832 | /* Note: control channel is opposite of extension channel */ | 837 | /* Note: control channel is opposite of extension channel */ |
833 | switch (ht_info->extension_chan_offset) { | 838 | switch (ht_info->extension_chan_offset) { |
834 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | 839 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: |
@@ -2390,39 +2395,46 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, | |||
2390 | priv->ibss_beacon = ieee80211_beacon_get(hw, vif); | 2395 | priv->ibss_beacon = ieee80211_beacon_get(hw, vif); |
2391 | } | 2396 | } |
2392 | 2397 | ||
2393 | if ((changes & BSS_CHANGED_BSSID) && !iwl_is_rfkill(priv)) { | 2398 | if (changes & BSS_CHANGED_BEACON_INT) { |
2394 | /* If there is currently a HW scan going on in the background | 2399 | priv->beacon_int = bss_conf->beacon_int; |
2395 | * then we need to cancel it else the RXON below will fail. */ | 2400 | /* TODO: in AP mode, do something to make this take effect */ |
2401 | } | ||
2402 | |||
2403 | if (changes & BSS_CHANGED_BSSID) { | ||
2404 | IWL_DEBUG_MAC80211(priv, "BSSID %pM\n", bss_conf->bssid); | ||
2405 | |||
2406 | /* | ||
2407 | * If there is currently a HW scan going on in the | ||
2408 | * background then we need to cancel it else the RXON | ||
2409 | * below/in post_associate will fail. | ||
2410 | */ | ||
2396 | if (iwl_scan_cancel_timeout(priv, 100)) { | 2411 | if (iwl_scan_cancel_timeout(priv, 100)) { |
2397 | IWL_WARN(priv, "Aborted scan still in progress " | 2412 | IWL_WARN(priv, "Aborted scan still in progress after 100ms\n"); |
2398 | "after 100ms\n"); | ||
2399 | IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n"); | 2413 | IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n"); |
2400 | mutex_unlock(&priv->mutex); | 2414 | mutex_unlock(&priv->mutex); |
2401 | return; | 2415 | return; |
2402 | } | 2416 | } |
2403 | memcpy(priv->staging_rxon.bssid_addr, | 2417 | |
2404 | bss_conf->bssid, ETH_ALEN); | 2418 | /* mac80211 only sets assoc when in STATION mode */ |
2405 | 2419 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC || | |
2406 | /* TODO: Audit driver for usage of these members and see | 2420 | bss_conf->assoc) { |
2407 | * if mac80211 deprecates them (priv->bssid looks like it | 2421 | memcpy(priv->staging_rxon.bssid_addr, |
2408 | * shouldn't be there, but I haven't scanned the IBSS code | 2422 | bss_conf->bssid, ETH_ALEN); |
2409 | * to verify) - jpk */ | 2423 | |
2410 | memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); | 2424 | /* currently needed in a few places */ |
2411 | 2425 | memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); | |
2412 | if (priv->iw_mode == NL80211_IFTYPE_AP) | 2426 | } else { |
2413 | iwlcore_config_ap(priv); | 2427 | priv->staging_rxon.filter_flags &= |
2414 | else { | 2428 | ~RXON_FILTER_ASSOC_MSK; |
2415 | int rc = iwlcore_commit_rxon(priv); | ||
2416 | if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc) | ||
2417 | iwl_rxon_add_station( | ||
2418 | priv, priv->active_rxon.bssid_addr, 1); | ||
2419 | } | 2429 | } |
2420 | } else if (!iwl_is_rfkill(priv)) { | 2430 | |
2421 | iwl_scan_cancel_timeout(priv, 100); | ||
2422 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | ||
2423 | iwlcore_commit_rxon(priv); | ||
2424 | } | 2431 | } |
2425 | 2432 | ||
2433 | /* | ||
2434 | * This needs to be after setting the BSSID in case | ||
2435 | * mac80211 decides to do both changes at once because | ||
2436 | * it will invoke post_associate. | ||
2437 | */ | ||
2426 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC && | 2438 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC && |
2427 | changes & BSS_CHANGED_BEACON) { | 2439 | changes & BSS_CHANGED_BEACON) { |
2428 | struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); | 2440 | struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); |
@@ -2431,8 +2443,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, | |||
2431 | iwl_mac_beacon_update(hw, beacon); | 2443 | iwl_mac_beacon_update(hw, beacon); |
2432 | } | 2444 | } |
2433 | 2445 | ||
2434 | mutex_unlock(&priv->mutex); | ||
2435 | |||
2436 | if (changes & BSS_CHANGED_ERP_PREAMBLE) { | 2446 | if (changes & BSS_CHANGED_ERP_PREAMBLE) { |
2437 | IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n", | 2447 | IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n", |
2438 | bss_conf->use_short_preamble); | 2448 | bss_conf->use_short_preamble); |
@@ -2450,6 +2460,23 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, | |||
2450 | priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; | 2460 | priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; |
2451 | } | 2461 | } |
2452 | 2462 | ||
2463 | if (changes & BSS_CHANGED_BASIC_RATES) { | ||
2464 | /* XXX use this information | ||
2465 | * | ||
2466 | * To do that, remove code from iwl_set_rate() and put something | ||
2467 | * like this here: | ||
2468 | * | ||
2469 | if (A-band) | ||
2470 | priv->staging_rxon.ofdm_basic_rates = | ||
2471 | bss_conf->basic_rates; | ||
2472 | else | ||
2473 | priv->staging_rxon.ofdm_basic_rates = | ||
2474 | bss_conf->basic_rates >> 4; | ||
2475 | priv->staging_rxon.cck_basic_rates = | ||
2476 | bss_conf->basic_rates & 0xF; | ||
2477 | */ | ||
2478 | } | ||
2479 | |||
2453 | if (changes & BSS_CHANGED_HT) { | 2480 | if (changes & BSS_CHANGED_HT) { |
2454 | iwl_ht_conf(priv, bss_conf); | 2481 | iwl_ht_conf(priv, bss_conf); |
2455 | 2482 | ||
@@ -2459,10 +2486,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, | |||
2459 | 2486 | ||
2460 | if (changes & BSS_CHANGED_ASSOC) { | 2487 | if (changes & BSS_CHANGED_ASSOC) { |
2461 | IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc); | 2488 | IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc); |
2462 | /* This should never happen as this function should | ||
2463 | * never be called from interrupt context. */ | ||
2464 | if (WARN_ON_ONCE(in_interrupt())) | ||
2465 | return; | ||
2466 | if (bss_conf->assoc) { | 2489 | if (bss_conf->assoc) { |
2467 | priv->assoc_id = bss_conf->aid; | 2490 | priv->assoc_id = bss_conf->aid; |
2468 | priv->beacon_int = bss_conf->beacon_int; | 2491 | priv->beacon_int = bss_conf->beacon_int; |
@@ -2470,27 +2493,35 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, | |||
2470 | priv->timestamp = bss_conf->timestamp; | 2493 | priv->timestamp = bss_conf->timestamp; |
2471 | priv->assoc_capability = bss_conf->assoc_capability; | 2494 | priv->assoc_capability = bss_conf->assoc_capability; |
2472 | 2495 | ||
2473 | /* we have just associated, don't start scan too early | 2496 | /* |
2474 | * leave time for EAPOL exchange to complete | 2497 | * We have just associated, don't start scan too early |
2498 | * leave time for EAPOL exchange to complete. | ||
2499 | * | ||
2500 | * XXX: do this in mac80211 | ||
2475 | */ | 2501 | */ |
2476 | priv->next_scan_jiffies = jiffies + | 2502 | priv->next_scan_jiffies = jiffies + |
2477 | IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; | 2503 | IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; |
2478 | mutex_lock(&priv->mutex); | 2504 | if (!iwl_is_rfkill(priv)) |
2479 | priv->cfg->ops->lib->post_associate(priv); | 2505 | priv->cfg->ops->lib->post_associate(priv); |
2480 | mutex_unlock(&priv->mutex); | 2506 | } else |
2481 | } else { | ||
2482 | priv->assoc_id = 0; | 2507 | priv->assoc_id = 0; |
2483 | IWL_DEBUG_MAC80211(priv, "DISASSOC %d\n", bss_conf->assoc); | 2508 | |
2509 | } | ||
2510 | |||
2511 | if (changes && iwl_is_associated(priv) && priv->assoc_id) { | ||
2512 | IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n", | ||
2513 | changes); | ||
2514 | ret = iwl_send_rxon_assoc(priv); | ||
2515 | if (!ret) { | ||
2516 | /* Sync active_rxon with latest change. */ | ||
2517 | memcpy((void *)&priv->active_rxon, | ||
2518 | &priv->staging_rxon, | ||
2519 | sizeof(struct iwl_rxon_cmd)); | ||
2484 | } | 2520 | } |
2485 | } else if (changes && iwl_is_associated(priv) && priv->assoc_id) { | ||
2486 | IWL_DEBUG_MAC80211(priv, "Associated Changes %d\n", changes); | ||
2487 | ret = iwl_send_rxon_assoc(priv); | ||
2488 | if (!ret) | ||
2489 | /* Sync active_rxon with latest change. */ | ||
2490 | memcpy((void *)&priv->active_rxon, | ||
2491 | &priv->staging_rxon, | ||
2492 | sizeof(struct iwl_rxon_cmd)); | ||
2493 | } | 2521 | } |
2522 | |||
2523 | mutex_unlock(&priv->mutex); | ||
2524 | |||
2494 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 2525 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
2495 | } | 2526 | } |
2496 | EXPORT_SYMBOL(iwl_bss_info_changed); | 2527 | EXPORT_SYMBOL(iwl_bss_info_changed); |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 83d31606dd00..cb9bd4c8f25e 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -2498,8 +2498,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv) | |||
2498 | struct iwl3945_rxon_cmd *active_rxon = | 2498 | struct iwl3945_rxon_cmd *active_rxon = |
2499 | (struct iwl3945_rxon_cmd *)(&priv->active_rxon); | 2499 | (struct iwl3945_rxon_cmd *)(&priv->active_rxon); |
2500 | 2500 | ||
2501 | memcpy(&priv->staging_rxon, &priv->active_rxon, | 2501 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; |
2502 | sizeof(priv->staging_rxon)); | ||
2503 | active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 2502 | active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
2504 | } else { | 2503 | } else { |
2505 | /* Initialize our rx_config data */ | 2504 | /* Initialize our rx_config data */ |
@@ -3147,7 +3146,6 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw) | |||
3147 | /* we should be verifying the device is ready to be opened */ | 3146 | /* we should be verifying the device is ready to be opened */ |
3148 | mutex_lock(&priv->mutex); | 3147 | mutex_lock(&priv->mutex); |
3149 | 3148 | ||
3150 | memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon)); | ||
3151 | /* fetch ucode file from disk, alloc and copy to bus-master buffers ... | 3149 | /* fetch ucode file from disk, alloc and copy to bus-master buffers ... |
3152 | * ucode filename and max sizes are card-specific. */ | 3150 | * ucode filename and max sizes are card-specific. */ |
3153 | 3151 | ||
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index 06a46d7b3d6c..6564282ce476 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c | |||
@@ -812,7 +812,6 @@ out: | |||
812 | static void if_spi_e2h(struct if_spi_card *card) | 812 | static void if_spi_e2h(struct if_spi_card *card) |
813 | { | 813 | { |
814 | int err = 0; | 814 | int err = 0; |
815 | unsigned long flags; | ||
816 | u32 cause; | 815 | u32 cause; |
817 | struct lbs_private *priv = card->priv; | 816 | struct lbs_private *priv = card->priv; |
818 | 817 | ||
@@ -827,10 +826,7 @@ static void if_spi_e2h(struct if_spi_card *card) | |||
827 | /* generate a card interrupt */ | 826 | /* generate a card interrupt */ |
828 | spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG, IF_SPI_CIC_HOST_EVENT); | 827 | spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG, IF_SPI_CIC_HOST_EVENT); |
829 | 828 | ||
830 | spin_lock_irqsave(&priv->driver_lock, flags); | ||
831 | lbs_queue_event(priv, cause & 0xff); | 829 | lbs_queue_event(priv, cause & 0xff); |
832 | spin_unlock_irqrestore(&priv->driver_lock, flags); | ||
833 | |||
834 | out: | 830 | out: |
835 | if (err) | 831 | if (err) |
836 | lbs_pr_err("%s: error %d\n", __func__, err); | 832 | lbs_pr_err("%s: error %d\n", __func__, err); |
@@ -875,7 +871,12 @@ static int lbs_spi_thread(void *data) | |||
875 | err = if_spi_c2h_data(card); | 871 | err = if_spi_c2h_data(card); |
876 | if (err) | 872 | if (err) |
877 | goto err; | 873 | goto err; |
878 | if (hiStatus & IF_SPI_HIST_CMD_DOWNLOAD_RDY) { | 874 | |
875 | /* workaround: in PS mode, the card does not set the Command | ||
876 | * Download Ready bit, but it sets TX Download Ready. */ | ||
877 | if (hiStatus & IF_SPI_HIST_CMD_DOWNLOAD_RDY || | ||
878 | (card->priv->psstate != PS_STATE_FULL_POWER && | ||
879 | (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY))) { | ||
879 | /* This means two things. First of all, | 880 | /* This means two things. First of all, |
880 | * if there was a previous command sent, the card has | 881 | * if there was a previous command sent, the card has |
881 | * successfully received it. | 882 | * successfully received it. |
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index 2faf0e14f05a..74909c4aaeea 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c | |||
@@ -177,7 +177,7 @@ dell_send_request(struct calling_interface_buffer *buffer, int class, | |||
177 | static int dell_rfkill_set(void *data, bool blocked) | 177 | static int dell_rfkill_set(void *data, bool blocked) |
178 | { | 178 | { |
179 | struct calling_interface_buffer buffer; | 179 | struct calling_interface_buffer buffer; |
180 | int disable = blocked ? 0 : 1; | 180 | int disable = blocked ? 1 : 0; |
181 | unsigned long radio = (unsigned long)data; | 181 | unsigned long radio = (unsigned long)data; |
182 | 182 | ||
183 | memset(&buffer, 0, sizeof(struct calling_interface_buffer)); | 183 | memset(&buffer, 0, sizeof(struct calling_interface_buffer)); |
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index e48d9a4506ff..dafaa4a92df5 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
@@ -1133,8 +1133,9 @@ static void sony_nc_rfkill_update() | |||
1133 | continue; | 1133 | continue; |
1134 | 1134 | ||
1135 | if (hwblock) { | 1135 | if (hwblock) { |
1136 | if (rfkill_set_hw_state(sony_rfkill_devices[i], true)) | 1136 | if (rfkill_set_hw_state(sony_rfkill_devices[i], true)) { |
1137 | sony_nc_rfkill_set((void *)i, true); | 1137 | /* we already know we're blocked */ |
1138 | } | ||
1138 | continue; | 1139 | continue; |
1139 | } | 1140 | } |
1140 | 1141 | ||
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 81d7f268418a..691cecd03b83 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c | |||
@@ -655,7 +655,7 @@ static void qeth_l2_set_multicast_list(struct net_device *dev) | |||
655 | for (dm = dev->mc_list; dm; dm = dm->next) | 655 | for (dm = dev->mc_list; dm; dm = dm->next) |
656 | qeth_l2_add_mc(card, dm->da_addr, 0); | 656 | qeth_l2_add_mc(card, dm->da_addr, 0); |
657 | 657 | ||
658 | list_for_each_entry(ha, &dev->uc_list, list) | 658 | list_for_each_entry(ha, &dev->uc.list, list) |
659 | qeth_l2_add_mc(card, ha->addr, 1); | 659 | qeth_l2_add_mc(card, ha->addr, 1); |
660 | 660 | ||
661 | spin_unlock_bh(&card->mclock); | 661 | spin_unlock_bh(&card->mclock); |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 9ea8d6dfe540..d4a4d9867794 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -224,6 +224,11 @@ struct netdev_hw_addr { | |||
224 | struct rcu_head rcu_head; | 224 | struct rcu_head rcu_head; |
225 | }; | 225 | }; |
226 | 226 | ||
227 | struct netdev_hw_addr_list { | ||
228 | struct list_head list; | ||
229 | int count; | ||
230 | }; | ||
231 | |||
227 | struct hh_cache | 232 | struct hh_cache |
228 | { | 233 | { |
229 | struct hh_cache *hh_next; /* Next entry */ | 234 | struct hh_cache *hh_next; /* Next entry */ |
@@ -776,9 +781,8 @@ struct net_device | |||
776 | unsigned char addr_len; /* hardware address length */ | 781 | unsigned char addr_len; /* hardware address length */ |
777 | unsigned short dev_id; /* for shared network cards */ | 782 | unsigned short dev_id; /* for shared network cards */ |
778 | 783 | ||
779 | struct list_head uc_list; /* Secondary unicast mac | 784 | struct netdev_hw_addr_list uc; /* Secondary unicast |
780 | addresses */ | 785 | mac addresses */ |
781 | int uc_count; /* Number of installed ucasts */ | ||
782 | int uc_promisc; | 786 | int uc_promisc; |
783 | spinlock_t addr_list_lock; | 787 | spinlock_t addr_list_lock; |
784 | struct dev_addr_list *mc_list; /* Multicast mac addresses */ | 788 | struct dev_addr_list *mc_list; /* Multicast mac addresses */ |
@@ -810,7 +814,8 @@ struct net_device | |||
810 | because most packets are | 814 | because most packets are |
811 | unicast) */ | 815 | unicast) */ |
812 | 816 | ||
813 | struct list_head dev_addr_list; /* list of device hw addresses */ | 817 | struct netdev_hw_addr_list dev_addrs; /* list of device |
818 | hw addresses */ | ||
814 | 819 | ||
815 | unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */ | 820 | unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */ |
816 | 821 | ||
@@ -1806,11 +1811,11 @@ static inline void netif_addr_unlock_bh(struct net_device *dev) | |||
1806 | } | 1811 | } |
1807 | 1812 | ||
1808 | /* | 1813 | /* |
1809 | * dev_addr_list walker. Should be used only for read access. Call with | 1814 | * dev_addrs walker. Should be used only for read access. Call with |
1810 | * rcu_read_lock held. | 1815 | * rcu_read_lock held. |
1811 | */ | 1816 | */ |
1812 | #define for_each_dev_addr(dev, ha) \ | 1817 | #define for_each_dev_addr(dev, ha) \ |
1813 | list_for_each_entry_rcu(ha, &dev->dev_addr_list, list) | 1818 | list_for_each_entry_rcu(ha, &dev->dev_addrs.list, list) |
1814 | 1819 | ||
1815 | /* These functions live elsewhere (drivers/net/net_init.c, but related) */ | 1820 | /* These functions live elsewhere (drivers/net/net_init.c, but related) */ |
1816 | 1821 | ||
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 63ef24bc01d0..b47b3f039d14 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -265,7 +265,7 @@ typedef unsigned char *sk_buff_data_t; | |||
265 | * @transport_header: Transport layer header | 265 | * @transport_header: Transport layer header |
266 | * @network_header: Network layer header | 266 | * @network_header: Network layer header |
267 | * @mac_header: Link layer header | 267 | * @mac_header: Link layer header |
268 | * @dst: destination entry | 268 | * @_skb_dst: destination entry |
269 | * @sp: the security path, used for xfrm | 269 | * @sp: the security path, used for xfrm |
270 | * @cb: Control buffer. Free for use by every layer. Put private vars here | 270 | * @cb: Control buffer. Free for use by every layer. Put private vars here |
271 | * @len: Length of actual data | 271 | * @len: Length of actual data |
diff --git a/include/net/sock.h b/include/net/sock.h index 95bd3fd75f94..07133c5e9868 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -1208,6 +1208,39 @@ static inline int skb_copy_to_page(struct sock *sk, char __user *from, | |||
1208 | return 0; | 1208 | return 0; |
1209 | } | 1209 | } |
1210 | 1210 | ||
1211 | /** | ||
1212 | * sk_wmem_alloc_get - returns write allocations | ||
1213 | * @sk: socket | ||
1214 | * | ||
1215 | * Returns sk_wmem_alloc minus initial offset of one | ||
1216 | */ | ||
1217 | static inline int sk_wmem_alloc_get(const struct sock *sk) | ||
1218 | { | ||
1219 | return atomic_read(&sk->sk_wmem_alloc) - 1; | ||
1220 | } | ||
1221 | |||
1222 | /** | ||
1223 | * sk_rmem_alloc_get - returns read allocations | ||
1224 | * @sk: socket | ||
1225 | * | ||
1226 | * Returns sk_rmem_alloc | ||
1227 | */ | ||
1228 | static inline int sk_rmem_alloc_get(const struct sock *sk) | ||
1229 | { | ||
1230 | return atomic_read(&sk->sk_rmem_alloc); | ||
1231 | } | ||
1232 | |||
1233 | /** | ||
1234 | * sk_has_allocations - check if allocations are outstanding | ||
1235 | * @sk: socket | ||
1236 | * | ||
1237 | * Returns true if socket has write or read allocations | ||
1238 | */ | ||
1239 | static inline int sk_has_allocations(const struct sock *sk) | ||
1240 | { | ||
1241 | return sk_wmem_alloc_get(sk) || sk_rmem_alloc_get(sk); | ||
1242 | } | ||
1243 | |||
1211 | /* | 1244 | /* |
1212 | * Queue a received datagram if it will fit. Stream and sequenced | 1245 | * Queue a received datagram if it will fit. Stream and sequenced |
1213 | * protocols can't normally use this as they need to fit buffers in | 1246 | * protocols can't normally use this as they need to fit buffers in |
diff --git a/include/net/x25.h b/include/net/x25.h index fc3f03d976f8..2cda04011568 100644 --- a/include/net/x25.h +++ b/include/net/x25.h | |||
@@ -187,7 +187,7 @@ extern int x25_addr_ntoa(unsigned char *, struct x25_address *, | |||
187 | extern int x25_addr_aton(unsigned char *, struct x25_address *, | 187 | extern int x25_addr_aton(unsigned char *, struct x25_address *, |
188 | struct x25_address *); | 188 | struct x25_address *); |
189 | extern struct sock *x25_find_socket(unsigned int, struct x25_neigh *); | 189 | extern struct sock *x25_find_socket(unsigned int, struct x25_neigh *); |
190 | extern void x25_destroy_socket(struct sock *); | 190 | extern void x25_destroy_socket_from_timer(struct sock *); |
191 | extern int x25_rx_call_request(struct sk_buff *, struct x25_neigh *, unsigned int); | 191 | extern int x25_rx_call_request(struct sk_buff *, struct x25_neigh *, unsigned int); |
192 | extern void x25_kill_by_neigh(struct x25_neigh *); | 192 | extern void x25_kill_by_neigh(struct x25_neigh *); |
193 | 193 | ||
diff --git a/net/appletalk/atalk_proc.c b/net/appletalk/atalk_proc.c index fd8e0847b254..80caad1a31a5 100644 --- a/net/appletalk/atalk_proc.c +++ b/net/appletalk/atalk_proc.c | |||
@@ -204,8 +204,8 @@ static int atalk_seq_socket_show(struct seq_file *seq, void *v) | |||
204 | "%02X %d\n", | 204 | "%02X %d\n", |
205 | s->sk_type, ntohs(at->src_net), at->src_node, at->src_port, | 205 | s->sk_type, ntohs(at->src_net), at->src_node, at->src_port, |
206 | ntohs(at->dest_net), at->dest_node, at->dest_port, | 206 | ntohs(at->dest_net), at->dest_node, at->dest_port, |
207 | atomic_read(&s->sk_wmem_alloc), | 207 | sk_wmem_alloc_get(s), |
208 | atomic_read(&s->sk_rmem_alloc), | 208 | sk_rmem_alloc_get(s), |
209 | s->sk_state, SOCK_INODE(s->sk_socket)->i_uid); | 209 | s->sk_state, SOCK_INODE(s->sk_socket)->i_uid); |
210 | out: | 210 | out: |
211 | return 0; | 211 | return 0; |
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index b603cbacdc58..590b83963622 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c | |||
@@ -162,8 +162,7 @@ static void atalk_destroy_timer(unsigned long data) | |||
162 | { | 162 | { |
163 | struct sock *sk = (struct sock *)data; | 163 | struct sock *sk = (struct sock *)data; |
164 | 164 | ||
165 | if (atomic_read(&sk->sk_wmem_alloc) || | 165 | if (sk_has_allocations(sk)) { |
166 | atomic_read(&sk->sk_rmem_alloc)) { | ||
167 | sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME; | 166 | sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME; |
168 | add_timer(&sk->sk_timer); | 167 | add_timer(&sk->sk_timer); |
169 | } else | 168 | } else |
@@ -175,8 +174,7 @@ static inline void atalk_destroy_socket(struct sock *sk) | |||
175 | atalk_remove_socket(sk); | 174 | atalk_remove_socket(sk); |
176 | skb_queue_purge(&sk->sk_receive_queue); | 175 | skb_queue_purge(&sk->sk_receive_queue); |
177 | 176 | ||
178 | if (atomic_read(&sk->sk_wmem_alloc) || | 177 | if (sk_has_allocations(sk)) { |
179 | atomic_read(&sk->sk_rmem_alloc)) { | ||
180 | setup_timer(&sk->sk_timer, atalk_destroy_timer, | 178 | setup_timer(&sk->sk_timer, atalk_destroy_timer, |
181 | (unsigned long)sk); | 179 | (unsigned long)sk); |
182 | sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME; | 180 | sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME; |
@@ -1750,8 +1748,7 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1750 | switch (cmd) { | 1748 | switch (cmd) { |
1751 | /* Protocol layer */ | 1749 | /* Protocol layer */ |
1752 | case TIOCOUTQ: { | 1750 | case TIOCOUTQ: { |
1753 | long amount = sk->sk_sndbuf - | 1751 | long amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); |
1754 | atomic_read(&sk->sk_wmem_alloc); | ||
1755 | 1752 | ||
1756 | if (amount < 0) | 1753 | if (amount < 0) |
1757 | amount = 0; | 1754 | amount = 0; |
diff --git a/net/atm/common.c b/net/atm/common.c index d34edbe754c8..c1c97936192c 100644 --- a/net/atm/common.c +++ b/net/atm/common.c | |||
@@ -62,15 +62,15 @@ static struct sk_buff *alloc_tx(struct atm_vcc *vcc,unsigned int size) | |||
62 | struct sk_buff *skb; | 62 | struct sk_buff *skb; |
63 | struct sock *sk = sk_atm(vcc); | 63 | struct sock *sk = sk_atm(vcc); |
64 | 64 | ||
65 | if (atomic_read(&sk->sk_wmem_alloc) && !atm_may_send(vcc, size)) { | 65 | if (sk_wmem_alloc_get(sk) && !atm_may_send(vcc, size)) { |
66 | pr_debug("Sorry: wmem_alloc = %d, size = %d, sndbuf = %d\n", | 66 | pr_debug("Sorry: wmem_alloc = %d, size = %d, sndbuf = %d\n", |
67 | atomic_read(&sk->sk_wmem_alloc), size, | 67 | sk_wmem_alloc_get(sk), size, |
68 | sk->sk_sndbuf); | 68 | sk->sk_sndbuf); |
69 | return NULL; | 69 | return NULL; |
70 | } | 70 | } |
71 | while (!(skb = alloc_skb(size,GFP_KERNEL))) schedule(); | 71 | while (!(skb = alloc_skb(size, GFP_KERNEL))) |
72 | pr_debug("AlTx %d += %d\n", atomic_read(&sk->sk_wmem_alloc), | 72 | schedule(); |
73 | skb->truesize); | 73 | pr_debug("AlTx %d += %d\n", sk_wmem_alloc_get(sk), skb->truesize); |
74 | atomic_add(skb->truesize, &sk->sk_wmem_alloc); | 74 | atomic_add(skb->truesize, &sk->sk_wmem_alloc); |
75 | return skb; | 75 | return skb; |
76 | } | 76 | } |
@@ -145,7 +145,7 @@ int vcc_create(struct net *net, struct socket *sock, int protocol, int family) | |||
145 | memset(&vcc->local,0,sizeof(struct sockaddr_atmsvc)); | 145 | memset(&vcc->local,0,sizeof(struct sockaddr_atmsvc)); |
146 | memset(&vcc->remote,0,sizeof(struct sockaddr_atmsvc)); | 146 | memset(&vcc->remote,0,sizeof(struct sockaddr_atmsvc)); |
147 | vcc->qos.txtp.max_sdu = 1 << 16; /* for meta VCs */ | 147 | vcc->qos.txtp.max_sdu = 1 << 16; /* for meta VCs */ |
148 | atomic_set(&sk->sk_wmem_alloc, 0); | 148 | atomic_set(&sk->sk_wmem_alloc, 1); |
149 | atomic_set(&sk->sk_rmem_alloc, 0); | 149 | atomic_set(&sk->sk_rmem_alloc, 0); |
150 | vcc->push = NULL; | 150 | vcc->push = NULL; |
151 | vcc->pop = NULL; | 151 | vcc->pop = NULL; |
diff --git a/net/atm/ioctl.c b/net/atm/ioctl.c index 76ed3c8d26e6..4da8892ced5f 100644 --- a/net/atm/ioctl.c +++ b/net/atm/ioctl.c | |||
@@ -63,8 +63,7 @@ static int do_vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg | |||
63 | error = -EINVAL; | 63 | error = -EINVAL; |
64 | goto done; | 64 | goto done; |
65 | } | 65 | } |
66 | error = put_user(sk->sk_sndbuf - | 66 | error = put_user(sk->sk_sndbuf - sk_wmem_alloc_get(sk), |
67 | atomic_read(&sk->sk_wmem_alloc), | ||
68 | (int __user *) argp) ? -EFAULT : 0; | 67 | (int __user *) argp) ? -EFAULT : 0; |
69 | goto done; | 68 | goto done; |
70 | case SIOCINQ: | 69 | case SIOCINQ: |
diff --git a/net/atm/proc.c b/net/atm/proc.c index e7b3b273907d..38de5ff61ecd 100644 --- a/net/atm/proc.c +++ b/net/atm/proc.c | |||
@@ -204,8 +204,8 @@ static void vcc_info(struct seq_file *seq, struct atm_vcc *vcc) | |||
204 | seq_printf(seq, "%3d", sk->sk_family); | 204 | seq_printf(seq, "%3d", sk->sk_family); |
205 | } | 205 | } |
206 | seq_printf(seq, " %04lx %5d %7d/%7d %7d/%7d [%d]\n", vcc->flags, sk->sk_err, | 206 | seq_printf(seq, " %04lx %5d %7d/%7d %7d/%7d [%d]\n", vcc->flags, sk->sk_err, |
207 | atomic_read(&sk->sk_wmem_alloc), sk->sk_sndbuf, | 207 | sk_wmem_alloc_get(sk), sk->sk_sndbuf, |
208 | atomic_read(&sk->sk_rmem_alloc), sk->sk_rcvbuf, | 208 | sk_rmem_alloc_get(sk), sk->sk_rcvbuf, |
209 | atomic_read(&sk->sk_refcnt)); | 209 | atomic_read(&sk->sk_refcnt)); |
210 | } | 210 | } |
211 | 211 | ||
diff --git a/net/atm/raw.c b/net/atm/raw.c index b0a2d8cb6744..cbfcc71a17b1 100644 --- a/net/atm/raw.c +++ b/net/atm/raw.c | |||
@@ -33,7 +33,7 @@ static void atm_pop_raw(struct atm_vcc *vcc,struct sk_buff *skb) | |||
33 | struct sock *sk = sk_atm(vcc); | 33 | struct sock *sk = sk_atm(vcc); |
34 | 34 | ||
35 | pr_debug("APopR (%d) %d -= %d\n", vcc->vci, | 35 | pr_debug("APopR (%d) %d -= %d\n", vcc->vci, |
36 | atomic_read(&sk->sk_wmem_alloc), skb->truesize); | 36 | sk_wmem_alloc_get(sk), skb->truesize); |
37 | atomic_sub(skb->truesize, &sk->sk_wmem_alloc); | 37 | atomic_sub(skb->truesize, &sk->sk_wmem_alloc); |
38 | dev_kfree_skb_any(skb); | 38 | dev_kfree_skb_any(skb); |
39 | sk->sk_write_space(sk); | 39 | sk->sk_write_space(sk); |
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index fd9d06f291dc..da0f64f82b57 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c | |||
@@ -330,8 +330,7 @@ void ax25_destroy_socket(ax25_cb *ax25) | |||
330 | } | 330 | } |
331 | 331 | ||
332 | if (ax25->sk != NULL) { | 332 | if (ax25->sk != NULL) { |
333 | if (atomic_read(&ax25->sk->sk_wmem_alloc) || | 333 | if (sk_has_allocations(ax25->sk)) { |
334 | atomic_read(&ax25->sk->sk_rmem_alloc)) { | ||
335 | /* Defer: outstanding buffers */ | 334 | /* Defer: outstanding buffers */ |
336 | setup_timer(&ax25->dtimer, ax25_destroy_timer, | 335 | setup_timer(&ax25->dtimer, ax25_destroy_timer, |
337 | (unsigned long)ax25); | 336 | (unsigned long)ax25); |
@@ -1691,7 +1690,8 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1691 | switch (cmd) { | 1690 | switch (cmd) { |
1692 | case TIOCOUTQ: { | 1691 | case TIOCOUTQ: { |
1693 | long amount; | 1692 | long amount; |
1694 | amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); | 1693 | |
1694 | amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); | ||
1695 | if (amount < 0) | 1695 | if (amount < 0) |
1696 | amount = 0; | 1696 | amount = 0; |
1697 | res = put_user(amount, (int __user *)argp); | 1697 | res = put_user(amount, (int __user *)argp); |
@@ -1781,8 +1781,8 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1781 | ax25_info.idletimer = ax25_display_timer(&ax25->idletimer) / (60 * HZ); | 1781 | ax25_info.idletimer = ax25_display_timer(&ax25->idletimer) / (60 * HZ); |
1782 | ax25_info.n2count = ax25->n2count; | 1782 | ax25_info.n2count = ax25->n2count; |
1783 | ax25_info.state = ax25->state; | 1783 | ax25_info.state = ax25->state; |
1784 | ax25_info.rcv_q = atomic_read(&sk->sk_rmem_alloc); | 1784 | ax25_info.rcv_q = sk_wmem_alloc_get(sk); |
1785 | ax25_info.snd_q = atomic_read(&sk->sk_wmem_alloc); | 1785 | ax25_info.snd_q = sk_rmem_alloc_get(sk); |
1786 | ax25_info.vs = ax25->vs; | 1786 | ax25_info.vs = ax25->vs; |
1787 | ax25_info.vr = ax25->vr; | 1787 | ax25_info.vr = ax25->vr; |
1788 | ax25_info.va = ax25->va; | 1788 | ax25_info.va = ax25->va; |
@@ -1922,8 +1922,8 @@ static int ax25_info_show(struct seq_file *seq, void *v) | |||
1922 | 1922 | ||
1923 | if (ax25->sk != NULL) { | 1923 | if (ax25->sk != NULL) { |
1924 | seq_printf(seq, " %d %d %lu\n", | 1924 | seq_printf(seq, " %d %d %lu\n", |
1925 | atomic_read(&ax25->sk->sk_wmem_alloc), | 1925 | sk_wmem_alloc_get(ax25->sk), |
1926 | atomic_read(&ax25->sk->sk_rmem_alloc), | 1926 | sk_rmem_alloc_get(ax25->sk), |
1927 | sock_i_ino(ax25->sk)); | 1927 | sock_i_ino(ax25->sk)); |
1928 | } else { | 1928 | } else { |
1929 | seq_puts(seq, " * * *\n"); | 1929 | seq_puts(seq, " * * *\n"); |
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 02b9baa1930b..0250e0600150 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -337,7 +337,7 @@ int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
337 | if (sk->sk_state == BT_LISTEN) | 337 | if (sk->sk_state == BT_LISTEN) |
338 | return -EINVAL; | 338 | return -EINVAL; |
339 | 339 | ||
340 | amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); | 340 | amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); |
341 | if (amount < 0) | 341 | if (amount < 0) |
342 | amount = 0; | 342 | amount = 0; |
343 | err = put_user(amount, (int __user *) arg); | 343 | err = put_user(amount, (int __user *) arg); |
diff --git a/net/core/dev.c b/net/core/dev.c index 576a61574a93..baf2dc13a34a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -3461,10 +3461,10 @@ void __dev_set_rx_mode(struct net_device *dev) | |||
3461 | /* Unicast addresses changes may only happen under the rtnl, | 3461 | /* Unicast addresses changes may only happen under the rtnl, |
3462 | * therefore calling __dev_set_promiscuity here is safe. | 3462 | * therefore calling __dev_set_promiscuity here is safe. |
3463 | */ | 3463 | */ |
3464 | if (dev->uc_count > 0 && !dev->uc_promisc) { | 3464 | if (dev->uc.count > 0 && !dev->uc_promisc) { |
3465 | __dev_set_promiscuity(dev, 1); | 3465 | __dev_set_promiscuity(dev, 1); |
3466 | dev->uc_promisc = 1; | 3466 | dev->uc_promisc = 1; |
3467 | } else if (dev->uc_count == 0 && dev->uc_promisc) { | 3467 | } else if (dev->uc.count == 0 && dev->uc_promisc) { |
3468 | __dev_set_promiscuity(dev, -1); | 3468 | __dev_set_promiscuity(dev, -1); |
3469 | dev->uc_promisc = 0; | 3469 | dev->uc_promisc = 0; |
3470 | } | 3470 | } |
@@ -3483,9 +3483,8 @@ void dev_set_rx_mode(struct net_device *dev) | |||
3483 | 3483 | ||
3484 | /* hw addresses list handling functions */ | 3484 | /* hw addresses list handling functions */ |
3485 | 3485 | ||
3486 | static int __hw_addr_add(struct list_head *list, int *delta, | 3486 | static int __hw_addr_add(struct netdev_hw_addr_list *list, unsigned char *addr, |
3487 | unsigned char *addr, int addr_len, | 3487 | int addr_len, unsigned char addr_type) |
3488 | unsigned char addr_type) | ||
3489 | { | 3488 | { |
3490 | struct netdev_hw_addr *ha; | 3489 | struct netdev_hw_addr *ha; |
3491 | int alloc_size; | 3490 | int alloc_size; |
@@ -3493,7 +3492,7 @@ static int __hw_addr_add(struct list_head *list, int *delta, | |||
3493 | if (addr_len > MAX_ADDR_LEN) | 3492 | if (addr_len > MAX_ADDR_LEN) |
3494 | return -EINVAL; | 3493 | return -EINVAL; |
3495 | 3494 | ||
3496 | list_for_each_entry(ha, list, list) { | 3495 | list_for_each_entry(ha, &list->list, list) { |
3497 | if (!memcmp(ha->addr, addr, addr_len) && | 3496 | if (!memcmp(ha->addr, addr, addr_len) && |
3498 | ha->type == addr_type) { | 3497 | ha->type == addr_type) { |
3499 | ha->refcount++; | 3498 | ha->refcount++; |
@@ -3512,9 +3511,8 @@ static int __hw_addr_add(struct list_head *list, int *delta, | |||
3512 | ha->type = addr_type; | 3511 | ha->type = addr_type; |
3513 | ha->refcount = 1; | 3512 | ha->refcount = 1; |
3514 | ha->synced = false; | 3513 | ha->synced = false; |
3515 | list_add_tail_rcu(&ha->list, list); | 3514 | list_add_tail_rcu(&ha->list, &list->list); |
3516 | if (delta) | 3515 | list->count++; |
3517 | (*delta)++; | ||
3518 | return 0; | 3516 | return 0; |
3519 | } | 3517 | } |
3520 | 3518 | ||
@@ -3526,120 +3524,121 @@ static void ha_rcu_free(struct rcu_head *head) | |||
3526 | kfree(ha); | 3524 | kfree(ha); |
3527 | } | 3525 | } |
3528 | 3526 | ||
3529 | static int __hw_addr_del(struct list_head *list, int *delta, | 3527 | static int __hw_addr_del(struct netdev_hw_addr_list *list, unsigned char *addr, |
3530 | unsigned char *addr, int addr_len, | 3528 | int addr_len, unsigned char addr_type) |
3531 | unsigned char addr_type) | ||
3532 | { | 3529 | { |
3533 | struct netdev_hw_addr *ha; | 3530 | struct netdev_hw_addr *ha; |
3534 | 3531 | ||
3535 | list_for_each_entry(ha, list, list) { | 3532 | list_for_each_entry(ha, &list->list, list) { |
3536 | if (!memcmp(ha->addr, addr, addr_len) && | 3533 | if (!memcmp(ha->addr, addr, addr_len) && |
3537 | (ha->type == addr_type || !addr_type)) { | 3534 | (ha->type == addr_type || !addr_type)) { |
3538 | if (--ha->refcount) | 3535 | if (--ha->refcount) |
3539 | return 0; | 3536 | return 0; |
3540 | list_del_rcu(&ha->list); | 3537 | list_del_rcu(&ha->list); |
3541 | call_rcu(&ha->rcu_head, ha_rcu_free); | 3538 | call_rcu(&ha->rcu_head, ha_rcu_free); |
3542 | if (delta) | 3539 | list->count--; |
3543 | (*delta)--; | ||
3544 | return 0; | 3540 | return 0; |
3545 | } | 3541 | } |
3546 | } | 3542 | } |
3547 | return -ENOENT; | 3543 | return -ENOENT; |
3548 | } | 3544 | } |
3549 | 3545 | ||
3550 | static int __hw_addr_add_multiple(struct list_head *to_list, int *to_delta, | 3546 | static int __hw_addr_add_multiple(struct netdev_hw_addr_list *to_list, |
3551 | struct list_head *from_list, int addr_len, | 3547 | struct netdev_hw_addr_list *from_list, |
3548 | int addr_len, | ||
3552 | unsigned char addr_type) | 3549 | unsigned char addr_type) |
3553 | { | 3550 | { |
3554 | int err; | 3551 | int err; |
3555 | struct netdev_hw_addr *ha, *ha2; | 3552 | struct netdev_hw_addr *ha, *ha2; |
3556 | unsigned char type; | 3553 | unsigned char type; |
3557 | 3554 | ||
3558 | list_for_each_entry(ha, from_list, list) { | 3555 | list_for_each_entry(ha, &from_list->list, list) { |
3559 | type = addr_type ? addr_type : ha->type; | 3556 | type = addr_type ? addr_type : ha->type; |
3560 | err = __hw_addr_add(to_list, to_delta, ha->addr, | 3557 | err = __hw_addr_add(to_list, ha->addr, addr_len, type); |
3561 | addr_len, type); | ||
3562 | if (err) | 3558 | if (err) |
3563 | goto unroll; | 3559 | goto unroll; |
3564 | } | 3560 | } |
3565 | return 0; | 3561 | return 0; |
3566 | 3562 | ||
3567 | unroll: | 3563 | unroll: |
3568 | list_for_each_entry(ha2, from_list, list) { | 3564 | list_for_each_entry(ha2, &from_list->list, list) { |
3569 | if (ha2 == ha) | 3565 | if (ha2 == ha) |
3570 | break; | 3566 | break; |
3571 | type = addr_type ? addr_type : ha2->type; | 3567 | type = addr_type ? addr_type : ha2->type; |
3572 | __hw_addr_del(to_list, to_delta, ha2->addr, | 3568 | __hw_addr_del(to_list, ha2->addr, addr_len, type); |
3573 | addr_len, type); | ||
3574 | } | 3569 | } |
3575 | return err; | 3570 | return err; |
3576 | } | 3571 | } |
3577 | 3572 | ||
3578 | static void __hw_addr_del_multiple(struct list_head *to_list, int *to_delta, | 3573 | static void __hw_addr_del_multiple(struct netdev_hw_addr_list *to_list, |
3579 | struct list_head *from_list, int addr_len, | 3574 | struct netdev_hw_addr_list *from_list, |
3575 | int addr_len, | ||
3580 | unsigned char addr_type) | 3576 | unsigned char addr_type) |
3581 | { | 3577 | { |
3582 | struct netdev_hw_addr *ha; | 3578 | struct netdev_hw_addr *ha; |
3583 | unsigned char type; | 3579 | unsigned char type; |
3584 | 3580 | ||
3585 | list_for_each_entry(ha, from_list, list) { | 3581 | list_for_each_entry(ha, &from_list->list, list) { |
3586 | type = addr_type ? addr_type : ha->type; | 3582 | type = addr_type ? addr_type : ha->type; |
3587 | __hw_addr_del(to_list, to_delta, ha->addr, | 3583 | __hw_addr_del(to_list, ha->addr, addr_len, addr_type); |
3588 | addr_len, addr_type); | ||
3589 | } | 3584 | } |
3590 | } | 3585 | } |
3591 | 3586 | ||
3592 | static int __hw_addr_sync(struct list_head *to_list, int *to_delta, | 3587 | static int __hw_addr_sync(struct netdev_hw_addr_list *to_list, |
3593 | struct list_head *from_list, int *from_delta, | 3588 | struct netdev_hw_addr_list *from_list, |
3594 | int addr_len) | 3589 | int addr_len) |
3595 | { | 3590 | { |
3596 | int err = 0; | 3591 | int err = 0; |
3597 | struct netdev_hw_addr *ha, *tmp; | 3592 | struct netdev_hw_addr *ha, *tmp; |
3598 | 3593 | ||
3599 | list_for_each_entry_safe(ha, tmp, from_list, list) { | 3594 | list_for_each_entry_safe(ha, tmp, &from_list->list, list) { |
3600 | if (!ha->synced) { | 3595 | if (!ha->synced) { |
3601 | err = __hw_addr_add(to_list, to_delta, ha->addr, | 3596 | err = __hw_addr_add(to_list, ha->addr, |
3602 | addr_len, ha->type); | 3597 | addr_len, ha->type); |
3603 | if (err) | 3598 | if (err) |
3604 | break; | 3599 | break; |
3605 | ha->synced = true; | 3600 | ha->synced = true; |
3606 | ha->refcount++; | 3601 | ha->refcount++; |
3607 | } else if (ha->refcount == 1) { | 3602 | } else if (ha->refcount == 1) { |
3608 | __hw_addr_del(to_list, to_delta, ha->addr, | 3603 | __hw_addr_del(to_list, ha->addr, addr_len, ha->type); |
3609 | addr_len, ha->type); | 3604 | __hw_addr_del(from_list, ha->addr, addr_len, ha->type); |
3610 | __hw_addr_del(from_list, from_delta, ha->addr, | ||
3611 | addr_len, ha->type); | ||
3612 | } | 3605 | } |
3613 | } | 3606 | } |
3614 | return err; | 3607 | return err; |
3615 | } | 3608 | } |
3616 | 3609 | ||
3617 | static void __hw_addr_unsync(struct list_head *to_list, int *to_delta, | 3610 | static void __hw_addr_unsync(struct netdev_hw_addr_list *to_list, |
3618 | struct list_head *from_list, int *from_delta, | 3611 | struct netdev_hw_addr_list *from_list, |
3619 | int addr_len) | 3612 | int addr_len) |
3620 | { | 3613 | { |
3621 | struct netdev_hw_addr *ha, *tmp; | 3614 | struct netdev_hw_addr *ha, *tmp; |
3622 | 3615 | ||
3623 | list_for_each_entry_safe(ha, tmp, from_list, list) { | 3616 | list_for_each_entry_safe(ha, tmp, &from_list->list, list) { |
3624 | if (ha->synced) { | 3617 | if (ha->synced) { |
3625 | __hw_addr_del(to_list, to_delta, ha->addr, | 3618 | __hw_addr_del(to_list, ha->addr, |
3626 | addr_len, ha->type); | 3619 | addr_len, ha->type); |
3627 | ha->synced = false; | 3620 | ha->synced = false; |
3628 | __hw_addr_del(from_list, from_delta, ha->addr, | 3621 | __hw_addr_del(from_list, ha->addr, |
3629 | addr_len, ha->type); | 3622 | addr_len, ha->type); |
3630 | } | 3623 | } |
3631 | } | 3624 | } |
3632 | } | 3625 | } |
3633 | 3626 | ||
3634 | 3627 | static void __hw_addr_flush(struct netdev_hw_addr_list *list) | |
3635 | static void __hw_addr_flush(struct list_head *list) | ||
3636 | { | 3628 | { |
3637 | struct netdev_hw_addr *ha, *tmp; | 3629 | struct netdev_hw_addr *ha, *tmp; |
3638 | 3630 | ||
3639 | list_for_each_entry_safe(ha, tmp, list, list) { | 3631 | list_for_each_entry_safe(ha, tmp, &list->list, list) { |
3640 | list_del_rcu(&ha->list); | 3632 | list_del_rcu(&ha->list); |
3641 | call_rcu(&ha->rcu_head, ha_rcu_free); | 3633 | call_rcu(&ha->rcu_head, ha_rcu_free); |
3642 | } | 3634 | } |
3635 | list->count = 0; | ||
3636 | } | ||
3637 | |||
3638 | static void __hw_addr_init(struct netdev_hw_addr_list *list) | ||
3639 | { | ||
3640 | INIT_LIST_HEAD(&list->list); | ||
3641 | list->count = 0; | ||
3643 | } | 3642 | } |
3644 | 3643 | ||
3645 | /* Device addresses handling functions */ | 3644 | /* Device addresses handling functions */ |
@@ -3648,7 +3647,7 @@ static void dev_addr_flush(struct net_device *dev) | |||
3648 | { | 3647 | { |
3649 | /* rtnl_mutex must be held here */ | 3648 | /* rtnl_mutex must be held here */ |
3650 | 3649 | ||
3651 | __hw_addr_flush(&dev->dev_addr_list); | 3650 | __hw_addr_flush(&dev->dev_addrs); |
3652 | dev->dev_addr = NULL; | 3651 | dev->dev_addr = NULL; |
3653 | } | 3652 | } |
3654 | 3653 | ||
@@ -3660,16 +3659,16 @@ static int dev_addr_init(struct net_device *dev) | |||
3660 | 3659 | ||
3661 | /* rtnl_mutex must be held here */ | 3660 | /* rtnl_mutex must be held here */ |
3662 | 3661 | ||
3663 | INIT_LIST_HEAD(&dev->dev_addr_list); | 3662 | __hw_addr_init(&dev->dev_addrs); |
3664 | memset(addr, 0, sizeof(addr)); | 3663 | memset(addr, 0, sizeof(addr)); |
3665 | err = __hw_addr_add(&dev->dev_addr_list, NULL, addr, sizeof(addr), | 3664 | err = __hw_addr_add(&dev->dev_addrs, addr, sizeof(addr), |
3666 | NETDEV_HW_ADDR_T_LAN); | 3665 | NETDEV_HW_ADDR_T_LAN); |
3667 | if (!err) { | 3666 | if (!err) { |
3668 | /* | 3667 | /* |
3669 | * Get the first (previously created) address from the list | 3668 | * Get the first (previously created) address from the list |
3670 | * and set dev_addr pointer to this location. | 3669 | * and set dev_addr pointer to this location. |
3671 | */ | 3670 | */ |
3672 | ha = list_first_entry(&dev->dev_addr_list, | 3671 | ha = list_first_entry(&dev->dev_addrs.list, |
3673 | struct netdev_hw_addr, list); | 3672 | struct netdev_hw_addr, list); |
3674 | dev->dev_addr = ha->addr; | 3673 | dev->dev_addr = ha->addr; |
3675 | } | 3674 | } |
@@ -3694,8 +3693,7 @@ int dev_addr_add(struct net_device *dev, unsigned char *addr, | |||
3694 | 3693 | ||
3695 | ASSERT_RTNL(); | 3694 | ASSERT_RTNL(); |
3696 | 3695 | ||
3697 | err = __hw_addr_add(&dev->dev_addr_list, NULL, addr, dev->addr_len, | 3696 | err = __hw_addr_add(&dev->dev_addrs, addr, dev->addr_len, addr_type); |
3698 | addr_type); | ||
3699 | if (!err) | 3697 | if (!err) |
3700 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); | 3698 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); |
3701 | return err; | 3699 | return err; |
@@ -3725,11 +3723,12 @@ int dev_addr_del(struct net_device *dev, unsigned char *addr, | |||
3725 | * We can not remove the first address from the list because | 3723 | * We can not remove the first address from the list because |
3726 | * dev->dev_addr points to that. | 3724 | * dev->dev_addr points to that. |
3727 | */ | 3725 | */ |
3728 | ha = list_first_entry(&dev->dev_addr_list, struct netdev_hw_addr, list); | 3726 | ha = list_first_entry(&dev->dev_addrs.list, |
3727 | struct netdev_hw_addr, list); | ||
3729 | if (ha->addr == dev->dev_addr && ha->refcount == 1) | 3728 | if (ha->addr == dev->dev_addr && ha->refcount == 1) |
3730 | return -ENOENT; | 3729 | return -ENOENT; |
3731 | 3730 | ||
3732 | err = __hw_addr_del(&dev->dev_addr_list, NULL, addr, dev->addr_len, | 3731 | err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len, |
3733 | addr_type); | 3732 | addr_type); |
3734 | if (!err) | 3733 | if (!err) |
3735 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); | 3734 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); |
@@ -3757,8 +3756,7 @@ int dev_addr_add_multiple(struct net_device *to_dev, | |||
3757 | 3756 | ||
3758 | if (from_dev->addr_len != to_dev->addr_len) | 3757 | if (from_dev->addr_len != to_dev->addr_len) |
3759 | return -EINVAL; | 3758 | return -EINVAL; |
3760 | err = __hw_addr_add_multiple(&to_dev->dev_addr_list, NULL, | 3759 | err = __hw_addr_add_multiple(&to_dev->dev_addrs, &from_dev->dev_addrs, |
3761 | &from_dev->dev_addr_list, | ||
3762 | to_dev->addr_len, addr_type); | 3760 | to_dev->addr_len, addr_type); |
3763 | if (!err) | 3761 | if (!err) |
3764 | call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); | 3762 | call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); |
@@ -3784,15 +3782,14 @@ int dev_addr_del_multiple(struct net_device *to_dev, | |||
3784 | 3782 | ||
3785 | if (from_dev->addr_len != to_dev->addr_len) | 3783 | if (from_dev->addr_len != to_dev->addr_len) |
3786 | return -EINVAL; | 3784 | return -EINVAL; |
3787 | __hw_addr_del_multiple(&to_dev->dev_addr_list, NULL, | 3785 | __hw_addr_del_multiple(&to_dev->dev_addrs, &from_dev->dev_addrs, |
3788 | &from_dev->dev_addr_list, | ||
3789 | to_dev->addr_len, addr_type); | 3786 | to_dev->addr_len, addr_type); |
3790 | call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); | 3787 | call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); |
3791 | return 0; | 3788 | return 0; |
3792 | } | 3789 | } |
3793 | EXPORT_SYMBOL(dev_addr_del_multiple); | 3790 | EXPORT_SYMBOL(dev_addr_del_multiple); |
3794 | 3791 | ||
3795 | /* unicast and multicast addresses handling functions */ | 3792 | /* multicast addresses handling functions */ |
3796 | 3793 | ||
3797 | int __dev_addr_delete(struct dev_addr_list **list, int *count, | 3794 | int __dev_addr_delete(struct dev_addr_list **list, int *count, |
3798 | void *addr, int alen, int glbl) | 3795 | void *addr, int alen, int glbl) |
@@ -3868,8 +3865,8 @@ int dev_unicast_delete(struct net_device *dev, void *addr) | |||
3868 | 3865 | ||
3869 | ASSERT_RTNL(); | 3866 | ASSERT_RTNL(); |
3870 | 3867 | ||
3871 | err = __hw_addr_del(&dev->uc_list, &dev->uc_count, addr, | 3868 | err = __hw_addr_del(&dev->uc, addr, dev->addr_len, |
3872 | dev->addr_len, NETDEV_HW_ADDR_T_UNICAST); | 3869 | NETDEV_HW_ADDR_T_UNICAST); |
3873 | if (!err) | 3870 | if (!err) |
3874 | __dev_set_rx_mode(dev); | 3871 | __dev_set_rx_mode(dev); |
3875 | return err; | 3872 | return err; |
@@ -3892,8 +3889,8 @@ int dev_unicast_add(struct net_device *dev, void *addr) | |||
3892 | 3889 | ||
3893 | ASSERT_RTNL(); | 3890 | ASSERT_RTNL(); |
3894 | 3891 | ||
3895 | err = __hw_addr_add(&dev->uc_list, &dev->uc_count, addr, | 3892 | err = __hw_addr_add(&dev->uc, addr, dev->addr_len, |
3896 | dev->addr_len, NETDEV_HW_ADDR_T_UNICAST); | 3893 | NETDEV_HW_ADDR_T_UNICAST); |
3897 | if (!err) | 3894 | if (!err) |
3898 | __dev_set_rx_mode(dev); | 3895 | __dev_set_rx_mode(dev); |
3899 | return err; | 3896 | return err; |
@@ -3966,8 +3963,7 @@ int dev_unicast_sync(struct net_device *to, struct net_device *from) | |||
3966 | if (to->addr_len != from->addr_len) | 3963 | if (to->addr_len != from->addr_len) |
3967 | return -EINVAL; | 3964 | return -EINVAL; |
3968 | 3965 | ||
3969 | err = __hw_addr_sync(&to->uc_list, &to->uc_count, | 3966 | err = __hw_addr_sync(&to->uc, &from->uc, to->addr_len); |
3970 | &from->uc_list, &from->uc_count, to->addr_len); | ||
3971 | if (!err) | 3967 | if (!err) |
3972 | __dev_set_rx_mode(to); | 3968 | __dev_set_rx_mode(to); |
3973 | return err; | 3969 | return err; |
@@ -3990,8 +3986,7 @@ void dev_unicast_unsync(struct net_device *to, struct net_device *from) | |||
3990 | if (to->addr_len != from->addr_len) | 3986 | if (to->addr_len != from->addr_len) |
3991 | return; | 3987 | return; |
3992 | 3988 | ||
3993 | __hw_addr_unsync(&to->uc_list, &to->uc_count, | 3989 | __hw_addr_unsync(&to->uc, &from->uc, to->addr_len); |
3994 | &from->uc_list, &from->uc_count, to->addr_len); | ||
3995 | __dev_set_rx_mode(to); | 3990 | __dev_set_rx_mode(to); |
3996 | } | 3991 | } |
3997 | EXPORT_SYMBOL(dev_unicast_unsync); | 3992 | EXPORT_SYMBOL(dev_unicast_unsync); |
@@ -4000,15 +3995,14 @@ static void dev_unicast_flush(struct net_device *dev) | |||
4000 | { | 3995 | { |
4001 | /* rtnl_mutex must be held here */ | 3996 | /* rtnl_mutex must be held here */ |
4002 | 3997 | ||
4003 | __hw_addr_flush(&dev->uc_list); | 3998 | __hw_addr_flush(&dev->uc); |
4004 | dev->uc_count = 0; | ||
4005 | } | 3999 | } |
4006 | 4000 | ||
4007 | static void dev_unicast_init(struct net_device *dev) | 4001 | static void dev_unicast_init(struct net_device *dev) |
4008 | { | 4002 | { |
4009 | /* rtnl_mutex must be held here */ | 4003 | /* rtnl_mutex must be held here */ |
4010 | 4004 | ||
4011 | INIT_LIST_HEAD(&dev->uc_list); | 4005 | __hw_addr_init(&dev->uc); |
4012 | } | 4006 | } |
4013 | 4007 | ||
4014 | 4008 | ||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 5c93435b0347..9e0597d189b0 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -204,6 +204,10 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, | |||
204 | skb->end = skb->tail + size; | 204 | skb->end = skb->tail + size; |
205 | kmemcheck_annotate_bitfield(skb, flags1); | 205 | kmemcheck_annotate_bitfield(skb, flags1); |
206 | kmemcheck_annotate_bitfield(skb, flags2); | 206 | kmemcheck_annotate_bitfield(skb, flags2); |
207 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | ||
208 | skb->mac_header = ~0U; | ||
209 | #endif | ||
210 | |||
207 | /* make sure we initialize shinfo sequentially */ | 211 | /* make sure we initialize shinfo sequentially */ |
208 | shinfo = skb_shinfo(skb); | 212 | shinfo = skb_shinfo(skb); |
209 | atomic_set(&shinfo->dataref, 1); | 213 | atomic_set(&shinfo->dataref, 1); |
@@ -665,7 +669,8 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) | |||
665 | /* {transport,network,mac}_header are relative to skb->head */ | 669 | /* {transport,network,mac}_header are relative to skb->head */ |
666 | new->transport_header += offset; | 670 | new->transport_header += offset; |
667 | new->network_header += offset; | 671 | new->network_header += offset; |
668 | new->mac_header += offset; | 672 | if (skb_mac_header_was_set(new)) |
673 | new->mac_header += offset; | ||
669 | #endif | 674 | #endif |
670 | skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size; | 675 | skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size; |
671 | skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs; | 676 | skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs; |
@@ -847,7 +852,8 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, | |||
847 | skb->tail += off; | 852 | skb->tail += off; |
848 | skb->transport_header += off; | 853 | skb->transport_header += off; |
849 | skb->network_header += off; | 854 | skb->network_header += off; |
850 | skb->mac_header += off; | 855 | if (skb_mac_header_was_set(skb)) |
856 | skb->mac_header += off; | ||
851 | skb->csum_start += nhead; | 857 | skb->csum_start += nhead; |
852 | skb->cloned = 0; | 858 | skb->cloned = 0; |
853 | skb->hdr_len = 0; | 859 | skb->hdr_len = 0; |
@@ -939,7 +945,8 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb, | |||
939 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | 945 | #ifdef NET_SKBUFF_DATA_USES_OFFSET |
940 | n->transport_header += off; | 946 | n->transport_header += off; |
941 | n->network_header += off; | 947 | n->network_header += off; |
942 | n->mac_header += off; | 948 | if (skb_mac_header_was_set(skb)) |
949 | n->mac_header += off; | ||
943 | #endif | 950 | #endif |
944 | 951 | ||
945 | return n; | 952 | return n; |
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index a5e3a593e472..d351b8db0df5 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c | |||
@@ -1240,7 +1240,7 @@ static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1240 | return val; | 1240 | return val; |
1241 | 1241 | ||
1242 | case TIOCOUTQ: | 1242 | case TIOCOUTQ: |
1243 | amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); | 1243 | amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); |
1244 | if (amount < 0) | 1244 | if (amount < 0) |
1245 | amount = 0; | 1245 | amount = 0; |
1246 | err = put_user(amount, (int __user *)arg); | 1246 | err = put_user(amount, (int __user *)arg); |
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index 8121bf0029e3..2e1f836d4240 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c | |||
@@ -540,8 +540,7 @@ static void econet_destroy_timer(unsigned long data) | |||
540 | { | 540 | { |
541 | struct sock *sk=(struct sock *)data; | 541 | struct sock *sk=(struct sock *)data; |
542 | 542 | ||
543 | if (!atomic_read(&sk->sk_wmem_alloc) && | 543 | if (!sk_has_allocations(sk)) { |
544 | !atomic_read(&sk->sk_rmem_alloc)) { | ||
545 | sk_free(sk); | 544 | sk_free(sk); |
546 | return; | 545 | return; |
547 | } | 546 | } |
@@ -579,8 +578,7 @@ static int econet_release(struct socket *sock) | |||
579 | 578 | ||
580 | skb_queue_purge(&sk->sk_receive_queue); | 579 | skb_queue_purge(&sk->sk_receive_queue); |
581 | 580 | ||
582 | if (atomic_read(&sk->sk_rmem_alloc) || | 581 | if (sk_has_allocations(sk)) { |
583 | atomic_read(&sk->sk_wmem_alloc)) { | ||
584 | sk->sk_timer.data = (unsigned long)sk; | 582 | sk->sk_timer.data = (unsigned long)sk; |
585 | sk->sk_timer.expires = jiffies + HZ; | 583 | sk->sk_timer.expires = jiffies + HZ; |
586 | sk->sk_timer.function = econet_destroy_timer; | 584 | sk->sk_timer.function = econet_destroy_timer; |
diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c index 1779677aed46..14d39840dd62 100644 --- a/net/ieee802154/dgram.c +++ b/net/ieee802154/dgram.c | |||
@@ -126,7 +126,8 @@ static int dgram_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
126 | switch (cmd) { | 126 | switch (cmd) { |
127 | case SIOCOUTQ: | 127 | case SIOCOUTQ: |
128 | { | 128 | { |
129 | int amount = atomic_read(&sk->sk_wmem_alloc); | 129 | int amount = sk_wmem_alloc_get(sk); |
130 | |||
130 | return put_user(amount, (int __user *)arg); | 131 | return put_user(amount, (int __user *)arg); |
131 | } | 132 | } |
132 | 133 | ||
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index d1a39b1277d6..012cf5a68581 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -391,13 +391,8 @@ static inline void tnode_free(struct tnode *tn) | |||
391 | static void tnode_free_safe(struct tnode *tn) | 391 | static void tnode_free_safe(struct tnode *tn) |
392 | { | 392 | { |
393 | BUG_ON(IS_LEAF(tn)); | 393 | BUG_ON(IS_LEAF(tn)); |
394 | 394 | tn->tnode_free = tnode_free_head; | |
395 | if (node_parent((struct node *) tn)) { | 395 | tnode_free_head = tn; |
396 | tn->tnode_free = tnode_free_head; | ||
397 | tnode_free_head = tn; | ||
398 | } else { | ||
399 | tnode_free(tn); | ||
400 | } | ||
401 | } | 396 | } |
402 | 397 | ||
403 | static void tnode_free_flush(void) | 398 | static void tnode_free_flush(void) |
@@ -1009,7 +1004,7 @@ fib_find_node(struct trie *t, u32 key) | |||
1009 | return NULL; | 1004 | return NULL; |
1010 | } | 1005 | } |
1011 | 1006 | ||
1012 | static struct node *trie_rebalance(struct trie *t, struct tnode *tn) | 1007 | static void trie_rebalance(struct trie *t, struct tnode *tn) |
1013 | { | 1008 | { |
1014 | int wasfull; | 1009 | int wasfull; |
1015 | t_key cindex, key; | 1010 | t_key cindex, key; |
@@ -1033,12 +1028,13 @@ static struct node *trie_rebalance(struct trie *t, struct tnode *tn) | |||
1033 | } | 1028 | } |
1034 | 1029 | ||
1035 | /* Handle last (top) tnode */ | 1030 | /* Handle last (top) tnode */ |
1036 | if (IS_TNODE(tn)) { | 1031 | if (IS_TNODE(tn)) |
1037 | tn = (struct tnode *)resize(t, (struct tnode *)tn); | 1032 | tn = (struct tnode *)resize(t, (struct tnode *)tn); |
1038 | tnode_free_flush(); | ||
1039 | } | ||
1040 | 1033 | ||
1041 | return (struct node *)tn; | 1034 | rcu_assign_pointer(t->trie, (struct node *)tn); |
1035 | tnode_free_flush(); | ||
1036 | |||
1037 | return; | ||
1042 | } | 1038 | } |
1043 | 1039 | ||
1044 | /* only used from updater-side */ | 1040 | /* only used from updater-side */ |
@@ -1186,7 +1182,7 @@ static struct list_head *fib_insert_node(struct trie *t, u32 key, int plen) | |||
1186 | 1182 | ||
1187 | /* Rebalance the trie */ | 1183 | /* Rebalance the trie */ |
1188 | 1184 | ||
1189 | rcu_assign_pointer(t->trie, trie_rebalance(t, tp)); | 1185 | trie_rebalance(t, tp); |
1190 | done: | 1186 | done: |
1191 | return fa_head; | 1187 | return fa_head; |
1192 | } | 1188 | } |
@@ -1605,7 +1601,7 @@ static void trie_leaf_remove(struct trie *t, struct leaf *l) | |||
1605 | if (tp) { | 1601 | if (tp) { |
1606 | t_key cindex = tkey_extract_bits(l->key, tp->pos, tp->bits); | 1602 | t_key cindex = tkey_extract_bits(l->key, tp->pos, tp->bits); |
1607 | put_child(t, (struct tnode *)tp, cindex, NULL); | 1603 | put_child(t, (struct tnode *)tp, cindex, NULL); |
1608 | rcu_assign_pointer(t->trie, trie_rebalance(t, tp)); | 1604 | trie_rebalance(t, tp); |
1609 | } else | 1605 | } else |
1610 | rcu_assign_pointer(t->trie, NULL); | 1606 | rcu_assign_pointer(t->trie, NULL); |
1611 | 1607 | ||
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index b0b273503e2a..a706a47f4dbb 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
@@ -156,10 +156,10 @@ static int inet_csk_diag_fill(struct sock *sk, | |||
156 | r->idiag_inode = sock_i_ino(sk); | 156 | r->idiag_inode = sock_i_ino(sk); |
157 | 157 | ||
158 | if (minfo) { | 158 | if (minfo) { |
159 | minfo->idiag_rmem = atomic_read(&sk->sk_rmem_alloc); | 159 | minfo->idiag_rmem = sk_rmem_alloc_get(sk); |
160 | minfo->idiag_wmem = sk->sk_wmem_queued; | 160 | minfo->idiag_wmem = sk->sk_wmem_queued; |
161 | minfo->idiag_fmem = sk->sk_forward_alloc; | 161 | minfo->idiag_fmem = sk->sk_forward_alloc; |
162 | minfo->idiag_tmem = atomic_read(&sk->sk_wmem_alloc); | 162 | minfo->idiag_tmem = sk_wmem_alloc_get(sk); |
163 | } | 163 | } |
164 | 164 | ||
165 | handler->idiag_get_info(sk, r, info); | 165 | handler->idiag_get_info(sk, r, info); |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 3dc9171a272f..2979f14bb188 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -799,7 +799,8 @@ static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
799 | { | 799 | { |
800 | switch (cmd) { | 800 | switch (cmd) { |
801 | case SIOCOUTQ: { | 801 | case SIOCOUTQ: { |
802 | int amount = atomic_read(&sk->sk_wmem_alloc); | 802 | int amount = sk_wmem_alloc_get(sk); |
803 | |||
803 | return put_user(amount, (int __user *)arg); | 804 | return put_user(amount, (int __user *)arg); |
804 | } | 805 | } |
805 | case SIOCINQ: { | 806 | case SIOCINQ: { |
@@ -935,8 +936,8 @@ static void raw_sock_seq_show(struct seq_file *seq, struct sock *sp, int i) | |||
935 | seq_printf(seq, "%4d: %08X:%04X %08X:%04X" | 936 | seq_printf(seq, "%4d: %08X:%04X %08X:%04X" |
936 | " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n", | 937 | " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n", |
937 | i, src, srcp, dest, destp, sp->sk_state, | 938 | i, src, srcp, dest, destp, sp->sk_state, |
938 | atomic_read(&sp->sk_wmem_alloc), | 939 | sk_wmem_alloc_get(sp), |
939 | atomic_read(&sp->sk_rmem_alloc), | 940 | sk_rmem_alloc_get(sp), |
940 | 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), | 941 | 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), |
941 | atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops)); | 942 | atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops)); |
942 | } | 943 | } |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 8f4158d7c9a6..80e3812837ad 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -840,7 +840,8 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
840 | switch (cmd) { | 840 | switch (cmd) { |
841 | case SIOCOUTQ: | 841 | case SIOCOUTQ: |
842 | { | 842 | { |
843 | int amount = atomic_read(&sk->sk_wmem_alloc); | 843 | int amount = sk_wmem_alloc_get(sk); |
844 | |||
844 | return put_user(amount, (int __user *)arg); | 845 | return put_user(amount, (int __user *)arg); |
845 | } | 846 | } |
846 | 847 | ||
@@ -1721,8 +1722,8 @@ static void udp4_format_sock(struct sock *sp, struct seq_file *f, | |||
1721 | seq_printf(f, "%4d: %08X:%04X %08X:%04X" | 1722 | seq_printf(f, "%4d: %08X:%04X %08X:%04X" |
1722 | " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d%n", | 1723 | " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d%n", |
1723 | bucket, src, srcp, dest, destp, sp->sk_state, | 1724 | bucket, src, srcp, dest, destp, sp->sk_state, |
1724 | atomic_read(&sp->sk_wmem_alloc), | 1725 | sk_wmem_alloc_get(sp), |
1725 | atomic_read(&sp->sk_rmem_alloc), | 1726 | sk_rmem_alloc_get(sp), |
1726 | 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), | 1727 | 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), |
1727 | atomic_read(&sp->sk_refcnt), sp, | 1728 | atomic_read(&sp->sk_refcnt), sp, |
1728 | atomic_read(&sp->sk_drops), len); | 1729 | atomic_read(&sp->sk_drops), len); |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 36a090d87a3d..8b0b6f948063 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -1130,7 +1130,8 @@ static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
1130 | switch(cmd) { | 1130 | switch(cmd) { |
1131 | case SIOCOUTQ: | 1131 | case SIOCOUTQ: |
1132 | { | 1132 | { |
1133 | int amount = atomic_read(&sk->sk_wmem_alloc); | 1133 | int amount = sk_wmem_alloc_get(sk); |
1134 | |||
1134 | return put_user(amount, (int __user *)arg); | 1135 | return put_user(amount, (int __user *)arg); |
1135 | } | 1136 | } |
1136 | case SIOCINQ: | 1137 | case SIOCINQ: |
@@ -1236,8 +1237,8 @@ static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i) | |||
1236 | dest->s6_addr32[0], dest->s6_addr32[1], | 1237 | dest->s6_addr32[0], dest->s6_addr32[1], |
1237 | dest->s6_addr32[2], dest->s6_addr32[3], destp, | 1238 | dest->s6_addr32[2], dest->s6_addr32[3], destp, |
1238 | sp->sk_state, | 1239 | sp->sk_state, |
1239 | atomic_read(&sp->sk_wmem_alloc), | 1240 | sk_wmem_alloc_get(sp), |
1240 | atomic_read(&sp->sk_rmem_alloc), | 1241 | sk_rmem_alloc_get(sp), |
1241 | 0, 0L, 0, | 1242 | 0, 0L, 0, |
1242 | sock_i_uid(sp), 0, | 1243 | sock_i_uid(sp), 0, |
1243 | sock_i_ino(sp), | 1244 | sock_i_ino(sp), |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index fc333d854728..023beda6b224 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -1061,8 +1061,8 @@ static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket | |||
1061 | dest->s6_addr32[0], dest->s6_addr32[1], | 1061 | dest->s6_addr32[0], dest->s6_addr32[1], |
1062 | dest->s6_addr32[2], dest->s6_addr32[3], destp, | 1062 | dest->s6_addr32[2], dest->s6_addr32[3], destp, |
1063 | sp->sk_state, | 1063 | sp->sk_state, |
1064 | atomic_read(&sp->sk_wmem_alloc), | 1064 | sk_wmem_alloc_get(sp), |
1065 | atomic_read(&sp->sk_rmem_alloc), | 1065 | sk_rmem_alloc_get(sp), |
1066 | 0, 0L, 0, | 1066 | 0, 0L, 0, |
1067 | sock_i_uid(sp), 0, | 1067 | sock_i_uid(sp), 0, |
1068 | sock_i_ino(sp), | 1068 | sock_i_ino(sp), |
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 1627050e29fd..417b0e309495 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c | |||
@@ -1835,7 +1835,7 @@ static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1835 | 1835 | ||
1836 | switch (cmd) { | 1836 | switch (cmd) { |
1837 | case TIOCOUTQ: | 1837 | case TIOCOUTQ: |
1838 | amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); | 1838 | amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); |
1839 | if (amount < 0) | 1839 | if (amount < 0) |
1840 | amount = 0; | 1840 | amount = 0; |
1841 | rc = put_user(amount, (int __user *)argp); | 1841 | rc = put_user(amount, (int __user *)argp); |
diff --git a/net/ipx/ipx_proc.c b/net/ipx/ipx_proc.c index 5ed97ad0e2e3..576178482f89 100644 --- a/net/ipx/ipx_proc.c +++ b/net/ipx/ipx_proc.c | |||
@@ -280,8 +280,8 @@ static int ipx_seq_socket_show(struct seq_file *seq, void *v) | |||
280 | } | 280 | } |
281 | 281 | ||
282 | seq_printf(seq, "%08X %08X %02X %03d\n", | 282 | seq_printf(seq, "%08X %08X %02X %03d\n", |
283 | atomic_read(&s->sk_wmem_alloc), | 283 | sk_wmem_alloc_get(s), |
284 | atomic_read(&s->sk_rmem_alloc), | 284 | sk_rmem_alloc_get(s), |
285 | s->sk_state, SOCK_INODE(s->sk_socket)->i_uid); | 285 | s->sk_state, SOCK_INODE(s->sk_socket)->i_uid); |
286 | out: | 286 | out: |
287 | return 0; | 287 | return 0; |
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index 3eb5bcc75f99..5922febe25c4 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c | |||
@@ -1762,7 +1762,8 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1762 | switch (cmd) { | 1762 | switch (cmd) { |
1763 | case TIOCOUTQ: { | 1763 | case TIOCOUTQ: { |
1764 | long amount; | 1764 | long amount; |
1765 | amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); | 1765 | |
1766 | amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); | ||
1766 | if (amount < 0) | 1767 | if (amount < 0) |
1767 | amount = 0; | 1768 | amount = 0; |
1768 | if (put_user(amount, (unsigned int __user *)arg)) | 1769 | if (put_user(amount, (unsigned int __user *)arg)) |
diff --git a/net/key/af_key.c b/net/key/af_key.c index 643c1be2d02e..dba9abd27f90 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -3662,8 +3662,8 @@ static int pfkey_seq_show(struct seq_file *f, void *v) | |||
3662 | seq_printf(f ,"%p %-6d %-6u %-6u %-6u %-6lu\n", | 3662 | seq_printf(f ,"%p %-6d %-6u %-6u %-6u %-6lu\n", |
3663 | s, | 3663 | s, |
3664 | atomic_read(&s->sk_refcnt), | 3664 | atomic_read(&s->sk_refcnt), |
3665 | atomic_read(&s->sk_rmem_alloc), | 3665 | sk_rmem_alloc_get(s), |
3666 | atomic_read(&s->sk_wmem_alloc), | 3666 | sk_wmem_alloc_get(s), |
3667 | sock_i_uid(s), | 3667 | sock_i_uid(s), |
3668 | sock_i_ino(s) | 3668 | sock_i_ino(s) |
3669 | ); | 3669 | ); |
diff --git a/net/llc/llc_proc.c b/net/llc/llc_proc.c index d208b3396d94..f97be471fe2e 100644 --- a/net/llc/llc_proc.c +++ b/net/llc/llc_proc.c | |||
@@ -134,8 +134,8 @@ static int llc_seq_socket_show(struct seq_file *seq, void *v) | |||
134 | seq_printf(seq, "@%02X ", llc->sap->laddr.lsap); | 134 | seq_printf(seq, "@%02X ", llc->sap->laddr.lsap); |
135 | llc_ui_format_mac(seq, llc->daddr.mac); | 135 | llc_ui_format_mac(seq, llc->daddr.mac); |
136 | seq_printf(seq, "@%02X %8d %8d %2d %3d %4d\n", llc->daddr.lsap, | 136 | seq_printf(seq, "@%02X %8d %8d %2d %3d %4d\n", llc->daddr.lsap, |
137 | atomic_read(&sk->sk_wmem_alloc), | 137 | sk_wmem_alloc_get(sk), |
138 | atomic_read(&sk->sk_rmem_alloc) - llc->copied_seq, | 138 | sk_rmem_alloc_get(sk) - llc->copied_seq, |
139 | sk->sk_state, | 139 | sk->sk_state, |
140 | sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : -1, | 140 | sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : -1, |
141 | llc->link); | 141 | llc->link); |
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 11c72311f35b..6c439cd5ccea 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
@@ -163,6 +163,29 @@ static const struct file_operations noack_ops = { | |||
163 | .open = mac80211_open_file_generic | 163 | .open = mac80211_open_file_generic |
164 | }; | 164 | }; |
165 | 165 | ||
166 | static ssize_t queues_read(struct file *file, char __user *user_buf, | ||
167 | size_t count, loff_t *ppos) | ||
168 | { | ||
169 | struct ieee80211_local *local = file->private_data; | ||
170 | unsigned long flags; | ||
171 | char buf[IEEE80211_MAX_QUEUES * 20]; | ||
172 | int q, res = 0; | ||
173 | |||
174 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | ||
175 | for (q = 0; q < local->hw.queues; q++) | ||
176 | res += sprintf(buf + res, "%02d: %#.8lx/%d\n", q, | ||
177 | local->queue_stop_reasons[q], | ||
178 | __netif_subqueue_stopped(local->mdev, q)); | ||
179 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | ||
180 | |||
181 | return simple_read_from_buffer(user_buf, count, ppos, buf, res); | ||
182 | } | ||
183 | |||
184 | static const struct file_operations queues_ops = { | ||
185 | .read = queues_read, | ||
186 | .open = mac80211_open_file_generic | ||
187 | }; | ||
188 | |||
166 | /* statistics stuff */ | 189 | /* statistics stuff */ |
167 | 190 | ||
168 | #define DEBUGFS_STATS_FILE(name, buflen, fmt, value...) \ | 191 | #define DEBUGFS_STATS_FILE(name, buflen, fmt, value...) \ |
@@ -298,6 +321,7 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
298 | DEBUGFS_ADD(total_ps_buffered); | 321 | DEBUGFS_ADD(total_ps_buffered); |
299 | DEBUGFS_ADD(wep_iv); | 322 | DEBUGFS_ADD(wep_iv); |
300 | DEBUGFS_ADD(tsf); | 323 | DEBUGFS_ADD(tsf); |
324 | DEBUGFS_ADD(queues); | ||
301 | DEBUGFS_ADD_MODE(reset, 0200); | 325 | DEBUGFS_ADD_MODE(reset, 0200); |
302 | DEBUGFS_ADD(noack); | 326 | DEBUGFS_ADD(noack); |
303 | 327 | ||
@@ -350,6 +374,7 @@ void debugfs_hw_del(struct ieee80211_local *local) | |||
350 | DEBUGFS_DEL(total_ps_buffered); | 374 | DEBUGFS_DEL(total_ps_buffered); |
351 | DEBUGFS_DEL(wep_iv); | 375 | DEBUGFS_DEL(wep_iv); |
352 | DEBUGFS_DEL(tsf); | 376 | DEBUGFS_DEL(tsf); |
377 | DEBUGFS_DEL(queues); | ||
353 | DEBUGFS_DEL(reset); | 378 | DEBUGFS_DEL(reset); |
354 | DEBUGFS_DEL(noack); | 379 | DEBUGFS_DEL(noack); |
355 | 380 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 4dbc28964196..68eb5052179a 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -783,6 +783,7 @@ struct ieee80211_local { | |||
783 | struct dentry *total_ps_buffered; | 783 | struct dentry *total_ps_buffered; |
784 | struct dentry *wep_iv; | 784 | struct dentry *wep_iv; |
785 | struct dentry *tsf; | 785 | struct dentry *tsf; |
786 | struct dentry *queues; | ||
786 | struct dentry *reset; | 787 | struct dentry *reset; |
787 | struct dentry *noack; | 788 | struct dentry *noack; |
788 | struct dentry *statistics; | 789 | struct dentry *statistics; |
@@ -1100,7 +1101,6 @@ void ieee802_11_parse_elems(u8 *start, size_t len, | |||
1100 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | 1101 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, |
1101 | struct ieee802_11_elems *elems, | 1102 | struct ieee802_11_elems *elems, |
1102 | u64 filter, u32 crc); | 1103 | u64 filter, u32 crc); |
1103 | int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freq); | ||
1104 | u32 ieee80211_mandatory_rates(struct ieee80211_local *local, | 1104 | u32 ieee80211_mandatory_rates(struct ieee80211_local *local, |
1105 | enum ieee80211_band band); | 1105 | enum ieee80211_band band); |
1106 | 1106 | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index d779c57a8220..aca22b00b6a3 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1102,14 +1102,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1102 | struct sta_info *sta; | 1102 | struct sta_info *sta; |
1103 | u32 changed = 0, config_changed = 0; | 1103 | u32 changed = 0, config_changed = 0; |
1104 | 1104 | ||
1105 | rcu_read_lock(); | ||
1106 | |||
1107 | sta = sta_info_get(local, ifmgd->bssid); | ||
1108 | if (!sta) { | ||
1109 | rcu_read_unlock(); | ||
1110 | return; | ||
1111 | } | ||
1112 | |||
1113 | if (deauth) { | 1105 | if (deauth) { |
1114 | ifmgd->direct_probe_tries = 0; | 1106 | ifmgd->direct_probe_tries = 0; |
1115 | ifmgd->auth_tries = 0; | 1107 | ifmgd->auth_tries = 0; |
@@ -1120,7 +1112,11 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1120 | netif_tx_stop_all_queues(sdata->dev); | 1112 | netif_tx_stop_all_queues(sdata->dev); |
1121 | netif_carrier_off(sdata->dev); | 1113 | netif_carrier_off(sdata->dev); |
1122 | 1114 | ||
1123 | ieee80211_sta_tear_down_BA_sessions(sta); | 1115 | rcu_read_lock(); |
1116 | sta = sta_info_get(local, ifmgd->bssid); | ||
1117 | if (sta) | ||
1118 | ieee80211_sta_tear_down_BA_sessions(sta); | ||
1119 | rcu_read_unlock(); | ||
1124 | 1120 | ||
1125 | bss = ieee80211_rx_bss_get(local, ifmgd->bssid, | 1121 | bss = ieee80211_rx_bss_get(local, ifmgd->bssid, |
1126 | conf->channel->center_freq, | 1122 | conf->channel->center_freq, |
@@ -1156,8 +1152,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1156 | ifmgd->ssid, ifmgd->ssid_len); | 1152 | ifmgd->ssid, ifmgd->ssid_len); |
1157 | } | 1153 | } |
1158 | 1154 | ||
1159 | rcu_read_unlock(); | ||
1160 | |||
1161 | ieee80211_set_wmm_default(sdata); | 1155 | ieee80211_set_wmm_default(sdata); |
1162 | 1156 | ||
1163 | ieee80211_recalc_idle(local); | 1157 | ieee80211_recalc_idle(local); |
@@ -2223,7 +2217,10 @@ static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata) | |||
2223 | capa_mask, capa_val); | 2217 | capa_mask, capa_val); |
2224 | 2218 | ||
2225 | if (bss) { | 2219 | if (bss) { |
2226 | ieee80211_set_freq(sdata, bss->cbss.channel->center_freq); | 2220 | local->oper_channel = bss->cbss.channel; |
2221 | local->oper_channel_type = NL80211_CHAN_NO_HT; | ||
2222 | ieee80211_hw_config(local, 0); | ||
2223 | |||
2227 | if (!(ifmgd->flags & IEEE80211_STA_SSID_SET)) | 2224 | if (!(ifmgd->flags & IEEE80211_STA_SSID_SET)) |
2228 | ieee80211_sta_set_ssid(sdata, bss->ssid, | 2225 | ieee80211_sta_set_ssid(sdata, bss->ssid, |
2229 | bss->ssid_len); | 2226 | bss->ssid_len); |
@@ -2445,6 +2442,14 @@ void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata) | |||
2445 | ieee80211_set_disassoc(sdata, true, true, | 2442 | ieee80211_set_disassoc(sdata, true, true, |
2446 | WLAN_REASON_DEAUTH_LEAVING); | 2443 | WLAN_REASON_DEAUTH_LEAVING); |
2447 | 2444 | ||
2445 | if (ifmgd->ssid_len == 0) { | ||
2446 | /* | ||
2447 | * Only allow association to be started if a valid SSID | ||
2448 | * is configured. | ||
2449 | */ | ||
2450 | return; | ||
2451 | } | ||
2452 | |||
2448 | if (!(ifmgd->flags & IEEE80211_STA_EXT_SME) || | 2453 | if (!(ifmgd->flags & IEEE80211_STA_EXT_SME) || |
2449 | ifmgd->state != IEEE80211_STA_MLME_ASSOCIATE) | 2454 | ifmgd->state != IEEE80211_STA_MLME_ASSOCIATE) |
2450 | set_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request); | 2455 | set_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request); |
@@ -2476,6 +2481,10 @@ int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size | |||
2476 | ifmgd = &sdata->u.mgd; | 2481 | ifmgd = &sdata->u.mgd; |
2477 | 2482 | ||
2478 | if (ifmgd->ssid_len != len || memcmp(ifmgd->ssid, ssid, len) != 0) { | 2483 | if (ifmgd->ssid_len != len || memcmp(ifmgd->ssid, ssid, len) != 0) { |
2484 | if (ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED) | ||
2485 | ieee80211_set_disassoc(sdata, true, true, | ||
2486 | WLAN_REASON_DEAUTH_LEAVING); | ||
2487 | |||
2479 | /* | 2488 | /* |
2480 | * Do not use reassociation if SSID is changed (different ESS). | 2489 | * Do not use reassociation if SSID is changed (different ESS). |
2481 | */ | 2490 | */ |
@@ -2500,6 +2509,11 @@ int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid) | |||
2500 | { | 2509 | { |
2501 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2510 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
2502 | 2511 | ||
2512 | if (compare_ether_addr(bssid, ifmgd->bssid) != 0 && | ||
2513 | ifmgd->state == IEEE80211_STA_MLME_ASSOCIATED) | ||
2514 | ieee80211_set_disassoc(sdata, true, true, | ||
2515 | WLAN_REASON_DEAUTH_LEAVING); | ||
2516 | |||
2503 | if (is_valid_ether_addr(bssid)) { | 2517 | if (is_valid_ether_addr(bssid)) { |
2504 | memcpy(ifmgd->bssid, bssid, ETH_ALEN); | 2518 | memcpy(ifmgd->bssid, bssid, ETH_ALEN); |
2505 | ifmgd->flags |= IEEE80211_STA_BSSID_SET; | 2519 | ifmgd->flags |= IEEE80211_STA_BSSID_SET; |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 66ce96a69f31..915e77769312 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -774,31 +774,6 @@ void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, | |||
774 | dev_queue_xmit(skb); | 774 | dev_queue_xmit(skb); |
775 | } | 775 | } |
776 | 776 | ||
777 | int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freqMHz) | ||
778 | { | ||
779 | int ret = -EINVAL; | ||
780 | struct ieee80211_channel *chan; | ||
781 | struct ieee80211_local *local = sdata->local; | ||
782 | |||
783 | chan = ieee80211_get_channel(local->hw.wiphy, freqMHz); | ||
784 | |||
785 | if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) { | ||
786 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && | ||
787 | chan->flags & IEEE80211_CHAN_NO_IBSS) | ||
788 | return ret; | ||
789 | local->oper_channel = chan; | ||
790 | local->oper_channel_type = NL80211_CHAN_NO_HT; | ||
791 | |||
792 | if (local->sw_scanning || local->hw_scanning) | ||
793 | ret = 0; | ||
794 | else | ||
795 | ret = ieee80211_hw_config( | ||
796 | local, IEEE80211_CONF_CHANGE_CHANNEL); | ||
797 | } | ||
798 | |||
799 | return ret; | ||
800 | } | ||
801 | |||
802 | u32 ieee80211_mandatory_rates(struct ieee80211_local *local, | 777 | u32 ieee80211_mandatory_rates(struct ieee80211_local *local, |
803 | enum ieee80211_band band) | 778 | enum ieee80211_band band) |
804 | { | 779 | { |
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index d2d81b103341..1da81f456744 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c | |||
@@ -55,6 +55,8 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev, | |||
55 | struct iw_freq *freq, char *extra) | 55 | struct iw_freq *freq, char *extra) |
56 | { | 56 | { |
57 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 57 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
58 | struct ieee80211_local *local = sdata->local; | ||
59 | struct ieee80211_channel *chan; | ||
58 | 60 | ||
59 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | 61 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) |
60 | return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra); | 62 | return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra); |
@@ -69,17 +71,38 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev, | |||
69 | IEEE80211_STA_AUTO_CHANNEL_SEL; | 71 | IEEE80211_STA_AUTO_CHANNEL_SEL; |
70 | return 0; | 72 | return 0; |
71 | } else | 73 | } else |
72 | return ieee80211_set_freq(sdata, | 74 | chan = ieee80211_get_channel(local->hw.wiphy, |
73 | ieee80211_channel_to_frequency(freq->m)); | 75 | ieee80211_channel_to_frequency(freq->m)); |
74 | } else { | 76 | } else { |
75 | int i, div = 1000000; | 77 | int i, div = 1000000; |
76 | for (i = 0; i < freq->e; i++) | 78 | for (i = 0; i < freq->e; i++) |
77 | div /= 10; | 79 | div /= 10; |
78 | if (div > 0) | 80 | if (div <= 0) |
79 | return ieee80211_set_freq(sdata, freq->m / div); | ||
80 | else | ||
81 | return -EINVAL; | 81 | return -EINVAL; |
82 | chan = ieee80211_get_channel(local->hw.wiphy, freq->m / div); | ||
82 | } | 83 | } |
84 | |||
85 | if (!chan) | ||
86 | return -EINVAL; | ||
87 | |||
88 | if (chan->flags & IEEE80211_CHAN_DISABLED) | ||
89 | return -EINVAL; | ||
90 | |||
91 | /* | ||
92 | * no change except maybe auto -> fixed, ignore the HT | ||
93 | * setting so you can fix a channel you're on already | ||
94 | */ | ||
95 | if (local->oper_channel == chan) | ||
96 | return 0; | ||
97 | |||
98 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | ||
99 | ieee80211_sta_req_auth(sdata); | ||
100 | |||
101 | local->oper_channel = chan; | ||
102 | local->oper_channel_type = NL80211_CHAN_NO_HT; | ||
103 | ieee80211_hw_config(local, 0); | ||
104 | |||
105 | return 0; | ||
83 | } | 106 | } |
84 | 107 | ||
85 | 108 | ||
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 8b6bbb3032b0..2936fa3b6dc8 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -1914,8 +1914,8 @@ static int netlink_seq_show(struct seq_file *seq, void *v) | |||
1914 | s->sk_protocol, | 1914 | s->sk_protocol, |
1915 | nlk->pid, | 1915 | nlk->pid, |
1916 | nlk->groups ? (u32)nlk->groups[0] : 0, | 1916 | nlk->groups ? (u32)nlk->groups[0] : 0, |
1917 | atomic_read(&s->sk_rmem_alloc), | 1917 | sk_rmem_alloc_get(s), |
1918 | atomic_read(&s->sk_wmem_alloc), | 1918 | sk_wmem_alloc_get(s), |
1919 | nlk->cb, | 1919 | nlk->cb, |
1920 | atomic_read(&s->sk_refcnt), | 1920 | atomic_read(&s->sk_refcnt), |
1921 | atomic_read(&s->sk_drops) | 1921 | atomic_read(&s->sk_drops) |
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index 3be0e016ab7d..ce51ce012cda 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c | |||
@@ -286,8 +286,7 @@ void nr_destroy_socket(struct sock *sk) | |||
286 | kfree_skb(skb); | 286 | kfree_skb(skb); |
287 | } | 287 | } |
288 | 288 | ||
289 | if (atomic_read(&sk->sk_wmem_alloc) || | 289 | if (sk_has_allocations(sk)) { |
290 | atomic_read(&sk->sk_rmem_alloc)) { | ||
291 | /* Defer: outstanding buffers */ | 290 | /* Defer: outstanding buffers */ |
292 | sk->sk_timer.function = nr_destroy_timer; | 291 | sk->sk_timer.function = nr_destroy_timer; |
293 | sk->sk_timer.expires = jiffies + 2 * HZ; | 292 | sk->sk_timer.expires = jiffies + 2 * HZ; |
@@ -1206,7 +1205,7 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1206 | long amount; | 1205 | long amount; |
1207 | 1206 | ||
1208 | lock_sock(sk); | 1207 | lock_sock(sk); |
1209 | amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); | 1208 | amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); |
1210 | if (amount < 0) | 1209 | if (amount < 0) |
1211 | amount = 0; | 1210 | amount = 0; |
1212 | release_sock(sk); | 1211 | release_sock(sk); |
@@ -1342,8 +1341,8 @@ static int nr_info_show(struct seq_file *seq, void *v) | |||
1342 | nr->n2count, | 1341 | nr->n2count, |
1343 | nr->n2, | 1342 | nr->n2, |
1344 | nr->window, | 1343 | nr->window, |
1345 | atomic_read(&s->sk_wmem_alloc), | 1344 | sk_wmem_alloc_get(s), |
1346 | atomic_read(&s->sk_rmem_alloc), | 1345 | sk_rmem_alloc_get(s), |
1347 | s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L); | 1346 | s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L); |
1348 | 1347 | ||
1349 | bh_unlock_sock(s); | 1348 | bh_unlock_sock(s); |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 4f76e5552d8e..ebe5718baa31 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -1987,7 +1987,8 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd, | |||
1987 | switch (cmd) { | 1987 | switch (cmd) { |
1988 | case SIOCOUTQ: | 1988 | case SIOCOUTQ: |
1989 | { | 1989 | { |
1990 | int amount = atomic_read(&sk->sk_wmem_alloc); | 1990 | int amount = sk_wmem_alloc_get(sk); |
1991 | |||
1991 | return put_user(amount, (int __user *)arg); | 1992 | return put_user(amount, (int __user *)arg); |
1992 | } | 1993 | } |
1993 | case SIOCINQ: | 1994 | case SIOCINQ: |
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 877a7f65f707..6bd8e93869ed 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c | |||
@@ -356,8 +356,7 @@ void rose_destroy_socket(struct sock *sk) | |||
356 | kfree_skb(skb); | 356 | kfree_skb(skb); |
357 | } | 357 | } |
358 | 358 | ||
359 | if (atomic_read(&sk->sk_wmem_alloc) || | 359 | if (sk_has_allocations(sk)) { |
360 | atomic_read(&sk->sk_rmem_alloc)) { | ||
361 | /* Defer: outstanding buffers */ | 360 | /* Defer: outstanding buffers */ |
362 | setup_timer(&sk->sk_timer, rose_destroy_timer, | 361 | setup_timer(&sk->sk_timer, rose_destroy_timer, |
363 | (unsigned long)sk); | 362 | (unsigned long)sk); |
@@ -1310,7 +1309,8 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1310 | switch (cmd) { | 1309 | switch (cmd) { |
1311 | case TIOCOUTQ: { | 1310 | case TIOCOUTQ: { |
1312 | long amount; | 1311 | long amount; |
1313 | amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); | 1312 | |
1313 | amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); | ||
1314 | if (amount < 0) | 1314 | if (amount < 0) |
1315 | amount = 0; | 1315 | amount = 0; |
1316 | return put_user(amount, (unsigned int __user *) argp); | 1316 | return put_user(amount, (unsigned int __user *) argp); |
@@ -1481,8 +1481,8 @@ static int rose_info_show(struct seq_file *seq, void *v) | |||
1481 | rose->hb / HZ, | 1481 | rose->hb / HZ, |
1482 | ax25_display_timer(&rose->idletimer) / (60 * HZ), | 1482 | ax25_display_timer(&rose->idletimer) / (60 * HZ), |
1483 | rose->idle / (60 * HZ), | 1483 | rose->idle / (60 * HZ), |
1484 | atomic_read(&s->sk_wmem_alloc), | 1484 | sk_wmem_alloc_get(s), |
1485 | atomic_read(&s->sk_rmem_alloc), | 1485 | sk_rmem_alloc_get(s), |
1486 | s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L); | 1486 | s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L); |
1487 | } | 1487 | } |
1488 | 1488 | ||
diff --git a/net/sched/act_police.c b/net/sched/act_police.c index f8f047b61245..723964c3ee4f 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c | |||
@@ -294,6 +294,8 @@ static int tcf_act_police(struct sk_buff *skb, struct tc_action *a, | |||
294 | if (police->tcfp_ewma_rate && | 294 | if (police->tcfp_ewma_rate && |
295 | police->tcf_rate_est.bps >= police->tcfp_ewma_rate) { | 295 | police->tcf_rate_est.bps >= police->tcfp_ewma_rate) { |
296 | police->tcf_qstats.overlimits++; | 296 | police->tcf_qstats.overlimits++; |
297 | if (police->tcf_action == TC_ACT_SHOT) | ||
298 | police->tcf_qstats.drops++; | ||
297 | spin_unlock(&police->tcf_lock); | 299 | spin_unlock(&police->tcf_lock); |
298 | return police->tcf_action; | 300 | return police->tcf_action; |
299 | } | 301 | } |
@@ -327,6 +329,8 @@ static int tcf_act_police(struct sk_buff *skb, struct tc_action *a, | |||
327 | } | 329 | } |
328 | 330 | ||
329 | police->tcf_qstats.overlimits++; | 331 | police->tcf_qstats.overlimits++; |
332 | if (police->tcf_action == TC_ACT_SHOT) | ||
333 | police->tcf_qstats.drops++; | ||
330 | spin_unlock(&police->tcf_lock); | 334 | spin_unlock(&police->tcf_lock); |
331 | return police->tcf_action; | 335 | return police->tcf_action; |
332 | } | 336 | } |
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index 266151ae85a3..18d85d259104 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c | |||
@@ -349,13 +349,13 @@ META_COLLECTOR(int_sk_type) | |||
349 | META_COLLECTOR(int_sk_rmem_alloc) | 349 | META_COLLECTOR(int_sk_rmem_alloc) |
350 | { | 350 | { |
351 | SKIP_NONLOCAL(skb); | 351 | SKIP_NONLOCAL(skb); |
352 | dst->value = atomic_read(&skb->sk->sk_rmem_alloc); | 352 | dst->value = sk_rmem_alloc_get(skb->sk); |
353 | } | 353 | } |
354 | 354 | ||
355 | META_COLLECTOR(int_sk_wmem_alloc) | 355 | META_COLLECTOR(int_sk_wmem_alloc) |
356 | { | 356 | { |
357 | SKIP_NONLOCAL(skb); | 357 | SKIP_NONLOCAL(skb); |
358 | dst->value = atomic_read(&skb->sk->sk_wmem_alloc); | 358 | dst->value = sk_wmem_alloc_get(skb->sk); |
359 | } | 359 | } |
360 | 360 | ||
361 | META_COLLECTOR(int_sk_omem_alloc) | 361 | META_COLLECTOR(int_sk_omem_alloc) |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 0f01e5d8a24f..35ba035970a2 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -130,7 +130,7 @@ static inline int sctp_wspace(struct sctp_association *asoc) | |||
130 | if (asoc->ep->sndbuf_policy) | 130 | if (asoc->ep->sndbuf_policy) |
131 | amt = asoc->sndbuf_used; | 131 | amt = asoc->sndbuf_used; |
132 | else | 132 | else |
133 | amt = atomic_read(&asoc->base.sk->sk_wmem_alloc); | 133 | amt = sk_wmem_alloc_get(asoc->base.sk); |
134 | 134 | ||
135 | if (amt >= asoc->base.sk->sk_sndbuf) { | 135 | if (amt >= asoc->base.sk->sk_sndbuf) { |
136 | if (asoc->base.sk->sk_userlocks & SOCK_SNDBUF_LOCK) | 136 | if (asoc->base.sk->sk_userlocks & SOCK_SNDBUF_LOCK) |
@@ -6523,7 +6523,7 @@ static int sctp_writeable(struct sock *sk) | |||
6523 | { | 6523 | { |
6524 | int amt = 0; | 6524 | int amt = 0; |
6525 | 6525 | ||
6526 | amt = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc); | 6526 | amt = sk->sk_sndbuf - sk_wmem_alloc_get(sk); |
6527 | if (amt < 0) | 6527 | if (amt < 0) |
6528 | amt = 0; | 6528 | amt = 0; |
6529 | return amt; | 6529 | return amt; |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 9dcc6e7f96ec..36d4e44d6233 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -1946,7 +1946,7 @@ static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1946 | 1946 | ||
1947 | switch (cmd) { | 1947 | switch (cmd) { |
1948 | case SIOCOUTQ: | 1948 | case SIOCOUTQ: |
1949 | amount = atomic_read(&sk->sk_wmem_alloc); | 1949 | amount = sk_wmem_alloc_get(sk); |
1950 | err = put_user(amount, (int __user *)arg); | 1950 | err = put_user(amount, (int __user *)arg); |
1951 | break; | 1951 | break; |
1952 | case SIOCINQ: | 1952 | case SIOCINQ: |
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index ed80af8ca5fb..21cdc872004e 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c | |||
@@ -332,14 +332,14 @@ static unsigned int x25_new_lci(struct x25_neigh *nb) | |||
332 | /* | 332 | /* |
333 | * Deferred destroy. | 333 | * Deferred destroy. |
334 | */ | 334 | */ |
335 | void x25_destroy_socket(struct sock *); | 335 | static void __x25_destroy_socket(struct sock *); |
336 | 336 | ||
337 | /* | 337 | /* |
338 | * handler for deferred kills. | 338 | * handler for deferred kills. |
339 | */ | 339 | */ |
340 | static void x25_destroy_timer(unsigned long data) | 340 | static void x25_destroy_timer(unsigned long data) |
341 | { | 341 | { |
342 | x25_destroy_socket((struct sock *)data); | 342 | x25_destroy_socket_from_timer((struct sock *)data); |
343 | } | 343 | } |
344 | 344 | ||
345 | /* | 345 | /* |
@@ -349,12 +349,10 @@ static void x25_destroy_timer(unsigned long data) | |||
349 | * will touch it and we are (fairly 8-) ) safe. | 349 | * will touch it and we are (fairly 8-) ) safe. |
350 | * Not static as it's used by the timer | 350 | * Not static as it's used by the timer |
351 | */ | 351 | */ |
352 | void x25_destroy_socket(struct sock *sk) | 352 | static void __x25_destroy_socket(struct sock *sk) |
353 | { | 353 | { |
354 | struct sk_buff *skb; | 354 | struct sk_buff *skb; |
355 | 355 | ||
356 | sock_hold(sk); | ||
357 | lock_sock(sk); | ||
358 | x25_stop_heartbeat(sk); | 356 | x25_stop_heartbeat(sk); |
359 | x25_stop_timer(sk); | 357 | x25_stop_timer(sk); |
360 | 358 | ||
@@ -374,8 +372,7 @@ void x25_destroy_socket(struct sock *sk) | |||
374 | kfree_skb(skb); | 372 | kfree_skb(skb); |
375 | } | 373 | } |
376 | 374 | ||
377 | if (atomic_read(&sk->sk_wmem_alloc) || | 375 | if (sk_has_allocations(sk)) { |
378 | atomic_read(&sk->sk_rmem_alloc)) { | ||
379 | /* Defer: outstanding buffers */ | 376 | /* Defer: outstanding buffers */ |
380 | sk->sk_timer.expires = jiffies + 10 * HZ; | 377 | sk->sk_timer.expires = jiffies + 10 * HZ; |
381 | sk->sk_timer.function = x25_destroy_timer; | 378 | sk->sk_timer.function = x25_destroy_timer; |
@@ -385,7 +382,22 @@ void x25_destroy_socket(struct sock *sk) | |||
385 | /* drop last reference so sock_put will free */ | 382 | /* drop last reference so sock_put will free */ |
386 | __sock_put(sk); | 383 | __sock_put(sk); |
387 | } | 384 | } |
385 | } | ||
386 | |||
387 | void x25_destroy_socket_from_timer(struct sock *sk) | ||
388 | { | ||
389 | sock_hold(sk); | ||
390 | bh_lock_sock(sk); | ||
391 | __x25_destroy_socket(sk); | ||
392 | bh_unlock_sock(sk); | ||
393 | sock_put(sk); | ||
394 | } | ||
388 | 395 | ||
396 | static void x25_destroy_socket(struct sock *sk) | ||
397 | { | ||
398 | sock_hold(sk); | ||
399 | lock_sock(sk); | ||
400 | __x25_destroy_socket(sk); | ||
389 | release_sock(sk); | 401 | release_sock(sk); |
390 | sock_put(sk); | 402 | sock_put(sk); |
391 | } | 403 | } |
@@ -1259,8 +1271,8 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1259 | 1271 | ||
1260 | switch (cmd) { | 1272 | switch (cmd) { |
1261 | case TIOCOUTQ: { | 1273 | case TIOCOUTQ: { |
1262 | int amount = sk->sk_sndbuf - | 1274 | int amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); |
1263 | atomic_read(&sk->sk_wmem_alloc); | 1275 | |
1264 | if (amount < 0) | 1276 | if (amount < 0) |
1265 | amount = 0; | 1277 | amount = 0; |
1266 | rc = put_user(amount, (unsigned int __user *)argp); | 1278 | rc = put_user(amount, (unsigned int __user *)argp); |
diff --git a/net/x25/x25_proc.c b/net/x25/x25_proc.c index 1afa44d25beb..0a04e62e0e18 100644 --- a/net/x25/x25_proc.c +++ b/net/x25/x25_proc.c | |||
@@ -163,8 +163,8 @@ static int x25_seq_socket_show(struct seq_file *seq, void *v) | |||
163 | devname, x25->lci & 0x0FFF, x25->state, x25->vs, x25->vr, | 163 | devname, x25->lci & 0x0FFF, x25->state, x25->vs, x25->vr, |
164 | x25->va, x25_display_timer(s) / HZ, x25->t2 / HZ, | 164 | x25->va, x25_display_timer(s) / HZ, x25->t2 / HZ, |
165 | x25->t21 / HZ, x25->t22 / HZ, x25->t23 / HZ, | 165 | x25->t21 / HZ, x25->t22 / HZ, x25->t23 / HZ, |
166 | atomic_read(&s->sk_wmem_alloc), | 166 | sk_wmem_alloc_get(s), |
167 | atomic_read(&s->sk_rmem_alloc), | 167 | sk_rmem_alloc_get(s), |
168 | s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L); | 168 | s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L); |
169 | out: | 169 | out: |
170 | return 0; | 170 | return 0; |
diff --git a/net/x25/x25_timer.c b/net/x25/x25_timer.c index d3e3e54db936..5c5db1a36399 100644 --- a/net/x25/x25_timer.c +++ b/net/x25/x25_timer.c | |||
@@ -113,7 +113,7 @@ static void x25_heartbeat_expiry(unsigned long param) | |||
113 | (sk->sk_state == TCP_LISTEN && | 113 | (sk->sk_state == TCP_LISTEN && |
114 | sock_flag(sk, SOCK_DEAD))) { | 114 | sock_flag(sk, SOCK_DEAD))) { |
115 | bh_unlock_sock(sk); | 115 | bh_unlock_sock(sk); |
116 | x25_destroy_socket(sk); | 116 | x25_destroy_socket_from_timer(sk); |
117 | return; | 117 | return; |
118 | } | 118 | } |
119 | break; | 119 | break; |