diff options
80 files changed, 1311 insertions, 450 deletions
diff --git a/Documentation/networking/igb.txt b/Documentation/networking/igb.txt new file mode 100644 index 000000000000..ab2d71831892 --- /dev/null +++ b/Documentation/networking/igb.txt | |||
| @@ -0,0 +1,132 @@ | |||
| 1 | Linux* Base Driver for Intel(R) Network Connection | ||
| 2 | ================================================== | ||
| 3 | |||
| 4 | Intel Gigabit Linux driver. | ||
| 5 | Copyright(c) 1999 - 2010 Intel Corporation. | ||
| 6 | |||
| 7 | Contents | ||
| 8 | ======== | ||
| 9 | |||
| 10 | - Identifying Your Adapter | ||
| 11 | - Additional Configurations | ||
| 12 | - Support | ||
| 13 | |||
| 14 | Identifying Your Adapter | ||
| 15 | ======================== | ||
| 16 | |||
| 17 | This driver supports all 82575, 82576 and 82580-based Intel (R) gigabit network | ||
| 18 | connections. | ||
| 19 | |||
| 20 | For specific information on how to identify your adapter, go to the Adapter & | ||
| 21 | Driver ID Guide at: | ||
| 22 | |||
| 23 | http://support.intel.com/support/go/network/adapter/idguide.htm | ||
| 24 | |||
| 25 | Command Line Parameters | ||
| 26 | ======================= | ||
| 27 | |||
| 28 | The default value for each parameter is generally the recommended setting, | ||
| 29 | unless otherwise noted. | ||
| 30 | |||
| 31 | max_vfs | ||
| 32 | ------- | ||
| 33 | Valid Range: 0-7 | ||
| 34 | Default Value: 0 | ||
| 35 | |||
| 36 | This parameter adds support for SR-IOV. It causes the driver to spawn up to | ||
| 37 | max_vfs worth of virtual function. | ||
| 38 | |||
| 39 | Additional Configurations | ||
| 40 | ========================= | ||
| 41 | |||
| 42 | Jumbo Frames | ||
| 43 | ------------ | ||
| 44 | Jumbo Frames support is enabled by changing the MTU to a value larger than | ||
| 45 | the default of 1500. Use the ifconfig command to increase the MTU size. | ||
| 46 | For example: | ||
| 47 | |||
| 48 | ifconfig eth<x> mtu 9000 up | ||
| 49 | |||
| 50 | This setting is not saved across reboots. | ||
| 51 | |||
| 52 | Notes: | ||
| 53 | |||
| 54 | - The maximum MTU setting for Jumbo Frames is 9216. This value coincides | ||
| 55 | with the maximum Jumbo Frames size of 9234 bytes. | ||
| 56 | |||
| 57 | - Using Jumbo Frames at 10 or 100 Mbps may result in poor performance or | ||
| 58 | loss of link. | ||
| 59 | |||
| 60 | Ethtool | ||
| 61 | ------- | ||
| 62 | The driver utilizes the ethtool interface for driver configuration and | ||
| 63 | diagnostics, as well as displaying statistical information. | ||
| 64 | |||
| 65 | http://sourceforge.net/projects/gkernel. | ||
| 66 | |||
| 67 | Enabling Wake on LAN* (WoL) | ||
| 68 | --------------------------- | ||
| 69 | WoL is configured through the Ethtool* utility. | ||
| 70 | |||
| 71 | For instructions on enabling WoL with Ethtool, refer to the Ethtool man page. | ||
| 72 | |||
| 73 | WoL will be enabled on the system during the next shut down or reboot. | ||
| 74 | For this driver version, in order to enable WoL, the igb driver must be | ||
| 75 | loaded when shutting down or rebooting the system. | ||
| 76 | |||
| 77 | Wake On LAN is only supported on port A of multi-port adapters. | ||
| 78 | |||
| 79 | Wake On LAN is not supported for the Intel(R) Gigabit VT Quad Port Server | ||
| 80 | Adapter. | ||
| 81 | |||
| 82 | Multiqueue | ||
| 83 | ---------- | ||
| 84 | In this mode, a separate MSI-X vector is allocated for each queue and one | ||
| 85 | for "other" interrupts such as link status change and errors. All | ||
| 86 | interrupts are throttled via interrupt moderation. Interrupt moderation | ||
| 87 | must be used to avoid interrupt storms while the driver is processing one | ||
| 88 | interrupt. The moderation value should be at least as large as the expected | ||
| 89 | time for the driver to process an interrupt. Multiqueue is off by default. | ||
| 90 | |||
| 91 | REQUIREMENTS: MSI-X support is required for Multiqueue. If MSI-X is not | ||
| 92 | found, the system will fallback to MSI or to Legacy interrupts. | ||
| 93 | |||
| 94 | LRO | ||
| 95 | --- | ||
| 96 | Large Receive Offload (LRO) is a technique for increasing inbound throughput | ||
| 97 | of high-bandwidth network connections by reducing CPU overhead. It works by | ||
| 98 | aggregating multiple incoming packets from a single stream into a larger | ||
| 99 | buffer before they are passed higher up the networking stack, thus reducing | ||
| 100 | the number of packets that have to be processed. LRO combines multiple | ||
| 101 | Ethernet frames into a single receive in the stack, thereby potentially | ||
| 102 | decreasing CPU utilization for receives. | ||
| 103 | |||
| 104 | NOTE: You need to have inet_lro enabled via either the CONFIG_INET_LRO or | ||
| 105 | CONFIG_INET_LRO_MODULE kernel config option. Additionally, if | ||
| 106 | CONFIG_INET_LRO_MODULE is used, the inet_lro module needs to be loaded | ||
| 107 | before the igb driver. | ||
| 108 | |||
| 109 | You can verify that the driver is using LRO by looking at these counters in | ||
| 110 | Ethtool: | ||
| 111 | |||
| 112 | lro_aggregated - count of total packets that were combined | ||
| 113 | lro_flushed - counts the number of packets flushed out of LRO | ||
| 114 | lro_no_desc - counts the number of times an LRO descriptor was not available | ||
| 115 | for the LRO packet | ||
| 116 | |||
| 117 | NOTE: IPv6 and UDP are not supported by LRO. | ||
| 118 | |||
| 119 | Support | ||
| 120 | ======= | ||
| 121 | |||
| 122 | For general information, go to the Intel support website at: | ||
| 123 | |||
| 124 | www.intel.com/support/ | ||
| 125 | |||
| 126 | or the Intel Wired Networking project hosted by Sourceforge at: | ||
| 127 | |||
| 128 | http://sourceforge.net/projects/e1000 | ||
| 129 | |||
| 130 | If an issue is identified with the released source code on the supported | ||
| 131 | kernel with a supported adapter, email the specific information related | ||
| 132 | to the issue to e1000-devel@lists.sf.net | ||
diff --git a/Documentation/networking/igbvf.txt b/Documentation/networking/igbvf.txt new file mode 100644 index 000000000000..056028138d9c --- /dev/null +++ b/Documentation/networking/igbvf.txt | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | Linux* Base Driver for Intel(R) Network Connection | ||
| 2 | ================================================== | ||
| 3 | |||
| 4 | Intel Gigabit Linux driver. | ||
| 5 | Copyright(c) 1999 - 2010 Intel Corporation. | ||
| 6 | |||
| 7 | Contents | ||
| 8 | ======== | ||
| 9 | |||
| 10 | - Identifying Your Adapter | ||
| 11 | - Additional Configurations | ||
| 12 | - Support | ||
| 13 | |||
| 14 | This file describes the igbvf Linux* Base Driver for Intel Network Connection. | ||
| 15 | |||
| 16 | The igbvf driver supports 82576-based virtual function devices that can only | ||
| 17 | be activated on kernels that support SR-IOV. SR-IOV requires the correct | ||
| 18 | platform and OS support. | ||
| 19 | |||
| 20 | The igbvf driver requires the igb driver, version 2.0 or later. The igbvf | ||
| 21 | driver supports virtual functions generated by the igb driver with a max_vfs | ||
| 22 | value of 1 or greater. For more information on the max_vfs parameter refer | ||
| 23 | to the README included with the igb driver. | ||
| 24 | |||
| 25 | The guest OS loading the igbvf driver must support MSI-X interrupts. | ||
| 26 | |||
| 27 | This driver is only supported as a loadable module at this time. Intel is | ||
| 28 | not supplying patches against the kernel source to allow for static linking | ||
| 29 | of the driver. For questions related to hardware requirements, refer to the | ||
| 30 | documentation supplied with your Intel Gigabit adapter. All hardware | ||
| 31 | requirements listed apply to use with Linux. | ||
| 32 | |||
| 33 | Instructions on updating ethtool can be found in the section "Additional | ||
| 34 | Configurations" later in this document. | ||
| 35 | |||
| 36 | VLANs: There is a limit of a total of 32 shared VLANs to 1 or more VFs. | ||
| 37 | |||
| 38 | Identifying Your Adapter | ||
| 39 | ======================== | ||
| 40 | |||
| 41 | The igbvf driver supports 82576-based virtual function devices that can only | ||
| 42 | be activated on kernels that support SR-IOV. | ||
| 43 | |||
| 44 | For more information on how to identify your adapter, go to the Adapter & | ||
| 45 | Driver ID Guide at: | ||
| 46 | |||
| 47 | http://support.intel.com/support/go/network/adapter/idguide.htm | ||
| 48 | |||
| 49 | For the latest Intel network drivers for Linux, refer to the following | ||
| 50 | website. In the search field, enter your adapter name or type, or use the | ||
| 51 | networking link on the left to search for your adapter: | ||
| 52 | |||
| 53 | http://downloadcenter.intel.com/scripts-df-external/Support_Intel.aspx | ||
| 54 | |||
| 55 | Additional Configurations | ||
| 56 | ========================= | ||
| 57 | |||
| 58 | Ethtool | ||
| 59 | ------- | ||
| 60 | The driver utilizes the ethtool interface for driver configuration and | ||
| 61 | diagnostics, as well as displaying statistical information. | ||
| 62 | |||
| 63 | http://sourceforge.net/projects/gkernel. | ||
| 64 | |||
| 65 | Support | ||
| 66 | ======= | ||
| 67 | |||
| 68 | For general information, go to the Intel support website at: | ||
| 69 | |||
| 70 | http://support.intel.com | ||
| 71 | |||
| 72 | or the Intel Wired Networking project hosted by Sourceforge at: | ||
| 73 | |||
| 74 | http://sourceforge.net/projects/e1000 | ||
| 75 | |||
| 76 | If an issue is identified with the released source code on the supported | ||
| 77 | kernel with a supported adapter, email the specific information related | ||
| 78 | to the issue to e1000-devel@lists.sf.net | ||
diff --git a/MAINTAINERS b/MAINTAINERS index c8a0a39d74a6..832f904db114 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -1085,7 +1085,6 @@ F: drivers/net/wireless/ath/ath5k/ | |||
| 1085 | ATHEROS ATH9K WIRELESS DRIVER | 1085 | ATHEROS ATH9K WIRELESS DRIVER |
| 1086 | M: "Luis R. Rodriguez" <lrodriguez@atheros.com> | 1086 | M: "Luis R. Rodriguez" <lrodriguez@atheros.com> |
| 1087 | M: Jouni Malinen <jmalinen@atheros.com> | 1087 | M: Jouni Malinen <jmalinen@atheros.com> |
| 1088 | M: Sujith Manoharan <Sujith.Manoharan@atheros.com> | ||
| 1089 | M: Vasanthakumar Thiagarajan <vasanth@atheros.com> | 1088 | M: Vasanthakumar Thiagarajan <vasanth@atheros.com> |
| 1090 | M: Senthil Balasubramanian <senthilkumar@atheros.com> | 1089 | M: Senthil Balasubramanian <senthilkumar@atheros.com> |
| 1091 | L: linux-wireless@vger.kernel.org | 1090 | L: linux-wireless@vger.kernel.org |
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index 6174965d9a4d..f916ddf63938 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c | |||
| @@ -781,7 +781,8 @@ static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci) | |||
| 781 | sk_for_each(s, node, head) { | 781 | sk_for_each(s, node, head) { |
| 782 | vcc = atm_sk(s); | 782 | vcc = atm_sk(s); |
| 783 | if (vcc->dev == dev && vcc->vci == vci && | 783 | if (vcc->dev == dev && vcc->vci == vci && |
| 784 | vcc->vpi == vpi && vcc->qos.rxtp.traffic_class != ATM_NONE) | 784 | vcc->vpi == vpi && vcc->qos.rxtp.traffic_class != ATM_NONE && |
| 785 | test_bit(ATM_VF_READY, &vcc->flags)) | ||
| 785 | goto out; | 786 | goto out; |
| 786 | } | 787 | } |
| 787 | vcc = NULL; | 788 | vcc = NULL; |
| @@ -907,6 +908,10 @@ static void pclose(struct atm_vcc *vcc) | |||
| 907 | clear_bit(ATM_VF_ADDR, &vcc->flags); | 908 | clear_bit(ATM_VF_ADDR, &vcc->flags); |
| 908 | clear_bit(ATM_VF_READY, &vcc->flags); | 909 | clear_bit(ATM_VF_READY, &vcc->flags); |
| 909 | 910 | ||
| 911 | /* Hold up vcc_destroy_socket() (our caller) until solos_bh() in the | ||
| 912 | tasklet has finished processing any incoming packets (and, more to | ||
| 913 | the point, using the vcc pointer). */ | ||
| 914 | tasklet_unlock_wait(&card->tlet); | ||
| 910 | return; | 915 | return; |
| 911 | } | 916 | } |
| 912 | 917 | ||
diff --git a/drivers/char/pcmcia/ipwireless/network.c b/drivers/char/pcmcia/ipwireless/network.c index 65920163f53d..9fe538347932 100644 --- a/drivers/char/pcmcia/ipwireless/network.c +++ b/drivers/char/pcmcia/ipwireless/network.c | |||
| @@ -239,7 +239,7 @@ static int ipwireless_ppp_ioctl(struct ppp_channel *ppp_channel, | |||
| 239 | return err; | 239 | return err; |
| 240 | } | 240 | } |
| 241 | 241 | ||
| 242 | static struct ppp_channel_ops ipwireless_ppp_channel_ops = { | 242 | static const struct ppp_channel_ops ipwireless_ppp_channel_ops = { |
| 243 | .start_xmit = ipwireless_ppp_start_xmit, | 243 | .start_xmit = ipwireless_ppp_start_xmit, |
| 244 | .ioctl = ipwireless_ppp_ioctl | 244 | .ioctl = ipwireless_ppp_ioctl |
| 245 | }; | 245 | }; |
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index 0ded3640b926..707d9c94cf9e 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c | |||
| @@ -1914,11 +1914,13 @@ static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb) | |||
| 1914 | * The next command will reopen the AT channel automatically. | 1914 | * The next command will reopen the AT channel automatically. |
| 1915 | */ | 1915 | */ |
| 1916 | if (cb->len == 3 && !memcmp(cb->buf, "+++", 3)) { | 1916 | if (cb->len == 3 && !memcmp(cb->buf, "+++", 3)) { |
| 1917 | kfree(cb); | ||
| 1918 | rc = req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT); | 1917 | rc = req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT); |
| 1919 | if (cb->wake_tasklet) | 1918 | if (cb->wake_tasklet) |
| 1920 | tasklet_schedule(cb->wake_tasklet); | 1919 | tasklet_schedule(cb->wake_tasklet); |
| 1921 | return rc < 0 ? rc : cb->len; | 1920 | if (!rc) |
| 1921 | rc = cb->len; | ||
| 1922 | kfree(cb); | ||
| 1923 | return rc; | ||
| 1922 | } | 1924 | } |
| 1923 | 1925 | ||
| 1924 | spin_lock_irqsave(&cs->cmdlock, flags); | 1926 | spin_lock_irqsave(&cs->cmdlock, flags); |
diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c index e5ea344a551a..bcc174e4f3b1 100644 --- a/drivers/isdn/gigaset/capi.c +++ b/drivers/isdn/gigaset/capi.c | |||
| @@ -1052,6 +1052,7 @@ static inline void remove_appl_from_channel(struct bc_state *bcs, | |||
| 1052 | do { | 1052 | do { |
| 1053 | if (bcap->bcnext == ap) { | 1053 | if (bcap->bcnext == ap) { |
| 1054 | bcap->bcnext = bcap->bcnext->bcnext; | 1054 | bcap->bcnext = bcap->bcnext->bcnext; |
| 1055 | spin_unlock_irqrestore(&bcs->aplock, flags); | ||
| 1055 | return; | 1056 | return; |
| 1056 | } | 1057 | } |
| 1057 | bcap = bcap->bcnext; | 1058 | bcap = bcap->bcnext; |
diff --git a/drivers/isdn/sc/ioctl.c b/drivers/isdn/sc/ioctl.c index 43c5dc3516e5..4cfdbe08ffd1 100644 --- a/drivers/isdn/sc/ioctl.c +++ b/drivers/isdn/sc/ioctl.c | |||
| @@ -174,7 +174,7 @@ int sc_ioctl(int card, scs_ioctl *data) | |||
| 174 | pr_debug("%s: SCIOGETSPID: ioctl received\n", | 174 | pr_debug("%s: SCIOGETSPID: ioctl received\n", |
| 175 | sc_adapter[card]->devicename); | 175 | sc_adapter[card]->devicename); |
| 176 | 176 | ||
| 177 | spid = kmalloc(SCIOC_SPIDSIZE, GFP_KERNEL); | 177 | spid = kzalloc(SCIOC_SPIDSIZE, GFP_KERNEL); |
| 178 | if (!spid) { | 178 | if (!spid) { |
| 179 | kfree(rcvmsg); | 179 | kfree(rcvmsg); |
| 180 | return -ENOMEM; | 180 | return -ENOMEM; |
| @@ -194,7 +194,7 @@ int sc_ioctl(int card, scs_ioctl *data) | |||
| 194 | kfree(rcvmsg); | 194 | kfree(rcvmsg); |
| 195 | return status; | 195 | return status; |
| 196 | } | 196 | } |
| 197 | strcpy(spid, rcvmsg->msg_data.byte_array); | 197 | strlcpy(spid, rcvmsg->msg_data.byte_array, SCIOC_SPIDSIZE); |
| 198 | 198 | ||
| 199 | /* | 199 | /* |
| 200 | * Package the switch type and send to user space | 200 | * Package the switch type and send to user space |
| @@ -266,12 +266,12 @@ int sc_ioctl(int card, scs_ioctl *data) | |||
| 266 | return status; | 266 | return status; |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | dn = kmalloc(SCIOC_DNSIZE, GFP_KERNEL); | 269 | dn = kzalloc(SCIOC_DNSIZE, GFP_KERNEL); |
| 270 | if (!dn) { | 270 | if (!dn) { |
| 271 | kfree(rcvmsg); | 271 | kfree(rcvmsg); |
| 272 | return -ENOMEM; | 272 | return -ENOMEM; |
| 273 | } | 273 | } |
| 274 | strcpy(dn, rcvmsg->msg_data.byte_array); | 274 | strlcpy(dn, rcvmsg->msg_data.byte_array, SCIOC_DNSIZE); |
| 275 | kfree(rcvmsg); | 275 | kfree(rcvmsg); |
| 276 | 276 | ||
| 277 | /* | 277 | /* |
| @@ -337,7 +337,7 @@ int sc_ioctl(int card, scs_ioctl *data) | |||
| 337 | pr_debug("%s: SCIOSTAT: ioctl received\n", | 337 | pr_debug("%s: SCIOSTAT: ioctl received\n", |
| 338 | sc_adapter[card]->devicename); | 338 | sc_adapter[card]->devicename); |
| 339 | 339 | ||
| 340 | bi = kmalloc (sizeof(boardInfo), GFP_KERNEL); | 340 | bi = kzalloc(sizeof(boardInfo), GFP_KERNEL); |
| 341 | if (!bi) { | 341 | if (!bi) { |
| 342 | kfree(rcvmsg); | 342 | kfree(rcvmsg); |
| 343 | return -ENOMEM; | 343 | return -ENOMEM; |
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 066fd5b09fda..ad19585d960b 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c | |||
| @@ -3198,17 +3198,17 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
| 3198 | } | 3198 | } |
| 3199 | } | 3199 | } |
| 3200 | 3200 | ||
| 3201 | err = pci_request_regions(pdev, DRV_NAME); | 3201 | err = pci_enable_device(pdev); |
| 3202 | if (err) { | 3202 | if (err) { |
| 3203 | /* Just info, some other driver may have claimed the device. */ | 3203 | dev_err(&pdev->dev, "cannot enable PCI device\n"); |
| 3204 | dev_info(&pdev->dev, "cannot obtain PCI resources\n"); | 3204 | goto out; |
| 3205 | return err; | ||
| 3206 | } | 3205 | } |
| 3207 | 3206 | ||
| 3208 | err = pci_enable_device(pdev); | 3207 | err = pci_request_regions(pdev, DRV_NAME); |
| 3209 | if (err) { | 3208 | if (err) { |
| 3210 | dev_err(&pdev->dev, "cannot enable PCI device\n"); | 3209 | /* Just info, some other driver may have claimed the device. */ |
| 3211 | goto out_release_regions; | 3210 | dev_info(&pdev->dev, "cannot obtain PCI resources\n"); |
| 3211 | goto out_disable_device; | ||
| 3212 | } | 3212 | } |
| 3213 | 3213 | ||
| 3214 | if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { | 3214 | if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { |
| @@ -3217,11 +3217,11 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
| 3217 | if (err) { | 3217 | if (err) { |
| 3218 | dev_err(&pdev->dev, "unable to obtain 64-bit DMA for " | 3218 | dev_err(&pdev->dev, "unable to obtain 64-bit DMA for " |
| 3219 | "coherent allocations\n"); | 3219 | "coherent allocations\n"); |
| 3220 | goto out_disable_device; | 3220 | goto out_release_regions; |
| 3221 | } | 3221 | } |
| 3222 | } else if ((err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) != 0) { | 3222 | } else if ((err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) != 0) { |
| 3223 | dev_err(&pdev->dev, "no usable DMA configuration\n"); | 3223 | dev_err(&pdev->dev, "no usable DMA configuration\n"); |
| 3224 | goto out_disable_device; | 3224 | goto out_release_regions; |
| 3225 | } | 3225 | } |
| 3226 | 3226 | ||
| 3227 | pci_set_master(pdev); | 3227 | pci_set_master(pdev); |
| @@ -3234,7 +3234,7 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
| 3234 | adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); | 3234 | adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); |
| 3235 | if (!adapter) { | 3235 | if (!adapter) { |
| 3236 | err = -ENOMEM; | 3236 | err = -ENOMEM; |
| 3237 | goto out_disable_device; | 3237 | goto out_release_regions; |
| 3238 | } | 3238 | } |
| 3239 | 3239 | ||
| 3240 | adapter->nofail_skb = | 3240 | adapter->nofail_skb = |
| @@ -3370,11 +3370,12 @@ out_free_dev: | |||
| 3370 | out_free_adapter: | 3370 | out_free_adapter: |
| 3371 | kfree(adapter); | 3371 | kfree(adapter); |
| 3372 | 3372 | ||
| 3373 | out_disable_device: | ||
| 3374 | pci_disable_device(pdev); | ||
| 3375 | out_release_regions: | 3373 | out_release_regions: |
| 3376 | pci_release_regions(pdev); | 3374 | pci_release_regions(pdev); |
| 3375 | out_disable_device: | ||
| 3376 | pci_disable_device(pdev); | ||
| 3377 | pci_set_drvdata(pdev, NULL); | 3377 | pci_set_drvdata(pdev, NULL); |
| 3378 | out: | ||
| 3378 | return err; | 3379 | return err; |
| 3379 | } | 3380 | } |
| 3380 | 3381 | ||
diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index a16563219ac9..7b6d07f50c71 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c | |||
| @@ -2462,23 +2462,24 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, | |||
| 2462 | version_printed = 1; | 2462 | version_printed = 1; |
| 2463 | } | 2463 | } |
| 2464 | 2464 | ||
| 2465 | |||
| 2465 | /* | 2466 | /* |
| 2466 | * Reserve PCI resources for the device. If we can't get them some | 2467 | * Initialize generic PCI device state. |
| 2467 | * other driver may have already claimed the device ... | ||
| 2468 | */ | 2468 | */ |
| 2469 | err = pci_request_regions(pdev, KBUILD_MODNAME); | 2469 | err = pci_enable_device(pdev); |
| 2470 | if (err) { | 2470 | if (err) { |
| 2471 | dev_err(&pdev->dev, "cannot obtain PCI resources\n"); | 2471 | dev_err(&pdev->dev, "cannot enable PCI device\n"); |
| 2472 | return err; | 2472 | return err; |
| 2473 | } | 2473 | } |
| 2474 | 2474 | ||
| 2475 | /* | 2475 | /* |
| 2476 | * Initialize generic PCI device state. | 2476 | * Reserve PCI resources for the device. If we can't get them some |
| 2477 | * other driver may have already claimed the device ... | ||
| 2477 | */ | 2478 | */ |
| 2478 | err = pci_enable_device(pdev); | 2479 | err = pci_request_regions(pdev, KBUILD_MODNAME); |
| 2479 | if (err) { | 2480 | if (err) { |
| 2480 | dev_err(&pdev->dev, "cannot enable PCI device\n"); | 2481 | dev_err(&pdev->dev, "cannot obtain PCI resources\n"); |
| 2481 | goto err_release_regions; | 2482 | goto err_disable_device; |
| 2482 | } | 2483 | } |
| 2483 | 2484 | ||
| 2484 | /* | 2485 | /* |
| @@ -2491,14 +2492,14 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, | |||
| 2491 | if (err) { | 2492 | if (err) { |
| 2492 | dev_err(&pdev->dev, "unable to obtain 64-bit DMA for" | 2493 | dev_err(&pdev->dev, "unable to obtain 64-bit DMA for" |
| 2493 | " coherent allocations\n"); | 2494 | " coherent allocations\n"); |
| 2494 | goto err_disable_device; | 2495 | goto err_release_regions; |
| 2495 | } | 2496 | } |
| 2496 | pci_using_dac = 1; | 2497 | pci_using_dac = 1; |
| 2497 | } else { | 2498 | } else { |
| 2498 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); | 2499 | err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); |
| 2499 | if (err != 0) { | 2500 | if (err != 0) { |
| 2500 | dev_err(&pdev->dev, "no usable DMA configuration\n"); | 2501 | dev_err(&pdev->dev, "no usable DMA configuration\n"); |
| 2501 | goto err_disable_device; | 2502 | goto err_release_regions; |
| 2502 | } | 2503 | } |
| 2503 | pci_using_dac = 0; | 2504 | pci_using_dac = 0; |
| 2504 | } | 2505 | } |
| @@ -2514,7 +2515,7 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, | |||
| 2514 | adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); | 2515 | adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); |
| 2515 | if (!adapter) { | 2516 | if (!adapter) { |
| 2516 | err = -ENOMEM; | 2517 | err = -ENOMEM; |
| 2517 | goto err_disable_device; | 2518 | goto err_release_regions; |
| 2518 | } | 2519 | } |
| 2519 | pci_set_drvdata(pdev, adapter); | 2520 | pci_set_drvdata(pdev, adapter); |
| 2520 | adapter->pdev = pdev; | 2521 | adapter->pdev = pdev; |
| @@ -2750,13 +2751,13 @@ err_free_adapter: | |||
| 2750 | kfree(adapter); | 2751 | kfree(adapter); |
| 2751 | pci_set_drvdata(pdev, NULL); | 2752 | pci_set_drvdata(pdev, NULL); |
| 2752 | 2753 | ||
| 2753 | err_disable_device: | ||
| 2754 | pci_disable_device(pdev); | ||
| 2755 | pci_clear_master(pdev); | ||
| 2756 | |||
| 2757 | err_release_regions: | 2754 | err_release_regions: |
| 2758 | pci_release_regions(pdev); | 2755 | pci_release_regions(pdev); |
| 2759 | pci_set_drvdata(pdev, NULL); | 2756 | pci_set_drvdata(pdev, NULL); |
| 2757 | pci_clear_master(pdev); | ||
| 2758 | |||
| 2759 | err_disable_device: | ||
| 2760 | pci_disable_device(pdev); | ||
| 2760 | 2761 | ||
| 2761 | err_out: | 2762 | err_out: |
| 2762 | return err; | 2763 | return err; |
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index d0824e322068..7fbd052ddb0a 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c | |||
| @@ -2944,8 +2944,8 @@ static int __devexit davinci_emac_remove(struct platform_device *pdev) | |||
| 2944 | release_mem_region(res->start, res->end - res->start + 1); | 2944 | release_mem_region(res->start, res->end - res->start + 1); |
| 2945 | 2945 | ||
| 2946 | unregister_netdev(ndev); | 2946 | unregister_netdev(ndev); |
| 2947 | free_netdev(ndev); | ||
| 2948 | iounmap(priv->remap_addr); | 2947 | iounmap(priv->remap_addr); |
| 2948 | free_netdev(ndev); | ||
| 2949 | 2949 | ||
| 2950 | clk_disable(emac_clk); | 2950 | clk_disable(emac_clk); |
| 2951 | clk_put(emac_clk); | 2951 | clk_put(emac_clk); |
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index b194bad29ace..8e2eab4e7c75 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
| @@ -1779,6 +1779,7 @@ static int e100_tx_clean(struct nic *nic) | |||
| 1779 | for (cb = nic->cb_to_clean; | 1779 | for (cb = nic->cb_to_clean; |
| 1780 | cb->status & cpu_to_le16(cb_complete); | 1780 | cb->status & cpu_to_le16(cb_complete); |
| 1781 | cb = nic->cb_to_clean = cb->next) { | 1781 | cb = nic->cb_to_clean = cb->next) { |
| 1782 | rmb(); /* read skb after status */ | ||
| 1782 | netif_printk(nic, tx_done, KERN_DEBUG, nic->netdev, | 1783 | netif_printk(nic, tx_done, KERN_DEBUG, nic->netdev, |
| 1783 | "cb[%d]->status = 0x%04X\n", | 1784 | "cb[%d]->status = 0x%04X\n", |
| 1784 | (int)(((void*)cb - (void*)nic->cbs)/sizeof(struct cb)), | 1785 | (int)(((void*)cb - (void*)nic->cbs)/sizeof(struct cb)), |
| @@ -1927,6 +1928,7 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx, | |||
| 1927 | 1928 | ||
| 1928 | netif_printk(nic, rx_status, KERN_DEBUG, nic->netdev, | 1929 | netif_printk(nic, rx_status, KERN_DEBUG, nic->netdev, |
| 1929 | "status=0x%04X\n", rfd_status); | 1930 | "status=0x%04X\n", rfd_status); |
| 1931 | rmb(); /* read size after status bit */ | ||
| 1930 | 1932 | ||
| 1931 | /* If data isn't ready, nothing to indicate */ | 1933 | /* If data isn't ready, nothing to indicate */ |
| 1932 | if (unlikely(!(rfd_status & cb_complete))) { | 1934 | if (unlikely(!(rfd_status & cb_complete))) { |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 02833af8a0b1..5cc39ed289c6 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
| @@ -3454,6 +3454,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter, | |||
| 3454 | while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) && | 3454 | while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) && |
| 3455 | (count < tx_ring->count)) { | 3455 | (count < tx_ring->count)) { |
| 3456 | bool cleaned = false; | 3456 | bool cleaned = false; |
| 3457 | rmb(); /* read buffer_info after eop_desc */ | ||
| 3457 | for ( ; !cleaned; count++) { | 3458 | for ( ; !cleaned; count++) { |
| 3458 | tx_desc = E1000_TX_DESC(*tx_ring, i); | 3459 | tx_desc = E1000_TX_DESC(*tx_ring, i); |
| 3459 | buffer_info = &tx_ring->buffer_info[i]; | 3460 | buffer_info = &tx_ring->buffer_info[i]; |
| @@ -3643,6 +3644,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, | |||
| 3643 | if (*work_done >= work_to_do) | 3644 | if (*work_done >= work_to_do) |
| 3644 | break; | 3645 | break; |
| 3645 | (*work_done)++; | 3646 | (*work_done)++; |
| 3647 | rmb(); /* read descriptor and rx_buffer_info after status DD */ | ||
| 3646 | 3648 | ||
| 3647 | status = rx_desc->status; | 3649 | status = rx_desc->status; |
| 3648 | skb = buffer_info->skb; | 3650 | skb = buffer_info->skb; |
| @@ -3849,6 +3851,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, | |||
| 3849 | if (*work_done >= work_to_do) | 3851 | if (*work_done >= work_to_do) |
| 3850 | break; | 3852 | break; |
| 3851 | (*work_done)++; | 3853 | (*work_done)++; |
| 3854 | rmb(); /* read descriptor and rx_buffer_info after status DD */ | ||
| 3852 | 3855 | ||
| 3853 | status = rx_desc->status; | 3856 | status = rx_desc->status; |
| 3854 | skb = buffer_info->skb; | 3857 | skb = buffer_info->skb; |
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 521c6ee1f32a..2b8ef44bd2b1 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
| @@ -781,6 +781,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, | |||
| 781 | if (*work_done >= work_to_do) | 781 | if (*work_done >= work_to_do) |
| 782 | break; | 782 | break; |
| 783 | (*work_done)++; | 783 | (*work_done)++; |
| 784 | rmb(); /* read descriptor and rx_buffer_info after status DD */ | ||
| 784 | 785 | ||
| 785 | status = rx_desc->status; | 786 | status = rx_desc->status; |
| 786 | skb = buffer_info->skb; | 787 | skb = buffer_info->skb; |
| @@ -991,6 +992,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) | |||
| 991 | while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) && | 992 | while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) && |
| 992 | (count < tx_ring->count)) { | 993 | (count < tx_ring->count)) { |
| 993 | bool cleaned = false; | 994 | bool cleaned = false; |
| 995 | rmb(); /* read buffer_info after eop_desc */ | ||
| 994 | for (; !cleaned; count++) { | 996 | for (; !cleaned; count++) { |
| 995 | tx_desc = E1000_TX_DESC(*tx_ring, i); | 997 | tx_desc = E1000_TX_DESC(*tx_ring, i); |
| 996 | buffer_info = &tx_ring->buffer_info[i]; | 998 | buffer_info = &tx_ring->buffer_info[i]; |
| @@ -1087,6 +1089,7 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, | |||
| 1087 | break; | 1089 | break; |
| 1088 | (*work_done)++; | 1090 | (*work_done)++; |
| 1089 | skb = buffer_info->skb; | 1091 | skb = buffer_info->skb; |
| 1092 | rmb(); /* read descriptor and rx_buffer_info after status DD */ | ||
| 1090 | 1093 | ||
| 1091 | /* in the packet split case this is header only */ | 1094 | /* in the packet split case this is header only */ |
| 1092 | prefetch(skb->data - NET_IP_ALIGN); | 1095 | prefetch(skb->data - NET_IP_ALIGN); |
| @@ -1286,6 +1289,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, | |||
| 1286 | if (*work_done >= work_to_do) | 1289 | if (*work_done >= work_to_do) |
| 1287 | break; | 1290 | break; |
| 1288 | (*work_done)++; | 1291 | (*work_done)++; |
| 1292 | rmb(); /* read descriptor and rx_buffer_info after status DD */ | ||
| 1289 | 1293 | ||
| 1290 | status = rx_desc->status; | 1294 | status = rx_desc->status; |
| 1291 | skb = buffer_info->skb; | 1295 | skb = buffer_info->skb; |
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 77a7f87d498e..9aab85366d21 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c | |||
| @@ -1087,10 +1087,7 @@ static int enic_set_port_profile(struct enic *enic, u8 *mac) | |||
| 1087 | { | 1087 | { |
| 1088 | struct vic_provinfo *vp; | 1088 | struct vic_provinfo *vp; |
| 1089 | u8 oui[3] = VIC_PROVINFO_CISCO_OUI; | 1089 | u8 oui[3] = VIC_PROVINFO_CISCO_OUI; |
| 1090 | u8 *uuid; | ||
| 1091 | char uuid_str[38]; | 1090 | char uuid_str[38]; |
| 1092 | static char *uuid_fmt = "%02X%02X%02X%02X-%02X%02X-%02X%02X-" | ||
| 1093 | "%02X%02X-%02X%02X%02X%02X%0X%02X"; | ||
| 1094 | int err; | 1091 | int err; |
| 1095 | 1092 | ||
| 1096 | err = enic_vnic_dev_deinit(enic); | 1093 | err = enic_vnic_dev_deinit(enic); |
| @@ -1121,24 +1118,14 @@ static int enic_set_port_profile(struct enic *enic, u8 *mac) | |||
| 1121 | ETH_ALEN, mac); | 1118 | ETH_ALEN, mac); |
| 1122 | 1119 | ||
| 1123 | if (enic->pp.set & ENIC_SET_INSTANCE) { | 1120 | if (enic->pp.set & ENIC_SET_INSTANCE) { |
| 1124 | uuid = enic->pp.instance_uuid; | 1121 | sprintf(uuid_str, "%pUB", enic->pp.instance_uuid); |
| 1125 | sprintf(uuid_str, uuid_fmt, | ||
| 1126 | uuid[0], uuid[1], uuid[2], uuid[3], | ||
| 1127 | uuid[4], uuid[5], uuid[6], uuid[7], | ||
| 1128 | uuid[8], uuid[9], uuid[10], uuid[11], | ||
| 1129 | uuid[12], uuid[13], uuid[14], uuid[15]); | ||
| 1130 | vic_provinfo_add_tlv(vp, | 1122 | vic_provinfo_add_tlv(vp, |
| 1131 | VIC_LINUX_PROV_TLV_CLIENT_UUID_STR, | 1123 | VIC_LINUX_PROV_TLV_CLIENT_UUID_STR, |
| 1132 | sizeof(uuid_str), uuid_str); | 1124 | sizeof(uuid_str), uuid_str); |
| 1133 | } | 1125 | } |
| 1134 | 1126 | ||
| 1135 | if (enic->pp.set & ENIC_SET_HOST) { | 1127 | if (enic->pp.set & ENIC_SET_HOST) { |
| 1136 | uuid = enic->pp.host_uuid; | 1128 | sprintf(uuid_str, "%pUB", enic->pp.host_uuid); |
| 1137 | sprintf(uuid_str, uuid_fmt, | ||
| 1138 | uuid[0], uuid[1], uuid[2], uuid[3], | ||
| 1139 | uuid[4], uuid[5], uuid[6], uuid[7], | ||
| 1140 | uuid[8], uuid[9], uuid[10], uuid[11], | ||
| 1141 | uuid[12], uuid[13], uuid[14], uuid[15]); | ||
| 1142 | vic_provinfo_add_tlv(vp, | 1129 | vic_provinfo_add_tlv(vp, |
| 1143 | VIC_LINUX_PROV_TLV_HOST_UUID_STR, | 1130 | VIC_LINUX_PROV_TLV_HOST_UUID_STR, |
| 1144 | sizeof(uuid_str), uuid_str); | 1131 | sizeof(uuid_str), uuid_str); |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index df5dcd23e4fc..9b4e5895f5f9 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
| @@ -5353,6 +5353,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector) | |||
| 5353 | 5353 | ||
| 5354 | while ((eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)) && | 5354 | while ((eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)) && |
| 5355 | (count < tx_ring->count)) { | 5355 | (count < tx_ring->count)) { |
| 5356 | rmb(); /* read buffer_info after eop_desc status */ | ||
| 5356 | for (cleaned = false; !cleaned; count++) { | 5357 | for (cleaned = false; !cleaned; count++) { |
| 5357 | tx_desc = E1000_TX_DESC_ADV(*tx_ring, i); | 5358 | tx_desc = E1000_TX_DESC_ADV(*tx_ring, i); |
| 5358 | buffer_info = &tx_ring->buffer_info[i]; | 5359 | buffer_info = &tx_ring->buffer_info[i]; |
| @@ -5558,6 +5559,7 @@ static bool igb_clean_rx_irq_adv(struct igb_q_vector *q_vector, | |||
| 5558 | if (*work_done >= budget) | 5559 | if (*work_done >= budget) |
| 5559 | break; | 5560 | break; |
| 5560 | (*work_done)++; | 5561 | (*work_done)++; |
| 5562 | rmb(); /* read descriptor and rx_buffer_info after status DD */ | ||
| 5561 | 5563 | ||
| 5562 | skb = buffer_info->skb; | 5564 | skb = buffer_info->skb; |
| 5563 | prefetch(skb->data - NET_IP_ALIGN); | 5565 | prefetch(skb->data - NET_IP_ALIGN); |
diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index ec808fa8dc21..c539f7c9c3e0 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c | |||
| @@ -248,6 +248,7 @@ static bool igbvf_clean_rx_irq(struct igbvf_adapter *adapter, | |||
| 248 | if (*work_done >= work_to_do) | 248 | if (*work_done >= work_to_do) |
| 249 | break; | 249 | break; |
| 250 | (*work_done)++; | 250 | (*work_done)++; |
| 251 | rmb(); /* read descriptor and rx_buffer_info after status DD */ | ||
| 251 | 252 | ||
| 252 | buffer_info = &rx_ring->buffer_info[i]; | 253 | buffer_info = &rx_ring->buffer_info[i]; |
| 253 | 254 | ||
| @@ -780,6 +781,7 @@ static bool igbvf_clean_tx_irq(struct igbvf_ring *tx_ring) | |||
| 780 | 781 | ||
| 781 | while ((eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)) && | 782 | while ((eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)) && |
| 782 | (count < tx_ring->count)) { | 783 | (count < tx_ring->count)) { |
| 784 | rmb(); /* read buffer_info after eop_desc status */ | ||
| 783 | for (cleaned = false; !cleaned; count++) { | 785 | for (cleaned = false; !cleaned; count++) { |
| 784 | tx_desc = IGBVF_TX_DESC_ADV(*tx_ring, i); | 786 | tx_desc = IGBVF_TX_DESC_ADV(*tx_ring, i); |
| 785 | buffer_info = &tx_ring->buffer_info[i]; | 787 | buffer_info = &tx_ring->buffer_info[i]; |
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index c6b75c83100c..45fc89b9ba64 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c | |||
| @@ -1816,6 +1816,7 @@ ixgb_clean_tx_irq(struct ixgb_adapter *adapter) | |||
| 1816 | 1816 | ||
| 1817 | while (eop_desc->status & IXGB_TX_DESC_STATUS_DD) { | 1817 | while (eop_desc->status & IXGB_TX_DESC_STATUS_DD) { |
| 1818 | 1818 | ||
| 1819 | rmb(); /* read buffer_info after eop_desc */ | ||
| 1819 | for (cleaned = false; !cleaned; ) { | 1820 | for (cleaned = false; !cleaned; ) { |
| 1820 | tx_desc = IXGB_TX_DESC(*tx_ring, i); | 1821 | tx_desc = IXGB_TX_DESC(*tx_ring, i); |
| 1821 | buffer_info = &tx_ring->buffer_info[i]; | 1822 | buffer_info = &tx_ring->buffer_info[i]; |
| @@ -1976,6 +1977,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter, int *work_done, int work_to_do) | |||
| 1976 | break; | 1977 | break; |
| 1977 | 1978 | ||
| 1978 | (*work_done)++; | 1979 | (*work_done)++; |
| 1980 | rmb(); /* read descriptor and rx_buffer_info after status DD */ | ||
| 1979 | status = rx_desc->status; | 1981 | status = rx_desc->status; |
| 1980 | skb = buffer_info->skb; | 1982 | skb = buffer_info->skb; |
| 1981 | buffer_info->skb = NULL; | 1983 | buffer_info->skb = NULL; |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 7d6a415bcf88..e32af434cc9d 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
| @@ -748,6 +748,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, | |||
| 748 | while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) && | 748 | while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) && |
| 749 | (count < tx_ring->work_limit)) { | 749 | (count < tx_ring->work_limit)) { |
| 750 | bool cleaned = false; | 750 | bool cleaned = false; |
| 751 | rmb(); /* read buffer_info after eop_desc */ | ||
| 751 | for ( ; !cleaned; count++) { | 752 | for ( ; !cleaned; count++) { |
| 752 | struct sk_buff *skb; | 753 | struct sk_buff *skb; |
| 753 | tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i); | 754 | tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i); |
| @@ -6155,9 +6156,11 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb) | |||
| 6155 | txq &= (adapter->ring_feature[RING_F_FCOE].indices - 1); | 6156 | txq &= (adapter->ring_feature[RING_F_FCOE].indices - 1); |
| 6156 | txq += adapter->ring_feature[RING_F_FCOE].mask; | 6157 | txq += adapter->ring_feature[RING_F_FCOE].mask; |
| 6157 | return txq; | 6158 | return txq; |
| 6159 | #ifdef CONFIG_IXGBE_DCB | ||
| 6158 | } else if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { | 6160 | } else if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { |
| 6159 | txq = adapter->fcoe.up; | 6161 | txq = adapter->fcoe.up; |
| 6160 | return txq; | 6162 | return txq; |
| 6163 | #endif | ||
| 6161 | } | 6164 | } |
| 6162 | } | 6165 | } |
| 6163 | #endif | 6166 | #endif |
| @@ -6216,10 +6219,14 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, | |||
| 6216 | if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED && | 6219 | if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED && |
| 6217 | (skb->protocol == htons(ETH_P_FCOE) || | 6220 | (skb->protocol == htons(ETH_P_FCOE) || |
| 6218 | skb->protocol == htons(ETH_P_FIP))) { | 6221 | skb->protocol == htons(ETH_P_FIP))) { |
| 6219 | tx_flags &= ~(IXGBE_TX_FLAGS_VLAN_PRIO_MASK | 6222 | #ifdef CONFIG_IXGBE_DCB |
| 6220 | << IXGBE_TX_FLAGS_VLAN_SHIFT); | 6223 | if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { |
| 6221 | tx_flags |= ((adapter->fcoe.up << 13) | 6224 | tx_flags &= ~(IXGBE_TX_FLAGS_VLAN_PRIO_MASK |
| 6222 | << IXGBE_TX_FLAGS_VLAN_SHIFT); | 6225 | << IXGBE_TX_FLAGS_VLAN_SHIFT); |
| 6226 | tx_flags |= ((adapter->fcoe.up << 13) | ||
| 6227 | << IXGBE_TX_FLAGS_VLAN_SHIFT); | ||
| 6228 | } | ||
| 6229 | #endif | ||
| 6223 | /* flag for FCoE offloads */ | 6230 | /* flag for FCoE offloads */ |
| 6224 | if (skb->protocol == htons(ETH_P_FCOE)) | 6231 | if (skb->protocol == htons(ETH_P_FCOE)) |
| 6225 | tx_flags |= IXGBE_TX_FLAGS_FCOE; | 6232 | tx_flags |= IXGBE_TX_FLAGS_FCOE; |
diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 3e291ccc629d..918c00359b0a 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c | |||
| @@ -231,6 +231,7 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_adapter *adapter, | |||
| 231 | while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) && | 231 | while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) && |
| 232 | (count < tx_ring->work_limit)) { | 232 | (count < tx_ring->work_limit)) { |
| 233 | bool cleaned = false; | 233 | bool cleaned = false; |
| 234 | rmb(); /* read buffer_info after eop_desc */ | ||
| 234 | for ( ; !cleaned; count++) { | 235 | for ( ; !cleaned; count++) { |
| 235 | struct sk_buff *skb; | 236 | struct sk_buff *skb; |
| 236 | tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i); | 237 | tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i); |
| @@ -518,6 +519,7 @@ static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, | |||
| 518 | break; | 519 | break; |
| 519 | (*work_done)++; | 520 | (*work_done)++; |
| 520 | 521 | ||
| 522 | rmb(); /* read descriptor and rx_buffer_info after status DD */ | ||
| 521 | if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) { | 523 | if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) { |
| 522 | hdr_info = le16_to_cpu(ixgbevf_get_hdr_info(rx_desc)); | 524 | hdr_info = le16_to_cpu(ixgbevf_get_hdr_info(rx_desc)); |
| 523 | len = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >> | 525 | len = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >> |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 6ce6ce1df6d2..fd86e18604e6 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
| @@ -2001,27 +2001,26 @@ static void netxen_tx_timeout_task(struct work_struct *work) | |||
| 2001 | if (++adapter->tx_timeo_cnt >= NX_MAX_TX_TIMEOUTS) | 2001 | if (++adapter->tx_timeo_cnt >= NX_MAX_TX_TIMEOUTS) |
| 2002 | goto request_reset; | 2002 | goto request_reset; |
| 2003 | 2003 | ||
| 2004 | rtnl_lock(); | ||
| 2004 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { | 2005 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { |
| 2005 | /* try to scrub interrupt */ | 2006 | /* try to scrub interrupt */ |
| 2006 | netxen_napi_disable(adapter); | 2007 | netxen_napi_disable(adapter); |
| 2007 | 2008 | ||
| 2008 | adapter->netdev->trans_start = jiffies; | ||
| 2009 | |||
| 2010 | netxen_napi_enable(adapter); | 2009 | netxen_napi_enable(adapter); |
| 2011 | 2010 | ||
| 2012 | netif_wake_queue(adapter->netdev); | 2011 | netif_wake_queue(adapter->netdev); |
| 2013 | 2012 | ||
| 2014 | clear_bit(__NX_RESETTING, &adapter->state); | 2013 | clear_bit(__NX_RESETTING, &adapter->state); |
| 2015 | return; | ||
| 2016 | } else { | 2014 | } else { |
| 2017 | clear_bit(__NX_RESETTING, &adapter->state); | 2015 | clear_bit(__NX_RESETTING, &adapter->state); |
| 2018 | if (!netxen_nic_reset_context(adapter)) { | 2016 | if (netxen_nic_reset_context(adapter)) { |
| 2019 | adapter->netdev->trans_start = jiffies; | 2017 | rtnl_unlock(); |
| 2020 | return; | 2018 | goto request_reset; |
| 2021 | } | 2019 | } |
| 2022 | |||
| 2023 | /* context reset failed, fall through for fw reset */ | ||
| 2024 | } | 2020 | } |
| 2021 | adapter->netdev->trans_start = jiffies; | ||
| 2022 | rtnl_unlock(); | ||
| 2023 | return; | ||
| 2025 | 2024 | ||
| 2026 | request_reset: | 2025 | request_reset: |
| 2027 | adapter->need_fw_reset = 1; | 2026 | adapter->need_fw_reset = 1; |
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c index 6c2e8fa0ca31..af50a530daee 100644 --- a/drivers/net/ppp_async.c +++ b/drivers/net/ppp_async.c | |||
| @@ -108,9 +108,9 @@ static void ppp_async_process(unsigned long arg); | |||
| 108 | static void async_lcp_peek(struct asyncppp *ap, unsigned char *data, | 108 | static void async_lcp_peek(struct asyncppp *ap, unsigned char *data, |
| 109 | int len, int inbound); | 109 | int len, int inbound); |
| 110 | 110 | ||
| 111 | static struct ppp_channel_ops async_ops = { | 111 | static const struct ppp_channel_ops async_ops = { |
| 112 | ppp_async_send, | 112 | .start_xmit = ppp_async_send, |
| 113 | ppp_async_ioctl | 113 | .ioctl = ppp_async_ioctl, |
| 114 | }; | 114 | }; |
| 115 | 115 | ||
| 116 | /* | 116 | /* |
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c index 52938da1e542..4c95ec3fb8d4 100644 --- a/drivers/net/ppp_synctty.c +++ b/drivers/net/ppp_synctty.c | |||
| @@ -97,9 +97,9 @@ static void ppp_sync_flush_output(struct syncppp *ap); | |||
| 97 | static void ppp_sync_input(struct syncppp *ap, const unsigned char *buf, | 97 | static void ppp_sync_input(struct syncppp *ap, const unsigned char *buf, |
| 98 | char *flags, int count); | 98 | char *flags, int count); |
| 99 | 99 | ||
| 100 | static struct ppp_channel_ops sync_ops = { | 100 | static const struct ppp_channel_ops sync_ops = { |
| 101 | ppp_sync_send, | 101 | .start_xmit = ppp_sync_send, |
| 102 | ppp_sync_ioctl | 102 | .ioctl = ppp_sync_ioctl, |
| 103 | }; | 103 | }; |
| 104 | 104 | ||
| 105 | /* | 105 | /* |
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index 344ef330e123..c07de359dc07 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c | |||
| @@ -92,7 +92,7 @@ | |||
| 92 | static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb); | 92 | static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb); |
| 93 | 93 | ||
| 94 | static const struct proto_ops pppoe_ops; | 94 | static const struct proto_ops pppoe_ops; |
| 95 | static struct ppp_channel_ops pppoe_chan_ops; | 95 | static const struct ppp_channel_ops pppoe_chan_ops; |
| 96 | 96 | ||
| 97 | /* per-net private data for this module */ | 97 | /* per-net private data for this module */ |
| 98 | static int pppoe_net_id __read_mostly; | 98 | static int pppoe_net_id __read_mostly; |
| @@ -963,7 +963,7 @@ static int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
| 963 | return __pppoe_xmit(sk, skb); | 963 | return __pppoe_xmit(sk, skb); |
| 964 | } | 964 | } |
| 965 | 965 | ||
| 966 | static struct ppp_channel_ops pppoe_chan_ops = { | 966 | static const struct ppp_channel_ops pppoe_chan_ops = { |
| 967 | .start_xmit = pppoe_xmit, | 967 | .start_xmit = pppoe_xmit, |
| 968 | }; | 968 | }; |
| 969 | 969 | ||
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 3b03794ac3f5..7f62e2dea28f 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
| @@ -1457,7 +1457,6 @@ int usbnet_resume (struct usb_interface *intf) | |||
| 1457 | spin_lock_irq(&dev->txq.lock); | 1457 | spin_lock_irq(&dev->txq.lock); |
| 1458 | while ((res = usb_get_from_anchor(&dev->deferred))) { | 1458 | while ((res = usb_get_from_anchor(&dev->deferred))) { |
| 1459 | 1459 | ||
| 1460 | printk(KERN_INFO"%s has delayed data\n", __func__); | ||
| 1461 | skb = (struct sk_buff *)res->context; | 1460 | skb = (struct sk_buff *)res->context; |
| 1462 | retval = usb_submit_urb(res, GFP_ATOMIC); | 1461 | retval = usb_submit_urb(res, GFP_ATOMIC); |
| 1463 | if (retval < 0) { | 1462 | if (retval < 0) { |
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 42dffd3e5795..fd69095ef6e3 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c | |||
| @@ -2763,12 +2763,12 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi | |||
| 2763 | 2763 | ||
| 2764 | vptr->dev = dev; | 2764 | vptr->dev = dev; |
| 2765 | 2765 | ||
| 2766 | dev->irq = pdev->irq; | ||
| 2767 | |||
| 2768 | ret = pci_enable_device(pdev); | 2766 | ret = pci_enable_device(pdev); |
| 2769 | if (ret < 0) | 2767 | if (ret < 0) |
| 2770 | goto err_free_dev; | 2768 | goto err_free_dev; |
| 2771 | 2769 | ||
| 2770 | dev->irq = pdev->irq; | ||
| 2771 | |||
| 2772 | ret = velocity_get_pci_info(vptr, pdev); | 2772 | ret = velocity_get_pci_info(vptr, pdev); |
| 2773 | if (ret < 0) { | 2773 | if (ret < 0) { |
| 2774 | /* error message already printed */ | 2774 | /* error message already printed */ |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index bb6b67f6b0cc..4598e9d2608f 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
| @@ -705,6 +705,19 @@ static int virtnet_close(struct net_device *dev) | |||
| 705 | return 0; | 705 | return 0; |
| 706 | } | 706 | } |
| 707 | 707 | ||
| 708 | static void virtnet_get_drvinfo(struct net_device *dev, | ||
| 709 | struct ethtool_drvinfo *drvinfo) | ||
| 710 | { | ||
| 711 | struct virtnet_info *vi = netdev_priv(dev); | ||
| 712 | struct virtio_device *vdev = vi->vdev; | ||
| 713 | |||
| 714 | strncpy(drvinfo->driver, KBUILD_MODNAME, ARRAY_SIZE(drvinfo->driver)); | ||
| 715 | strncpy(drvinfo->version, "N/A", ARRAY_SIZE(drvinfo->version)); | ||
| 716 | strncpy(drvinfo->fw_version, "N/A", ARRAY_SIZE(drvinfo->fw_version)); | ||
| 717 | strncpy(drvinfo->bus_info, dev_name(&vdev->dev), | ||
| 718 | ARRAY_SIZE(drvinfo->bus_info)); | ||
| 719 | } | ||
| 720 | |||
| 708 | static int virtnet_set_tx_csum(struct net_device *dev, u32 data) | 721 | static int virtnet_set_tx_csum(struct net_device *dev, u32 data) |
| 709 | { | 722 | { |
| 710 | struct virtnet_info *vi = netdev_priv(dev); | 723 | struct virtnet_info *vi = netdev_priv(dev); |
| @@ -817,6 +830,7 @@ static void virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid) | |||
| 817 | } | 830 | } |
| 818 | 831 | ||
| 819 | static const struct ethtool_ops virtnet_ethtool_ops = { | 832 | static const struct ethtool_ops virtnet_ethtool_ops = { |
| 833 | .get_drvinfo = virtnet_get_drvinfo, | ||
| 820 | .set_tx_csum = virtnet_set_tx_csum, | 834 | .set_tx_csum = virtnet_set_tx_csum, |
| 821 | .set_sg = ethtool_op_set_sg, | 835 | .set_sg = ethtool_op_set_sg, |
| 822 | .set_tso = ethtool_op_set_tso, | 836 | .set_tso = ethtool_op_set_tso, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index dabafb874c36..fe7418aefc4a 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c | |||
| @@ -63,6 +63,7 @@ static bool ar9002_hw_per_calibration(struct ath_hw *ah, | |||
| 63 | u8 rxchainmask, | 63 | u8 rxchainmask, |
| 64 | struct ath9k_cal_list *currCal) | 64 | struct ath9k_cal_list *currCal) |
| 65 | { | 65 | { |
| 66 | struct ath9k_hw_cal_data *caldata = ah->caldata; | ||
| 66 | bool iscaldone = false; | 67 | bool iscaldone = false; |
| 67 | 68 | ||
| 68 | if (currCal->calState == CAL_RUNNING) { | 69 | if (currCal->calState == CAL_RUNNING) { |
| @@ -81,14 +82,14 @@ static bool ar9002_hw_per_calibration(struct ath_hw *ah, | |||
| 81 | } | 82 | } |
| 82 | 83 | ||
| 83 | currCal->calData->calPostProc(ah, numChains); | 84 | currCal->calData->calPostProc(ah, numChains); |
| 84 | ichan->CalValid |= currCal->calData->calType; | 85 | caldata->CalValid |= currCal->calData->calType; |
| 85 | currCal->calState = CAL_DONE; | 86 | currCal->calState = CAL_DONE; |
| 86 | iscaldone = true; | 87 | iscaldone = true; |
| 87 | } else { | 88 | } else { |
| 88 | ar9002_hw_setup_calibration(ah, currCal); | 89 | ar9002_hw_setup_calibration(ah, currCal); |
| 89 | } | 90 | } |
| 90 | } | 91 | } |
| 91 | } else if (!(ichan->CalValid & currCal->calData->calType)) { | 92 | } else if (!(caldata->CalValid & currCal->calData->calType)) { |
| 92 | ath9k_hw_reset_calibration(ah, currCal); | 93 | ath9k_hw_reset_calibration(ah, currCal); |
| 93 | } | 94 | } |
| 94 | 95 | ||
| @@ -686,8 +687,13 @@ static bool ar9002_hw_calibrate(struct ath_hw *ah, | |||
| 686 | { | 687 | { |
| 687 | bool iscaldone = true; | 688 | bool iscaldone = true; |
| 688 | struct ath9k_cal_list *currCal = ah->cal_list_curr; | 689 | struct ath9k_cal_list *currCal = ah->cal_list_curr; |
| 690 | bool nfcal, nfcal_pending = false; | ||
| 689 | 691 | ||
| 690 | if (currCal && | 692 | nfcal = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF); |
| 693 | if (ah->caldata) | ||
| 694 | nfcal_pending = ah->caldata->nfcal_pending; | ||
| 695 | |||
| 696 | if (currCal && !nfcal && | ||
| 691 | (currCal->calState == CAL_RUNNING || | 697 | (currCal->calState == CAL_RUNNING || |
| 692 | currCal->calState == CAL_WAITING)) { | 698 | currCal->calState == CAL_WAITING)) { |
| 693 | iscaldone = ar9002_hw_per_calibration(ah, chan, | 699 | iscaldone = ar9002_hw_per_calibration(ah, chan, |
| @@ -703,7 +709,7 @@ static bool ar9002_hw_calibrate(struct ath_hw *ah, | |||
| 703 | } | 709 | } |
| 704 | 710 | ||
| 705 | /* Do NF cal only at longer intervals */ | 711 | /* Do NF cal only at longer intervals */ |
| 706 | if (longcal) { | 712 | if (longcal || nfcal_pending) { |
| 707 | /* Do periodic PAOffset Cal */ | 713 | /* Do periodic PAOffset Cal */ |
| 708 | ar9002_hw_pa_cal(ah, false); | 714 | ar9002_hw_pa_cal(ah, false); |
| 709 | ar9002_hw_olc_temp_compensation(ah); | 715 | ar9002_hw_olc_temp_compensation(ah); |
| @@ -712,16 +718,18 @@ static bool ar9002_hw_calibrate(struct ath_hw *ah, | |||
| 712 | * Get the value from the previous NF cal and update | 718 | * Get the value from the previous NF cal and update |
| 713 | * history buffer. | 719 | * history buffer. |
| 714 | */ | 720 | */ |
| 715 | ath9k_hw_getnf(ah, chan); | 721 | if (ath9k_hw_getnf(ah, chan)) { |
| 716 | 722 | /* | |
| 717 | /* | 723 | * Load the NF from history buffer of the current |
| 718 | * Load the NF from history buffer of the current channel. | 724 | * channel. |
| 719 | * NF is slow time-variant, so it is OK to use a historical | 725 | * NF is slow time-variant, so it is OK to use a |
| 720 | * value. | 726 | * historical value. |
| 721 | */ | 727 | */ |
| 722 | ath9k_hw_loadnf(ah, ah->curchan); | 728 | ath9k_hw_loadnf(ah, ah->curchan); |
| 729 | } | ||
| 723 | 730 | ||
| 724 | ath9k_hw_start_nfcal(ah); | 731 | if (longcal) |
| 732 | ath9k_hw_start_nfcal(ah, false); | ||
| 725 | } | 733 | } |
| 726 | 734 | ||
| 727 | return iscaldone; | 735 | return iscaldone; |
| @@ -869,8 +877,10 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) | |||
| 869 | ar9002_hw_pa_cal(ah, true); | 877 | ar9002_hw_pa_cal(ah, true); |
| 870 | 878 | ||
| 871 | /* Do NF Calibration after DC offset and other calibrations */ | 879 | /* Do NF Calibration after DC offset and other calibrations */ |
| 872 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, | 880 | ath9k_hw_start_nfcal(ah, true); |
| 873 | REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF); | 881 | |
| 882 | if (ah->caldata) | ||
| 883 | ah->caldata->nfcal_pending = true; | ||
| 874 | 884 | ||
| 875 | ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; | 885 | ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; |
| 876 | 886 | ||
| @@ -901,7 +911,8 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) | |||
| 901 | ath9k_hw_reset_calibration(ah, ah->cal_list_curr); | 911 | ath9k_hw_reset_calibration(ah, ah->cal_list_curr); |
| 902 | } | 912 | } |
| 903 | 913 | ||
| 904 | chan->CalValid = 0; | 914 | if (ah->caldata) |
| 915 | ah->caldata->CalValid = 0; | ||
| 905 | 916 | ||
| 906 | return true; | 917 | return true; |
| 907 | } | 918 | } |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 5a0650399136..4674ea8c9c99 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c | |||
| @@ -68,6 +68,7 @@ static bool ar9003_hw_per_calibration(struct ath_hw *ah, | |||
| 68 | u8 rxchainmask, | 68 | u8 rxchainmask, |
| 69 | struct ath9k_cal_list *currCal) | 69 | struct ath9k_cal_list *currCal) |
| 70 | { | 70 | { |
| 71 | struct ath9k_hw_cal_data *caldata = ah->caldata; | ||
| 71 | /* Cal is assumed not done until explicitly set below */ | 72 | /* Cal is assumed not done until explicitly set below */ |
| 72 | bool iscaldone = false; | 73 | bool iscaldone = false; |
| 73 | 74 | ||
| @@ -95,7 +96,7 @@ static bool ar9003_hw_per_calibration(struct ath_hw *ah, | |||
| 95 | currCal->calData->calPostProc(ah, numChains); | 96 | currCal->calData->calPostProc(ah, numChains); |
| 96 | 97 | ||
| 97 | /* Calibration has finished. */ | 98 | /* Calibration has finished. */ |
| 98 | ichan->CalValid |= currCal->calData->calType; | 99 | caldata->CalValid |= currCal->calData->calType; |
| 99 | currCal->calState = CAL_DONE; | 100 | currCal->calState = CAL_DONE; |
| 100 | iscaldone = true; | 101 | iscaldone = true; |
| 101 | } else { | 102 | } else { |
| @@ -106,7 +107,7 @@ static bool ar9003_hw_per_calibration(struct ath_hw *ah, | |||
| 106 | ar9003_hw_setup_calibration(ah, currCal); | 107 | ar9003_hw_setup_calibration(ah, currCal); |
| 107 | } | 108 | } |
| 108 | } | 109 | } |
| 109 | } else if (!(ichan->CalValid & currCal->calData->calType)) { | 110 | } else if (!(caldata->CalValid & currCal->calData->calType)) { |
| 110 | /* If current cal is marked invalid in channel, kick it off */ | 111 | /* If current cal is marked invalid in channel, kick it off */ |
| 111 | ath9k_hw_reset_calibration(ah, currCal); | 112 | ath9k_hw_reset_calibration(ah, currCal); |
| 112 | } | 113 | } |
| @@ -149,6 +150,12 @@ static bool ar9003_hw_calibrate(struct ath_hw *ah, | |||
| 149 | /* Do NF cal only at longer intervals */ | 150 | /* Do NF cal only at longer intervals */ |
| 150 | if (longcal) { | 151 | if (longcal) { |
| 151 | /* | 152 | /* |
| 153 | * Get the value from the previous NF cal and update | ||
| 154 | * history buffer. | ||
| 155 | */ | ||
| 156 | ath9k_hw_getnf(ah, chan); | ||
| 157 | |||
| 158 | /* | ||
| 152 | * Load the NF from history buffer of the current channel. | 159 | * Load the NF from history buffer of the current channel. |
| 153 | * NF is slow time-variant, so it is OK to use a historical | 160 | * NF is slow time-variant, so it is OK to use a historical |
| 154 | * value. | 161 | * value. |
| @@ -156,7 +163,7 @@ static bool ar9003_hw_calibrate(struct ath_hw *ah, | |||
| 156 | ath9k_hw_loadnf(ah, ah->curchan); | 163 | ath9k_hw_loadnf(ah, ah->curchan); |
| 157 | 164 | ||
| 158 | /* start NF calibration, without updating BB NF register */ | 165 | /* start NF calibration, without updating BB NF register */ |
| 159 | ath9k_hw_start_nfcal(ah); | 166 | ath9k_hw_start_nfcal(ah, false); |
| 160 | } | 167 | } |
| 161 | 168 | ||
| 162 | return iscaldone; | 169 | return iscaldone; |
| @@ -762,6 +769,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
| 762 | /* Revert chainmasks to their original values before NF cal */ | 769 | /* Revert chainmasks to their original values before NF cal */ |
| 763 | ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); | 770 | ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); |
| 764 | 771 | ||
| 772 | ath9k_hw_start_nfcal(ah, true); | ||
| 773 | |||
| 765 | /* Initialize list pointers */ | 774 | /* Initialize list pointers */ |
| 766 | ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; | 775 | ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; |
| 767 | 776 | ||
| @@ -785,7 +794,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
| 785 | if (ah->cal_list_curr) | 794 | if (ah->cal_list_curr) |
| 786 | ath9k_hw_reset_calibration(ah, ah->cal_list_curr); | 795 | ath9k_hw_reset_calibration(ah, ah->cal_list_curr); |
| 787 | 796 | ||
| 788 | chan->CalValid = 0; | 797 | if (ah->caldata) |
| 798 | ah->caldata->CalValid = 0; | ||
| 789 | 799 | ||
| 790 | return true; | 800 | return true; |
| 791 | } | 801 | } |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index ace8d2678b18..b883b174385b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
| @@ -41,6 +41,20 @@ | |||
| 41 | #define LE16(x) __constant_cpu_to_le16(x) | 41 | #define LE16(x) __constant_cpu_to_le16(x) |
| 42 | #define LE32(x) __constant_cpu_to_le32(x) | 42 | #define LE32(x) __constant_cpu_to_le32(x) |
| 43 | 43 | ||
| 44 | /* Local defines to distinguish between extension and control CTL's */ | ||
| 45 | #define EXT_ADDITIVE (0x8000) | ||
| 46 | #define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE) | ||
| 47 | #define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE) | ||
| 48 | #define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE) | ||
| 49 | #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */ | ||
| 50 | #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */ | ||
| 51 | #define PWRINCR_3_TO_1_CHAIN 9 /* 10*log(3)*2 */ | ||
| 52 | #define PWRINCR_3_TO_2_CHAIN 3 /* floor(10*log(3/2)*2) */ | ||
| 53 | #define PWRINCR_2_TO_1_CHAIN 6 /* 10*log(2)*2 */ | ||
| 54 | |||
| 55 | #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */ | ||
| 56 | #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */ | ||
| 57 | |||
| 44 | static const struct ar9300_eeprom ar9300_default = { | 58 | static const struct ar9300_eeprom ar9300_default = { |
| 45 | .eepromVersion = 2, | 59 | .eepromVersion = 2, |
| 46 | .templateVersion = 2, | 60 | .templateVersion = 2, |
| @@ -609,6 +623,14 @@ static const struct ar9300_eeprom ar9300_default = { | |||
| 609 | } | 623 | } |
| 610 | }; | 624 | }; |
| 611 | 625 | ||
| 626 | static u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz) | ||
| 627 | { | ||
| 628 | if (fbin == AR9300_BCHAN_UNUSED) | ||
| 629 | return fbin; | ||
| 630 | |||
| 631 | return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin)); | ||
| 632 | } | ||
| 633 | |||
| 612 | static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah) | 634 | static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah) |
| 613 | { | 635 | { |
| 614 | return 0; | 636 | return 0; |
| @@ -1417,9 +1439,9 @@ static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray) | |||
| 1417 | #undef POW_SM | 1439 | #undef POW_SM |
| 1418 | } | 1440 | } |
| 1419 | 1441 | ||
| 1420 | static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq) | 1442 | static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq, |
| 1443 | u8 *targetPowerValT2) | ||
| 1421 | { | 1444 | { |
| 1422 | u8 targetPowerValT2[ar9300RateSize]; | ||
| 1423 | /* XXX: hard code for now, need to get from eeprom struct */ | 1445 | /* XXX: hard code for now, need to get from eeprom struct */ |
| 1424 | u8 ht40PowerIncForPdadc = 0; | 1446 | u8 ht40PowerIncForPdadc = 0; |
| 1425 | bool is2GHz = false; | 1447 | bool is2GHz = false; |
| @@ -1553,9 +1575,6 @@ static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq) | |||
| 1553 | "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]); | 1575 | "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]); |
| 1554 | i++; | 1576 | i++; |
| 1555 | } | 1577 | } |
| 1556 | |||
| 1557 | /* Write target power array to registers */ | ||
| 1558 | ar9003_hw_tx_power_regwrite(ah, targetPowerValT2); | ||
| 1559 | } | 1578 | } |
| 1560 | 1579 | ||
| 1561 | static int ar9003_hw_cal_pier_get(struct ath_hw *ah, | 1580 | static int ar9003_hw_cal_pier_get(struct ath_hw *ah, |
| @@ -1799,14 +1818,369 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) | |||
| 1799 | return 0; | 1818 | return 0; |
| 1800 | } | 1819 | } |
| 1801 | 1820 | ||
| 1821 | static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep, | ||
| 1822 | int idx, | ||
| 1823 | int edge, | ||
| 1824 | bool is2GHz) | ||
| 1825 | { | ||
| 1826 | struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G; | ||
| 1827 | struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G; | ||
| 1828 | |||
| 1829 | if (is2GHz) | ||
| 1830 | return ctl_2g[idx].ctlEdges[edge].tPower; | ||
| 1831 | else | ||
| 1832 | return ctl_5g[idx].ctlEdges[edge].tPower; | ||
| 1833 | } | ||
| 1834 | |||
| 1835 | static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep, | ||
| 1836 | int idx, | ||
| 1837 | unsigned int edge, | ||
| 1838 | u16 freq, | ||
| 1839 | bool is2GHz) | ||
| 1840 | { | ||
| 1841 | struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G; | ||
| 1842 | struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G; | ||
| 1843 | |||
| 1844 | u8 *ctl_freqbin = is2GHz ? | ||
| 1845 | &eep->ctl_freqbin_2G[idx][0] : | ||
| 1846 | &eep->ctl_freqbin_5G[idx][0]; | ||
| 1847 | |||
| 1848 | if (is2GHz) { | ||
| 1849 | if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq && | ||
| 1850 | ctl_2g[idx].ctlEdges[edge - 1].flag) | ||
| 1851 | return ctl_2g[idx].ctlEdges[edge - 1].tPower; | ||
| 1852 | } else { | ||
| 1853 | if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq && | ||
| 1854 | ctl_5g[idx].ctlEdges[edge - 1].flag) | ||
| 1855 | return ctl_5g[idx].ctlEdges[edge - 1].tPower; | ||
| 1856 | } | ||
| 1857 | |||
| 1858 | return AR9300_MAX_RATE_POWER; | ||
| 1859 | } | ||
| 1860 | |||
| 1861 | /* | ||
| 1862 | * Find the maximum conformance test limit for the given channel and CTL info | ||
| 1863 | */ | ||
| 1864 | static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep, | ||
| 1865 | u16 freq, int idx, bool is2GHz) | ||
| 1866 | { | ||
| 1867 | u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER; | ||
| 1868 | u8 *ctl_freqbin = is2GHz ? | ||
| 1869 | &eep->ctl_freqbin_2G[idx][0] : | ||
| 1870 | &eep->ctl_freqbin_5G[idx][0]; | ||
| 1871 | u16 num_edges = is2GHz ? | ||
| 1872 | AR9300_NUM_BAND_EDGES_2G : AR9300_NUM_BAND_EDGES_5G; | ||
| 1873 | unsigned int edge; | ||
| 1874 | |||
| 1875 | /* Get the edge power */ | ||
| 1876 | for (edge = 0; | ||
| 1877 | (edge < num_edges) && (ctl_freqbin[edge] != AR9300_BCHAN_UNUSED); | ||
| 1878 | edge++) { | ||
| 1879 | /* | ||
| 1880 | * If there's an exact channel match or an inband flag set | ||
| 1881 | * on the lower channel use the given rdEdgePower | ||
| 1882 | */ | ||
| 1883 | if (freq == ath9k_hw_fbin2freq(ctl_freqbin[edge], is2GHz)) { | ||
| 1884 | twiceMaxEdgePower = | ||
| 1885 | ar9003_hw_get_direct_edge_power(eep, idx, | ||
| 1886 | edge, is2GHz); | ||
| 1887 | break; | ||
| 1888 | } else if ((edge > 0) && | ||
| 1889 | (freq < ath9k_hw_fbin2freq(ctl_freqbin[edge], | ||
| 1890 | is2GHz))) { | ||
| 1891 | twiceMaxEdgePower = | ||
| 1892 | ar9003_hw_get_indirect_edge_power(eep, idx, | ||
| 1893 | edge, freq, | ||
| 1894 | is2GHz); | ||
| 1895 | /* | ||
| 1896 | * Leave loop - no more affecting edges possible in | ||
| 1897 | * this monotonic increasing list | ||
| 1898 | */ | ||
| 1899 | break; | ||
| 1900 | } | ||
| 1901 | } | ||
| 1902 | return twiceMaxEdgePower; | ||
| 1903 | } | ||
| 1904 | |||
| 1905 | static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah, | ||
| 1906 | struct ath9k_channel *chan, | ||
| 1907 | u8 *pPwrArray, u16 cfgCtl, | ||
| 1908 | u8 twiceAntennaReduction, | ||
| 1909 | u8 twiceMaxRegulatoryPower, | ||
| 1910 | u16 powerLimit) | ||
| 1911 | { | ||
| 1912 | struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); | ||
| 1913 | struct ath_common *common = ath9k_hw_common(ah); | ||
| 1914 | struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep; | ||
| 1915 | u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER; | ||
| 1916 | static const u16 tpScaleReductionTable[5] = { | ||
| 1917 | 0, 3, 6, 9, AR9300_MAX_RATE_POWER | ||
| 1918 | }; | ||
| 1919 | int i; | ||
| 1920 | int16_t twiceLargestAntenna; | ||
| 1921 | u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; | ||
| 1922 | u16 ctlModesFor11a[] = { | ||
| 1923 | CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 | ||
| 1924 | }; | ||
| 1925 | u16 ctlModesFor11g[] = { | ||
| 1926 | CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, | ||
| 1927 | CTL_11G_EXT, CTL_2GHT40 | ||
| 1928 | }; | ||
| 1929 | u16 numCtlModes, *pCtlMode, ctlMode, freq; | ||
| 1930 | struct chan_centers centers; | ||
| 1931 | u8 *ctlIndex; | ||
| 1932 | u8 ctlNum; | ||
| 1933 | u16 twiceMinEdgePower; | ||
| 1934 | bool is2ghz = IS_CHAN_2GHZ(chan); | ||
| 1935 | |||
| 1936 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
| 1937 | |||
| 1938 | /* Compute TxPower reduction due to Antenna Gain */ | ||
| 1939 | if (is2ghz) | ||
| 1940 | twiceLargestAntenna = pEepData->modalHeader2G.antennaGain; | ||
| 1941 | else | ||
| 1942 | twiceLargestAntenna = pEepData->modalHeader5G.antennaGain; | ||
| 1943 | |||
| 1944 | twiceLargestAntenna = (int16_t)min((twiceAntennaReduction) - | ||
| 1945 | twiceLargestAntenna, 0); | ||
| 1946 | |||
| 1947 | /* | ||
| 1948 | * scaledPower is the minimum of the user input power level | ||
| 1949 | * and the regulatory allowed power level | ||
| 1950 | */ | ||
| 1951 | maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; | ||
| 1952 | |||
| 1953 | if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) { | ||
| 1954 | maxRegAllowedPower -= | ||
| 1955 | (tpScaleReductionTable[(regulatory->tp_scale)] * 2); | ||
| 1956 | } | ||
| 1957 | |||
| 1958 | scaledPower = min(powerLimit, maxRegAllowedPower); | ||
| 1959 | |||
| 1960 | /* | ||
| 1961 | * Reduce scaled Power by number of chains active to get | ||
| 1962 | * to per chain tx power level | ||
| 1963 | */ | ||
| 1964 | switch (ar5416_get_ntxchains(ah->txchainmask)) { | ||
| 1965 | case 1: | ||
| 1966 | break; | ||
| 1967 | case 2: | ||
| 1968 | scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; | ||
| 1969 | break; | ||
| 1970 | case 3: | ||
| 1971 | scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; | ||
| 1972 | break; | ||
| 1973 | } | ||
| 1974 | |||
| 1975 | scaledPower = max((u16)0, scaledPower); | ||
| 1976 | |||
| 1977 | /* | ||
| 1978 | * Get target powers from EEPROM - our baseline for TX Power | ||
| 1979 | */ | ||
| 1980 | if (is2ghz) { | ||
| 1981 | /* Setup for CTL modes */ | ||
| 1982 | /* CTL_11B, CTL_11G, CTL_2GHT20 */ | ||
| 1983 | numCtlModes = | ||
| 1984 | ARRAY_SIZE(ctlModesFor11g) - | ||
| 1985 | SUB_NUM_CTL_MODES_AT_2G_40; | ||
| 1986 | pCtlMode = ctlModesFor11g; | ||
| 1987 | if (IS_CHAN_HT40(chan)) | ||
| 1988 | /* All 2G CTL's */ | ||
| 1989 | numCtlModes = ARRAY_SIZE(ctlModesFor11g); | ||
| 1990 | } else { | ||
| 1991 | /* Setup for CTL modes */ | ||
| 1992 | /* CTL_11A, CTL_5GHT20 */ | ||
| 1993 | numCtlModes = ARRAY_SIZE(ctlModesFor11a) - | ||
| 1994 | SUB_NUM_CTL_MODES_AT_5G_40; | ||
| 1995 | pCtlMode = ctlModesFor11a; | ||
| 1996 | if (IS_CHAN_HT40(chan)) | ||
| 1997 | /* All 5G CTL's */ | ||
| 1998 | numCtlModes = ARRAY_SIZE(ctlModesFor11a); | ||
| 1999 | } | ||
| 2000 | |||
| 2001 | /* | ||
| 2002 | * For MIMO, need to apply regulatory caps individually across | ||
| 2003 | * dynamically running modes: CCK, OFDM, HT20, HT40 | ||
| 2004 | * | ||
| 2005 | * The outer loop walks through each possible applicable runtime mode. | ||
| 2006 | * The inner loop walks through each ctlIndex entry in EEPROM. | ||
| 2007 | * The ctl value is encoded as [7:4] == test group, [3:0] == test mode. | ||
| 2008 | */ | ||
| 2009 | for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { | ||
| 2010 | bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) || | ||
| 2011 | (pCtlMode[ctlMode] == CTL_2GHT40); | ||
| 2012 | if (isHt40CtlMode) | ||
| 2013 | freq = centers.synth_center; | ||
| 2014 | else if (pCtlMode[ctlMode] & EXT_ADDITIVE) | ||
| 2015 | freq = centers.ext_center; | ||
| 2016 | else | ||
| 2017 | freq = centers.ctl_center; | ||
| 2018 | |||
| 2019 | ath_print(common, ATH_DBG_REGULATORY, | ||
| 2020 | "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, " | ||
| 2021 | "EXT_ADDITIVE %d\n", | ||
| 2022 | ctlMode, numCtlModes, isHt40CtlMode, | ||
| 2023 | (pCtlMode[ctlMode] & EXT_ADDITIVE)); | ||
| 2024 | |||
| 2025 | /* walk through each CTL index stored in EEPROM */ | ||
| 2026 | if (is2ghz) { | ||
| 2027 | ctlIndex = pEepData->ctlIndex_2G; | ||
| 2028 | ctlNum = AR9300_NUM_CTLS_2G; | ||
| 2029 | } else { | ||
| 2030 | ctlIndex = pEepData->ctlIndex_5G; | ||
| 2031 | ctlNum = AR9300_NUM_CTLS_5G; | ||
| 2032 | } | ||
| 2033 | |||
| 2034 | for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) { | ||
| 2035 | ath_print(common, ATH_DBG_REGULATORY, | ||
| 2036 | "LOOP-Ctlidx %d: cfgCtl 0x%2.2x " | ||
| 2037 | "pCtlMode 0x%2.2x ctlIndex 0x%2.2x " | ||
| 2038 | "chan %dn", | ||
| 2039 | i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i], | ||
| 2040 | chan->channel); | ||
| 2041 | |||
| 2042 | /* | ||
| 2043 | * compare test group from regulatory | ||
| 2044 | * channel list with test mode from pCtlMode | ||
| 2045 | * list | ||
| 2046 | */ | ||
| 2047 | if ((((cfgCtl & ~CTL_MODE_M) | | ||
| 2048 | (pCtlMode[ctlMode] & CTL_MODE_M)) == | ||
| 2049 | ctlIndex[i]) || | ||
| 2050 | (((cfgCtl & ~CTL_MODE_M) | | ||
| 2051 | (pCtlMode[ctlMode] & CTL_MODE_M)) == | ||
| 2052 | ((ctlIndex[i] & CTL_MODE_M) | | ||
| 2053 | SD_NO_CTL))) { | ||
| 2054 | twiceMinEdgePower = | ||
| 2055 | ar9003_hw_get_max_edge_power(pEepData, | ||
| 2056 | freq, i, | ||
| 2057 | is2ghz); | ||
| 2058 | |||
| 2059 | if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) | ||
| 2060 | /* | ||
| 2061 | * Find the minimum of all CTL | ||
| 2062 | * edge powers that apply to | ||
| 2063 | * this channel | ||
| 2064 | */ | ||
| 2065 | twiceMaxEdgePower = | ||
| 2066 | min(twiceMaxEdgePower, | ||
| 2067 | twiceMinEdgePower); | ||
| 2068 | else { | ||
| 2069 | /* specific */ | ||
| 2070 | twiceMaxEdgePower = | ||
| 2071 | twiceMinEdgePower; | ||
| 2072 | break; | ||
| 2073 | } | ||
| 2074 | } | ||
| 2075 | } | ||
| 2076 | |||
| 2077 | minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower); | ||
| 2078 | |||
| 2079 | ath_print(common, ATH_DBG_REGULATORY, | ||
| 2080 | "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d " | ||
| 2081 | "sP %d minCtlPwr %d\n", | ||
| 2082 | ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower, | ||
| 2083 | scaledPower, minCtlPower); | ||
| 2084 | |||
| 2085 | /* Apply ctl mode to correct target power set */ | ||
| 2086 | switch (pCtlMode[ctlMode]) { | ||
| 2087 | case CTL_11B: | ||
| 2088 | for (i = ALL_TARGET_LEGACY_1L_5L; | ||
| 2089 | i <= ALL_TARGET_LEGACY_11S; i++) | ||
| 2090 | pPwrArray[i] = | ||
| 2091 | (u8)min((u16)pPwrArray[i], | ||
| 2092 | minCtlPower); | ||
| 2093 | break; | ||
| 2094 | case CTL_11A: | ||
| 2095 | case CTL_11G: | ||
| 2096 | for (i = ALL_TARGET_LEGACY_6_24; | ||
| 2097 | i <= ALL_TARGET_LEGACY_54; i++) | ||
| 2098 | pPwrArray[i] = | ||
| 2099 | (u8)min((u16)pPwrArray[i], | ||
| 2100 | minCtlPower); | ||
| 2101 | break; | ||
| 2102 | case CTL_5GHT20: | ||
| 2103 | case CTL_2GHT20: | ||
| 2104 | for (i = ALL_TARGET_HT20_0_8_16; | ||
| 2105 | i <= ALL_TARGET_HT20_21; i++) | ||
| 2106 | pPwrArray[i] = | ||
| 2107 | (u8)min((u16)pPwrArray[i], | ||
| 2108 | minCtlPower); | ||
| 2109 | pPwrArray[ALL_TARGET_HT20_22] = | ||
| 2110 | (u8)min((u16)pPwrArray[ALL_TARGET_HT20_22], | ||
| 2111 | minCtlPower); | ||
| 2112 | pPwrArray[ALL_TARGET_HT20_23] = | ||
| 2113 | (u8)min((u16)pPwrArray[ALL_TARGET_HT20_23], | ||
| 2114 | minCtlPower); | ||
| 2115 | break; | ||
| 2116 | case CTL_5GHT40: | ||
| 2117 | case CTL_2GHT40: | ||
| 2118 | for (i = ALL_TARGET_HT40_0_8_16; | ||
| 2119 | i <= ALL_TARGET_HT40_23; i++) | ||
| 2120 | pPwrArray[i] = | ||
| 2121 | (u8)min((u16)pPwrArray[i], | ||
| 2122 | minCtlPower); | ||
| 2123 | break; | ||
| 2124 | default: | ||
| 2125 | break; | ||
| 2126 | } | ||
| 2127 | } /* end ctl mode checking */ | ||
| 2128 | } | ||
| 2129 | |||
| 1802 | static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, | 2130 | static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, |
| 1803 | struct ath9k_channel *chan, u16 cfgCtl, | 2131 | struct ath9k_channel *chan, u16 cfgCtl, |
| 1804 | u8 twiceAntennaReduction, | 2132 | u8 twiceAntennaReduction, |
| 1805 | u8 twiceMaxRegulatoryPower, | 2133 | u8 twiceMaxRegulatoryPower, |
| 1806 | u8 powerLimit) | 2134 | u8 powerLimit) |
| 1807 | { | 2135 | { |
| 1808 | ah->txpower_limit = powerLimit; | 2136 | struct ath_common *common = ath9k_hw_common(ah); |
| 1809 | ar9003_hw_set_target_power_eeprom(ah, chan->channel); | 2137 | u8 targetPowerValT2[ar9300RateSize]; |
| 2138 | unsigned int i = 0; | ||
| 2139 | |||
| 2140 | ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2); | ||
| 2141 | ar9003_hw_set_power_per_rate_table(ah, chan, | ||
| 2142 | targetPowerValT2, cfgCtl, | ||
| 2143 | twiceAntennaReduction, | ||
| 2144 | twiceMaxRegulatoryPower, | ||
| 2145 | powerLimit); | ||
| 2146 | |||
| 2147 | while (i < ar9300RateSize) { | ||
| 2148 | ath_print(common, ATH_DBG_EEPROM, | ||
| 2149 | "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); | ||
| 2150 | i++; | ||
| 2151 | ath_print(common, ATH_DBG_EEPROM, | ||
| 2152 | "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); | ||
| 2153 | i++; | ||
| 2154 | ath_print(common, ATH_DBG_EEPROM, | ||
| 2155 | "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); | ||
| 2156 | i++; | ||
| 2157 | ath_print(common, ATH_DBG_EEPROM, | ||
| 2158 | "TPC[%02d] 0x%08x\n\n", i, targetPowerValT2[i]); | ||
| 2159 | i++; | ||
| 2160 | } | ||
| 2161 | |||
| 2162 | /* Write target power array to registers */ | ||
| 2163 | ar9003_hw_tx_power_regwrite(ah, targetPowerValT2); | ||
| 2164 | |||
| 2165 | /* | ||
| 2166 | * This is the TX power we send back to driver core, | ||
| 2167 | * and it can use to pass to userspace to display our | ||
| 2168 | * currently configured TX power setting. | ||
| 2169 | * | ||
| 2170 | * Since power is rate dependent, use one of the indices | ||
| 2171 | * from the AR9300_Rates enum to select an entry from | ||
| 2172 | * targetPowerValT2[] to report. Currently returns the | ||
| 2173 | * power for HT40 MCS 0, HT20 MCS 0, or OFDM 6 Mbps | ||
| 2174 | * as CCK power is less interesting (?). | ||
| 2175 | */ | ||
| 2176 | i = ALL_TARGET_LEGACY_6_24; /* legacy */ | ||
| 2177 | if (IS_CHAN_HT40(chan)) | ||
| 2178 | i = ALL_TARGET_HT40_0_8_16; /* ht40 */ | ||
| 2179 | else if (IS_CHAN_HT20(chan)) | ||
| 2180 | i = ALL_TARGET_HT20_0_8_16; /* ht20 */ | ||
| 2181 | |||
| 2182 | ah->txpower_limit = targetPowerValT2[i]; | ||
| 2183 | |||
| 1810 | ar9003_hw_calibration_apply(ah, chan->channel); | 2184 | ar9003_hw_calibration_apply(ah, chan->channel); |
| 1811 | } | 2185 | } |
| 1812 | 2186 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 49e0c865ce5c..7c38229ba670 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c | |||
| @@ -577,10 +577,11 @@ static bool create_pa_curve(u32 *data_L, u32 *data_U, u32 *pa_table, u16 *gain) | |||
| 577 | } | 577 | } |
| 578 | 578 | ||
| 579 | void ar9003_paprd_populate_single_table(struct ath_hw *ah, | 579 | void ar9003_paprd_populate_single_table(struct ath_hw *ah, |
| 580 | struct ath9k_channel *chan, int chain) | 580 | struct ath9k_hw_cal_data *caldata, |
| 581 | int chain) | ||
| 581 | { | 582 | { |
| 582 | u32 *paprd_table_val = chan->pa_table[chain]; | 583 | u32 *paprd_table_val = caldata->pa_table[chain]; |
| 583 | u32 small_signal_gain = chan->small_signal_gain[chain]; | 584 | u32 small_signal_gain = caldata->small_signal_gain[chain]; |
| 584 | u32 training_power; | 585 | u32 training_power; |
| 585 | u32 reg = 0; | 586 | u32 reg = 0; |
| 586 | int i; | 587 | int i; |
| @@ -654,17 +655,17 @@ int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain) | |||
| 654 | } | 655 | } |
| 655 | EXPORT_SYMBOL(ar9003_paprd_setup_gain_table); | 656 | EXPORT_SYMBOL(ar9003_paprd_setup_gain_table); |
| 656 | 657 | ||
| 657 | int ar9003_paprd_create_curve(struct ath_hw *ah, struct ath9k_channel *chan, | 658 | int ar9003_paprd_create_curve(struct ath_hw *ah, |
| 658 | int chain) | 659 | struct ath9k_hw_cal_data *caldata, int chain) |
| 659 | { | 660 | { |
| 660 | u16 *small_signal_gain = &chan->small_signal_gain[chain]; | 661 | u16 *small_signal_gain = &caldata->small_signal_gain[chain]; |
| 661 | u32 *pa_table = chan->pa_table[chain]; | 662 | u32 *pa_table = caldata->pa_table[chain]; |
| 662 | u32 *data_L, *data_U; | 663 | u32 *data_L, *data_U; |
| 663 | int i, status = 0; | 664 | int i, status = 0; |
| 664 | u32 *buf; | 665 | u32 *buf; |
| 665 | u32 reg; | 666 | u32 reg; |
| 666 | 667 | ||
| 667 | memset(chan->pa_table[chain], 0, sizeof(chan->pa_table[chain])); | 668 | memset(caldata->pa_table[chain], 0, sizeof(caldata->pa_table[chain])); |
| 668 | 669 | ||
| 669 | buf = kmalloc(2 * 48 * sizeof(u32), GFP_ATOMIC); | 670 | buf = kmalloc(2 * 48 * sizeof(u32), GFP_ATOMIC); |
| 670 | if (!buf) | 671 | if (!buf) |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index a753a431bb13..a491854fa38a 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
| @@ -542,7 +542,11 @@ static void ar9003_hw_prog_ini(struct ath_hw *ah, | |||
| 542 | u32 reg = INI_RA(iniArr, i, 0); | 542 | u32 reg = INI_RA(iniArr, i, 0); |
| 543 | u32 val = INI_RA(iniArr, i, column); | 543 | u32 val = INI_RA(iniArr, i, column); |
| 544 | 544 | ||
| 545 | REG_WRITE(ah, reg, val); | 545 | if (reg >= 0x16000 && reg < 0x17000) |
| 546 | ath9k_hw_analog_shift_regwrite(ah, reg, val); | ||
| 547 | else | ||
| 548 | REG_WRITE(ah, reg, val); | ||
| 549 | |||
| 546 | DO_DELAY(regWrites); | 550 | DO_DELAY(regWrites); |
| 547 | } | 551 | } |
| 548 | } | 552 | } |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 998ae2c49ed2..07f26ee7a723 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
| @@ -510,7 +510,7 @@ void ath_deinit_leds(struct ath_softc *sc); | |||
| 510 | #define SC_OP_BEACONS BIT(1) | 510 | #define SC_OP_BEACONS BIT(1) |
| 511 | #define SC_OP_RXAGGR BIT(2) | 511 | #define SC_OP_RXAGGR BIT(2) |
| 512 | #define SC_OP_TXAGGR BIT(3) | 512 | #define SC_OP_TXAGGR BIT(3) |
| 513 | #define SC_OP_FULL_RESET BIT(4) | 513 | #define SC_OP_OFFCHANNEL BIT(4) |
| 514 | #define SC_OP_PREAMBLE_SHORT BIT(5) | 514 | #define SC_OP_PREAMBLE_SHORT BIT(5) |
| 515 | #define SC_OP_PROTECT_ENABLE BIT(6) | 515 | #define SC_OP_PROTECT_ENABLE BIT(6) |
| 516 | #define SC_OP_RXFLUSH BIT(7) | 516 | #define SC_OP_RXFLUSH BIT(7) |
| @@ -609,6 +609,7 @@ struct ath_softc { | |||
| 609 | struct ath_wiphy { | 609 | struct ath_wiphy { |
| 610 | struct ath_softc *sc; /* shared for all virtual wiphys */ | 610 | struct ath_softc *sc; /* shared for all virtual wiphys */ |
| 611 | struct ieee80211_hw *hw; | 611 | struct ieee80211_hw *hw; |
| 612 | struct ath9k_hw_cal_data caldata; | ||
| 612 | enum ath_wiphy_state { | 613 | enum ath_wiphy_state { |
| 613 | ATH_WIPHY_INACTIVE, | 614 | ATH_WIPHY_INACTIVE, |
| 614 | ATH_WIPHY_ACTIVE, | 615 | ATH_WIPHY_ACTIVE, |
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 139289e4e933..45208690c0ec 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c | |||
| @@ -22,23 +22,6 @@ | |||
| 22 | /* We can tune this as we go by monitoring really low values */ | 22 | /* We can tune this as we go by monitoring really low values */ |
| 23 | #define ATH9K_NF_TOO_LOW -60 | 23 | #define ATH9K_NF_TOO_LOW -60 |
| 24 | 24 | ||
| 25 | /* AR5416 may return very high value (like -31 dBm), in those cases the nf | ||
| 26 | * is incorrect and we should use the static NF value. Later we can try to | ||
| 27 | * find out why they are reporting these values */ | ||
| 28 | |||
| 29 | static bool ath9k_hw_nf_in_range(struct ath_hw *ah, s16 nf) | ||
| 30 | { | ||
| 31 | if (nf > ATH9K_NF_TOO_LOW) { | ||
| 32 | ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, | ||
| 33 | "noise floor value detected (%d) is " | ||
| 34 | "lower than what we think is a " | ||
| 35 | "reasonable value (%d)\n", | ||
| 36 | nf, ATH9K_NF_TOO_LOW); | ||
| 37 | return false; | ||
| 38 | } | ||
| 39 | return true; | ||
| 40 | } | ||
| 41 | |||
| 42 | static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer) | 25 | static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer) |
| 43 | { | 26 | { |
| 44 | int16_t nfval; | 27 | int16_t nfval; |
| @@ -121,6 +104,19 @@ void ath9k_hw_reset_calibration(struct ath_hw *ah, | |||
| 121 | ah->cal_samples = 0; | 104 | ah->cal_samples = 0; |
| 122 | } | 105 | } |
| 123 | 106 | ||
| 107 | static s16 ath9k_hw_get_default_nf(struct ath_hw *ah, | ||
| 108 | struct ath9k_channel *chan) | ||
| 109 | { | ||
| 110 | struct ath_nf_limits *limit; | ||
| 111 | |||
| 112 | if (!chan || IS_CHAN_2GHZ(chan)) | ||
| 113 | limit = &ah->nf_2g; | ||
| 114 | else | ||
| 115 | limit = &ah->nf_5g; | ||
| 116 | |||
| 117 | return limit->nominal; | ||
| 118 | } | ||
| 119 | |||
| 124 | /* This is done for the currently configured channel */ | 120 | /* This is done for the currently configured channel */ |
| 125 | bool ath9k_hw_reset_calvalid(struct ath_hw *ah) | 121 | bool ath9k_hw_reset_calvalid(struct ath_hw *ah) |
| 126 | { | 122 | { |
| @@ -128,7 +124,7 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah) | |||
| 128 | struct ieee80211_conf *conf = &common->hw->conf; | 124 | struct ieee80211_conf *conf = &common->hw->conf; |
| 129 | struct ath9k_cal_list *currCal = ah->cal_list_curr; | 125 | struct ath9k_cal_list *currCal = ah->cal_list_curr; |
| 130 | 126 | ||
| 131 | if (!ah->curchan) | 127 | if (!ah->caldata) |
| 132 | return true; | 128 | return true; |
| 133 | 129 | ||
| 134 | if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah)) | 130 | if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah)) |
| @@ -151,37 +147,55 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah) | |||
| 151 | "Resetting Cal %d state for channel %u\n", | 147 | "Resetting Cal %d state for channel %u\n", |
| 152 | currCal->calData->calType, conf->channel->center_freq); | 148 | currCal->calData->calType, conf->channel->center_freq); |
| 153 | 149 | ||
| 154 | ah->curchan->CalValid &= ~currCal->calData->calType; | 150 | ah->caldata->CalValid &= ~currCal->calData->calType; |
| 155 | currCal->calState = CAL_WAITING; | 151 | currCal->calState = CAL_WAITING; |
| 156 | 152 | ||
| 157 | return false; | 153 | return false; |
| 158 | } | 154 | } |
| 159 | EXPORT_SYMBOL(ath9k_hw_reset_calvalid); | 155 | EXPORT_SYMBOL(ath9k_hw_reset_calvalid); |
| 160 | 156 | ||
| 161 | void ath9k_hw_start_nfcal(struct ath_hw *ah) | 157 | void ath9k_hw_start_nfcal(struct ath_hw *ah, bool update) |
| 162 | { | 158 | { |
| 159 | if (ah->caldata) | ||
| 160 | ah->caldata->nfcal_pending = true; | ||
| 161 | |||
| 163 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, | 162 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, |
| 164 | AR_PHY_AGC_CONTROL_ENABLE_NF); | 163 | AR_PHY_AGC_CONTROL_ENABLE_NF); |
| 165 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, | 164 | |
| 165 | if (update) | ||
| 166 | REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, | ||
| 167 | AR_PHY_AGC_CONTROL_NO_UPDATE_NF); | ||
| 168 | else | ||
| 169 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, | ||
| 166 | AR_PHY_AGC_CONTROL_NO_UPDATE_NF); | 170 | AR_PHY_AGC_CONTROL_NO_UPDATE_NF); |
| 171 | |||
| 167 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); | 172 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); |
| 168 | } | 173 | } |
| 169 | 174 | ||
| 170 | void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) | 175 | void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) |
| 171 | { | 176 | { |
| 172 | struct ath9k_nfcal_hist *h; | 177 | struct ath9k_nfcal_hist *h = NULL; |
| 173 | unsigned i, j; | 178 | unsigned i, j; |
| 174 | int32_t val; | 179 | int32_t val; |
| 175 | u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; | 180 | u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; |
| 176 | struct ath_common *common = ath9k_hw_common(ah); | 181 | struct ath_common *common = ath9k_hw_common(ah); |
| 182 | s16 default_nf = ath9k_hw_get_default_nf(ah, chan); | ||
| 177 | 183 | ||
| 178 | h = ah->nfCalHist; | 184 | if (ah->caldata) |
| 185 | h = ah->caldata->nfCalHist; | ||
| 179 | 186 | ||
| 180 | for (i = 0; i < NUM_NF_READINGS; i++) { | 187 | for (i = 0; i < NUM_NF_READINGS; i++) { |
| 181 | if (chainmask & (1 << i)) { | 188 | if (chainmask & (1 << i)) { |
| 189 | s16 nfval; | ||
| 190 | |||
| 191 | if (h) | ||
| 192 | nfval = h[i].privNF; | ||
| 193 | else | ||
| 194 | nfval = default_nf; | ||
| 195 | |||
| 182 | val = REG_READ(ah, ah->nf_regs[i]); | 196 | val = REG_READ(ah, ah->nf_regs[i]); |
| 183 | val &= 0xFFFFFE00; | 197 | val &= 0xFFFFFE00; |
| 184 | val |= (((u32) (h[i].privNF) << 1) & 0x1ff); | 198 | val |= (((u32) nfval << 1) & 0x1ff); |
| 185 | REG_WRITE(ah, ah->nf_regs[i], val); | 199 | REG_WRITE(ah, ah->nf_regs[i], val); |
| 186 | } | 200 | } |
| 187 | } | 201 | } |
| @@ -277,22 +291,25 @@ static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf) | |||
| 277 | } | 291 | } |
| 278 | } | 292 | } |
| 279 | 293 | ||
| 280 | int16_t ath9k_hw_getnf(struct ath_hw *ah, | 294 | bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan) |
| 281 | struct ath9k_channel *chan) | ||
| 282 | { | 295 | { |
| 283 | struct ath_common *common = ath9k_hw_common(ah); | 296 | struct ath_common *common = ath9k_hw_common(ah); |
| 284 | int16_t nf, nfThresh; | 297 | int16_t nf, nfThresh; |
| 285 | int16_t nfarray[NUM_NF_READINGS] = { 0 }; | 298 | int16_t nfarray[NUM_NF_READINGS] = { 0 }; |
| 286 | struct ath9k_nfcal_hist *h; | 299 | struct ath9k_nfcal_hist *h; |
| 287 | struct ieee80211_channel *c = chan->chan; | 300 | struct ieee80211_channel *c = chan->chan; |
| 301 | struct ath9k_hw_cal_data *caldata = ah->caldata; | ||
| 302 | |||
| 303 | if (!caldata) | ||
| 304 | return false; | ||
| 288 | 305 | ||
| 289 | chan->channelFlags &= (~CHANNEL_CW_INT); | 306 | chan->channelFlags &= (~CHANNEL_CW_INT); |
| 290 | if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { | 307 | if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { |
| 291 | ath_print(common, ATH_DBG_CALIBRATE, | 308 | ath_print(common, ATH_DBG_CALIBRATE, |
| 292 | "NF did not complete in calibration window\n"); | 309 | "NF did not complete in calibration window\n"); |
| 293 | nf = 0; | 310 | nf = 0; |
| 294 | chan->rawNoiseFloor = nf; | 311 | caldata->rawNoiseFloor = nf; |
| 295 | return chan->rawNoiseFloor; | 312 | return false; |
| 296 | } else { | 313 | } else { |
| 297 | ath9k_hw_do_getnf(ah, nfarray); | 314 | ath9k_hw_do_getnf(ah, nfarray); |
| 298 | ath9k_hw_nf_sanitize(ah, nfarray); | 315 | ath9k_hw_nf_sanitize(ah, nfarray); |
| @@ -307,47 +324,40 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah, | |||
| 307 | } | 324 | } |
| 308 | } | 325 | } |
| 309 | 326 | ||
| 310 | h = ah->nfCalHist; | 327 | h = caldata->nfCalHist; |
| 311 | 328 | caldata->nfcal_pending = false; | |
| 312 | ath9k_hw_update_nfcal_hist_buffer(h, nfarray); | 329 | ath9k_hw_update_nfcal_hist_buffer(h, nfarray); |
| 313 | chan->rawNoiseFloor = h[0].privNF; | 330 | caldata->rawNoiseFloor = h[0].privNF; |
| 314 | 331 | return true; | |
| 315 | return chan->rawNoiseFloor; | ||
| 316 | } | 332 | } |
| 317 | 333 | ||
| 318 | void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah) | 334 | void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, |
| 335 | struct ath9k_channel *chan) | ||
| 319 | { | 336 | { |
| 320 | struct ath_nf_limits *limit; | 337 | struct ath9k_nfcal_hist *h; |
| 338 | s16 default_nf; | ||
| 321 | int i, j; | 339 | int i, j; |
| 322 | 340 | ||
| 323 | if (!ah->curchan || IS_CHAN_2GHZ(ah->curchan)) | 341 | if (!ah->caldata) |
| 324 | limit = &ah->nf_2g; | 342 | return; |
| 325 | else | ||
| 326 | limit = &ah->nf_5g; | ||
| 327 | 343 | ||
| 344 | h = ah->caldata->nfCalHist; | ||
| 345 | default_nf = ath9k_hw_get_default_nf(ah, chan); | ||
| 328 | for (i = 0; i < NUM_NF_READINGS; i++) { | 346 | for (i = 0; i < NUM_NF_READINGS; i++) { |
| 329 | ah->nfCalHist[i].currIndex = 0; | 347 | h[i].currIndex = 0; |
| 330 | ah->nfCalHist[i].privNF = limit->nominal; | 348 | h[i].privNF = default_nf; |
| 331 | ah->nfCalHist[i].invalidNFcount = | 349 | h[i].invalidNFcount = AR_PHY_CCA_FILTERWINDOW_LENGTH; |
| 332 | AR_PHY_CCA_FILTERWINDOW_LENGTH; | ||
| 333 | for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) { | 350 | for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) { |
| 334 | ah->nfCalHist[i].nfCalBuffer[j] = limit->nominal; | 351 | h[i].nfCalBuffer[j] = default_nf; |
| 335 | } | 352 | } |
| 336 | } | 353 | } |
| 337 | } | 354 | } |
| 338 | 355 | ||
| 339 | s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan) | 356 | s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan) |
| 340 | { | 357 | { |
| 341 | s16 nf; | 358 | if (!ah->caldata || !ah->caldata->rawNoiseFloor) |
| 342 | 359 | return ath9k_hw_get_default_nf(ah, chan); | |
| 343 | if (chan->rawNoiseFloor == 0) | ||
| 344 | nf = -96; | ||
| 345 | else | ||
| 346 | nf = chan->rawNoiseFloor; | ||
| 347 | |||
| 348 | if (!ath9k_hw_nf_in_range(ah, nf)) | ||
| 349 | nf = ATH_DEFAULT_NOISE_FLOOR; | ||
| 350 | 360 | ||
| 351 | return nf; | 361 | return ah->caldata->rawNoiseFloor; |
| 352 | } | 362 | } |
| 353 | EXPORT_SYMBOL(ath9k_hw_getchan_noise); | 363 | EXPORT_SYMBOL(ath9k_hw_getchan_noise); |
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h index cd60d09cdda7..0a304b3eeeb6 100644 --- a/drivers/net/wireless/ath/ath9k/calib.h +++ b/drivers/net/wireless/ath/ath9k/calib.h | |||
| @@ -108,11 +108,11 @@ struct ath9k_pacal_info{ | |||
| 108 | }; | 108 | }; |
| 109 | 109 | ||
| 110 | bool ath9k_hw_reset_calvalid(struct ath_hw *ah); | 110 | bool ath9k_hw_reset_calvalid(struct ath_hw *ah); |
| 111 | void ath9k_hw_start_nfcal(struct ath_hw *ah); | 111 | void ath9k_hw_start_nfcal(struct ath_hw *ah, bool update); |
| 112 | void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan); | 112 | void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan); |
| 113 | int16_t ath9k_hw_getnf(struct ath_hw *ah, | 113 | bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan); |
| 114 | struct ath9k_channel *chan); | 114 | void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, |
| 115 | void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah); | 115 | struct ath9k_channel *chan); |
| 116 | s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan); | 116 | s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan); |
| 117 | void ath9k_hw_reset_calibration(struct ath_hw *ah, | 117 | void ath9k_hw_reset_calibration(struct ath_hw *ah, |
| 118 | struct ath9k_cal_list *currCal); | 118 | struct ath9k_cal_list *currCal); |
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 3756400e6bf9..43b9e21bc562 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h | |||
| @@ -353,6 +353,8 @@ struct ath9k_htc_priv { | |||
| 353 | u16 seq_no; | 353 | u16 seq_no; |
| 354 | u32 bmiss_cnt; | 354 | u32 bmiss_cnt; |
| 355 | 355 | ||
| 356 | struct ath9k_hw_cal_data caldata[38]; | ||
| 357 | |||
| 356 | spinlock_t beacon_lock; | 358 | spinlock_t beacon_lock; |
| 357 | 359 | ||
| 358 | bool tx_queues_stop; | 360 | bool tx_queues_stop; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index cf9bcc67ade2..ebed9d1691a5 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
| @@ -125,6 +125,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, | |||
| 125 | struct ieee80211_conf *conf = &common->hw->conf; | 125 | struct ieee80211_conf *conf = &common->hw->conf; |
| 126 | bool fastcc = true; | 126 | bool fastcc = true; |
| 127 | struct ieee80211_channel *channel = hw->conf.channel; | 127 | struct ieee80211_channel *channel = hw->conf.channel; |
| 128 | struct ath9k_hw_cal_data *caldata; | ||
| 128 | enum htc_phymode mode; | 129 | enum htc_phymode mode; |
| 129 | __be16 htc_mode; | 130 | __be16 htc_mode; |
| 130 | u8 cmd_rsp; | 131 | u8 cmd_rsp; |
| @@ -149,7 +150,8 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, | |||
| 149 | priv->ah->curchan->channel, | 150 | priv->ah->curchan->channel, |
| 150 | channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf)); | 151 | channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf)); |
| 151 | 152 | ||
| 152 | ret = ath9k_hw_reset(ah, hchan, fastcc); | 153 | caldata = &priv->caldata[channel->hw_value]; |
| 154 | ret = ath9k_hw_reset(ah, hchan, caldata, fastcc); | ||
| 153 | if (ret) { | 155 | if (ret) { |
| 154 | ath_print(common, ATH_DBG_FATAL, | 156 | ath_print(common, ATH_DBG_FATAL, |
| 155 | "Unable to reset channel (%u Mhz) " | 157 | "Unable to reset channel (%u Mhz) " |
| @@ -1028,7 +1030,7 @@ static void ath9k_htc_radio_enable(struct ieee80211_hw *hw) | |||
| 1028 | ah->curchan = ath9k_cmn_get_curchannel(hw, ah); | 1030 | ah->curchan = ath9k_cmn_get_curchannel(hw, ah); |
| 1029 | 1031 | ||
| 1030 | /* Reset the HW */ | 1032 | /* Reset the HW */ |
| 1031 | ret = ath9k_hw_reset(ah, ah->curchan, false); | 1033 | ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); |
| 1032 | if (ret) { | 1034 | if (ret) { |
| 1033 | ath_print(common, ATH_DBG_FATAL, | 1035 | ath_print(common, ATH_DBG_FATAL, |
| 1034 | "Unable to reset hardware; reset status %d " | 1036 | "Unable to reset hardware; reset status %d " |
| @@ -1091,7 +1093,7 @@ static void ath9k_htc_radio_disable(struct ieee80211_hw *hw) | |||
| 1091 | ah->curchan = ath9k_cmn_get_curchannel(hw, ah); | 1093 | ah->curchan = ath9k_cmn_get_curchannel(hw, ah); |
| 1092 | 1094 | ||
| 1093 | /* Reset the HW */ | 1095 | /* Reset the HW */ |
| 1094 | ret = ath9k_hw_reset(ah, ah->curchan, false); | 1096 | ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); |
| 1095 | if (ret) { | 1097 | if (ret) { |
| 1096 | ath_print(common, ATH_DBG_FATAL, | 1098 | ath_print(common, ATH_DBG_FATAL, |
| 1097 | "Unable to reset hardware; reset status %d " | 1099 | "Unable to reset hardware; reset status %d " |
| @@ -1179,7 +1181,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) | |||
| 1179 | ath9k_hw_configpcipowersave(ah, 0, 0); | 1181 | ath9k_hw_configpcipowersave(ah, 0, 0); |
| 1180 | 1182 | ||
| 1181 | ath9k_hw_htc_resetinit(ah); | 1183 | ath9k_hw_htc_resetinit(ah); |
| 1182 | ret = ath9k_hw_reset(ah, init_channel, false); | 1184 | ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false); |
| 1183 | if (ret) { | 1185 | if (ret) { |
| 1184 | ath_print(common, ATH_DBG_FATAL, | 1186 | ath_print(common, ATH_DBG_FATAL, |
| 1185 | "Unable to reset hardware; reset status %d " | 1187 | "Unable to reset hardware; reset status %d " |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 8d291ccf5c88..3384ca164562 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
| @@ -610,7 +610,6 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
| 610 | else | 610 | else |
| 611 | ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S); | 611 | ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S); |
| 612 | 612 | ||
| 613 | ath9k_init_nfcal_hist_buffer(ah); | ||
| 614 | ah->bb_watchdog_timeout_ms = 25; | 613 | ah->bb_watchdog_timeout_ms = 25; |
| 615 | 614 | ||
| 616 | common->state = ATH_HW_INITIALIZED; | 615 | common->state = ATH_HW_INITIALIZED; |
| @@ -1183,9 +1182,6 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, | |||
| 1183 | 1182 | ||
| 1184 | ath9k_hw_spur_mitigate_freq(ah, chan); | 1183 | ath9k_hw_spur_mitigate_freq(ah, chan); |
| 1185 | 1184 | ||
| 1186 | if (!chan->oneTimeCalsDone) | ||
| 1187 | chan->oneTimeCalsDone = true; | ||
| 1188 | |||
| 1189 | return true; | 1185 | return true; |
| 1190 | } | 1186 | } |
| 1191 | 1187 | ||
| @@ -1218,7 +1214,7 @@ bool ath9k_hw_check_alive(struct ath_hw *ah) | |||
| 1218 | EXPORT_SYMBOL(ath9k_hw_check_alive); | 1214 | EXPORT_SYMBOL(ath9k_hw_check_alive); |
| 1219 | 1215 | ||
| 1220 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | 1216 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, |
| 1221 | bool bChannelChange) | 1217 | struct ath9k_hw_cal_data *caldata, bool bChannelChange) |
| 1222 | { | 1218 | { |
| 1223 | struct ath_common *common = ath9k_hw_common(ah); | 1219 | struct ath_common *common = ath9k_hw_common(ah); |
| 1224 | u32 saveLedState; | 1220 | u32 saveLedState; |
| @@ -1243,9 +1239,19 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
| 1243 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) | 1239 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) |
| 1244 | return -EIO; | 1240 | return -EIO; |
| 1245 | 1241 | ||
| 1246 | if (curchan && !ah->chip_fullsleep) | 1242 | if (curchan && !ah->chip_fullsleep && ah->caldata) |
| 1247 | ath9k_hw_getnf(ah, curchan); | 1243 | ath9k_hw_getnf(ah, curchan); |
| 1248 | 1244 | ||
| 1245 | ah->caldata = caldata; | ||
| 1246 | if (caldata && | ||
| 1247 | (chan->channel != caldata->channel || | ||
| 1248 | (chan->channelFlags & ~CHANNEL_CW_INT) != | ||
| 1249 | (caldata->channelFlags & ~CHANNEL_CW_INT))) { | ||
| 1250 | /* Operating channel changed, reset channel calibration data */ | ||
| 1251 | memset(caldata, 0, sizeof(*caldata)); | ||
| 1252 | ath9k_init_nfcal_hist_buffer(ah, chan); | ||
| 1253 | } | ||
| 1254 | |||
| 1249 | if (bChannelChange && | 1255 | if (bChannelChange && |
| 1250 | (ah->chip_fullsleep != true) && | 1256 | (ah->chip_fullsleep != true) && |
| 1251 | (ah->curchan != NULL) && | 1257 | (ah->curchan != NULL) && |
| @@ -1256,7 +1262,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
| 1256 | 1262 | ||
| 1257 | if (ath9k_hw_channel_change(ah, chan)) { | 1263 | if (ath9k_hw_channel_change(ah, chan)) { |
| 1258 | ath9k_hw_loadnf(ah, ah->curchan); | 1264 | ath9k_hw_loadnf(ah, ah->curchan); |
| 1259 | ath9k_hw_start_nfcal(ah); | 1265 | ath9k_hw_start_nfcal(ah, true); |
| 1260 | return 0; | 1266 | return 0; |
| 1261 | } | 1267 | } |
| 1262 | } | 1268 | } |
| @@ -1461,11 +1467,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
| 1461 | if (ah->btcoex_hw.enabled) | 1467 | if (ah->btcoex_hw.enabled) |
| 1462 | ath9k_hw_btcoex_enable(ah); | 1468 | ath9k_hw_btcoex_enable(ah); |
| 1463 | 1469 | ||
| 1464 | if (AR_SREV_9300_20_OR_LATER(ah)) { | 1470 | if (AR_SREV_9300_20_OR_LATER(ah)) |
| 1465 | ath9k_hw_loadnf(ah, curchan); | ||
| 1466 | ath9k_hw_start_nfcal(ah); | ||
| 1467 | ar9003_hw_bb_watchdog_config(ah); | 1471 | ar9003_hw_bb_watchdog_config(ah); |
| 1468 | } | ||
| 1469 | 1472 | ||
| 1470 | return 0; | 1473 | return 0; |
| 1471 | } | 1474 | } |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 2d30efc0b94f..399f7c1283cd 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
| @@ -346,19 +346,25 @@ enum ath9k_int { | |||
| 346 | CHANNEL_HT40PLUS | \ | 346 | CHANNEL_HT40PLUS | \ |
| 347 | CHANNEL_HT40MINUS) | 347 | CHANNEL_HT40MINUS) |
| 348 | 348 | ||
| 349 | struct ath9k_channel { | 349 | struct ath9k_hw_cal_data { |
| 350 | struct ieee80211_channel *chan; | ||
| 351 | u16 channel; | 350 | u16 channel; |
| 352 | u32 channelFlags; | 351 | u32 channelFlags; |
| 353 | u32 chanmode; | ||
| 354 | int32_t CalValid; | 352 | int32_t CalValid; |
| 355 | bool oneTimeCalsDone; | ||
| 356 | int8_t iCoff; | 353 | int8_t iCoff; |
| 357 | int8_t qCoff; | 354 | int8_t qCoff; |
| 358 | int16_t rawNoiseFloor; | 355 | int16_t rawNoiseFloor; |
| 359 | bool paprd_done; | 356 | bool paprd_done; |
| 357 | bool nfcal_pending; | ||
| 360 | u16 small_signal_gain[AR9300_MAX_CHAINS]; | 358 | u16 small_signal_gain[AR9300_MAX_CHAINS]; |
| 361 | u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ]; | 359 | u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ]; |
| 360 | struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; | ||
| 361 | }; | ||
| 362 | |||
| 363 | struct ath9k_channel { | ||
| 364 | struct ieee80211_channel *chan; | ||
| 365 | u16 channel; | ||
| 366 | u32 channelFlags; | ||
| 367 | u32 chanmode; | ||
| 362 | }; | 368 | }; |
| 363 | 369 | ||
| 364 | #define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \ | 370 | #define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \ |
| @@ -669,7 +675,7 @@ struct ath_hw { | |||
| 669 | enum nl80211_iftype opmode; | 675 | enum nl80211_iftype opmode; |
| 670 | enum ath9k_power_mode power_mode; | 676 | enum ath9k_power_mode power_mode; |
| 671 | 677 | ||
| 672 | struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; | 678 | struct ath9k_hw_cal_data *caldata; |
| 673 | struct ath9k_pacal_info pacal_info; | 679 | struct ath9k_pacal_info pacal_info; |
| 674 | struct ar5416Stats stats; | 680 | struct ar5416Stats stats; |
| 675 | struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES]; | 681 | struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES]; |
| @@ -863,7 +869,7 @@ const char *ath9k_hw_probe(u16 vendorid, u16 devid); | |||
| 863 | void ath9k_hw_deinit(struct ath_hw *ah); | 869 | void ath9k_hw_deinit(struct ath_hw *ah); |
| 864 | int ath9k_hw_init(struct ath_hw *ah); | 870 | int ath9k_hw_init(struct ath_hw *ah); |
| 865 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | 871 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, |
| 866 | bool bChannelChange); | 872 | struct ath9k_hw_cal_data *caldata, bool bChannelChange); |
| 867 | int ath9k_hw_fill_cap_info(struct ath_hw *ah); | 873 | int ath9k_hw_fill_cap_info(struct ath_hw *ah); |
| 868 | u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan); | 874 | u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan); |
| 869 | 875 | ||
| @@ -958,9 +964,10 @@ void ar9003_hw_bb_watchdog_read(struct ath_hw *ah); | |||
| 958 | void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah); | 964 | void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah); |
| 959 | void ar9003_paprd_enable(struct ath_hw *ah, bool val); | 965 | void ar9003_paprd_enable(struct ath_hw *ah, bool val); |
| 960 | void ar9003_paprd_populate_single_table(struct ath_hw *ah, | 966 | void ar9003_paprd_populate_single_table(struct ath_hw *ah, |
| 961 | struct ath9k_channel *chan, int chain); | 967 | struct ath9k_hw_cal_data *caldata, |
| 962 | int ar9003_paprd_create_curve(struct ath_hw *ah, struct ath9k_channel *chan, | 968 | int chain); |
| 963 | int chain); | 969 | int ar9003_paprd_create_curve(struct ath_hw *ah, |
| 970 | struct ath9k_hw_cal_data *caldata, int chain); | ||
| 964 | int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain); | 971 | int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain); |
| 965 | int ar9003_paprd_init_table(struct ath_hw *ah); | 972 | int ar9003_paprd_init_table(struct ath_hw *ah); |
| 966 | bool ar9003_paprd_is_done(struct ath_hw *ah); | 973 | bool ar9003_paprd_is_done(struct ath_hw *ah); |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 0429dda0961f..3caa32316e7b 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
| @@ -154,6 +154,27 @@ void ath9k_ps_restore(struct ath_softc *sc) | |||
| 154 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | 154 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | static void ath_start_ani(struct ath_common *common) | ||
| 158 | { | ||
| 159 | struct ath_hw *ah = common->ah; | ||
| 160 | unsigned long timestamp = jiffies_to_msecs(jiffies); | ||
| 161 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
| 162 | |||
| 163 | if (!(sc->sc_flags & SC_OP_ANI_RUN)) | ||
| 164 | return; | ||
| 165 | |||
| 166 | if (sc->sc_flags & SC_OP_OFFCHANNEL) | ||
| 167 | return; | ||
| 168 | |||
| 169 | common->ani.longcal_timer = timestamp; | ||
| 170 | common->ani.shortcal_timer = timestamp; | ||
| 171 | common->ani.checkani_timer = timestamp; | ||
| 172 | |||
| 173 | mod_timer(&common->ani.timer, | ||
| 174 | jiffies + | ||
| 175 | msecs_to_jiffies((u32)ah->config.ani_poll_interval)); | ||
| 176 | } | ||
| 177 | |||
| 157 | /* | 178 | /* |
| 158 | * Set/change channels. If the channel is really being changed, it's done | 179 | * Set/change channels. If the channel is really being changed, it's done |
| 159 | * by reseting the chip. To accomplish this we must first cleanup any pending | 180 | * by reseting the chip. To accomplish this we must first cleanup any pending |
| @@ -162,16 +183,23 @@ void ath9k_ps_restore(struct ath_softc *sc) | |||
| 162 | int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | 183 | int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, |
| 163 | struct ath9k_channel *hchan) | 184 | struct ath9k_channel *hchan) |
| 164 | { | 185 | { |
| 186 | struct ath_wiphy *aphy = hw->priv; | ||
| 165 | struct ath_hw *ah = sc->sc_ah; | 187 | struct ath_hw *ah = sc->sc_ah; |
| 166 | struct ath_common *common = ath9k_hw_common(ah); | 188 | struct ath_common *common = ath9k_hw_common(ah); |
| 167 | struct ieee80211_conf *conf = &common->hw->conf; | 189 | struct ieee80211_conf *conf = &common->hw->conf; |
| 168 | bool fastcc = true, stopped; | 190 | bool fastcc = true, stopped; |
| 169 | struct ieee80211_channel *channel = hw->conf.channel; | 191 | struct ieee80211_channel *channel = hw->conf.channel; |
| 192 | struct ath9k_hw_cal_data *caldata = NULL; | ||
| 170 | int r; | 193 | int r; |
| 171 | 194 | ||
| 172 | if (sc->sc_flags & SC_OP_INVALID) | 195 | if (sc->sc_flags & SC_OP_INVALID) |
| 173 | return -EIO; | 196 | return -EIO; |
| 174 | 197 | ||
| 198 | del_timer_sync(&common->ani.timer); | ||
| 199 | cancel_work_sync(&sc->paprd_work); | ||
| 200 | cancel_work_sync(&sc->hw_check_work); | ||
| 201 | cancel_delayed_work_sync(&sc->tx_complete_work); | ||
| 202 | |||
| 175 | ath9k_ps_wakeup(sc); | 203 | ath9k_ps_wakeup(sc); |
| 176 | 204 | ||
| 177 | /* | 205 | /* |
| @@ -191,9 +219,12 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
| 191 | * to flush data frames already in queue because of | 219 | * to flush data frames already in queue because of |
| 192 | * changing channel. */ | 220 | * changing channel. */ |
| 193 | 221 | ||
| 194 | if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET)) | 222 | if (!stopped || !(sc->sc_flags & SC_OP_OFFCHANNEL)) |
| 195 | fastcc = false; | 223 | fastcc = false; |
| 196 | 224 | ||
| 225 | if (!(sc->sc_flags & SC_OP_OFFCHANNEL)) | ||
| 226 | caldata = &aphy->caldata; | ||
| 227 | |||
| 197 | ath_print(common, ATH_DBG_CONFIG, | 228 | ath_print(common, ATH_DBG_CONFIG, |
| 198 | "(%u MHz) -> (%u MHz), conf_is_ht40: %d\n", | 229 | "(%u MHz) -> (%u MHz), conf_is_ht40: %d\n", |
| 199 | sc->sc_ah->curchan->channel, | 230 | sc->sc_ah->curchan->channel, |
| @@ -201,7 +232,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
| 201 | 232 | ||
| 202 | spin_lock_bh(&sc->sc_resetlock); | 233 | spin_lock_bh(&sc->sc_resetlock); |
| 203 | 234 | ||
| 204 | r = ath9k_hw_reset(ah, hchan, fastcc); | 235 | r = ath9k_hw_reset(ah, hchan, caldata, fastcc); |
| 205 | if (r) { | 236 | if (r) { |
| 206 | ath_print(common, ATH_DBG_FATAL, | 237 | ath_print(common, ATH_DBG_FATAL, |
| 207 | "Unable to reset channel (%u MHz), " | 238 | "Unable to reset channel (%u MHz), " |
| @@ -212,8 +243,6 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
| 212 | } | 243 | } |
| 213 | spin_unlock_bh(&sc->sc_resetlock); | 244 | spin_unlock_bh(&sc->sc_resetlock); |
| 214 | 245 | ||
| 215 | sc->sc_flags &= ~SC_OP_FULL_RESET; | ||
| 216 | |||
| 217 | if (ath_startrecv(sc) != 0) { | 246 | if (ath_startrecv(sc) != 0) { |
| 218 | ath_print(common, ATH_DBG_FATAL, | 247 | ath_print(common, ATH_DBG_FATAL, |
| 219 | "Unable to restart recv logic\n"); | 248 | "Unable to restart recv logic\n"); |
| @@ -225,6 +254,12 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
| 225 | ath_update_txpow(sc); | 254 | ath_update_txpow(sc); |
| 226 | ath9k_hw_set_interrupts(ah, ah->imask); | 255 | ath9k_hw_set_interrupts(ah, ah->imask); |
| 227 | 256 | ||
| 257 | if (!(sc->sc_flags & (SC_OP_OFFCHANNEL | SC_OP_SCANNING))) { | ||
| 258 | ath_start_ani(common); | ||
| 259 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); | ||
| 260 | ath_beacon_config(sc, NULL); | ||
| 261 | } | ||
| 262 | |||
| 228 | ps_restore: | 263 | ps_restore: |
| 229 | ath9k_ps_restore(sc); | 264 | ath9k_ps_restore(sc); |
| 230 | return r; | 265 | return r; |
| @@ -233,17 +268,19 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
| 233 | static void ath_paprd_activate(struct ath_softc *sc) | 268 | static void ath_paprd_activate(struct ath_softc *sc) |
| 234 | { | 269 | { |
| 235 | struct ath_hw *ah = sc->sc_ah; | 270 | struct ath_hw *ah = sc->sc_ah; |
| 271 | struct ath9k_hw_cal_data *caldata = ah->caldata; | ||
| 236 | int chain; | 272 | int chain; |
| 237 | 273 | ||
| 238 | if (!ah->curchan->paprd_done) | 274 | if (!caldata || !caldata->paprd_done) |
| 239 | return; | 275 | return; |
| 240 | 276 | ||
| 241 | ath9k_ps_wakeup(sc); | 277 | ath9k_ps_wakeup(sc); |
| 278 | ar9003_paprd_enable(ah, false); | ||
| 242 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { | 279 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { |
| 243 | if (!(ah->caps.tx_chainmask & BIT(chain))) | 280 | if (!(ah->caps.tx_chainmask & BIT(chain))) |
| 244 | continue; | 281 | continue; |
| 245 | 282 | ||
| 246 | ar9003_paprd_populate_single_table(ah, ah->curchan, chain); | 283 | ar9003_paprd_populate_single_table(ah, caldata, chain); |
| 247 | } | 284 | } |
| 248 | 285 | ||
| 249 | ar9003_paprd_enable(ah, true); | 286 | ar9003_paprd_enable(ah, true); |
| @@ -261,6 +298,7 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
| 261 | int band = hw->conf.channel->band; | 298 | int band = hw->conf.channel->band; |
| 262 | struct ieee80211_supported_band *sband = &sc->sbands[band]; | 299 | struct ieee80211_supported_band *sband = &sc->sbands[band]; |
| 263 | struct ath_tx_control txctl; | 300 | struct ath_tx_control txctl; |
| 301 | struct ath9k_hw_cal_data *caldata = ah->caldata; | ||
| 264 | int qnum, ftype; | 302 | int qnum, ftype; |
| 265 | int chain_ok = 0; | 303 | int chain_ok = 0; |
| 266 | int chain; | 304 | int chain; |
| @@ -268,6 +306,9 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
| 268 | int time_left; | 306 | int time_left; |
| 269 | int i; | 307 | int i; |
| 270 | 308 | ||
| 309 | if (!caldata) | ||
| 310 | return; | ||
| 311 | |||
| 271 | skb = alloc_skb(len, GFP_KERNEL); | 312 | skb = alloc_skb(len, GFP_KERNEL); |
| 272 | if (!skb) | 313 | if (!skb) |
| 273 | return; | 314 | return; |
| @@ -322,7 +363,7 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
| 322 | if (!ar9003_paprd_is_done(ah)) | 363 | if (!ar9003_paprd_is_done(ah)) |
| 323 | break; | 364 | break; |
| 324 | 365 | ||
| 325 | if (ar9003_paprd_create_curve(ah, ah->curchan, chain) != 0) | 366 | if (ar9003_paprd_create_curve(ah, caldata, chain) != 0) |
| 326 | break; | 367 | break; |
| 327 | 368 | ||
| 328 | chain_ok = 1; | 369 | chain_ok = 1; |
| @@ -330,7 +371,7 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
| 330 | kfree_skb(skb); | 371 | kfree_skb(skb); |
| 331 | 372 | ||
| 332 | if (chain_ok) { | 373 | if (chain_ok) { |
| 333 | ah->curchan->paprd_done = true; | 374 | caldata->paprd_done = true; |
| 334 | ath_paprd_activate(sc); | 375 | ath_paprd_activate(sc); |
| 335 | } | 376 | } |
| 336 | 377 | ||
| @@ -439,33 +480,14 @@ set_timer: | |||
| 439 | cal_interval = min(cal_interval, (u32)short_cal_interval); | 480 | cal_interval = min(cal_interval, (u32)short_cal_interval); |
| 440 | 481 | ||
| 441 | mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); | 482 | mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); |
| 442 | if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && | 483 | if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) { |
| 443 | !(sc->sc_flags & SC_OP_SCANNING)) { | 484 | if (!ah->caldata->paprd_done) |
| 444 | if (!sc->sc_ah->curchan->paprd_done) | ||
| 445 | ieee80211_queue_work(sc->hw, &sc->paprd_work); | 485 | ieee80211_queue_work(sc->hw, &sc->paprd_work); |
| 446 | else | 486 | else |
| 447 | ath_paprd_activate(sc); | 487 | ath_paprd_activate(sc); |
| 448 | } | 488 | } |
| 449 | } | 489 | } |
| 450 | 490 | ||
| 451 | static void ath_start_ani(struct ath_common *common) | ||
| 452 | { | ||
| 453 | struct ath_hw *ah = common->ah; | ||
| 454 | unsigned long timestamp = jiffies_to_msecs(jiffies); | ||
| 455 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
| 456 | |||
| 457 | if (!(sc->sc_flags & SC_OP_ANI_RUN)) | ||
| 458 | return; | ||
| 459 | |||
| 460 | common->ani.longcal_timer = timestamp; | ||
| 461 | common->ani.shortcal_timer = timestamp; | ||
| 462 | common->ani.checkani_timer = timestamp; | ||
| 463 | |||
| 464 | mod_timer(&common->ani.timer, | ||
| 465 | jiffies + | ||
| 466 | msecs_to_jiffies((u32)ah->config.ani_poll_interval)); | ||
| 467 | } | ||
| 468 | |||
| 469 | /* | 491 | /* |
| 470 | * Update tx/rx chainmask. For legacy association, | 492 | * Update tx/rx chainmask. For legacy association, |
| 471 | * hard code chainmask to 1x1, for 11n association, use | 493 | * hard code chainmask to 1x1, for 11n association, use |
| @@ -477,7 +499,7 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht) | |||
| 477 | struct ath_hw *ah = sc->sc_ah; | 499 | struct ath_hw *ah = sc->sc_ah; |
| 478 | struct ath_common *common = ath9k_hw_common(ah); | 500 | struct ath_common *common = ath9k_hw_common(ah); |
| 479 | 501 | ||
| 480 | if ((sc->sc_flags & SC_OP_SCANNING) || is_ht || | 502 | if ((sc->sc_flags & SC_OP_OFFCHANNEL) || is_ht || |
| 481 | (ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE)) { | 503 | (ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE)) { |
| 482 | common->tx_chainmask = ah->caps.tx_chainmask; | 504 | common->tx_chainmask = ah->caps.tx_chainmask; |
| 483 | common->rx_chainmask = ah->caps.rx_chainmask; | 505 | common->rx_chainmask = ah->caps.rx_chainmask; |
| @@ -817,7 +839,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
| 817 | ah->curchan = ath_get_curchannel(sc, sc->hw); | 839 | ah->curchan = ath_get_curchannel(sc, sc->hw); |
| 818 | 840 | ||
| 819 | spin_lock_bh(&sc->sc_resetlock); | 841 | spin_lock_bh(&sc->sc_resetlock); |
| 820 | r = ath9k_hw_reset(ah, ah->curchan, false); | 842 | r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); |
| 821 | if (r) { | 843 | if (r) { |
| 822 | ath_print(common, ATH_DBG_FATAL, | 844 | ath_print(common, ATH_DBG_FATAL, |
| 823 | "Unable to reset channel (%u MHz), " | 845 | "Unable to reset channel (%u MHz), " |
| @@ -877,7 +899,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
| 877 | ah->curchan = ath_get_curchannel(sc, hw); | 899 | ah->curchan = ath_get_curchannel(sc, hw); |
| 878 | 900 | ||
| 879 | spin_lock_bh(&sc->sc_resetlock); | 901 | spin_lock_bh(&sc->sc_resetlock); |
| 880 | r = ath9k_hw_reset(ah, ah->curchan, false); | 902 | r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); |
| 881 | if (r) { | 903 | if (r) { |
| 882 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, | 904 | ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, |
| 883 | "Unable to reset channel (%u MHz), " | 905 | "Unable to reset channel (%u MHz), " |
| @@ -910,7 +932,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
| 910 | ath_flushrecv(sc); | 932 | ath_flushrecv(sc); |
| 911 | 933 | ||
| 912 | spin_lock_bh(&sc->sc_resetlock); | 934 | spin_lock_bh(&sc->sc_resetlock); |
| 913 | r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false); | 935 | r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false); |
| 914 | if (r) | 936 | if (r) |
| 915 | ath_print(common, ATH_DBG_FATAL, | 937 | ath_print(common, ATH_DBG_FATAL, |
| 916 | "Unable to reset hardware; reset status %d\n", r); | 938 | "Unable to reset hardware; reset status %d\n", r); |
| @@ -1085,7 +1107,7 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
| 1085 | * and then setup of the interrupt mask. | 1107 | * and then setup of the interrupt mask. |
| 1086 | */ | 1108 | */ |
| 1087 | spin_lock_bh(&sc->sc_resetlock); | 1109 | spin_lock_bh(&sc->sc_resetlock); |
| 1088 | r = ath9k_hw_reset(ah, init_channel, false); | 1110 | r = ath9k_hw_reset(ah, init_channel, ah->caldata, false); |
| 1089 | if (r) { | 1111 | if (r) { |
| 1090 | ath_print(common, ATH_DBG_FATAL, | 1112 | ath_print(common, ATH_DBG_FATAL, |
| 1091 | "Unable to reset hardware; reset status %d " | 1113 | "Unable to reset hardware; reset status %d " |
| @@ -1579,6 +1601,10 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
| 1579 | 1601 | ||
| 1580 | aphy->chan_idx = pos; | 1602 | aphy->chan_idx = pos; |
| 1581 | aphy->chan_is_ht = conf_is_ht(conf); | 1603 | aphy->chan_is_ht = conf_is_ht(conf); |
| 1604 | if (hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) | ||
| 1605 | sc->sc_flags |= SC_OP_OFFCHANNEL; | ||
| 1606 | else | ||
| 1607 | sc->sc_flags &= ~SC_OP_OFFCHANNEL; | ||
| 1582 | 1608 | ||
| 1583 | if (aphy->state == ATH_WIPHY_SCAN || | 1609 | if (aphy->state == ATH_WIPHY_SCAN || |
| 1584 | aphy->state == ATH_WIPHY_ACTIVE) | 1610 | aphy->state == ATH_WIPHY_ACTIVE) |
| @@ -1990,7 +2016,6 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw) | |||
| 1990 | { | 2016 | { |
| 1991 | struct ath_wiphy *aphy = hw->priv; | 2017 | struct ath_wiphy *aphy = hw->priv; |
| 1992 | struct ath_softc *sc = aphy->sc; | 2018 | struct ath_softc *sc = aphy->sc; |
| 1993 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
| 1994 | 2019 | ||
| 1995 | mutex_lock(&sc->mutex); | 2020 | mutex_lock(&sc->mutex); |
| 1996 | if (ath9k_wiphy_scanning(sc)) { | 2021 | if (ath9k_wiphy_scanning(sc)) { |
| @@ -2008,10 +2033,6 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw) | |||
| 2008 | aphy->state = ATH_WIPHY_SCAN; | 2033 | aphy->state = ATH_WIPHY_SCAN; |
| 2009 | ath9k_wiphy_pause_all_forced(sc, aphy); | 2034 | ath9k_wiphy_pause_all_forced(sc, aphy); |
| 2010 | sc->sc_flags |= SC_OP_SCANNING; | 2035 | sc->sc_flags |= SC_OP_SCANNING; |
| 2011 | del_timer_sync(&common->ani.timer); | ||
| 2012 | cancel_work_sync(&sc->paprd_work); | ||
| 2013 | cancel_work_sync(&sc->hw_check_work); | ||
| 2014 | cancel_delayed_work_sync(&sc->tx_complete_work); | ||
| 2015 | mutex_unlock(&sc->mutex); | 2036 | mutex_unlock(&sc->mutex); |
| 2016 | } | 2037 | } |
| 2017 | 2038 | ||
| @@ -2023,15 +2044,10 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) | |||
| 2023 | { | 2044 | { |
| 2024 | struct ath_wiphy *aphy = hw->priv; | 2045 | struct ath_wiphy *aphy = hw->priv; |
| 2025 | struct ath_softc *sc = aphy->sc; | 2046 | struct ath_softc *sc = aphy->sc; |
| 2026 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
| 2027 | 2047 | ||
| 2028 | mutex_lock(&sc->mutex); | 2048 | mutex_lock(&sc->mutex); |
| 2029 | aphy->state = ATH_WIPHY_ACTIVE; | 2049 | aphy->state = ATH_WIPHY_ACTIVE; |
| 2030 | sc->sc_flags &= ~SC_OP_SCANNING; | 2050 | sc->sc_flags &= ~SC_OP_SCANNING; |
| 2031 | sc->sc_flags |= SC_OP_FULL_RESET; | ||
| 2032 | ath_start_ani(common); | ||
| 2033 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); | ||
| 2034 | ath_beacon_config(sc, NULL); | ||
| 2035 | mutex_unlock(&sc->mutex); | 2051 | mutex_unlock(&sc->mutex); |
| 2036 | } | 2052 | } |
| 2037 | 2053 | ||
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index da0cfe90c38a..a3fc987ebab0 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
| @@ -1140,6 +1140,11 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
| 1140 | if (flush) | 1140 | if (flush) |
| 1141 | goto requeue; | 1141 | goto requeue; |
| 1142 | 1142 | ||
| 1143 | retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs, | ||
| 1144 | rxs, &decrypt_error); | ||
| 1145 | if (retval) | ||
| 1146 | goto requeue; | ||
| 1147 | |||
| 1143 | rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp; | 1148 | rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp; |
| 1144 | if (rs.rs_tstamp > tsf_lower && | 1149 | if (rs.rs_tstamp > tsf_lower && |
| 1145 | unlikely(rs.rs_tstamp - tsf_lower > 0x10000000)) | 1150 | unlikely(rs.rs_tstamp - tsf_lower > 0x10000000)) |
| @@ -1149,11 +1154,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
| 1149 | unlikely(tsf_lower - rs.rs_tstamp > 0x10000000)) | 1154 | unlikely(tsf_lower - rs.rs_tstamp > 0x10000000)) |
| 1150 | rxs->mactime += 0x100000000ULL; | 1155 | rxs->mactime += 0x100000000ULL; |
| 1151 | 1156 | ||
| 1152 | retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs, | ||
| 1153 | rxs, &decrypt_error); | ||
| 1154 | if (retval) | ||
| 1155 | goto requeue; | ||
| 1156 | |||
| 1157 | /* Ensure we always have an skb to requeue once we are done | 1157 | /* Ensure we always have an skb to requeue once we are done |
| 1158 | * processing the current buffer's skb */ | 1158 | * processing the current buffer's skb */ |
| 1159 | requeue_skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_ATOMIC); | 1159 | requeue_skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_ATOMIC); |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 501b72821b4d..4dda14e36227 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
| @@ -120,26 +120,14 @@ static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid) | |||
| 120 | list_add_tail(&ac->list, &txq->axq_acq); | 120 | list_add_tail(&ac->list, &txq->axq_acq); |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | static void ath_tx_pause_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | ||
| 124 | { | ||
| 125 | struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; | ||
| 126 | |||
| 127 | spin_lock_bh(&txq->axq_lock); | ||
| 128 | tid->paused++; | ||
| 129 | spin_unlock_bh(&txq->axq_lock); | ||
| 130 | } | ||
| 131 | |||
| 132 | static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | 123 | static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid) |
| 133 | { | 124 | { |
| 134 | struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; | 125 | struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; |
| 135 | 126 | ||
| 136 | BUG_ON(tid->paused <= 0); | 127 | WARN_ON(!tid->paused); |
| 137 | spin_lock_bh(&txq->axq_lock); | ||
| 138 | |||
| 139 | tid->paused--; | ||
| 140 | 128 | ||
| 141 | if (tid->paused > 0) | 129 | spin_lock_bh(&txq->axq_lock); |
| 142 | goto unlock; | 130 | tid->paused = false; |
| 143 | 131 | ||
| 144 | if (list_empty(&tid->buf_q)) | 132 | if (list_empty(&tid->buf_q)) |
| 145 | goto unlock; | 133 | goto unlock; |
| @@ -157,15 +145,10 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | |||
| 157 | struct list_head bf_head; | 145 | struct list_head bf_head; |
| 158 | INIT_LIST_HEAD(&bf_head); | 146 | INIT_LIST_HEAD(&bf_head); |
| 159 | 147 | ||
| 160 | BUG_ON(tid->paused <= 0); | 148 | WARN_ON(!tid->paused); |
| 161 | spin_lock_bh(&txq->axq_lock); | ||
| 162 | 149 | ||
| 163 | tid->paused--; | 150 | spin_lock_bh(&txq->axq_lock); |
| 164 | 151 | tid->paused = false; | |
| 165 | if (tid->paused > 0) { | ||
| 166 | spin_unlock_bh(&txq->axq_lock); | ||
| 167 | return; | ||
| 168 | } | ||
| 169 | 152 | ||
| 170 | while (!list_empty(&tid->buf_q)) { | 153 | while (!list_empty(&tid->buf_q)) { |
| 171 | bf = list_first_entry(&tid->buf_q, struct ath_buf, list); | 154 | bf = list_first_entry(&tid->buf_q, struct ath_buf, list); |
| @@ -811,7 +794,7 @@ void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, | |||
| 811 | an = (struct ath_node *)sta->drv_priv; | 794 | an = (struct ath_node *)sta->drv_priv; |
| 812 | txtid = ATH_AN_2_TID(an, tid); | 795 | txtid = ATH_AN_2_TID(an, tid); |
| 813 | txtid->state |= AGGR_ADDBA_PROGRESS; | 796 | txtid->state |= AGGR_ADDBA_PROGRESS; |
| 814 | ath_tx_pause_tid(sc, txtid); | 797 | txtid->paused = true; |
| 815 | *ssn = txtid->seq_start; | 798 | *ssn = txtid->seq_start; |
| 816 | } | 799 | } |
| 817 | 800 | ||
| @@ -835,10 +818,9 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) | |||
| 835 | return; | 818 | return; |
| 836 | } | 819 | } |
| 837 | 820 | ||
| 838 | ath_tx_pause_tid(sc, txtid); | ||
| 839 | |||
| 840 | /* drop all software retried frames and mark this TID */ | 821 | /* drop all software retried frames and mark this TID */ |
| 841 | spin_lock_bh(&txq->axq_lock); | 822 | spin_lock_bh(&txq->axq_lock); |
| 823 | txtid->paused = true; | ||
| 842 | while (!list_empty(&txtid->buf_q)) { | 824 | while (!list_empty(&txtid->buf_q)) { |
| 843 | bf = list_first_entry(&txtid->buf_q, struct ath_buf, list); | 825 | bf = list_first_entry(&txtid->buf_q, struct ath_buf, list); |
| 844 | if (!bf_isretried(bf)) { | 826 | if (!bf_isretried(bf)) { |
| @@ -1181,7 +1163,7 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | |||
| 1181 | "Failed to stop TX DMA. Resetting hardware!\n"); | 1163 | "Failed to stop TX DMA. Resetting hardware!\n"); |
| 1182 | 1164 | ||
| 1183 | spin_lock_bh(&sc->sc_resetlock); | 1165 | spin_lock_bh(&sc->sc_resetlock); |
| 1184 | r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false); | 1166 | r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false); |
| 1185 | if (r) | 1167 | if (r) |
| 1186 | ath_print(common, ATH_DBG_FATAL, | 1168 | ath_print(common, ATH_DBG_FATAL, |
| 1187 | "Unable to reset hardware; reset status %d\n", | 1169 | "Unable to reset hardware; reset status %d\n", |
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index c24c5efeae1f..16bbfa3189a5 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c | |||
| @@ -1924,6 +1924,10 @@ static int ipw2100_net_init(struct net_device *dev) | |||
| 1924 | bg_band->channels = | 1924 | bg_band->channels = |
| 1925 | kzalloc(geo->bg_channels * | 1925 | kzalloc(geo->bg_channels * |
| 1926 | sizeof(struct ieee80211_channel), GFP_KERNEL); | 1926 | sizeof(struct ieee80211_channel), GFP_KERNEL); |
| 1927 | if (!bg_band->channels) { | ||
| 1928 | ipw2100_down(priv); | ||
| 1929 | return -ENOMEM; | ||
| 1930 | } | ||
| 1927 | /* translate geo->bg to bg_band.channels */ | 1931 | /* translate geo->bg to bg_band.channels */ |
| 1928 | for (i = 0; i < geo->bg_channels; i++) { | 1932 | for (i = 0; i < geo->bg_channels; i++) { |
| 1929 | bg_band->channels[i].band = IEEE80211_BAND_2GHZ; | 1933 | bg_band->channels[i].band = IEEE80211_BAND_2GHZ; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c index f052c6d09b37..d706b8afbe5a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c | |||
| @@ -980,7 +980,7 @@ ssize_t iwl_ucode_bt_stats_read(struct file *file, | |||
| 980 | le32_to_cpu(bt->lo_priority_tx_req_cnt), | 980 | le32_to_cpu(bt->lo_priority_tx_req_cnt), |
| 981 | accum_bt->lo_priority_tx_req_cnt); | 981 | accum_bt->lo_priority_tx_req_cnt); |
| 982 | pos += scnprintf(buf + pos, bufsz - pos, | 982 | pos += scnprintf(buf + pos, bufsz - pos, |
| 983 | "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n", | 983 | "lo_priority_tx_denied_cnt:\t%u\t\t\t%u\n", |
| 984 | le32_to_cpu(bt->lo_priority_tx_denied_cnt), | 984 | le32_to_cpu(bt->lo_priority_tx_denied_cnt), |
| 985 | accum_bt->lo_priority_tx_denied_cnt); | 985 | accum_bt->lo_priority_tx_denied_cnt); |
| 986 | pos += scnprintf(buf + pos, bufsz - pos, | 986 | pos += scnprintf(buf + pos, bufsz - pos, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index a1b6d202d57c..9dd9e64c2b0b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
| @@ -1429,7 +1429,7 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv, | |||
| 1429 | void iwl_free_tfds_in_queue(struct iwl_priv *priv, | 1429 | void iwl_free_tfds_in_queue(struct iwl_priv *priv, |
| 1430 | int sta_id, int tid, int freed) | 1430 | int sta_id, int tid, int freed) |
| 1431 | { | 1431 | { |
| 1432 | WARN_ON(!spin_is_locked(&priv->sta_lock)); | 1432 | lockdep_assert_held(&priv->sta_lock); |
| 1433 | 1433 | ||
| 1434 | if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed) | 1434 | if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed) |
| 1435 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | 1435 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 35c86d22b14b..23e5c42e7d7e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
| @@ -300,8 +300,9 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, | |||
| 300 | struct ieee80211_sta *sta) | 300 | struct ieee80211_sta *sta) |
| 301 | { | 301 | { |
| 302 | int ret = -EAGAIN; | 302 | int ret = -EAGAIN; |
| 303 | u32 load = rs_tl_get_load(lq_data, tid); | ||
| 303 | 304 | ||
| 304 | if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { | 305 | if (load > IWL_AGG_LOAD_THRESHOLD) { |
| 305 | IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", | 306 | IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", |
| 306 | sta->addr, tid); | 307 | sta->addr, tid); |
| 307 | ret = ieee80211_start_tx_ba_session(sta, tid); | 308 | ret = ieee80211_start_tx_ba_session(sta, tid); |
| @@ -311,12 +312,14 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, | |||
| 311 | * this might be cause by reloading firmware | 312 | * this might be cause by reloading firmware |
| 312 | * stop the tx ba session here | 313 | * stop the tx ba session here |
| 313 | */ | 314 | */ |
| 314 | IWL_DEBUG_HT(priv, "Fail start Tx agg on tid: %d\n", | 315 | IWL_ERR(priv, "Fail start Tx agg on tid: %d\n", |
| 315 | tid); | 316 | tid); |
| 316 | ieee80211_stop_tx_ba_session(sta, tid); | 317 | ieee80211_stop_tx_ba_session(sta, tid); |
| 317 | } | 318 | } |
| 318 | } else | 319 | } else { |
| 319 | IWL_ERR(priv, "Fail finding valid aggregation tid: %d\n", tid); | 320 | IWL_ERR(priv, "Aggregation not enabled for tid %d " |
| 321 | "because load = %u\n", tid, load); | ||
| 322 | } | ||
| 320 | return ret; | 323 | return ret; |
| 321 | } | 324 | } |
| 322 | 325 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 55a1b31fd09a..d04502d54df3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c | |||
| @@ -1117,7 +1117,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv, | |||
| 1117 | u8 *addr = priv->stations[sta_id].sta.sta.addr; | 1117 | u8 *addr = priv->stations[sta_id].sta.sta.addr; |
| 1118 | struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid]; | 1118 | struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid]; |
| 1119 | 1119 | ||
| 1120 | WARN_ON(!spin_is_locked(&priv->sta_lock)); | 1120 | lockdep_assert_held(&priv->sta_lock); |
| 1121 | 1121 | ||
| 1122 | switch (priv->stations[sta_id].tid[tid].agg.state) { | 1122 | switch (priv->stations[sta_id].tid[tid].agg.state) { |
| 1123 | case IWL_EMPTYING_HW_QUEUE_DELBA: | 1123 | case IWL_EMPTYING_HW_QUEUE_DELBA: |
| @@ -1331,7 +1331,14 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
| 1331 | tid = ba_resp->tid; | 1331 | tid = ba_resp->tid; |
| 1332 | agg = &priv->stations[sta_id].tid[tid].agg; | 1332 | agg = &priv->stations[sta_id].tid[tid].agg; |
| 1333 | if (unlikely(agg->txq_id != scd_flow)) { | 1333 | if (unlikely(agg->txq_id != scd_flow)) { |
| 1334 | IWL_ERR(priv, "BA scd_flow %d does not match txq_id %d\n", | 1334 | /* |
| 1335 | * FIXME: this is a uCode bug which need to be addressed, | ||
| 1336 | * log the information and return for now! | ||
| 1337 | * since it is possible happen very often and in order | ||
| 1338 | * not to fill the syslog, don't enable the logging by default | ||
| 1339 | */ | ||
| 1340 | IWL_DEBUG_TX_REPLY(priv, | ||
| 1341 | "BA scd_flow %d does not match txq_id %d\n", | ||
| 1335 | scd_flow, agg->txq_id); | 1342 | scd_flow, agg->txq_id); |
| 1336 | return; | 1343 | return; |
| 1337 | } | 1344 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 8024d44ce4bb..8ccb6d205b6d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
| @@ -2000,6 +2000,7 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, | |||
| 2000 | struct ieee80211_vif *vif) | 2000 | struct ieee80211_vif *vif) |
| 2001 | { | 2001 | { |
| 2002 | struct iwl_priv *priv = hw->priv; | 2002 | struct iwl_priv *priv = hw->priv; |
| 2003 | bool scan_completed = false; | ||
| 2003 | 2004 | ||
| 2004 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 2005 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
| 2005 | 2006 | ||
| @@ -2013,7 +2014,7 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, | |||
| 2013 | if (priv->vif == vif) { | 2014 | if (priv->vif == vif) { |
| 2014 | priv->vif = NULL; | 2015 | priv->vif = NULL; |
| 2015 | if (priv->scan_vif == vif) { | 2016 | if (priv->scan_vif == vif) { |
| 2016 | ieee80211_scan_completed(priv->hw, true); | 2017 | scan_completed = true; |
| 2017 | priv->scan_vif = NULL; | 2018 | priv->scan_vif = NULL; |
| 2018 | priv->scan_request = NULL; | 2019 | priv->scan_request = NULL; |
| 2019 | } | 2020 | } |
| @@ -2021,6 +2022,9 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, | |||
| 2021 | } | 2022 | } |
| 2022 | mutex_unlock(&priv->mutex); | 2023 | mutex_unlock(&priv->mutex); |
| 2023 | 2024 | ||
| 2025 | if (scan_completed) | ||
| 2026 | ieee80211_scan_completed(priv->hw, true); | ||
| 2027 | |||
| 2024 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 2028 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
| 2025 | 2029 | ||
| 2026 | } | 2030 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 5c2bcef5df0c..0b961a353ff6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h | |||
| @@ -71,7 +71,7 @@ do { \ | |||
| 71 | #define IWL_DEBUG(__priv, level, fmt, args...) | 71 | #define IWL_DEBUG(__priv, level, fmt, args...) |
| 72 | #define IWL_DEBUG_LIMIT(__priv, level, fmt, args...) | 72 | #define IWL_DEBUG_LIMIT(__priv, level, fmt, args...) |
| 73 | static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level, | 73 | static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level, |
| 74 | void *p, u32 len) | 74 | const void *p, u32 len) |
| 75 | {} | 75 | {} |
| 76 | #endif /* CONFIG_IWLWIFI_DEBUG */ | 76 | #endif /* CONFIG_IWLWIFI_DEBUG */ |
| 77 | 77 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index ae7319bb3a99..4cf864c664ee 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h | |||
| @@ -193,7 +193,7 @@ TRACE_EVENT(iwlwifi_dev_tx, | |||
| 193 | __entry->framelen = buf0_len + buf1_len; | 193 | __entry->framelen = buf0_len + buf1_len; |
| 194 | memcpy(__get_dynamic_array(tfd), tfd, tfdlen); | 194 | memcpy(__get_dynamic_array(tfd), tfd, tfdlen); |
| 195 | memcpy(__get_dynamic_array(buf0), buf0, buf0_len); | 195 | memcpy(__get_dynamic_array(buf0), buf0, buf0_len); |
| 196 | memcpy(__get_dynamic_array(buf1), buf1, buf0_len); | 196 | memcpy(__get_dynamic_array(buf1), buf1, buf1_len); |
| 197 | ), | 197 | ), |
| 198 | TP_printk("[%p] TX %.2x (%zu bytes)", | 198 | TP_printk("[%p] TX %.2x (%zu bytes)", |
| 199 | __entry->priv, | 199 | __entry->priv, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index b0c6b0473901..a4b3663a262f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
| @@ -298,7 +298,7 @@ EXPORT_SYMBOL(iwl_init_scan_params); | |||
| 298 | 298 | ||
| 299 | static int iwl_scan_initiate(struct iwl_priv *priv, struct ieee80211_vif *vif) | 299 | static int iwl_scan_initiate(struct iwl_priv *priv, struct ieee80211_vif *vif) |
| 300 | { | 300 | { |
| 301 | WARN_ON(!mutex_is_locked(&priv->mutex)); | 301 | lockdep_assert_held(&priv->mutex); |
| 302 | 302 | ||
| 303 | IWL_DEBUG_INFO(priv, "Starting scan...\n"); | 303 | IWL_DEBUG_INFO(priv, "Starting scan...\n"); |
| 304 | set_bit(STATUS_SCANNING, &priv->status); | 304 | set_bit(STATUS_SCANNING, &priv->status); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 9511f03f07e0..7e0829be5e78 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
| @@ -773,7 +773,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty) | |||
| 773 | 773 | ||
| 774 | int iwl_restore_default_wep_keys(struct iwl_priv *priv) | 774 | int iwl_restore_default_wep_keys(struct iwl_priv *priv) |
| 775 | { | 775 | { |
| 776 | WARN_ON(!mutex_is_locked(&priv->mutex)); | 776 | lockdep_assert_held(&priv->mutex); |
| 777 | 777 | ||
| 778 | return iwl_send_static_wepkey_cmd(priv, 0); | 778 | return iwl_send_static_wepkey_cmd(priv, 0); |
| 779 | } | 779 | } |
| @@ -784,7 +784,7 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv, | |||
| 784 | { | 784 | { |
| 785 | int ret; | 785 | int ret; |
| 786 | 786 | ||
| 787 | WARN_ON(!mutex_is_locked(&priv->mutex)); | 787 | lockdep_assert_held(&priv->mutex); |
| 788 | 788 | ||
| 789 | IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n", | 789 | IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n", |
| 790 | keyconf->keyidx); | 790 | keyconf->keyidx); |
| @@ -808,7 +808,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv, | |||
| 808 | { | 808 | { |
| 809 | int ret; | 809 | int ret; |
| 810 | 810 | ||
| 811 | WARN_ON(!mutex_is_locked(&priv->mutex)); | 811 | lockdep_assert_held(&priv->mutex); |
| 812 | 812 | ||
| 813 | if (keyconf->keylen != WEP_KEY_LEN_128 && | 813 | if (keyconf->keylen != WEP_KEY_LEN_128 && |
| 814 | keyconf->keylen != WEP_KEY_LEN_64) { | 814 | keyconf->keylen != WEP_KEY_LEN_64) { |
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 25f902760980..8e9fbfd804b6 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
| @@ -257,6 +257,29 @@ static int lbs_add_supported_rates_tlv(u8 *tlv) | |||
| 257 | return sizeof(rate_tlv->header) + i; | 257 | return sizeof(rate_tlv->header) + i; |
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | /* Add common rates from a TLV and return the new end of the TLV */ | ||
| 261 | static u8 * | ||
| 262 | add_ie_rates(u8 *tlv, const u8 *ie, int *nrates) | ||
| 263 | { | ||
| 264 | int hw, ap, ap_max = ie[1]; | ||
| 265 | u8 hw_rate; | ||
| 266 | |||
| 267 | /* Advance past IE header */ | ||
| 268 | ie += 2; | ||
| 269 | |||
| 270 | lbs_deb_hex(LBS_DEB_ASSOC, "AP IE Rates", (u8 *) ie, ap_max); | ||
| 271 | |||
| 272 | for (hw = 0; hw < ARRAY_SIZE(lbs_rates); hw++) { | ||
| 273 | hw_rate = lbs_rates[hw].bitrate / 5; | ||
| 274 | for (ap = 0; ap < ap_max; ap++) { | ||
| 275 | if (hw_rate == (ie[ap] & 0x7f)) { | ||
| 276 | *tlv++ = ie[ap]; | ||
| 277 | *nrates = *nrates + 1; | ||
| 278 | } | ||
| 279 | } | ||
| 280 | } | ||
| 281 | return tlv; | ||
| 282 | } | ||
| 260 | 283 | ||
| 261 | /* | 284 | /* |
| 262 | * Adds a TLV with all rates the hardware *and* BSS supports. | 285 | * Adds a TLV with all rates the hardware *and* BSS supports. |
| @@ -264,8 +287,11 @@ static int lbs_add_supported_rates_tlv(u8 *tlv) | |||
| 264 | static int lbs_add_common_rates_tlv(u8 *tlv, struct cfg80211_bss *bss) | 287 | static int lbs_add_common_rates_tlv(u8 *tlv, struct cfg80211_bss *bss) |
| 265 | { | 288 | { |
| 266 | struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv; | 289 | struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv; |
| 267 | const u8 *rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES); | 290 | const u8 *rates_eid, *ext_rates_eid; |
| 268 | int n; | 291 | int n = 0; |
| 292 | |||
| 293 | rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES); | ||
| 294 | ext_rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES); | ||
| 269 | 295 | ||
| 270 | /* | 296 | /* |
| 271 | * 01 00 TLV_TYPE_RATES | 297 | * 01 00 TLV_TYPE_RATES |
| @@ -275,26 +301,21 @@ static int lbs_add_common_rates_tlv(u8 *tlv, struct cfg80211_bss *bss) | |||
| 275 | rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES); | 301 | rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES); |
| 276 | tlv += sizeof(rate_tlv->header); | 302 | tlv += sizeof(rate_tlv->header); |
| 277 | 303 | ||
| 278 | if (!rates_eid) { | 304 | /* Add basic rates */ |
| 305 | if (rates_eid) { | ||
| 306 | tlv = add_ie_rates(tlv, rates_eid, &n); | ||
| 307 | |||
| 308 | /* Add extended rates, if any */ | ||
| 309 | if (ext_rates_eid) | ||
| 310 | tlv = add_ie_rates(tlv, ext_rates_eid, &n); | ||
| 311 | } else { | ||
| 312 | lbs_deb_assoc("assoc: bss had no basic rate IE\n"); | ||
| 279 | /* Fallback: add basic 802.11b rates */ | 313 | /* Fallback: add basic 802.11b rates */ |
| 280 | *tlv++ = 0x82; | 314 | *tlv++ = 0x82; |
| 281 | *tlv++ = 0x84; | 315 | *tlv++ = 0x84; |
| 282 | *tlv++ = 0x8b; | 316 | *tlv++ = 0x8b; |
| 283 | *tlv++ = 0x96; | 317 | *tlv++ = 0x96; |
| 284 | n = 4; | 318 | n = 4; |
| 285 | } else { | ||
| 286 | int hw, ap; | ||
| 287 | u8 ap_max = rates_eid[1]; | ||
| 288 | n = 0; | ||
| 289 | for (hw = 0; hw < ARRAY_SIZE(lbs_rates); hw++) { | ||
| 290 | u8 hw_rate = lbs_rates[hw].bitrate / 5; | ||
| 291 | for (ap = 0; ap < ap_max; ap++) { | ||
| 292 | if (hw_rate == (rates_eid[ap+2] & 0x7f)) { | ||
| 293 | *tlv++ = rates_eid[ap+2]; | ||
| 294 | n++; | ||
| 295 | } | ||
| 296 | } | ||
| 297 | } | ||
| 298 | } | 319 | } |
| 299 | 320 | ||
| 300 | rate_tlv->header.len = cpu_to_le16(n); | 321 | rate_tlv->header.len = cpu_to_le16(n); |
| @@ -465,7 +486,15 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, | |||
| 465 | lbs_deb_enter(LBS_DEB_CFG80211); | 486 | lbs_deb_enter(LBS_DEB_CFG80211); |
| 466 | 487 | ||
| 467 | bsssize = get_unaligned_le16(&scanresp->bssdescriptsize); | 488 | bsssize = get_unaligned_le16(&scanresp->bssdescriptsize); |
| 468 | nr_sets = le16_to_cpu(resp->size); | 489 | nr_sets = le16_to_cpu(scanresp->nr_sets); |
| 490 | |||
| 491 | lbs_deb_scan("scan response: %d BSSs (%d bytes); resp size %d bytes\n", | ||
| 492 | nr_sets, bsssize, le16_to_cpu(resp->size)); | ||
| 493 | |||
| 494 | if (nr_sets == 0) { | ||
| 495 | ret = 0; | ||
| 496 | goto done; | ||
| 497 | } | ||
| 469 | 498 | ||
| 470 | /* | 499 | /* |
| 471 | * The general layout of the scan response is described in chapter | 500 | * The general layout of the scan response is described in chapter |
| @@ -670,8 +699,13 @@ static void lbs_scan_worker(struct work_struct *work) | |||
| 670 | 699 | ||
| 671 | if (priv->scan_channel >= priv->scan_req->n_channels) { | 700 | if (priv->scan_channel >= priv->scan_req->n_channels) { |
| 672 | /* Mark scan done */ | 701 | /* Mark scan done */ |
| 673 | cfg80211_scan_done(priv->scan_req, false); | 702 | if (priv->internal_scan) |
| 703 | kfree(priv->scan_req); | ||
| 704 | else | ||
| 705 | cfg80211_scan_done(priv->scan_req, false); | ||
| 706 | |||
| 674 | priv->scan_req = NULL; | 707 | priv->scan_req = NULL; |
| 708 | priv->last_scan = jiffies; | ||
| 675 | } | 709 | } |
| 676 | 710 | ||
| 677 | /* Restart network */ | 711 | /* Restart network */ |
| @@ -682,10 +716,33 @@ static void lbs_scan_worker(struct work_struct *work) | |||
| 682 | 716 | ||
| 683 | kfree(scan_cmd); | 717 | kfree(scan_cmd); |
| 684 | 718 | ||
| 719 | /* Wake up anything waiting on scan completion */ | ||
| 720 | if (priv->scan_req == NULL) { | ||
| 721 | lbs_deb_scan("scan: waking up waiters\n"); | ||
| 722 | wake_up_all(&priv->scan_q); | ||
| 723 | } | ||
| 724 | |||
| 685 | out_no_scan_cmd: | 725 | out_no_scan_cmd: |
| 686 | lbs_deb_leave(LBS_DEB_SCAN); | 726 | lbs_deb_leave(LBS_DEB_SCAN); |
| 687 | } | 727 | } |
| 688 | 728 | ||
| 729 | static void _internal_start_scan(struct lbs_private *priv, bool internal, | ||
| 730 | struct cfg80211_scan_request *request) | ||
| 731 | { | ||
| 732 | lbs_deb_enter(LBS_DEB_CFG80211); | ||
| 733 | |||
| 734 | lbs_deb_scan("scan: ssids %d, channels %d, ie_len %zd\n", | ||
| 735 | request->n_ssids, request->n_channels, request->ie_len); | ||
| 736 | |||
| 737 | priv->scan_channel = 0; | ||
| 738 | queue_delayed_work(priv->work_thread, &priv->scan_work, | ||
| 739 | msecs_to_jiffies(50)); | ||
| 740 | |||
| 741 | priv->scan_req = request; | ||
| 742 | priv->internal_scan = internal; | ||
| 743 | |||
| 744 | lbs_deb_leave(LBS_DEB_CFG80211); | ||
| 745 | } | ||
| 689 | 746 | ||
| 690 | static int lbs_cfg_scan(struct wiphy *wiphy, | 747 | static int lbs_cfg_scan(struct wiphy *wiphy, |
| 691 | struct net_device *dev, | 748 | struct net_device *dev, |
| @@ -702,18 +759,11 @@ static int lbs_cfg_scan(struct wiphy *wiphy, | |||
| 702 | goto out; | 759 | goto out; |
| 703 | } | 760 | } |
| 704 | 761 | ||
| 705 | lbs_deb_scan("scan: ssids %d, channels %d, ie_len %zd\n", | 762 | _internal_start_scan(priv, false, request); |
| 706 | request->n_ssids, request->n_channels, request->ie_len); | ||
| 707 | |||
| 708 | priv->scan_channel = 0; | ||
| 709 | queue_delayed_work(priv->work_thread, &priv->scan_work, | ||
| 710 | msecs_to_jiffies(50)); | ||
| 711 | 763 | ||
| 712 | if (priv->surpriseremoved) | 764 | if (priv->surpriseremoved) |
| 713 | ret = -EIO; | 765 | ret = -EIO; |
| 714 | 766 | ||
| 715 | priv->scan_req = request; | ||
| 716 | |||
| 717 | out: | 767 | out: |
| 718 | lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); | 768 | lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); |
| 719 | return ret; | 769 | return ret; |
| @@ -1000,6 +1050,7 @@ static int lbs_associate(struct lbs_private *priv, | |||
| 1000 | int status; | 1050 | int status; |
| 1001 | int ret; | 1051 | int ret; |
| 1002 | u8 *pos = &(cmd->iebuf[0]); | 1052 | u8 *pos = &(cmd->iebuf[0]); |
| 1053 | u8 *tmp; | ||
| 1003 | 1054 | ||
| 1004 | lbs_deb_enter(LBS_DEB_CFG80211); | 1055 | lbs_deb_enter(LBS_DEB_CFG80211); |
| 1005 | 1056 | ||
| @@ -1044,7 +1095,9 @@ static int lbs_associate(struct lbs_private *priv, | |||
| 1044 | pos += lbs_add_cf_param_tlv(pos); | 1095 | pos += lbs_add_cf_param_tlv(pos); |
| 1045 | 1096 | ||
| 1046 | /* add rates TLV */ | 1097 | /* add rates TLV */ |
| 1098 | tmp = pos + 4; /* skip Marvell IE header */ | ||
| 1047 | pos += lbs_add_common_rates_tlv(pos, bss); | 1099 | pos += lbs_add_common_rates_tlv(pos, bss); |
| 1100 | lbs_deb_hex(LBS_DEB_ASSOC, "Common Rates", tmp, pos - tmp); | ||
| 1048 | 1101 | ||
| 1049 | /* add auth type TLV */ | 1102 | /* add auth type TLV */ |
| 1050 | if (priv->fwrelease >= 0x09000000) | 1103 | if (priv->fwrelease >= 0x09000000) |
| @@ -1124,7 +1177,62 @@ done: | |||
| 1124 | return ret; | 1177 | return ret; |
| 1125 | } | 1178 | } |
| 1126 | 1179 | ||
| 1180 | static struct cfg80211_scan_request * | ||
| 1181 | _new_connect_scan_req(struct wiphy *wiphy, struct cfg80211_connect_params *sme) | ||
| 1182 | { | ||
| 1183 | struct cfg80211_scan_request *creq = NULL; | ||
| 1184 | int i, n_channels = 0; | ||
| 1185 | enum ieee80211_band band; | ||
| 1186 | |||
| 1187 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | ||
| 1188 | if (wiphy->bands[band]) | ||
| 1189 | n_channels += wiphy->bands[band]->n_channels; | ||
| 1190 | } | ||
| 1191 | |||
| 1192 | creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) + | ||
| 1193 | n_channels * sizeof(void *), | ||
| 1194 | GFP_ATOMIC); | ||
| 1195 | if (!creq) | ||
| 1196 | return NULL; | ||
| 1197 | |||
| 1198 | /* SSIDs come after channels */ | ||
| 1199 | creq->ssids = (void *)&creq->channels[n_channels]; | ||
| 1200 | creq->n_channels = n_channels; | ||
| 1201 | creq->n_ssids = 1; | ||
| 1202 | |||
| 1203 | /* Scan all available channels */ | ||
| 1204 | i = 0; | ||
| 1205 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | ||
| 1206 | int j; | ||
| 1207 | |||
| 1208 | if (!wiphy->bands[band]) | ||
| 1209 | continue; | ||
| 1210 | |||
| 1211 | for (j = 0; j < wiphy->bands[band]->n_channels; j++) { | ||
| 1212 | /* ignore disabled channels */ | ||
| 1213 | if (wiphy->bands[band]->channels[j].flags & | ||
| 1214 | IEEE80211_CHAN_DISABLED) | ||
| 1215 | continue; | ||
| 1216 | |||
| 1217 | creq->channels[i] = &wiphy->bands[band]->channels[j]; | ||
| 1218 | i++; | ||
| 1219 | } | ||
| 1220 | } | ||
| 1221 | if (i) { | ||
| 1222 | /* Set real number of channels specified in creq->channels[] */ | ||
| 1223 | creq->n_channels = i; | ||
| 1224 | |||
| 1225 | /* Scan for the SSID we're going to connect to */ | ||
| 1226 | memcpy(creq->ssids[0].ssid, sme->ssid, sme->ssid_len); | ||
| 1227 | creq->ssids[0].ssid_len = sme->ssid_len; | ||
| 1228 | } else { | ||
| 1229 | /* No channels found... */ | ||
| 1230 | kfree(creq); | ||
| 1231 | creq = NULL; | ||
| 1232 | } | ||
| 1127 | 1233 | ||
| 1234 | return creq; | ||
| 1235 | } | ||
| 1128 | 1236 | ||
| 1129 | static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev, | 1237 | static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev, |
| 1130 | struct cfg80211_connect_params *sme) | 1238 | struct cfg80211_connect_params *sme) |
| @@ -1136,37 +1244,43 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev, | |||
| 1136 | 1244 | ||
| 1137 | lbs_deb_enter(LBS_DEB_CFG80211); | 1245 | lbs_deb_enter(LBS_DEB_CFG80211); |
| 1138 | 1246 | ||
| 1139 | if (sme->bssid) { | 1247 | if (!sme->bssid) { |
| 1140 | bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, | 1248 | /* Run a scan if one isn't in-progress already and if the last |
| 1141 | sme->ssid, sme->ssid_len, | 1249 | * scan was done more than 2 seconds ago. |
| 1142 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); | ||
| 1143 | } else { | ||
| 1144 | /* | ||
| 1145 | * Here we have an impedance mismatch. The firmware command | ||
| 1146 | * CMD_802_11_ASSOCIATE always needs a BSSID, it cannot | ||
| 1147 | * connect otherwise. However, for the connect-API of | ||
| 1148 | * cfg80211 the bssid is purely optional. We don't get one, | ||
| 1149 | * except the user specifies one on the "iw" command line. | ||
| 1150 | * | ||
| 1151 | * If we don't got one, we could initiate a scan and look | ||
| 1152 | * for the best matching cfg80211_bss entry. | ||
| 1153 | * | ||
| 1154 | * Or, better yet, net/wireless/sme.c get's rewritten into | ||
| 1155 | * something more generally useful. | ||
| 1156 | */ | 1250 | */ |
| 1157 | lbs_pr_err("TODO: no BSS specified\n"); | 1251 | if (priv->scan_req == NULL && |
| 1158 | ret = -ENOTSUPP; | 1252 | time_after(jiffies, priv->last_scan + (2 * HZ))) { |
| 1159 | goto done; | 1253 | struct cfg80211_scan_request *creq; |
| 1160 | } | ||
| 1161 | 1254 | ||
| 1255 | creq = _new_connect_scan_req(wiphy, sme); | ||
| 1256 | if (!creq) { | ||
| 1257 | ret = -EINVAL; | ||
| 1258 | goto done; | ||
| 1259 | } | ||
| 1260 | |||
| 1261 | lbs_deb_assoc("assoc: scanning for compatible AP\n"); | ||
| 1262 | _internal_start_scan(priv, true, creq); | ||
| 1263 | } | ||
| 1264 | |||
| 1265 | /* Wait for any in-progress scan to complete */ | ||
| 1266 | lbs_deb_assoc("assoc: waiting for scan to complete\n"); | ||
| 1267 | wait_event_interruptible_timeout(priv->scan_q, | ||
| 1268 | (priv->scan_req == NULL), | ||
| 1269 | (15 * HZ)); | ||
| 1270 | lbs_deb_assoc("assoc: scanning competed\n"); | ||
| 1271 | } | ||
| 1162 | 1272 | ||
| 1273 | /* Find the BSS we want using available scan results */ | ||
| 1274 | bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, | ||
| 1275 | sme->ssid, sme->ssid_len, | ||
| 1276 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); | ||
| 1163 | if (!bss) { | 1277 | if (!bss) { |
| 1164 | lbs_pr_err("assicate: bss %pM not in scan results\n", | 1278 | lbs_pr_err("assoc: bss %pM not in scan results\n", |
| 1165 | sme->bssid); | 1279 | sme->bssid); |
| 1166 | ret = -ENOENT; | 1280 | ret = -ENOENT; |
| 1167 | goto done; | 1281 | goto done; |
| 1168 | } | 1282 | } |
| 1169 | lbs_deb_assoc("trying %pM", sme->bssid); | 1283 | lbs_deb_assoc("trying %pM\n", bss->bssid); |
| 1170 | lbs_deb_assoc("cipher 0x%x, key index %d, key len %d\n", | 1284 | lbs_deb_assoc("cipher 0x%x, key index %d, key len %d\n", |
| 1171 | sme->crypto.cipher_group, | 1285 | sme->crypto.cipher_group, |
| 1172 | sme->key_idx, sme->key_len); | 1286 | sme->key_idx, sme->key_len); |
| @@ -1229,7 +1343,7 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev, | |||
| 1229 | lbs_set_radio(priv, preamble, 1); | 1343 | lbs_set_radio(priv, preamble, 1); |
| 1230 | 1344 | ||
| 1231 | /* Do the actual association */ | 1345 | /* Do the actual association */ |
| 1232 | lbs_associate(priv, bss, sme); | 1346 | ret = lbs_associate(priv, bss, sme); |
| 1233 | 1347 | ||
| 1234 | done: | 1348 | done: |
| 1235 | if (bss) | 1349 | if (bss) |
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 3c7e255e18c7..f062ed583901 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h | |||
| @@ -161,6 +161,11 @@ struct lbs_private { | |||
| 161 | /** Scanning */ | 161 | /** Scanning */ |
| 162 | struct delayed_work scan_work; | 162 | struct delayed_work scan_work; |
| 163 | int scan_channel; | 163 | int scan_channel; |
| 164 | /* Queue of things waiting for scan completion */ | ||
| 165 | wait_queue_head_t scan_q; | ||
| 166 | /* Whether the scan was initiated internally and not by cfg80211 */ | ||
| 167 | bool internal_scan; | ||
| 168 | unsigned long last_scan; | ||
| 164 | }; | 169 | }; |
| 165 | 170 | ||
| 166 | extern struct cmd_confirm_sleep confirm_sleep; | 171 | extern struct cmd_confirm_sleep confirm_sleep; |
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 258967144b96..24958a86747b 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c | |||
| @@ -719,6 +719,7 @@ static int lbs_init_adapter(struct lbs_private *priv) | |||
| 719 | priv->deep_sleep_required = 0; | 719 | priv->deep_sleep_required = 0; |
| 720 | priv->wakeup_dev_required = 0; | 720 | priv->wakeup_dev_required = 0; |
| 721 | init_waitqueue_head(&priv->ds_awake_q); | 721 | init_waitqueue_head(&priv->ds_awake_q); |
| 722 | init_waitqueue_head(&priv->scan_q); | ||
| 722 | priv->authtype_auto = 1; | 723 | priv->authtype_auto = 1; |
| 723 | priv->is_host_sleep_configured = 0; | 724 | priv->is_host_sleep_configured = 0; |
| 724 | priv->is_host_sleep_activated = 0; | 725 | priv->is_host_sleep_activated = 0; |
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index 822f8dc26e9c..71a101fb2e4e 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c | |||
| @@ -43,6 +43,8 @@ static DEFINE_PCI_DEVICE_TABLE(p54p_table) = { | |||
| 43 | { PCI_DEVICE(0x1260, 0x3886) }, | 43 | { PCI_DEVICE(0x1260, 0x3886) }, |
| 44 | /* Intersil PRISM Xbow Wireless LAN adapter (Symbol AP-300) */ | 44 | /* Intersil PRISM Xbow Wireless LAN adapter (Symbol AP-300) */ |
| 45 | { PCI_DEVICE(0x1260, 0xffff) }, | 45 | { PCI_DEVICE(0x1260, 0xffff) }, |
| 46 | /* Standard Microsystems Corp SMC2802W Wireless PCI */ | ||
| 47 | { PCI_DEVICE(0x10b8, 0x2802) }, | ||
| 46 | { }, | 48 | { }, |
| 47 | }; | 49 | }; |
| 48 | 50 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 19b262e1ddbe..63c2cc408e15 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c | |||
| @@ -240,16 +240,16 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) | |||
| 240 | struct rt2x00_dev *rt2x00dev; | 240 | struct rt2x00_dev *rt2x00dev; |
| 241 | int retval; | 241 | int retval; |
| 242 | 242 | ||
| 243 | retval = pci_request_regions(pci_dev, pci_name(pci_dev)); | 243 | retval = pci_enable_device(pci_dev); |
| 244 | if (retval) { | 244 | if (retval) { |
| 245 | ERROR_PROBE("PCI request regions failed.\n"); | 245 | ERROR_PROBE("Enable device failed.\n"); |
| 246 | return retval; | 246 | return retval; |
| 247 | } | 247 | } |
| 248 | 248 | ||
| 249 | retval = pci_enable_device(pci_dev); | 249 | retval = pci_request_regions(pci_dev, pci_name(pci_dev)); |
| 250 | if (retval) { | 250 | if (retval) { |
| 251 | ERROR_PROBE("Enable device failed.\n"); | 251 | ERROR_PROBE("PCI request regions failed.\n"); |
| 252 | goto exit_release_regions; | 252 | goto exit_disable_device; |
| 253 | } | 253 | } |
| 254 | 254 | ||
| 255 | pci_set_master(pci_dev); | 255 | pci_set_master(pci_dev); |
| @@ -260,14 +260,14 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) | |||
| 260 | if (dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32))) { | 260 | if (dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32))) { |
| 261 | ERROR_PROBE("PCI DMA not supported.\n"); | 261 | ERROR_PROBE("PCI DMA not supported.\n"); |
| 262 | retval = -EIO; | 262 | retval = -EIO; |
| 263 | goto exit_disable_device; | 263 | goto exit_release_regions; |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw); | 266 | hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw); |
| 267 | if (!hw) { | 267 | if (!hw) { |
| 268 | ERROR_PROBE("Failed to allocate hardware.\n"); | 268 | ERROR_PROBE("Failed to allocate hardware.\n"); |
| 269 | retval = -ENOMEM; | 269 | retval = -ENOMEM; |
| 270 | goto exit_disable_device; | 270 | goto exit_release_regions; |
| 271 | } | 271 | } |
| 272 | 272 | ||
| 273 | pci_set_drvdata(pci_dev, hw); | 273 | pci_set_drvdata(pci_dev, hw); |
| @@ -300,13 +300,12 @@ exit_free_reg: | |||
| 300 | exit_free_device: | 300 | exit_free_device: |
| 301 | ieee80211_free_hw(hw); | 301 | ieee80211_free_hw(hw); |
| 302 | 302 | ||
| 303 | exit_disable_device: | ||
| 304 | if (retval != -EBUSY) | ||
| 305 | pci_disable_device(pci_dev); | ||
| 306 | |||
| 307 | exit_release_regions: | 303 | exit_release_regions: |
| 308 | pci_release_regions(pci_dev); | 304 | pci_release_regions(pci_dev); |
| 309 | 305 | ||
| 306 | exit_disable_device: | ||
| 307 | pci_disable_device(pci_dev); | ||
| 308 | |||
| 310 | pci_set_drvdata(pci_dev, NULL); | 309 | pci_set_drvdata(pci_dev, NULL); |
| 311 | 310 | ||
| 312 | return retval; | 311 | return retval; |
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c index 1d8178563d76..b50c39aaec05 100644 --- a/drivers/net/wireless/rtl818x/rtl8180_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c | |||
| @@ -695,6 +695,8 @@ static void rtl8180_beacon_work(struct work_struct *work) | |||
| 695 | 695 | ||
| 696 | /* grab a fresh beacon */ | 696 | /* grab a fresh beacon */ |
| 697 | skb = ieee80211_beacon_get(dev, vif); | 697 | skb = ieee80211_beacon_get(dev, vif); |
| 698 | if (!skb) | ||
| 699 | goto resched; | ||
| 698 | 700 | ||
| 699 | /* | 701 | /* |
| 700 | * update beacon timestamp w/ TSF value | 702 | * update beacon timestamp w/ TSF value |
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c index 96d25fb50495..4cb99c541e2a 100644 --- a/drivers/net/wireless/wl12xx/wl1271_spi.c +++ b/drivers/net/wireless/wl12xx/wl1271_spi.c | |||
| @@ -160,9 +160,8 @@ static void wl1271_spi_init(struct wl1271 *wl) | |||
| 160 | spi_message_add_tail(&t, &m); | 160 | spi_message_add_tail(&t, &m); |
| 161 | 161 | ||
| 162 | spi_sync(wl_to_spi(wl), &m); | 162 | spi_sync(wl_to_spi(wl), &m); |
| 163 | kfree(cmd); | ||
| 164 | |||
| 165 | wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN); | 163 | wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN); |
| 164 | kfree(cmd); | ||
| 166 | } | 165 | } |
| 167 | 166 | ||
| 168 | #define WL1271_BUSY_WORD_TIMEOUT 1000 | 167 | #define WL1271_BUSY_WORD_TIMEOUT 1000 |
diff --git a/include/linux/ppp_channel.h b/include/linux/ppp_channel.h index bff98ec1bfed..5d87f810a3b7 100644 --- a/include/linux/ppp_channel.h +++ b/include/linux/ppp_channel.h | |||
| @@ -36,7 +36,7 @@ struct ppp_channel_ops { | |||
| 36 | 36 | ||
| 37 | struct ppp_channel { | 37 | struct ppp_channel { |
| 38 | void *private; /* channel private data */ | 38 | void *private; /* channel private data */ |
| 39 | struct ppp_channel_ops *ops; /* operations for this channel */ | 39 | const struct ppp_channel_ops *ops; /* operations for this channel */ |
| 40 | int mtu; /* max transmit packet size */ | 40 | int mtu; /* max transmit packet size */ |
| 41 | int hdrlen; /* amount of headroom channel needs */ | 41 | int hdrlen; /* amount of headroom channel needs */ |
| 42 | void *ppp; /* opaque to channel */ | 42 | void *ppp; /* opaque to channel */ |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index d20d9e7a9bbd..77eb60d2b496 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
| @@ -1379,6 +1379,11 @@ static inline int skb_network_offset(const struct sk_buff *skb) | |||
| 1379 | return skb_network_header(skb) - skb->data; | 1379 | return skb_network_header(skb) - skb->data; |
| 1380 | } | 1380 | } |
| 1381 | 1381 | ||
| 1382 | static inline int pskb_network_may_pull(struct sk_buff *skb, unsigned int len) | ||
| 1383 | { | ||
| 1384 | return pskb_may_pull(skb, skb_network_offset(skb) + len); | ||
| 1385 | } | ||
| 1386 | |||
| 1382 | /* | 1387 | /* |
| 1383 | * CPUs often take a performance hit when accessing unaligned memory | 1388 | * CPUs often take a performance hit when accessing unaligned memory |
| 1384 | * locations. The actual performance hit varies, it can be small if the | 1389 | * locations. The actual performance hit varies, it can be small if the |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 8b28962e737e..4568b938ca35 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
| @@ -132,7 +132,7 @@ struct hci_dev { | |||
| 132 | 132 | ||
| 133 | struct inquiry_cache inq_cache; | 133 | struct inquiry_cache inq_cache; |
| 134 | struct hci_conn_hash conn_hash; | 134 | struct hci_conn_hash conn_hash; |
| 135 | struct bdaddr_list blacklist; | 135 | struct list_head blacklist; |
| 136 | 136 | ||
| 137 | struct hci_dev_stats stat; | 137 | struct hci_dev_stats stat; |
| 138 | 138 | ||
diff --git a/net/atm/pppoatm.c b/net/atm/pppoatm.c index e49bb6d948a1..e9aced0ec56b 100644 --- a/net/atm/pppoatm.c +++ b/net/atm/pppoatm.c | |||
| @@ -260,7 +260,7 @@ static int pppoatm_devppp_ioctl(struct ppp_channel *chan, unsigned int cmd, | |||
| 260 | return -ENOTTY; | 260 | return -ENOTTY; |
| 261 | } | 261 | } |
| 262 | 262 | ||
| 263 | static /*const*/ struct ppp_channel_ops pppoatm_ops = { | 263 | static const struct ppp_channel_ops pppoatm_ops = { |
| 264 | .start_xmit = pppoatm_send, | 264 | .start_xmit = pppoatm_send, |
| 265 | .ioctl = pppoatm_devppp_ioctl, | 265 | .ioctl = pppoatm_devppp_ioctl, |
| 266 | }; | 266 | }; |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 8303f1c9ef54..c52f091ee6de 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
| @@ -924,7 +924,7 @@ int hci_register_dev(struct hci_dev *hdev) | |||
| 924 | 924 | ||
| 925 | hci_conn_hash_init(hdev); | 925 | hci_conn_hash_init(hdev); |
| 926 | 926 | ||
| 927 | INIT_LIST_HEAD(&hdev->blacklist.list); | 927 | INIT_LIST_HEAD(&hdev->blacklist); |
| 928 | 928 | ||
| 929 | memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); | 929 | memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); |
| 930 | 930 | ||
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 4f170a595934..83acd164d39e 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
| @@ -168,9 +168,8 @@ static int hci_sock_release(struct socket *sock) | |||
| 168 | struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr) | 168 | struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr) |
| 169 | { | 169 | { |
| 170 | struct list_head *p; | 170 | struct list_head *p; |
| 171 | struct bdaddr_list *blacklist = &hdev->blacklist; | ||
| 172 | 171 | ||
| 173 | list_for_each(p, &blacklist->list) { | 172 | list_for_each(p, &hdev->blacklist) { |
| 174 | struct bdaddr_list *b; | 173 | struct bdaddr_list *b; |
| 175 | 174 | ||
| 176 | b = list_entry(p, struct bdaddr_list, list); | 175 | b = list_entry(p, struct bdaddr_list, list); |
| @@ -202,7 +201,7 @@ static int hci_blacklist_add(struct hci_dev *hdev, void __user *arg) | |||
| 202 | 201 | ||
| 203 | bacpy(&entry->bdaddr, &bdaddr); | 202 | bacpy(&entry->bdaddr, &bdaddr); |
| 204 | 203 | ||
| 205 | list_add(&entry->list, &hdev->blacklist.list); | 204 | list_add(&entry->list, &hdev->blacklist); |
| 206 | 205 | ||
| 207 | return 0; | 206 | return 0; |
| 208 | } | 207 | } |
| @@ -210,9 +209,8 @@ static int hci_blacklist_add(struct hci_dev *hdev, void __user *arg) | |||
| 210 | int hci_blacklist_clear(struct hci_dev *hdev) | 209 | int hci_blacklist_clear(struct hci_dev *hdev) |
| 211 | { | 210 | { |
| 212 | struct list_head *p, *n; | 211 | struct list_head *p, *n; |
| 213 | struct bdaddr_list *blacklist = &hdev->blacklist; | ||
| 214 | 212 | ||
| 215 | list_for_each_safe(p, n, &blacklist->list) { | 213 | list_for_each_safe(p, n, &hdev->blacklist) { |
| 216 | struct bdaddr_list *b; | 214 | struct bdaddr_list *b; |
| 217 | 215 | ||
| 218 | b = list_entry(p, struct bdaddr_list, list); | 216 | b = list_entry(p, struct bdaddr_list, list); |
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index ce44c47eeac1..8fb967beee80 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
| @@ -439,12 +439,11 @@ static const struct file_operations inquiry_cache_fops = { | |||
| 439 | static int blacklist_show(struct seq_file *f, void *p) | 439 | static int blacklist_show(struct seq_file *f, void *p) |
| 440 | { | 440 | { |
| 441 | struct hci_dev *hdev = f->private; | 441 | struct hci_dev *hdev = f->private; |
| 442 | struct bdaddr_list *blacklist = &hdev->blacklist; | ||
| 443 | struct list_head *l; | 442 | struct list_head *l; |
| 444 | 443 | ||
| 445 | hci_dev_lock_bh(hdev); | 444 | hci_dev_lock_bh(hdev); |
| 446 | 445 | ||
| 447 | list_for_each(l, &blacklist->list) { | 446 | list_for_each(l, &hdev->blacklist) { |
| 448 | struct bdaddr_list *b; | 447 | struct bdaddr_list *b; |
| 449 | bdaddr_t bdaddr; | 448 | bdaddr_t bdaddr; |
| 450 | 449 | ||
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 9ba1e8eee37c..3e3cd9d4e52c 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
| @@ -2527,6 +2527,10 @@ done: | |||
| 2527 | if (pi->imtu != L2CAP_DEFAULT_MTU) | 2527 | if (pi->imtu != L2CAP_DEFAULT_MTU) |
| 2528 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu); | 2528 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu); |
| 2529 | 2529 | ||
| 2530 | if (!(pi->conn->feat_mask & L2CAP_FEAT_ERTM) && | ||
| 2531 | !(pi->conn->feat_mask & L2CAP_FEAT_STREAMING)) | ||
| 2532 | break; | ||
| 2533 | |||
| 2530 | rfc.mode = L2CAP_MODE_BASIC; | 2534 | rfc.mode = L2CAP_MODE_BASIC; |
| 2531 | rfc.txwin_size = 0; | 2535 | rfc.txwin_size = 0; |
| 2532 | rfc.max_transmit = 0; | 2536 | rfc.max_transmit = 0; |
| @@ -2534,6 +2538,8 @@ done: | |||
| 2534 | rfc.monitor_timeout = 0; | 2538 | rfc.monitor_timeout = 0; |
| 2535 | rfc.max_pdu_size = 0; | 2539 | rfc.max_pdu_size = 0; |
| 2536 | 2540 | ||
| 2541 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), | ||
| 2542 | (unsigned long) &rfc); | ||
| 2537 | break; | 2543 | break; |
| 2538 | 2544 | ||
| 2539 | case L2CAP_MODE_ERTM: | 2545 | case L2CAP_MODE_ERTM: |
| @@ -2546,6 +2552,9 @@ done: | |||
| 2546 | if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10) | 2552 | if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10) |
| 2547 | rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); | 2553 | rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); |
| 2548 | 2554 | ||
| 2555 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), | ||
| 2556 | (unsigned long) &rfc); | ||
| 2557 | |||
| 2549 | if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS)) | 2558 | if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS)) |
| 2550 | break; | 2559 | break; |
| 2551 | 2560 | ||
| @@ -2566,6 +2575,9 @@ done: | |||
| 2566 | if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10) | 2575 | if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10) |
| 2567 | rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); | 2576 | rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); |
| 2568 | 2577 | ||
| 2578 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), | ||
| 2579 | (unsigned long) &rfc); | ||
| 2580 | |||
| 2569 | if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS)) | 2581 | if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS)) |
| 2570 | break; | 2582 | break; |
| 2571 | 2583 | ||
| @@ -2577,9 +2589,6 @@ done: | |||
| 2577 | break; | 2589 | break; |
| 2578 | } | 2590 | } |
| 2579 | 2591 | ||
| 2580 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc), | ||
| 2581 | (unsigned long) &rfc); | ||
| 2582 | |||
| 2583 | /* FIXME: Need actual value of the flush timeout */ | 2592 | /* FIXME: Need actual value of the flush timeout */ |
| 2584 | //if (flush_to != L2CAP_DEFAULT_FLUSH_TO) | 2593 | //if (flush_to != L2CAP_DEFAULT_FLUSH_TO) |
| 2585 | // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to); | 2594 | // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to); |
| @@ -3339,6 +3348,15 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm | |||
| 3339 | 3348 | ||
| 3340 | del_timer(&conn->info_timer); | 3349 | del_timer(&conn->info_timer); |
| 3341 | 3350 | ||
| 3351 | if (result != L2CAP_IR_SUCCESS) { | ||
| 3352 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE; | ||
| 3353 | conn->info_ident = 0; | ||
| 3354 | |||
| 3355 | l2cap_conn_start(conn); | ||
| 3356 | |||
| 3357 | return 0; | ||
| 3358 | } | ||
| 3359 | |||
| 3342 | if (type == L2CAP_IT_FEAT_MASK) { | 3360 | if (type == L2CAP_IT_FEAT_MASK) { |
| 3343 | conn->feat_mask = get_unaligned_le32(rsp->data); | 3361 | conn->feat_mask = get_unaligned_le32(rsp->data); |
| 3344 | 3362 | ||
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 026205c18b78..befc3a52aa04 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c | |||
| @@ -1183,7 +1183,7 @@ int __init rfcomm_init_ttys(void) | |||
| 1183 | return 0; | 1183 | return 0; |
| 1184 | } | 1184 | } |
| 1185 | 1185 | ||
| 1186 | void __exit rfcomm_cleanup_ttys(void) | 1186 | void rfcomm_cleanup_ttys(void) |
| 1187 | { | 1187 | { |
| 1188 | tty_unregister_driver(rfcomm_tty_driver); | 1188 | tty_unregister_driver(rfcomm_tty_driver); |
| 1189 | put_tty_driver(rfcomm_tty_driver); | 1189 | put_tty_driver(rfcomm_tty_driver); |
diff --git a/net/core/dev.c b/net/core/dev.c index e1c1cdcc2bb0..1ae654391442 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -2517,6 +2517,7 @@ int netif_rx(struct sk_buff *skb) | |||
| 2517 | struct rps_dev_flow voidflow, *rflow = &voidflow; | 2517 | struct rps_dev_flow voidflow, *rflow = &voidflow; |
| 2518 | int cpu; | 2518 | int cpu; |
| 2519 | 2519 | ||
| 2520 | preempt_disable(); | ||
| 2520 | rcu_read_lock(); | 2521 | rcu_read_lock(); |
| 2521 | 2522 | ||
| 2522 | cpu = get_rps_cpu(skb->dev, skb, &rflow); | 2523 | cpu = get_rps_cpu(skb->dev, skb, &rflow); |
| @@ -2526,6 +2527,7 @@ int netif_rx(struct sk_buff *skb) | |||
| 2526 | ret = enqueue_to_backlog(skb, cpu, &rflow->last_qtail); | 2527 | ret = enqueue_to_backlog(skb, cpu, &rflow->last_qtail); |
| 2527 | 2528 | ||
| 2528 | rcu_read_unlock(); | 2529 | rcu_read_unlock(); |
| 2530 | preempt_enable(); | ||
| 2529 | } | 2531 | } |
| 2530 | #else | 2532 | #else |
| 2531 | { | 2533 | { |
| @@ -3072,7 +3074,7 @@ enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | |||
| 3072 | int mac_len; | 3074 | int mac_len; |
| 3073 | enum gro_result ret; | 3075 | enum gro_result ret; |
| 3074 | 3076 | ||
| 3075 | if (!(skb->dev->features & NETIF_F_GRO)) | 3077 | if (!(skb->dev->features & NETIF_F_GRO) || netpoll_rx_on(skb)) |
| 3076 | goto normal; | 3078 | goto normal; |
| 3077 | 3079 | ||
| 3078 | if (skb_is_gso(skb) || skb_has_frags(skb)) | 3080 | if (skb_is_gso(skb) || skb_has_frags(skb)) |
| @@ -3159,9 +3161,6 @@ __napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | |||
| 3159 | { | 3161 | { |
| 3160 | struct sk_buff *p; | 3162 | struct sk_buff *p; |
| 3161 | 3163 | ||
| 3162 | if (netpoll_rx_on(skb)) | ||
| 3163 | return GRO_NORMAL; | ||
| 3164 | |||
| 3165 | for (p = napi->gro_list; p; p = p->next) { | 3164 | for (p = napi->gro_list; p; p = p->next) { |
| 3166 | NAPI_GRO_CB(p)->same_flow = | 3165 | NAPI_GRO_CB(p)->same_flow = |
| 3167 | (p->dev == skb->dev) && | 3166 | (p->dev == skb->dev) && |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 3c426cb318e7..e663b78a2ef6 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
| @@ -3930,7 +3930,7 @@ u8 *tcp_parse_md5sig_option(struct tcphdr *th) | |||
| 3930 | if (opsize < 2 || opsize > length) | 3930 | if (opsize < 2 || opsize > length) |
| 3931 | return NULL; | 3931 | return NULL; |
| 3932 | if (opcode == TCPOPT_MD5SIG) | 3932 | if (opcode == TCPOPT_MD5SIG) |
| 3933 | return ptr; | 3933 | return opsize == TCPOLEN_MD5SIG ? ptr : NULL; |
| 3934 | } | 3934 | } |
| 3935 | ptr += opsize - 2; | 3935 | ptr += opsize - 2; |
| 3936 | length -= opsize; | 3936 | length -= opsize; |
diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c index 800bc53b7f63..dfe7b38dd4af 100644 --- a/net/irda/irnet/irnet_ppp.c +++ b/net/irda/irnet/irnet_ppp.c | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | /* Please put other headers in irnet.h - Thanks */ | 20 | /* Please put other headers in irnet.h - Thanks */ |
| 21 | 21 | ||
| 22 | /* Generic PPP callbacks (to call us) */ | 22 | /* Generic PPP callbacks (to call us) */ |
| 23 | static struct ppp_channel_ops irnet_ppp_ops = { | 23 | static const struct ppp_channel_ops irnet_ppp_ops = { |
| 24 | .start_xmit = ppp_irnet_send, | 24 | .start_xmit = ppp_irnet_send, |
| 25 | .ioctl = ppp_irnet_ioctl | 25 | .ioctl = ppp_irnet_ioctl |
| 26 | }; | 26 | }; |
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index 90d82b3f2889..ff954b3e94b6 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c | |||
| @@ -135,7 +135,10 @@ struct pppol2tp_session { | |||
| 135 | 135 | ||
| 136 | static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb); | 136 | static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb); |
| 137 | 137 | ||
| 138 | static struct ppp_channel_ops pppol2tp_chan_ops = { pppol2tp_xmit , NULL }; | 138 | static const struct ppp_channel_ops pppol2tp_chan_ops = { |
| 139 | .start_xmit = pppol2tp_xmit, | ||
| 140 | }; | ||
| 141 | |||
| 139 | static const struct proto_ops pppol2tp_ops; | 142 | static const struct proto_ops pppol2tp_ops; |
| 140 | 143 | ||
| 141 | /* Helpers to obtain tunnel/session contexts from sockets. | 144 | /* Helpers to obtain tunnel/session contexts from sockets. |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 7cc4f913a431..798a91b100cc 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
| @@ -685,10 +685,12 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
| 685 | 685 | ||
| 686 | return 0; | 686 | return 0; |
| 687 | 687 | ||
| 688 | #ifdef CONFIG_INET | ||
| 688 | fail_ifa: | 689 | fail_ifa: |
| 689 | pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY, | 690 | pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY, |
| 690 | &local->network_latency_notifier); | 691 | &local->network_latency_notifier); |
| 691 | rtnl_lock(); | 692 | rtnl_lock(); |
| 693 | #endif | ||
| 692 | fail_pm_qos: | 694 | fail_pm_qos: |
| 693 | ieee80211_led_exit(local); | 695 | ieee80211_led_exit(local); |
| 694 | ieee80211_remove_interfaces(local); | 696 | ieee80211_remove_interfaces(local); |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 41f20fb7e670..872d7b6ef6b3 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
| @@ -400,19 +400,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
| 400 | else | 400 | else |
| 401 | __set_bit(SCAN_SW_SCANNING, &local->scanning); | 401 | __set_bit(SCAN_SW_SCANNING, &local->scanning); |
| 402 | 402 | ||
| 403 | /* | ||
| 404 | * Kicking off the scan need not be protected, | ||
| 405 | * only the scan variable stuff, since now | ||
| 406 | * local->scan_req is assigned and other callers | ||
| 407 | * will abort their scan attempts. | ||
| 408 | * | ||
| 409 | * This avoids too many locking dependencies | ||
| 410 | * so that the scan completed calls have more | ||
| 411 | * locking freedom. | ||
| 412 | */ | ||
| 413 | |||
| 414 | ieee80211_recalc_idle(local); | 403 | ieee80211_recalc_idle(local); |
| 415 | mutex_unlock(&local->scan_mtx); | ||
| 416 | 404 | ||
| 417 | if (local->ops->hw_scan) { | 405 | if (local->ops->hw_scan) { |
| 418 | WARN_ON(!ieee80211_prep_hw_scan(local)); | 406 | WARN_ON(!ieee80211_prep_hw_scan(local)); |
| @@ -420,8 +408,6 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
| 420 | } else | 408 | } else |
| 421 | rc = ieee80211_start_sw_scan(local); | 409 | rc = ieee80211_start_sw_scan(local); |
| 422 | 410 | ||
| 423 | mutex_lock(&local->scan_mtx); | ||
| 424 | |||
| 425 | if (rc) { | 411 | if (rc) { |
| 426 | kfree(local->hw_scan_req); | 412 | kfree(local->hw_scan_req); |
| 427 | local->hw_scan_req = NULL; | 413 | local->hw_scan_req = NULL; |
diff --git a/net/rxrpc/ar-ack.c b/net/rxrpc/ar-ack.c index 2714da167fb8..b6ffe4e1b84a 100644 --- a/net/rxrpc/ar-ack.c +++ b/net/rxrpc/ar-ack.c | |||
| @@ -245,6 +245,9 @@ static void rxrpc_resend_timer(struct rxrpc_call *call) | |||
| 245 | _enter("%d,%d,%d", | 245 | _enter("%d,%d,%d", |
| 246 | call->acks_tail, call->acks_unacked, call->acks_head); | 246 | call->acks_tail, call->acks_unacked, call->acks_head); |
| 247 | 247 | ||
| 248 | if (call->state >= RXRPC_CALL_COMPLETE) | ||
| 249 | return; | ||
| 250 | |||
| 248 | resend = 0; | 251 | resend = 0; |
| 249 | resend_at = 0; | 252 | resend_at = 0; |
| 250 | 253 | ||
diff --git a/net/rxrpc/ar-call.c b/net/rxrpc/ar-call.c index 909d092de9f4..bf656c230ba9 100644 --- a/net/rxrpc/ar-call.c +++ b/net/rxrpc/ar-call.c | |||
| @@ -786,6 +786,7 @@ static void rxrpc_call_life_expired(unsigned long _call) | |||
| 786 | 786 | ||
| 787 | /* | 787 | /* |
| 788 | * handle resend timer expiry | 788 | * handle resend timer expiry |
| 789 | * - may not take call->state_lock as this can deadlock against del_timer_sync() | ||
| 789 | */ | 790 | */ |
| 790 | static void rxrpc_resend_time_expired(unsigned long _call) | 791 | static void rxrpc_resend_time_expired(unsigned long _call) |
| 791 | { | 792 | { |
| @@ -796,12 +797,9 @@ static void rxrpc_resend_time_expired(unsigned long _call) | |||
| 796 | if (call->state >= RXRPC_CALL_COMPLETE) | 797 | if (call->state >= RXRPC_CALL_COMPLETE) |
| 797 | return; | 798 | return; |
| 798 | 799 | ||
| 799 | read_lock_bh(&call->state_lock); | ||
| 800 | clear_bit(RXRPC_CALL_RUN_RTIMER, &call->flags); | 800 | clear_bit(RXRPC_CALL_RUN_RTIMER, &call->flags); |
| 801 | if (call->state < RXRPC_CALL_COMPLETE && | 801 | if (!test_and_set_bit(RXRPC_CALL_RESEND_TIMER, &call->events)) |
| 802 | !test_and_set_bit(RXRPC_CALL_RESEND_TIMER, &call->events)) | ||
| 803 | rxrpc_queue_call(call); | 802 | rxrpc_queue_call(call); |
| 804 | read_unlock_bh(&call->state_lock); | ||
| 805 | } | 803 | } |
| 806 | 804 | ||
| 807 | /* | 805 | /* |
diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c index d0386a413e8d..509a2d53a99d 100644 --- a/net/sched/act_nat.c +++ b/net/sched/act_nat.c | |||
| @@ -114,6 +114,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, | |||
| 114 | int egress; | 114 | int egress; |
| 115 | int action; | 115 | int action; |
| 116 | int ihl; | 116 | int ihl; |
| 117 | int noff; | ||
| 117 | 118 | ||
| 118 | spin_lock(&p->tcf_lock); | 119 | spin_lock(&p->tcf_lock); |
| 119 | 120 | ||
| @@ -132,7 +133,8 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, | |||
| 132 | if (unlikely(action == TC_ACT_SHOT)) | 133 | if (unlikely(action == TC_ACT_SHOT)) |
| 133 | goto drop; | 134 | goto drop; |
| 134 | 135 | ||
| 135 | if (!pskb_may_pull(skb, sizeof(*iph))) | 136 | noff = skb_network_offset(skb); |
| 137 | if (!pskb_may_pull(skb, sizeof(*iph) + noff)) | ||
| 136 | goto drop; | 138 | goto drop; |
| 137 | 139 | ||
| 138 | iph = ip_hdr(skb); | 140 | iph = ip_hdr(skb); |
| @@ -144,7 +146,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, | |||
| 144 | 146 | ||
| 145 | if (!((old_addr ^ addr) & mask)) { | 147 | if (!((old_addr ^ addr) & mask)) { |
| 146 | if (skb_cloned(skb) && | 148 | if (skb_cloned(skb) && |
| 147 | !skb_clone_writable(skb, sizeof(*iph)) && | 149 | !skb_clone_writable(skb, sizeof(*iph) + noff) && |
| 148 | pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) | 150 | pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) |
| 149 | goto drop; | 151 | goto drop; |
| 150 | 152 | ||
| @@ -172,9 +174,9 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, | |||
| 172 | { | 174 | { |
| 173 | struct tcphdr *tcph; | 175 | struct tcphdr *tcph; |
| 174 | 176 | ||
| 175 | if (!pskb_may_pull(skb, ihl + sizeof(*tcph)) || | 177 | if (!pskb_may_pull(skb, ihl + sizeof(*tcph) + noff) || |
| 176 | (skb_cloned(skb) && | 178 | (skb_cloned(skb) && |
| 177 | !skb_clone_writable(skb, ihl + sizeof(*tcph)) && | 179 | !skb_clone_writable(skb, ihl + sizeof(*tcph) + noff) && |
| 178 | pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) | 180 | pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) |
| 179 | goto drop; | 181 | goto drop; |
| 180 | 182 | ||
| @@ -186,9 +188,9 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, | |||
| 186 | { | 188 | { |
| 187 | struct udphdr *udph; | 189 | struct udphdr *udph; |
| 188 | 190 | ||
| 189 | if (!pskb_may_pull(skb, ihl + sizeof(*udph)) || | 191 | if (!pskb_may_pull(skb, ihl + sizeof(*udph) + noff) || |
| 190 | (skb_cloned(skb) && | 192 | (skb_cloned(skb) && |
| 191 | !skb_clone_writable(skb, ihl + sizeof(*udph)) && | 193 | !skb_clone_writable(skb, ihl + sizeof(*udph) + noff) && |
| 192 | pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) | 194 | pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) |
| 193 | goto drop; | 195 | goto drop; |
| 194 | 196 | ||
| @@ -205,7 +207,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, | |||
| 205 | { | 207 | { |
| 206 | struct icmphdr *icmph; | 208 | struct icmphdr *icmph; |
| 207 | 209 | ||
| 208 | if (!pskb_may_pull(skb, ihl + sizeof(*icmph))) | 210 | if (!pskb_may_pull(skb, ihl + sizeof(*icmph) + noff)) |
| 209 | goto drop; | 211 | goto drop; |
| 210 | 212 | ||
| 211 | icmph = (void *)(skb_network_header(skb) + ihl); | 213 | icmph = (void *)(skb_network_header(skb) + ihl); |
| @@ -215,7 +217,8 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, | |||
| 215 | (icmph->type != ICMP_PARAMETERPROB)) | 217 | (icmph->type != ICMP_PARAMETERPROB)) |
| 216 | break; | 218 | break; |
| 217 | 219 | ||
| 218 | if (!pskb_may_pull(skb, ihl + sizeof(*icmph) + sizeof(*iph))) | 220 | if (!pskb_may_pull(skb, ihl + sizeof(*icmph) + sizeof(*iph) + |
| 221 | noff)) | ||
| 219 | goto drop; | 222 | goto drop; |
| 220 | 223 | ||
| 221 | icmph = (void *)(skb_network_header(skb) + ihl); | 224 | icmph = (void *)(skb_network_header(skb) + ihl); |
| @@ -229,8 +232,8 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, | |||
| 229 | break; | 232 | break; |
| 230 | 233 | ||
| 231 | if (skb_cloned(skb) && | 234 | if (skb_cloned(skb) && |
| 232 | !skb_clone_writable(skb, | 235 | !skb_clone_writable(skb, ihl + sizeof(*icmph) + |
| 233 | ihl + sizeof(*icmph) + sizeof(*iph)) && | 236 | sizeof(*iph) + noff) && |
| 234 | pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) | 237 | pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) |
| 235 | goto drop; | 238 | goto drop; |
| 236 | 239 | ||
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index f73542d2cdd0..e17096e3913c 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c | |||
| @@ -65,37 +65,47 @@ static inline u32 addr_fold(void *addr) | |||
| 65 | return (a & 0xFFFFFFFF) ^ (BITS_PER_LONG > 32 ? a >> 32 : 0); | 65 | return (a & 0xFFFFFFFF) ^ (BITS_PER_LONG > 32 ? a >> 32 : 0); |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | static u32 flow_get_src(const struct sk_buff *skb) | 68 | static u32 flow_get_src(struct sk_buff *skb) |
| 69 | { | 69 | { |
| 70 | switch (skb->protocol) { | 70 | switch (skb->protocol) { |
| 71 | case htons(ETH_P_IP): | 71 | case htons(ETH_P_IP): |
| 72 | return ntohl(ip_hdr(skb)->saddr); | 72 | if (pskb_network_may_pull(skb, sizeof(struct iphdr))) |
| 73 | return ntohl(ip_hdr(skb)->saddr); | ||
| 74 | break; | ||
| 73 | case htons(ETH_P_IPV6): | 75 | case htons(ETH_P_IPV6): |
| 74 | return ntohl(ipv6_hdr(skb)->saddr.s6_addr32[3]); | 76 | if (pskb_network_may_pull(skb, sizeof(struct ipv6hdr))) |
| 75 | default: | 77 | return ntohl(ipv6_hdr(skb)->saddr.s6_addr32[3]); |
| 76 | return addr_fold(skb->sk); | 78 | break; |
| 77 | } | 79 | } |
| 80 | |||
| 81 | return addr_fold(skb->sk); | ||
| 78 | } | 82 | } |
| 79 | 83 | ||
| 80 | static u32 flow_get_dst(const struct sk_buff *skb) | 84 | static u32 flow_get_dst(struct sk_buff *skb) |
| 81 | { | 85 | { |
| 82 | switch (skb->protocol) { | 86 | switch (skb->protocol) { |
| 83 | case htons(ETH_P_IP): | 87 | case htons(ETH_P_IP): |
| 84 | return ntohl(ip_hdr(skb)->daddr); | 88 | if (pskb_network_may_pull(skb, sizeof(struct iphdr))) |
| 89 | return ntohl(ip_hdr(skb)->daddr); | ||
| 90 | break; | ||
| 85 | case htons(ETH_P_IPV6): | 91 | case htons(ETH_P_IPV6): |
| 86 | return ntohl(ipv6_hdr(skb)->daddr.s6_addr32[3]); | 92 | if (pskb_network_may_pull(skb, sizeof(struct ipv6hdr))) |
| 87 | default: | 93 | return ntohl(ipv6_hdr(skb)->daddr.s6_addr32[3]); |
| 88 | return addr_fold(skb_dst(skb)) ^ (__force u16)skb->protocol; | 94 | break; |
| 89 | } | 95 | } |
| 96 | |||
| 97 | return addr_fold(skb_dst(skb)) ^ (__force u16)skb->protocol; | ||
| 90 | } | 98 | } |
| 91 | 99 | ||
| 92 | static u32 flow_get_proto(const struct sk_buff *skb) | 100 | static u32 flow_get_proto(struct sk_buff *skb) |
| 93 | { | 101 | { |
| 94 | switch (skb->protocol) { | 102 | switch (skb->protocol) { |
| 95 | case htons(ETH_P_IP): | 103 | case htons(ETH_P_IP): |
| 96 | return ip_hdr(skb)->protocol; | 104 | return pskb_network_may_pull(skb, sizeof(struct iphdr)) ? |
| 105 | ip_hdr(skb)->protocol : 0; | ||
| 97 | case htons(ETH_P_IPV6): | 106 | case htons(ETH_P_IPV6): |
| 98 | return ipv6_hdr(skb)->nexthdr; | 107 | return pskb_network_may_pull(skb, sizeof(struct ipv6hdr)) ? |
| 108 | ipv6_hdr(skb)->nexthdr : 0; | ||
| 99 | default: | 109 | default: |
| 100 | return 0; | 110 | return 0; |
| 101 | } | 111 | } |
| @@ -116,58 +126,64 @@ static int has_ports(u8 protocol) | |||
| 116 | } | 126 | } |
| 117 | } | 127 | } |
| 118 | 128 | ||
| 119 | static u32 flow_get_proto_src(const struct sk_buff *skb) | 129 | static u32 flow_get_proto_src(struct sk_buff *skb) |
| 120 | { | 130 | { |
| 121 | u32 res = 0; | ||
| 122 | |||
| 123 | switch (skb->protocol) { | 131 | switch (skb->protocol) { |
| 124 | case htons(ETH_P_IP): { | 132 | case htons(ETH_P_IP): { |
| 125 | struct iphdr *iph = ip_hdr(skb); | 133 | struct iphdr *iph; |
| 126 | 134 | ||
| 135 | if (!pskb_network_may_pull(skb, sizeof(*iph))) | ||
| 136 | break; | ||
| 137 | iph = ip_hdr(skb); | ||
| 127 | if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && | 138 | if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && |
| 128 | has_ports(iph->protocol)) | 139 | has_ports(iph->protocol) && |
| 129 | res = ntohs(*(__be16 *)((void *)iph + iph->ihl * 4)); | 140 | pskb_network_may_pull(skb, iph->ihl * 4 + 2)) |
| 141 | return ntohs(*(__be16 *)((void *)iph + iph->ihl * 4)); | ||
| 130 | break; | 142 | break; |
| 131 | } | 143 | } |
| 132 | case htons(ETH_P_IPV6): { | 144 | case htons(ETH_P_IPV6): { |
| 133 | struct ipv6hdr *iph = ipv6_hdr(skb); | 145 | struct ipv6hdr *iph; |
| 134 | 146 | ||
| 147 | if (!pskb_network_may_pull(skb, sizeof(*iph) + 2)) | ||
| 148 | break; | ||
| 149 | iph = ipv6_hdr(skb); | ||
| 135 | if (has_ports(iph->nexthdr)) | 150 | if (has_ports(iph->nexthdr)) |
| 136 | res = ntohs(*(__be16 *)&iph[1]); | 151 | return ntohs(*(__be16 *)&iph[1]); |
| 137 | break; | 152 | break; |
| 138 | } | 153 | } |
| 139 | default: | ||
| 140 | res = addr_fold(skb->sk); | ||
| 141 | } | 154 | } |
| 142 | 155 | ||
| 143 | return res; | 156 | return addr_fold(skb->sk); |
| 144 | } | 157 | } |
| 145 | 158 | ||
| 146 | static u32 flow_get_proto_dst(const struct sk_buff *skb) | 159 | static u32 flow_get_proto_dst(struct sk_buff *skb) |
| 147 | { | 160 | { |
| 148 | u32 res = 0; | ||
| 149 | |||
| 150 | switch (skb->protocol) { | 161 | switch (skb->protocol) { |
| 151 | case htons(ETH_P_IP): { | 162 | case htons(ETH_P_IP): { |
| 152 | struct iphdr *iph = ip_hdr(skb); | 163 | struct iphdr *iph; |
| 153 | 164 | ||
| 165 | if (!pskb_network_may_pull(skb, sizeof(*iph))) | ||
| 166 | break; | ||
| 167 | iph = ip_hdr(skb); | ||
| 154 | if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && | 168 | if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && |
| 155 | has_ports(iph->protocol)) | 169 | has_ports(iph->protocol) && |
| 156 | res = ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 + 2)); | 170 | pskb_network_may_pull(skb, iph->ihl * 4 + 4)) |
| 171 | return ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 + 2)); | ||
| 157 | break; | 172 | break; |
| 158 | } | 173 | } |
| 159 | case htons(ETH_P_IPV6): { | 174 | case htons(ETH_P_IPV6): { |
| 160 | struct ipv6hdr *iph = ipv6_hdr(skb); | 175 | struct ipv6hdr *iph; |
| 161 | 176 | ||
| 177 | if (!pskb_network_may_pull(skb, sizeof(*iph) + 4)) | ||
| 178 | break; | ||
| 179 | iph = ipv6_hdr(skb); | ||
| 162 | if (has_ports(iph->nexthdr)) | 180 | if (has_ports(iph->nexthdr)) |
| 163 | res = ntohs(*(__be16 *)((void *)&iph[1] + 2)); | 181 | return ntohs(*(__be16 *)((void *)&iph[1] + 2)); |
| 164 | break; | 182 | break; |
| 165 | } | 183 | } |
| 166 | default: | ||
| 167 | res = addr_fold(skb_dst(skb)) ^ (__force u16)skb->protocol; | ||
| 168 | } | 184 | } |
| 169 | 185 | ||
| 170 | return res; | 186 | return addr_fold(skb_dst(skb)) ^ (__force u16)skb->protocol; |
| 171 | } | 187 | } |
| 172 | 188 | ||
| 173 | static u32 flow_get_iif(const struct sk_buff *skb) | 189 | static u32 flow_get_iif(const struct sk_buff *skb) |
| @@ -211,7 +227,7 @@ static u32 flow_get_nfct(const struct sk_buff *skb) | |||
| 211 | }) | 227 | }) |
| 212 | #endif | 228 | #endif |
| 213 | 229 | ||
| 214 | static u32 flow_get_nfct_src(const struct sk_buff *skb) | 230 | static u32 flow_get_nfct_src(struct sk_buff *skb) |
| 215 | { | 231 | { |
| 216 | switch (skb->protocol) { | 232 | switch (skb->protocol) { |
| 217 | case htons(ETH_P_IP): | 233 | case htons(ETH_P_IP): |
| @@ -223,7 +239,7 @@ fallback: | |||
| 223 | return flow_get_src(skb); | 239 | return flow_get_src(skb); |
| 224 | } | 240 | } |
| 225 | 241 | ||
| 226 | static u32 flow_get_nfct_dst(const struct sk_buff *skb) | 242 | static u32 flow_get_nfct_dst(struct sk_buff *skb) |
| 227 | { | 243 | { |
| 228 | switch (skb->protocol) { | 244 | switch (skb->protocol) { |
| 229 | case htons(ETH_P_IP): | 245 | case htons(ETH_P_IP): |
| @@ -235,14 +251,14 @@ fallback: | |||
| 235 | return flow_get_dst(skb); | 251 | return flow_get_dst(skb); |
| 236 | } | 252 | } |
| 237 | 253 | ||
| 238 | static u32 flow_get_nfct_proto_src(const struct sk_buff *skb) | 254 | static u32 flow_get_nfct_proto_src(struct sk_buff *skb) |
| 239 | { | 255 | { |
| 240 | return ntohs(CTTUPLE(skb, src.u.all)); | 256 | return ntohs(CTTUPLE(skb, src.u.all)); |
| 241 | fallback: | 257 | fallback: |
| 242 | return flow_get_proto_src(skb); | 258 | return flow_get_proto_src(skb); |
| 243 | } | 259 | } |
| 244 | 260 | ||
| 245 | static u32 flow_get_nfct_proto_dst(const struct sk_buff *skb) | 261 | static u32 flow_get_nfct_proto_dst(struct sk_buff *skb) |
| 246 | { | 262 | { |
| 247 | return ntohs(CTTUPLE(skb, dst.u.all)); | 263 | return ntohs(CTTUPLE(skb, dst.u.all)); |
| 248 | fallback: | 264 | fallback: |
| @@ -281,7 +297,7 @@ static u32 flow_get_vlan_tag(const struct sk_buff *skb) | |||
| 281 | return tag & VLAN_VID_MASK; | 297 | return tag & VLAN_VID_MASK; |
| 282 | } | 298 | } |
| 283 | 299 | ||
| 284 | static u32 flow_key_get(const struct sk_buff *skb, int key) | 300 | static u32 flow_key_get(struct sk_buff *skb, int key) |
| 285 | { | 301 | { |
| 286 | switch (key) { | 302 | switch (key) { |
| 287 | case FLOW_KEY_SRC: | 303 | case FLOW_KEY_SRC: |
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index dd9414e44200..425a1790b048 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h | |||
| @@ -143,9 +143,17 @@ static int rsvp_classify(struct sk_buff *skb, struct tcf_proto *tp, | |||
| 143 | u8 tunnelid = 0; | 143 | u8 tunnelid = 0; |
| 144 | u8 *xprt; | 144 | u8 *xprt; |
| 145 | #if RSVP_DST_LEN == 4 | 145 | #if RSVP_DST_LEN == 4 |
| 146 | struct ipv6hdr *nhptr = ipv6_hdr(skb); | 146 | struct ipv6hdr *nhptr; |
| 147 | |||
| 148 | if (!pskb_network_may_pull(skb, sizeof(*nhptr))) | ||
| 149 | return -1; | ||
| 150 | nhptr = ipv6_hdr(skb); | ||
| 147 | #else | 151 | #else |
| 148 | struct iphdr *nhptr = ip_hdr(skb); | 152 | struct iphdr *nhptr; |
| 153 | |||
| 154 | if (!pskb_network_may_pull(skb, sizeof(*nhptr))) | ||
| 155 | return -1; | ||
| 156 | nhptr = ip_hdr(skb); | ||
| 149 | #endif | 157 | #endif |
| 150 | 158 | ||
| 151 | restart: | 159 | restart: |
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index c65762823f5e..534f33231c17 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c | |||
| @@ -122,7 +122,11 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb) | |||
| 122 | switch (skb->protocol) { | 122 | switch (skb->protocol) { |
| 123 | case htons(ETH_P_IP): | 123 | case htons(ETH_P_IP): |
| 124 | { | 124 | { |
| 125 | const struct iphdr *iph = ip_hdr(skb); | 125 | const struct iphdr *iph; |
| 126 | |||
| 127 | if (!pskb_network_may_pull(skb, sizeof(*iph))) | ||
| 128 | goto err; | ||
| 129 | iph = ip_hdr(skb); | ||
| 126 | h = (__force u32)iph->daddr; | 130 | h = (__force u32)iph->daddr; |
| 127 | h2 = (__force u32)iph->saddr ^ iph->protocol; | 131 | h2 = (__force u32)iph->saddr ^ iph->protocol; |
| 128 | if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && | 132 | if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && |
| @@ -131,25 +135,32 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb) | |||
| 131 | iph->protocol == IPPROTO_UDPLITE || | 135 | iph->protocol == IPPROTO_UDPLITE || |
| 132 | iph->protocol == IPPROTO_SCTP || | 136 | iph->protocol == IPPROTO_SCTP || |
| 133 | iph->protocol == IPPROTO_DCCP || | 137 | iph->protocol == IPPROTO_DCCP || |
| 134 | iph->protocol == IPPROTO_ESP)) | 138 | iph->protocol == IPPROTO_ESP) && |
| 139 | pskb_network_may_pull(skb, iph->ihl * 4 + 4)) | ||
| 135 | h2 ^= *(((u32*)iph) + iph->ihl); | 140 | h2 ^= *(((u32*)iph) + iph->ihl); |
| 136 | break; | 141 | break; |
| 137 | } | 142 | } |
| 138 | case htons(ETH_P_IPV6): | 143 | case htons(ETH_P_IPV6): |
| 139 | { | 144 | { |
| 140 | struct ipv6hdr *iph = ipv6_hdr(skb); | 145 | struct ipv6hdr *iph; |
| 146 | |||
| 147 | if (!pskb_network_may_pull(skb, sizeof(*iph))) | ||
| 148 | goto err; | ||
| 149 | iph = ipv6_hdr(skb); | ||
| 141 | h = (__force u32)iph->daddr.s6_addr32[3]; | 150 | h = (__force u32)iph->daddr.s6_addr32[3]; |
| 142 | h2 = (__force u32)iph->saddr.s6_addr32[3] ^ iph->nexthdr; | 151 | h2 = (__force u32)iph->saddr.s6_addr32[3] ^ iph->nexthdr; |
| 143 | if (iph->nexthdr == IPPROTO_TCP || | 152 | if ((iph->nexthdr == IPPROTO_TCP || |
| 144 | iph->nexthdr == IPPROTO_UDP || | 153 | iph->nexthdr == IPPROTO_UDP || |
| 145 | iph->nexthdr == IPPROTO_UDPLITE || | 154 | iph->nexthdr == IPPROTO_UDPLITE || |
| 146 | iph->nexthdr == IPPROTO_SCTP || | 155 | iph->nexthdr == IPPROTO_SCTP || |
| 147 | iph->nexthdr == IPPROTO_DCCP || | 156 | iph->nexthdr == IPPROTO_DCCP || |
| 148 | iph->nexthdr == IPPROTO_ESP) | 157 | iph->nexthdr == IPPROTO_ESP) && |
| 158 | pskb_network_may_pull(skb, sizeof(*iph) + 4)) | ||
| 149 | h2 ^= *(u32*)&iph[1]; | 159 | h2 ^= *(u32*)&iph[1]; |
| 150 | break; | 160 | break; |
| 151 | } | 161 | } |
| 152 | default: | 162 | default: |
| 163 | err: | ||
| 153 | h = (unsigned long)skb_dst(skb) ^ (__force u32)skb->protocol; | 164 | h = (unsigned long)skb_dst(skb) ^ (__force u32)skb->protocol; |
| 154 | h2 = (unsigned long)skb->sk; | 165 | h2 = (unsigned long)skb->sk; |
| 155 | } | 166 | } |
| @@ -502,6 +513,12 @@ static unsigned long sfq_get(struct Qdisc *sch, u32 classid) | |||
| 502 | return 0; | 513 | return 0; |
| 503 | } | 514 | } |
| 504 | 515 | ||
| 516 | static unsigned long sfq_bind(struct Qdisc *sch, unsigned long parent, | ||
| 517 | u32 classid) | ||
| 518 | { | ||
| 519 | return 0; | ||
| 520 | } | ||
| 521 | |||
| 505 | static struct tcf_proto **sfq_find_tcf(struct Qdisc *sch, unsigned long cl) | 522 | static struct tcf_proto **sfq_find_tcf(struct Qdisc *sch, unsigned long cl) |
| 506 | { | 523 | { |
| 507 | struct sfq_sched_data *q = qdisc_priv(sch); | 524 | struct sfq_sched_data *q = qdisc_priv(sch); |
| @@ -556,6 +573,7 @@ static void sfq_walk(struct Qdisc *sch, struct qdisc_walker *arg) | |||
| 556 | static const struct Qdisc_class_ops sfq_class_ops = { | 573 | static const struct Qdisc_class_ops sfq_class_ops = { |
| 557 | .get = sfq_get, | 574 | .get = sfq_get, |
| 558 | .tcf_chain = sfq_find_tcf, | 575 | .tcf_chain = sfq_find_tcf, |
| 576 | .bind_tcf = sfq_bind, | ||
| 559 | .dump = sfq_dump_class, | 577 | .dump = sfq_dump_class, |
| 560 | .dump_stats = sfq_dump_class_stats, | 578 | .dump_stats = sfq_dump_class_stats, |
| 561 | .walk = sfq_walk, | 579 | .walk = sfq_walk, |
